@@ -602,7 +602,7 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
602602 byEmailNoOrg : Map < string , number > ;
603603 byAccountIdOrgScoped : Map < string , number [ ] > ;
604604 byRefreshTokenOrgScoped : Map < string , number [ ] > ;
605- byRefreshTokenGlobal : Map < string , number > ;
605+ byRefreshTokenGlobal : Map < string , number [ ] > ;
606606 } ;
607607
608608 const resolveUniqueOrgScopedMatch = (
@@ -629,7 +629,7 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
629629 const byEmailNoOrg = new Map < string , number > ( ) ;
630630 const byAccountIdOrgScoped = new Map < string , number [ ] > ( ) ;
631631 const byRefreshTokenOrgScoped = new Map < string , number [ ] > ( ) ;
632- const byRefreshTokenGlobal = new Map < string , number > ( ) ;
632+ const byRefreshTokenGlobal = new Map < string , number [ ] > ( ) ;
633633
634634 for ( let i = 0 ; i < accounts . length ; i += 1 ) {
635635 const account = accounts [ i ] ;
@@ -640,9 +640,10 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
640640 const refreshToken = account . refreshToken ?. trim ( ) ;
641641 const email = account . email ?. trim ( ) ;
642642
643- // Global refresh token index: first entry wins (keeps earliest/primary).
644- if ( refreshToken && ! byRefreshTokenGlobal . has ( refreshToken ) ) {
645- byRefreshTokenGlobal . set ( refreshToken , i ) ;
643+ // Track all refresh-token matches. Callers can require uniqueness
644+ // so org variants that share a token do not collapse accidentally.
645+ if ( refreshToken ) {
646+ pushIndex ( byRefreshTokenGlobal , refreshToken , i ) ;
646647 }
647648
648649 if ( organizationId ) {
@@ -722,9 +723,9 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
722723 ) ;
723724 if ( orgScoped !== undefined ) return orgScoped ;
724725
725- // Absolute last resort: same refresh token = same human account.
726- // Catches org-scoped entries invisible to no- org lookups .
727- return identityIndexes . byRefreshTokenGlobal . get ( result . refresh ) ;
726+ // Absolute last resort: only collapse when refresh token maps to a
727+ // single account. Avoids merging distinct org-scoped variants .
728+ return asUniqueIndex ( identityIndexes . byRefreshTokenGlobal . get ( result . refresh ) ) ;
728729 } ) ( ) ;
729730
730731 if ( existingIndex === undefined ) {
@@ -821,28 +822,10 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
821822 entry . fallbackIndex = i ;
822823 }
823824
824- for ( const entry of refreshMap . values ( ) ) {
825- const fallbackIndex = entry . fallbackIndex ;
826- if ( typeof fallbackIndex !== "number" ) continue ;
827- const orgIndices = Array . from ( entry . byOrg . values ( ) ) ;
828- if ( orgIndices . length === 0 ) continue ;
829-
830- const [ firstOrgIndex , ...otherOrgIndices ] = orgIndices ;
831- if ( typeof firstOrgIndex !== "number" ) continue ;
832-
833- let preferredOrgIndex = firstOrgIndex ;
834- for ( const orgIndex of otherOrgIndices ) {
835- preferredOrgIndex = pickNewestAccountIndex ( preferredOrgIndex , orgIndex ) ;
836- }
837-
838- mergeAccountRecords ( preferredOrgIndex , fallbackIndex ) ;
839- indicesToRemove . add ( fallbackIndex ) ;
840- }
841-
842- if ( indicesToRemove . size > 0 ) {
843- accounts = accounts . filter ( ( _ , index ) => ! indicesToRemove . has ( index ) ) ;
844- }
845- } ;
825+ if ( indicesToRemove . size > 0 ) {
826+ accounts = accounts . filter ( ( _ , index ) => ! indicesToRemove . has ( index ) ) ;
827+ }
828+ } ;
846829
847830 const collectIdentityKeys = (
848831 account : { organizationId ?: string ; accountId ?: string ; refreshToken ?: string } | undefined ,
0 commit comments