@@ -110,6 +110,97 @@ describe("promoteAuthProfileInOrder", () => {
110110 }
111111 } ) ;
112112
113+ it ( "rewrites existing inline openai-codex oauth secrets during runtime load" , ( ) => {
114+ const stateDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "openclaw-auth-profile-rewrite-" ) ) ;
115+ const agentDir = path . join ( stateDir , "agents" , "main" , "agent" ) ;
116+ const previousStateDir = process . env . OPENCLAW_STATE_DIR ;
117+ process . env . OPENCLAW_STATE_DIR = stateDir ;
118+ try {
119+ fs . mkdirSync ( agentDir , { recursive : true } ) ;
120+ const profileId = "openai-codex:default" ;
121+ const expires = Date . now ( ) + 60 * 60 * 1000 ;
122+ fs . writeFileSync (
123+ resolveAuthStorePath ( agentDir ) ,
124+ `${ JSON . stringify (
125+ {
126+ version : AUTH_STORE_VERSION ,
127+ profiles : {
128+ [ profileId ] : {
129+ type : "oauth" ,
130+ provider : "openai-codex" ,
131+ access : "existing-access-token" ,
132+ refresh : "existing-refresh-token" ,
133+ idToken : "existing-id-token" ,
134+ expires,
135+ accountId : "acct-existing" ,
136+ } ,
137+ } ,
138+ order : {
139+ "openai-codex" : [ profileId ] ,
140+ } ,
141+ } ,
142+ null ,
143+ 2 ,
144+ ) } \n`,
145+ ) ;
146+
147+ expect (
148+ loadAuthProfileStoreForRuntime ( agentDir , { externalCli : { mode : "none" } } ) . profiles [
149+ profileId
150+ ] ,
151+ ) . toMatchObject ( {
152+ type : "oauth" ,
153+ provider : "openai-codex" ,
154+ access : "existing-access-token" ,
155+ refresh : "existing-refresh-token" ,
156+ idToken : "existing-id-token" ,
157+ } ) ;
158+
159+ const persisted = JSON . parse ( fs . readFileSync ( resolveAuthStorePath ( agentDir ) , "utf8" ) ) as {
160+ profiles : Record < string , Record < string , unknown > > ;
161+ order ?: Record < string , string [ ] > ;
162+ } ;
163+ const credential = persisted . profiles [ profileId ] ;
164+ expect ( credential ) . toMatchObject ( {
165+ type : "oauth" ,
166+ provider : "openai-codex" ,
167+ expires,
168+ accountId : "acct-existing" ,
169+ oauthRef : {
170+ source : "openclaw-credentials" ,
171+ provider : "openai-codex" ,
172+ id : expect . any ( String ) ,
173+ } ,
174+ } ) ;
175+ expect ( persisted . order ?. [ "openai-codex" ] ) . toEqual ( [ profileId ] ) ;
176+ expect ( credential ) . not . toHaveProperty ( "access" ) ;
177+ expect ( credential ) . not . toHaveProperty ( "refresh" ) ;
178+ expect ( credential ) . not . toHaveProperty ( "idToken" ) ;
179+ const persistedAgentTree = readPersistedAgentTree ( agentDir ) ;
180+ expect ( persistedAgentTree ) . not . toContain ( "existing-access-token" ) ;
181+ expect ( persistedAgentTree ) . not . toContain ( "existing-refresh-token" ) ;
182+ expect ( persistedAgentTree ) . not . toContain ( "existing-id-token" ) ;
183+
184+ clearRuntimeAuthProfileStoreSnapshots ( ) ;
185+ expect (
186+ loadAuthProfileStoreWithoutExternalProfiles ( agentDir ) . profiles [ profileId ] ,
187+ ) . toMatchObject ( {
188+ type : "oauth" ,
189+ provider : "openai-codex" ,
190+ access : "existing-access-token" ,
191+ refresh : "existing-refresh-token" ,
192+ idToken : "existing-id-token" ,
193+ } ) ;
194+ } finally {
195+ if ( previousStateDir === undefined ) {
196+ delete process . env . OPENCLAW_STATE_DIR ;
197+ } else {
198+ process . env . OPENCLAW_STATE_DIR = previousStateDir ;
199+ }
200+ fs . rmSync ( stateDir , { recursive : true , force : true } ) ;
201+ }
202+ } ) ;
203+
113204 it ( "moves a relogin profile to the front of an existing per-agent provider order" , async ( ) => {
114205 const stateDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "openclaw-auth-order-promote-" ) ) ;
115206 const agentDir = path . join ( stateDir , "agents" , "main" , "agent" ) ;
0 commit comments