credential broker: Play tokens from POST /api/google/token (cached, single flight, local key fallback), grants and APIs per package in validate, Play write preflight, apps check and the desktop Accounts view; Google 403 names the API or grant, no retry
This commit is contained in:
parent
304407e523
commit
2c5e30090f
27 changed files with 1145 additions and 43 deletions
|
|
@ -9,6 +9,7 @@ import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, renameSyn
|
|||
import { homedir } from 'node:os';
|
||||
import { isAbsolute, join, resolve } from 'node:path';
|
||||
import { maskUser, PROFILE_KEYS, PROFILE_RE, profileDir, profileEnv, profileNames } from './credentials';
|
||||
import { brokerConfig, profileBrokerOff } from './broker';
|
||||
|
||||
export type Kind = 'apple' | 'play';
|
||||
/** The store keys that move to a profile (one developer account's), never the app's own ones. */
|
||||
|
|
@ -36,12 +37,19 @@ export function profileIdentity(name: string): Identity {
|
|||
}
|
||||
|
||||
/** One line per profile for `storebound accounts`: stores, masked Play e-mail. No key ids, no values. */
|
||||
export function describeProfiles(): { profile: string; apple: boolean; play: boolean; playAccount: string | null; vendor: boolean; playDeveloperId?: string | null; error?: string }[] {
|
||||
export function describeProfiles(): { profile: string; apple: boolean; play: boolean; playAccount: string | null; vendor: boolean; playDeveloperId?: string | null;
|
||||
/** Where Play tokens come from: the credential broker (~/.storebound/broker.json), the profile's key file, or none. */
|
||||
playSource: 'broker' | 'file' | null; error?: string }[] {
|
||||
let broker = false;
|
||||
try { broker = !!brokerConfig(); } catch { /* a broken broker.json: doctor reports it */ }
|
||||
return profileNames().map(profile => {
|
||||
try {
|
||||
const id = profileIdentity(profile);
|
||||
return { profile, apple: !!id.appleKeyId, play: !!id.playEmail, playAccount: id.playEmail ? maskUser(id.playEmail) : null, vendor: id.vendor, playDeveloperId: id.playDeveloperId };
|
||||
} catch (e) { return { profile, apple: false, play: false, playAccount: null, vendor: false, error: (e as Error).message }; }
|
||||
const email = id.playEmail ?? profileEnv(profile).PLAY_SERVICE_ACCOUNT_EMAIL ?? null;
|
||||
const viaBroker = broker && !profileBrokerOff(profile) && !!email;
|
||||
const playSource = viaBroker ? 'broker' as const : id.playEmail ? 'file' as const : null;
|
||||
return { profile, apple: !!id.appleKeyId, play: !!playSource, playAccount: email && playSource ? maskUser(email) : null, vendor: id.vendor, playDeveloperId: id.playDeveloperId, playSource };
|
||||
} catch (e) { return { profile, apple: false, play: false, playAccount: null, vendor: false, playSource: null, error: (e as Error).message }; }
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue