Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
import {
readCodexCliCredentialsCached,
readMiniMaxCliCredentialsCached,
} from "../cli-credentials.js";
import {
EXTERNAL_CLI_SYNC_TTL_MS,
MINIMAX_CLI_PROFILE_ID,
OPENAI_CODEX_DEFAULT_PROFILE_ID,
} from "./constants.js";
import { log } from "./constants.js";
import {
areOAuthCredentialsEquivalent,
hasUsableOAuthCredential,
isSafeToAdoptBootstrapOAuthIdentity,
isSafeToOverwriteStoredOAuthIdentity,
shouldBootstrapFromExternalCliCredential,
shouldReplaceStoredOAuthCredential,
} from "./oauth-shared.js";
import type { AuthProfileStore, OAuthCredential } from "./types.js";
export {
areOAuthCredentialsEquivalent,
hasUsableOAuthCredential,
isSafeToAdoptBootstrapOAuthIdentity,
isSafeToOverwriteStoredOAuthIdentity,
shouldBootstrapFromExternalCliCredential,
shouldReplaceStoredOAuthCredential,
} from "./oauth-shared.js";
export type ExternalCliResolvedProfile = {
profileId: string;
credential: OAuthCredential;
};
type ExternalCliSyncProvider = {
profileId: string;
provider: string;
readCredentials: () => OAuthCredential | null;
// bootstrapOnly providers adopt the external CLI credential only to
// seed an empty slot; once a local OAuth credential exists for the
// profile, the local refresh token is treated as canonical and the
// CLI state must not replace or shadow it. Codex requires this to
// avoid clobbering a locally refreshed token with stale CLI state.
bootstrapOnly?: boolean;
};
function normalizeAuthIdentityToken(value: string | undefined): string | undefined {
const trimmed = value?.trim();
return trimmed ? trimmed : undefined;
}
function normalizeAuthEmailToken(value: string | undefined): string | undefined {
return normalizeAuthIdentityToken(value)?.toLowerCase();
}
// Keep this gate aligned with the canonical identity-copy rule in oauth.ts.
export function isSafeToUseExternalCliCredential(
existing: OAuthCredential | undefined,
imported: OAuthCredential,
): boolean {
if (!existing) {
return true;
}
if (existing.provider !== imported.provider) {
return false;
}
const existingAccountId = normalizeAuthIdentityToken(existing.accountId);
const importedAccountId = normalizeAuthIdentityToken(imported.accountId);
const existingEmail = normalizeAuthEmailToken(existing.email);
const importedEmail = normalizeAuthEmailToken(imported.email);
if (existingAccountId !== undefined && importedAccountId !== undefined) {
return existingAccountId === importedAccountId;
}
if (existingEmail !== undefined && importedEmail !== undefined) {
return existingEmail === importedEmail;
}
const existingHasIdentity = existingAccountId !== undefined || existingEmail !== undefined;
if (existingHasIdentity) {
return false;
}
return true;
}
const EXTERNAL_CLI_SYNC_PROVIDERS: ExternalCliSyncProvider[] = [
{
profileId: OPENAI_CODEX_DEFAULT_PROFILE_ID,
provider: "openai-codex",
readCredentials: () => readCodexCliCredentialsCached({ ttlMs: EXTERNAL_CLI_SYNC_TTL_MS }),
bootstrapOnly: true,
},
{
profileId: MINIMAX_CLI_PROFILE_ID,
provider: "minimax-portal",
readCredentials: () => readMiniMaxCliCredentialsCached({ ttlMs: EXTERNAL_CLI_SYNC_TTL_MS }),
},
];
function resolveExternalCliSyncProvider(params: {
profileId: string;
credential?: OAuthCredential;
}): ExternalCliSyncProvider | null {
const provider = EXTERNAL_CLI_SYNC_PROVIDERS.find(
(entry) => entry.profileId === params.profileId,
);
if (!provider) {
return null;
}
if (params.credential && provider.provider !== params.credential.provider) {
return null;
}
return provider;
}
export function readExternalCliBootstrapCredential(params: {
profileId: string;
credential: OAuthCredential;
}): OAuthCredential | null {
const provider = resolveExternalCliSyncProvider(params);
if (!provider) {
return null;
}
// bootstrapOnly providers must not replace an existing local credential
// during runtime refresh. The oauth-manager only calls this hook when a
// local credential is already present, so returning null here keeps the
// locally stored refresh token canonical.
if (provider.bootstrapOnly) {
return null;
}
return provider.readCredentials();
}
export const readManagedExternalCliCredential = readExternalCliBootstrapCredential;
export function resolveExternalCliAuthProfiles(
store: AuthProfileStore,
): ExternalCliResolvedProfile[] {
const profiles: ExternalCliResolvedProfile[] = [];
const now = Date.now();
for (const providerConfig of EXTERNAL_CLI_SYNC_PROVIDERS) {
const creds = providerConfig.readCredentials();
if (!creds) {
continue;
}
const existing = store.profiles[providerConfig.profileId];
const existingOAuth =
existing?.type === "oauth" && existing.provider === providerConfig.provider
? existing
: undefined;
if (existing && !existingOAuth) {
log.debug("kept explicit local auth over external cli bootstrap", {
profileId: providerConfig.profileId,
provider: providerConfig.provider,
localType: existing.type,
localProvider: existing.provider,
});
continue;
}
if (providerConfig.bootstrapOnly && existingOAuth) {
log.debug("kept local oauth over external cli bootstrap-only provider", {
profileId: providerConfig.profileId,
provider: providerConfig.provider,
});
continue;
}
if (existingOAuth && !isSafeToUseExternalCliCredential(existingOAuth, creds)) {
log.warn("refused external cli oauth bootstrap: identity mismatch", {
profileId: providerConfig.profileId,
provider: providerConfig.provider,
});
continue;
}
if (
existingOAuth &&
!isSafeToAdoptBootstrapOAuthIdentity(existingOAuth, creds) &&
!areOAuthCredentialsEquivalent(existingOAuth, creds)
) {
log.warn("refused external cli oauth bootstrap: identity mismatch or missing binding", {
profileId: providerConfig.profileId,
provider: providerConfig.provider,
});
continue;
}
if (
!shouldBootstrapFromExternalCliCredential({
existing: existingOAuth,
imported: creds,
now,
})
) {
if (existingOAuth) {
log.debug("kept usable local oauth over external cli bootstrap", {
profileId: providerConfig.profileId,
provider: providerConfig.provider,
localExpires: existingOAuth.expires,
externalExpires: creds.expires,
});
}
continue;
}
log.debug("used external cli oauth bootstrap because local oauth was missing or unusable", {
profileId: providerConfig.profileId,
provider: providerConfig.provider,
localExpires: existingOAuth?.expires,
externalExpires: creds.expires,
});
profiles.push({
profileId: providerConfig.profileId,
credential: creds,
});
}
return profiles;
}
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-04-27)
¤
*© Formatika GbR, Deutschland
|
|