@@ -755,7 +755,66 @@ describe("Token Utils Module", () => {
755755 } ) ;
756756 } ) ;
757757
758+ it ( "follows token identities when the binding is id_token-derived" , ( ) => {
759+ mockedDecodeJWT . mockImplementation ( ( token ?: string ) => {
760+ if ( token === "access-token" ) {
761+ return {
762+ [ JWT_CLAIM_PATH ] : {
763+ chatgpt_account_id : "acc_id_token" ,
764+ } ,
765+ } ;
766+ }
767+ if ( token === "id-token" ) {
768+ return {
769+ email : "id-token@example.com" ,
770+ } ;
771+ }
772+ return null ;
773+ } ) ;
774+
775+ expect (
776+ resolveRuntimeRequestIdentity ( {
777+ storedAccountId : "workspace-alpha" ,
778+ source : "id_token" ,
779+ storedEmail : "stored@example.com" ,
780+ accessToken : "access-token" ,
781+ idToken : "id-token" ,
782+ } ) ,
783+ ) . toEqual ( {
784+ accountId : "acc_id_token" ,
785+ email : "id-token@example.com" ,
786+ tokenAccountId : "acc_id_token" ,
787+ } ) ;
788+ } ) ;
789+
790+ it ( "falls back to the token accountId when token-derived routing has no stored accountId" , ( ) => {
791+ mockedDecodeJWT . mockImplementation ( ( token ?: string ) => {
792+ if ( token === "access-token" ) {
793+ return {
794+ [ JWT_CLAIM_PATH ] : {
795+ chatgpt_account_id : "acc_live" ,
796+ email : "live@example.com" ,
797+ } ,
798+ } ;
799+ }
800+ return null ;
801+ } ) ;
802+
803+ expect (
804+ resolveRuntimeRequestIdentity ( {
805+ source : "token" ,
806+ storedEmail : "stored@example.com" ,
807+ accessToken : "access-token" ,
808+ } ) ,
809+ ) . toEqual ( {
810+ accountId : "acc_live" ,
811+ email : "live@example.com" ,
812+ tokenAccountId : "acc_live" ,
813+ } ) ;
814+ } ) ;
815+
758816 it ( "falls back to sanitized stored email when the live token has none" , ( ) => {
817+ mockedDecodeJWT . mockReturnValue ( null ) ;
759818 expect (
760819 resolveRuntimeRequestIdentity ( {
761820 storedAccountId : "workspace-alpha" ,
0 commit comments