@@ -21,6 +21,7 @@ import {
2121 resolveRequestAccountId ,
2222 sanitizeEmail ,
2323 selectBestAccountCandidate ,
24+ shouldUpdateAccountIdFromToken ,
2425} from "./accounts.js" ;
2526import { ACCOUNT_LIMITS } from "./constants.js" ;
2627import {
@@ -905,6 +906,55 @@ function resolveAccountSelection(tokens: TokenSuccess): TokenSuccessWithAccount
905906 } ;
906907}
907908
909+ function resolveStoredAccountIdentity (
910+ storedAccountId : string | undefined ,
911+ storedAccountIdSource : AccountIdSource | undefined ,
912+ tokenAccountId : string | undefined ,
913+ ) : { accountId ?: string ; accountIdSource ?: AccountIdSource } {
914+ const accountId = resolveRequestAccountId (
915+ storedAccountId ,
916+ storedAccountIdSource ,
917+ tokenAccountId ,
918+ ) ;
919+ if ( ! accountId ) {
920+ return { } ;
921+ }
922+
923+ if ( ! shouldUpdateAccountIdFromToken ( storedAccountIdSource , storedAccountId ) ) {
924+ return {
925+ accountId,
926+ accountIdSource : storedAccountIdSource ,
927+ } ;
928+ }
929+
930+ return {
931+ accountId,
932+ accountIdSource : accountId === tokenAccountId ? "token" : storedAccountIdSource ,
933+ } ;
934+ }
935+
936+ function applyTokenAccountIdentity (
937+ account : { accountId ?: string ; accountIdSource ?: AccountIdSource } ,
938+ tokenAccountId : string | undefined ,
939+ ) : boolean {
940+ const nextIdentity = resolveStoredAccountIdentity (
941+ account . accountId ,
942+ account . accountIdSource ,
943+ tokenAccountId ,
944+ ) ;
945+ if ( ! nextIdentity . accountId ) {
946+ return false ;
947+ }
948+ if ( nextIdentity . accountId === account . accountId
949+ && nextIdentity . accountIdSource === account . accountIdSource ) {
950+ return false ;
951+ }
952+
953+ account . accountId = nextIdentity . accountId ;
954+ account . accountIdSource = nextIdentity . accountIdSource ;
955+ return true ;
956+ }
957+
908958async function promptManualCallback ( state : string ) : Promise < string | null > {
909959 if ( ! input . isTTY || ! output . isTTY ) {
910960 return null ;
@@ -1567,9 +1617,7 @@ async function runHealthCheck(options: HealthCheckOptions = {}): Promise<void> {
15671617 account . email = nextEmail ;
15681618 changed = true ;
15691619 }
1570- if ( tokenAccountId && tokenAccountId !== account . accountId ) {
1571- account . accountId = tokenAccountId ;
1572- account . accountIdSource = "token" ;
1620+ if ( applyTokenAccountIdentity ( account , tokenAccountId ) ) {
15731621 changed = true ;
15741622 }
15751623 if ( account . enabled === false ) {
@@ -2466,7 +2514,9 @@ function upsertRecoveredFlaggedAccount(
24662514 now : number ,
24672515) : { restored : boolean ; changed : boolean ; message : string } {
24682516 const nextEmail = sanitizeEmail ( extractAccountEmail ( refreshResult . access , refreshResult . idToken ) ) ?? flagged . email ;
2469- const nextAccountId = extractAccountId ( refreshResult . access ) ?? flagged . accountId ;
2517+ const tokenAccountId = extractAccountId ( refreshResult . access ) ;
2518+ const { accountId : nextAccountId , accountIdSource : nextAccountIdSource } =
2519+ resolveStoredAccountIdentity ( flagged . accountId , flagged . accountIdSource , tokenAccountId ) ;
24702520 const existingIndex = findExistingAccountIndexForFlagged (
24712521 storage ,
24722522 flagged ,
@@ -2497,9 +2547,15 @@ function upsertRecoveredFlaggedAccount(
24972547 existing . email = nextEmail ;
24982548 changed = true ;
24992549 }
2500- if ( nextAccountId && nextAccountId !== existing . accountId ) {
2550+ if (
2551+ nextAccountId !== undefined &&
2552+ (
2553+ ( nextAccountId !== existing . accountId )
2554+ || ( nextAccountIdSource !== existing . accountIdSource )
2555+ )
2556+ ) {
25012557 existing . accountId = nextAccountId ;
2502- existing . accountIdSource = "token" ;
2558+ existing . accountIdSource = nextAccountIdSource ;
25032559 changed = true ;
25042560 }
25052561 if ( existing . enabled === false ) {
@@ -2531,7 +2587,7 @@ function upsertRecoveredFlaggedAccount(
25312587 accessToken : refreshResult . access ,
25322588 expiresAt : refreshResult . expires ,
25332589 accountId : nextAccountId ,
2534- accountIdSource : nextAccountId ? "token" : flagged . accountIdSource ,
2590+ accountIdSource : nextAccountIdSource ,
25352591 accountLabel : flagged . accountLabel ,
25362592 email : nextEmail ,
25372593 addedAt : flagged . addedAt ?? now ,
@@ -2617,13 +2673,19 @@ async function runVerifyFlagged(args: string[]): Promise<number> {
26172673 const { index : i , flagged, label, result } = check ;
26182674 if ( result . type === "success" ) {
26192675 if ( ! options . restore ) {
2676+ const tokenAccountId = extractAccountId ( result . access ) ;
2677+ const nextIdentity = resolveStoredAccountIdentity (
2678+ flagged . accountId ,
2679+ flagged . accountIdSource ,
2680+ tokenAccountId ,
2681+ ) ;
26202682 const nextFlagged : FlaggedAccountMetadataV1 = {
26212683 ...flagged ,
26222684 refreshToken : result . refresh ,
26232685 accessToken : result . access ,
26242686 expiresAt : result . expires ,
2625- accountId : extractAccountId ( result . access ) ?? flagged . accountId ,
2626- accountIdSource : extractAccountId ( result . access ) ? "token" : flagged . accountIdSource ,
2687+ accountId : nextIdentity . accountId ,
2688+ accountIdSource : nextIdentity . accountIdSource ,
26272689 email : sanitizeEmail ( extractAccountEmail ( result . access , result . idToken ) ) ?? flagged . email ,
26282690 lastUsed : now ,
26292691 lastError : undefined ,
@@ -2654,13 +2716,19 @@ async function runVerifyFlagged(args: string[]): Promise<number> {
26542716 continue ;
26552717 }
26562718
2719+ const tokenAccountId = extractAccountId ( result . access ) ;
2720+ const nextIdentity = resolveStoredAccountIdentity (
2721+ flagged . accountId ,
2722+ flagged . accountIdSource ,
2723+ tokenAccountId ,
2724+ ) ;
26572725 const updatedFlagged : FlaggedAccountMetadataV1 = {
26582726 ...flagged ,
26592727 refreshToken : result . refresh ,
26602728 accessToken : result . access ,
26612729 expiresAt : result . expires ,
2662- accountId : extractAccountId ( result . access ) ?? flagged . accountId ,
2663- accountIdSource : extractAccountId ( result . access ) ? "token" : flagged . accountIdSource ,
2730+ accountId : nextIdentity . accountId ,
2731+ accountIdSource : nextIdentity . accountIdSource ,
26642732 email : sanitizeEmail ( extractAccountEmail ( result . access , result . idToken ) ) ?? flagged . email ,
26652733 lastUsed : now ,
26662734 lastError : upsertResult . message ,
@@ -3613,10 +3681,7 @@ async function runDoctor(args: string[]): Promise<number> {
36133681 activeAccount . refreshToken = refreshResult . refresh ;
36143682 activeAccount . expiresAt = refreshResult . expires ;
36153683 if ( refreshedEmail ) activeAccount . email = refreshedEmail ;
3616- if ( refreshedAccountId ) {
3617- activeAccount . accountId = refreshedAccountId ;
3618- activeAccount . accountIdSource = "token" ;
3619- }
3684+ applyTokenAccountIdentity ( activeAccount , refreshedAccountId ) ;
36203685 syncAccessToken = refreshResult . access ;
36213686 syncRefreshToken = refreshResult . refresh ;
36223687 syncExpiresAt = refreshResult . expires ;
@@ -4007,10 +4072,7 @@ async function runSwitch(args: string[]): Promise<number> {
40074072 if ( nextEmail && nextEmail !== account . email ) {
40084073 account . email = nextEmail ;
40094074 }
4010- if ( tokenAccountId && tokenAccountId !== account . accountId ) {
4011- account . accountId = tokenAccountId ;
4012- account . accountIdSource = "token" ;
4013- }
4075+ applyTokenAccountIdentity ( account , tokenAccountId ) ;
40144076 syncAccessToken = refreshResult . access ;
40154077 syncRefreshToken = refreshResult . refresh ;
40164078 syncExpiresAt = refreshResult . expires ;
@@ -4091,9 +4153,7 @@ export async function autoSyncActiveAccountToCodex(): Promise<boolean> {
40914153 account . email = nextEmail ;
40924154 changed = true ;
40934155 }
4094- if ( tokenAccountId && tokenAccountId !== account . accountId ) {
4095- account . accountId = tokenAccountId ;
4096- account . accountIdSource = "token" ;
4156+ if ( applyTokenAccountIdentity ( account , tokenAccountId ) ) {
40974157 changed = true ;
40984158 }
40994159 syncAccessToken = refreshResult . access ;
0 commit comments