From 6cd74b200bf2eac8013ba0c8c1beed97d456bf48 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Wed, 3 Jun 2026 12:11:30 +0530 Subject: [PATCH] Add separate account session login route --- .../schema/json/ClientRequest.json | 24 ++++++++ .../codex_app_server_protocol.schemas.json | 24 ++++++++ .../codex_app_server_protocol.v2.schemas.json | 24 ++++++++ .../schema/typescript/ClientRequest.ts | 2 +- .../src/protocol/common.rs | 8 +++ codex-rs/app-server/src/account_sessions.rs | 10 ---- codex-rs/app-server/src/message_processor.rs | 5 ++ .../request_processors/account_processor.rs | 59 ++++++++++++------- 8 files changed, 124 insertions(+), 32 deletions(-) diff --git a/codex-rs/app-server-protocol/schema/json/ClientRequest.json b/codex-rs/app-server-protocol/schema/json/ClientRequest.json index f0e2ff4a8c..c5a2d52333 100644 --- a/codex-rs/app-server-protocol/schema/json/ClientRequest.json +++ b/codex-rs/app-server-protocol/schema/json/ClientRequest.json @@ -5941,6 +5941,30 @@ "title": "AccountSession/addRequest", "type": "object" }, + { + "properties": { + "id": { + "$ref": "#/definitions/RequestId" + }, + "method": { + "enum": [ + "accountSession/login/start" + ], + "title": "AccountSession/login/startRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/LoginAccountParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "AccountSession/login/startRequest", + "type": "object" + }, { "properties": { "id": { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 37dbb2af8c..e8062d270e 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -1811,6 +1811,30 @@ "title": "AccountSession/addRequest", "type": "object" }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "accountSession/login/start" + ], + "title": "AccountSession/login/startRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/LoginAccountParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "AccountSession/login/startRequest", + "type": "object" + }, { "properties": { "id": { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index cbdce1dd8a..230ebc3197 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -2739,6 +2739,30 @@ "title": "AccountSession/addRequest", "type": "object" }, + { + "properties": { + "id": { + "$ref": "#/definitions/RequestId" + }, + "method": { + "enum": [ + "accountSession/login/start" + ], + "title": "AccountSession/login/startRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/LoginAccountParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "AccountSession/login/startRequest", + "type": "object" + }, { "properties": { "id": { diff --git a/codex-rs/app-server-protocol/schema/typescript/ClientRequest.ts b/codex-rs/app-server-protocol/schema/typescript/ClientRequest.ts index 2aec503709..c85dc01ff9 100644 --- a/codex-rs/app-server-protocol/schema/typescript/ClientRequest.ts +++ b/codex-rs/app-server-protocol/schema/typescript/ClientRequest.ts @@ -90,4 +90,4 @@ import type { WindowsSandboxSetupStartParams } from "./v2/WindowsSandboxSetupSta /** * Request from the client to the server. */ -export type ClientRequest ={ "method": "initialize", id: RequestId, params: InitializeParams, } | { "method": "thread/start", id: RequestId, params: ThreadStartParams, } | { "method": "thread/resume", id: RequestId, params: ThreadResumeParams, } | { "method": "thread/fork", id: RequestId, params: ThreadForkParams, } | { "method": "thread/archive", id: RequestId, params: ThreadArchiveParams, } | { "method": "thread/unsubscribe", id: RequestId, params: ThreadUnsubscribeParams, } | { "method": "thread/name/set", id: RequestId, params: ThreadSetNameParams, } | { "method": "thread/goal/set", id: RequestId, params: ThreadGoalSetParams, } | { "method": "thread/goal/get", id: RequestId, params: ThreadGoalGetParams, } | { "method": "thread/goal/clear", id: RequestId, params: ThreadGoalClearParams, } | { "method": "thread/metadata/update", id: RequestId, params: ThreadMetadataUpdateParams, } | { "method": "thread/unarchive", id: RequestId, params: ThreadUnarchiveParams, } | { "method": "thread/compact/start", id: RequestId, params: ThreadCompactStartParams, } | { "method": "thread/shellCommand", id: RequestId, params: ThreadShellCommandParams, } | { "method": "thread/approveGuardianDeniedAction", id: RequestId, params: ThreadApproveGuardianDeniedActionParams, } | { "method": "thread/rollback", id: RequestId, params: ThreadRollbackParams, } | { "method": "thread/list", id: RequestId, params: ThreadListParams, } | { "method": "thread/loaded/list", id: RequestId, params: ThreadLoadedListParams, } | { "method": "thread/read", id: RequestId, params: ThreadReadParams, } | { "method": "thread/inject_items", id: RequestId, params: ThreadInjectItemsParams, } | { "method": "skills/list", id: RequestId, params: SkillsListParams, } | { "method": "skills/extraRoots/set", id: RequestId, params: SkillsExtraRootsSetParams, } | { "method": "hooks/list", id: RequestId, params: HooksListParams, } | { "method": "marketplace/add", id: RequestId, params: MarketplaceAddParams, } | { "method": "marketplace/remove", id: RequestId, params: MarketplaceRemoveParams, } | { "method": "marketplace/upgrade", id: RequestId, params: MarketplaceUpgradeParams, } | { "method": "plugin/list", id: RequestId, params: PluginListParams, } | { "method": "plugin/installed", id: RequestId, params: PluginInstalledParams, } | { "method": "plugin/read", id: RequestId, params: PluginReadParams, } | { "method": "plugin/skill/read", id: RequestId, params: PluginSkillReadParams, } | { "method": "plugin/share/save", id: RequestId, params: PluginShareSaveParams, } | { "method": "plugin/share/updateTargets", id: RequestId, params: PluginShareUpdateTargetsParams, } | { "method": "plugin/share/list", id: RequestId, params: PluginShareListParams, } | { "method": "plugin/share/checkout", id: RequestId, params: PluginShareCheckoutParams, } | { "method": "plugin/share/delete", id: RequestId, params: PluginShareDeleteParams, } | { "method": "app/list", id: RequestId, params: AppsListParams, } | { "method": "fs/readFile", id: RequestId, params: FsReadFileParams, } | { "method": "fs/writeFile", id: RequestId, params: FsWriteFileParams, } | { "method": "fs/createDirectory", id: RequestId, params: FsCreateDirectoryParams, } | { "method": "fs/getMetadata", id: RequestId, params: FsGetMetadataParams, } | { "method": "fs/readDirectory", id: RequestId, params: FsReadDirectoryParams, } | { "method": "fs/remove", id: RequestId, params: FsRemoveParams, } | { "method": "fs/copy", id: RequestId, params: FsCopyParams, } | { "method": "fs/watch", id: RequestId, params: FsWatchParams, } | { "method": "fs/unwatch", id: RequestId, params: FsUnwatchParams, } | { "method": "skills/config/write", id: RequestId, params: SkillsConfigWriteParams, } | { "method": "plugin/install", id: RequestId, params: PluginInstallParams, } | { "method": "plugin/uninstall", id: RequestId, params: PluginUninstallParams, } | { "method": "turn/start", id: RequestId, params: TurnStartParams, } | { "method": "turn/steer", id: RequestId, params: TurnSteerParams, } | { "method": "turn/interrupt", id: RequestId, params: TurnInterruptParams, } | { "method": "review/start", id: RequestId, params: ReviewStartParams, } | { "method": "model/list", id: RequestId, params: ModelListParams, } | { "method": "modelProvider/capabilities/read", id: RequestId, params: ModelProviderCapabilitiesReadParams, } | { "method": "experimentalFeature/list", id: RequestId, params: ExperimentalFeatureListParams, } | { "method": "permissionProfile/list", id: RequestId, params: PermissionProfileListParams, } | { "method": "experimentalFeature/enablement/set", id: RequestId, params: ExperimentalFeatureEnablementSetParams, } | { "method": "mcpServer/oauth/login", id: RequestId, params: McpServerOauthLoginParams, } | { "method": "config/mcpServer/reload", id: RequestId, params: undefined, } | { "method": "mcpServerStatus/list", id: RequestId, params: ListMcpServerStatusParams, } | { "method": "mcpServer/resource/read", id: RequestId, params: McpResourceReadParams, } | { "method": "mcpServer/tool/call", id: RequestId, params: McpServerToolCallParams, } | { "method": "windowsSandbox/setupStart", id: RequestId, params: WindowsSandboxSetupStartParams, } | { "method": "windowsSandbox/readiness", id: RequestId, params: undefined, } | { "method": "account/login/start", id: RequestId, params: LoginAccountParams, } | { "method": "account/login/cancel", id: RequestId, params: CancelLoginAccountParams, } | { "method": "accountSession/add", id: RequestId, params: AccountSessionsAddParams, } | { "method": "accountSession/list", id: RequestId, params: AccountSessionsListParams, } | { "method": "accountSession/logout", id: RequestId, params: AccountSessionsLogoutParams, } | { "method": "accountSession/switch", id: RequestId, params: AccountSessionsSwitchParams, } | { "method": "account/logout", id: RequestId, params: undefined, } | { "method": "account/rateLimits/read", id: RequestId, params: undefined, } | { "method": "account/sendAddCreditsNudgeEmail", id: RequestId, params: SendAddCreditsNudgeEmailParams, } | { "method": "feedback/upload", id: RequestId, params: FeedbackUploadParams, } | { "method": "command/exec", id: RequestId, params: CommandExecParams, } | { "method": "command/exec/write", id: RequestId, params: CommandExecWriteParams, } | { "method": "command/exec/terminate", id: RequestId, params: CommandExecTerminateParams, } | { "method": "command/exec/resize", id: RequestId, params: CommandExecResizeParams, } | { "method": "config/read", id: RequestId, params: ConfigReadParams, } | { "method": "externalAgentConfig/detect", id: RequestId, params: ExternalAgentConfigDetectParams, } | { "method": "externalAgentConfig/import", id: RequestId, params: ExternalAgentConfigImportParams, } | { "method": "config/value/write", id: RequestId, params: ConfigValueWriteParams, } | { "method": "config/batchWrite", id: RequestId, params: ConfigBatchWriteParams, } | { "method": "configRequirements/read", id: RequestId, params: undefined, } | { "method": "account/read", id: RequestId, params: GetAccountParams, } | { "method": "getConversationSummary", id: RequestId, params: GetConversationSummaryParams, } | { "method": "gitDiffToRemote", id: RequestId, params: GitDiffToRemoteParams, } | { "method": "getAuthStatus", id: RequestId, params: GetAuthStatusParams, } | { "method": "fuzzyFileSearch", id: RequestId, params: FuzzyFileSearchParams, }; +export type ClientRequest ={ "method": "initialize", id: RequestId, params: InitializeParams, } | { "method": "thread/start", id: RequestId, params: ThreadStartParams, } | { "method": "thread/resume", id: RequestId, params: ThreadResumeParams, } | { "method": "thread/fork", id: RequestId, params: ThreadForkParams, } | { "method": "thread/archive", id: RequestId, params: ThreadArchiveParams, } | { "method": "thread/unsubscribe", id: RequestId, params: ThreadUnsubscribeParams, } | { "method": "thread/name/set", id: RequestId, params: ThreadSetNameParams, } | { "method": "thread/goal/set", id: RequestId, params: ThreadGoalSetParams, } | { "method": "thread/goal/get", id: RequestId, params: ThreadGoalGetParams, } | { "method": "thread/goal/clear", id: RequestId, params: ThreadGoalClearParams, } | { "method": "thread/metadata/update", id: RequestId, params: ThreadMetadataUpdateParams, } | { "method": "thread/unarchive", id: RequestId, params: ThreadUnarchiveParams, } | { "method": "thread/compact/start", id: RequestId, params: ThreadCompactStartParams, } | { "method": "thread/shellCommand", id: RequestId, params: ThreadShellCommandParams, } | { "method": "thread/approveGuardianDeniedAction", id: RequestId, params: ThreadApproveGuardianDeniedActionParams, } | { "method": "thread/rollback", id: RequestId, params: ThreadRollbackParams, } | { "method": "thread/list", id: RequestId, params: ThreadListParams, } | { "method": "thread/loaded/list", id: RequestId, params: ThreadLoadedListParams, } | { "method": "thread/read", id: RequestId, params: ThreadReadParams, } | { "method": "thread/inject_items", id: RequestId, params: ThreadInjectItemsParams, } | { "method": "skills/list", id: RequestId, params: SkillsListParams, } | { "method": "skills/extraRoots/set", id: RequestId, params: SkillsExtraRootsSetParams, } | { "method": "hooks/list", id: RequestId, params: HooksListParams, } | { "method": "marketplace/add", id: RequestId, params: MarketplaceAddParams, } | { "method": "marketplace/remove", id: RequestId, params: MarketplaceRemoveParams, } | { "method": "marketplace/upgrade", id: RequestId, params: MarketplaceUpgradeParams, } | { "method": "plugin/list", id: RequestId, params: PluginListParams, } | { "method": "plugin/installed", id: RequestId, params: PluginInstalledParams, } | { "method": "plugin/read", id: RequestId, params: PluginReadParams, } | { "method": "plugin/skill/read", id: RequestId, params: PluginSkillReadParams, } | { "method": "plugin/share/save", id: RequestId, params: PluginShareSaveParams, } | { "method": "plugin/share/updateTargets", id: RequestId, params: PluginShareUpdateTargetsParams, } | { "method": "plugin/share/list", id: RequestId, params: PluginShareListParams, } | { "method": "plugin/share/checkout", id: RequestId, params: PluginShareCheckoutParams, } | { "method": "plugin/share/delete", id: RequestId, params: PluginShareDeleteParams, } | { "method": "app/list", id: RequestId, params: AppsListParams, } | { "method": "fs/readFile", id: RequestId, params: FsReadFileParams, } | { "method": "fs/writeFile", id: RequestId, params: FsWriteFileParams, } | { "method": "fs/createDirectory", id: RequestId, params: FsCreateDirectoryParams, } | { "method": "fs/getMetadata", id: RequestId, params: FsGetMetadataParams, } | { "method": "fs/readDirectory", id: RequestId, params: FsReadDirectoryParams, } | { "method": "fs/remove", id: RequestId, params: FsRemoveParams, } | { "method": "fs/copy", id: RequestId, params: FsCopyParams, } | { "method": "fs/watch", id: RequestId, params: FsWatchParams, } | { "method": "fs/unwatch", id: RequestId, params: FsUnwatchParams, } | { "method": "skills/config/write", id: RequestId, params: SkillsConfigWriteParams, } | { "method": "plugin/install", id: RequestId, params: PluginInstallParams, } | { "method": "plugin/uninstall", id: RequestId, params: PluginUninstallParams, } | { "method": "turn/start", id: RequestId, params: TurnStartParams, } | { "method": "turn/steer", id: RequestId, params: TurnSteerParams, } | { "method": "turn/interrupt", id: RequestId, params: TurnInterruptParams, } | { "method": "review/start", id: RequestId, params: ReviewStartParams, } | { "method": "model/list", id: RequestId, params: ModelListParams, } | { "method": "modelProvider/capabilities/read", id: RequestId, params: ModelProviderCapabilitiesReadParams, } | { "method": "experimentalFeature/list", id: RequestId, params: ExperimentalFeatureListParams, } | { "method": "permissionProfile/list", id: RequestId, params: PermissionProfileListParams, } | { "method": "experimentalFeature/enablement/set", id: RequestId, params: ExperimentalFeatureEnablementSetParams, } | { "method": "mcpServer/oauth/login", id: RequestId, params: McpServerOauthLoginParams, } | { "method": "config/mcpServer/reload", id: RequestId, params: undefined, } | { "method": "mcpServerStatus/list", id: RequestId, params: ListMcpServerStatusParams, } | { "method": "mcpServer/resource/read", id: RequestId, params: McpResourceReadParams, } | { "method": "mcpServer/tool/call", id: RequestId, params: McpServerToolCallParams, } | { "method": "windowsSandbox/setupStart", id: RequestId, params: WindowsSandboxSetupStartParams, } | { "method": "windowsSandbox/readiness", id: RequestId, params: undefined, } | { "method": "account/login/start", id: RequestId, params: LoginAccountParams, } | { "method": "account/login/cancel", id: RequestId, params: CancelLoginAccountParams, } | { "method": "accountSession/add", id: RequestId, params: AccountSessionsAddParams, } | { "method": "accountSession/login/start", id: RequestId, params: LoginAccountParams, } | { "method": "accountSession/list", id: RequestId, params: AccountSessionsListParams, } | { "method": "accountSession/logout", id: RequestId, params: AccountSessionsLogoutParams, } | { "method": "accountSession/switch", id: RequestId, params: AccountSessionsSwitchParams, } | { "method": "account/logout", id: RequestId, params: undefined, } | { "method": "account/rateLimits/read", id: RequestId, params: undefined, } | { "method": "account/sendAddCreditsNudgeEmail", id: RequestId, params: SendAddCreditsNudgeEmailParams, } | { "method": "feedback/upload", id: RequestId, params: FeedbackUploadParams, } | { "method": "command/exec", id: RequestId, params: CommandExecParams, } | { "method": "command/exec/write", id: RequestId, params: CommandExecWriteParams, } | { "method": "command/exec/terminate", id: RequestId, params: CommandExecTerminateParams, } | { "method": "command/exec/resize", id: RequestId, params: CommandExecResizeParams, } | { "method": "config/read", id: RequestId, params: ConfigReadParams, } | { "method": "externalAgentConfig/detect", id: RequestId, params: ExternalAgentConfigDetectParams, } | { "method": "externalAgentConfig/import", id: RequestId, params: ExternalAgentConfigImportParams, } | { "method": "config/value/write", id: RequestId, params: ConfigValueWriteParams, } | { "method": "config/batchWrite", id: RequestId, params: ConfigBatchWriteParams, } | { "method": "configRequirements/read", id: RequestId, params: undefined, } | { "method": "account/read", id: RequestId, params: GetAccountParams, } | { "method": "getConversationSummary", id: RequestId, params: GetConversationSummaryParams, } | { "method": "gitDiffToRemote", id: RequestId, params: GitDiffToRemoteParams, } | { "method": "getAuthStatus", id: RequestId, params: GetAuthStatusParams, } | { "method": "fuzzyFileSearch", id: RequestId, params: FuzzyFileSearchParams, }; diff --git a/codex-rs/app-server-protocol/src/protocol/common.rs b/codex-rs/app-server-protocol/src/protocol/common.rs index f73701c22a..87fba66997 100644 --- a/codex-rs/app-server-protocol/src/protocol/common.rs +++ b/codex-rs/app-server-protocol/src/protocol/common.rs @@ -943,6 +943,14 @@ client_request_definitions! { response: v2::AccountSessionsResponse, }, + AccountSessionsLogin => "accountSession/login/start" { + params: v2::LoginAccountParams, + inspect_params: true, + serialization: global("account-auth"), + manual_payload_conversion: manual, + response: v2::LoginAccountResponse, + }, + AccountSessionsList => "accountSession/list" { params: v2::AccountSessionsListParams, serialization: global("account-auth"), diff --git a/codex-rs/app-server/src/account_sessions.rs b/codex-rs/app-server/src/account_sessions.rs index d8078f2e14..8e35875b80 100644 --- a/codex-rs/app-server/src/account_sessions.rs +++ b/codex-rs/app-server/src/account_sessions.rs @@ -289,16 +289,6 @@ impl<'a> AccountSessionsStore<'a> { self.save(&stored) } - pub(crate) async fn revoke_all_and_clear(&self) -> std::io::Result<()> { - let stored = self.load()?; - for session in stored.sessions { - if let Err(err) = revoke_auth_dot_json(&session.auth_json).await { - tracing::warn!("failed to revoke saved account session during logout: {err}"); - } - } - self.clear() - } - fn load(&self) -> std::io::Result { match self.read()? { Some(stored) => Ok(stored), diff --git a/codex-rs/app-server/src/message_processor.rs b/codex-rs/app-server/src/message_processor.rs index 256b0a7c67..d189f533a5 100644 --- a/codex-rs/app-server/src/message_processor.rs +++ b/codex-rs/app-server/src/message_processor.rs @@ -1289,6 +1289,11 @@ impl MessageProcessor { ClientRequest::AccountSessionsAdd { params, .. } => { self.account_processor.add_account_session(params).await } + ClientRequest::AccountSessionsLogin { params, .. } => { + self.account_processor + .login_account_session(request_id.clone(), params) + .await + } ClientRequest::AccountSessionsList { params, .. } => { self.account_processor.list_account_sessions(params).await } diff --git a/codex-rs/app-server/src/request_processors/account_processor.rs b/codex-rs/app-server/src/request_processors/account_processor.rs index 61f1580a10..fa86f35cef 100644 --- a/codex-rs/app-server/src/request_processors/account_processor.rs +++ b/codex-rs/app-server/src/request_processors/account_processor.rs @@ -86,7 +86,20 @@ impl AccountRequestProcessor { request_id: ConnectionRequestId, params: LoginAccountParams, ) -> Result, JSONRPCErrorError> { - self.login_v2(request_id, params).await.map(|()| None) + self.login_v2(request_id, params, /*revoke_previous_auth*/ true) + .await + .map(|()| None) + } + + pub(crate) async fn login_account_session( + &self, + request_id: ConnectionRequestId, + params: LoginAccountParams, + ) -> Result, JSONRPCErrorError> { + self.sync_active_account_session()?; + self.login_v2(request_id, params, /*revoke_previous_auth*/ false) + .await + .map(|()| None) } pub(crate) async fn logout_account( @@ -296,6 +309,7 @@ impl AccountRequestProcessor { &self, request_id: ConnectionRequestId, params: LoginAccountParams, + revoke_previous_auth: bool, ) -> Result<(), JSONRPCErrorError> { match params { LoginAccountParams::ApiKey { api_key } => { @@ -305,11 +319,12 @@ impl AccountRequestProcessor { LoginAccountParams::Chatgpt { codex_streamlined_login, } => { - self.login_chatgpt_v2(request_id, codex_streamlined_login) + self.login_chatgpt_v2(request_id, codex_streamlined_login, revoke_previous_auth) .await; } LoginAccountParams::ChatgptDeviceCode => { - self.login_chatgpt_device_code_v2(request_id).await; + self.login_chatgpt_device_code_v2(request_id, revoke_previous_auth) + .await; } LoginAccountParams::ChatgptAuthTokens { access_token, @@ -351,8 +366,6 @@ impl AccountRequestProcessor { )); } - self.sync_active_account_session()?; - // Cancel any active login attempt. { let mut guard = self.active_login.lock().await; @@ -392,6 +405,7 @@ impl AccountRequestProcessor { async fn login_chatgpt_common( &self, codex_streamlined_login: bool, + revoke_previous_auth: bool, ) -> std::result::Result { let config = self.config.as_ref(); @@ -405,12 +419,10 @@ impl AccountRequestProcessor { )); } - self.sync_active_account_session()?; - let opts = LoginServerOptions { open_browser: false, codex_streamlined_login, - revoke_previous_auth: false, + revoke_previous_auth, ..LoginServerOptions::new( config.codex_home.to_path_buf(), CLIENT_ID.to_string(), @@ -445,16 +457,22 @@ impl AccountRequestProcessor { &self, request_id: ConnectionRequestId, codex_streamlined_login: bool, + revoke_previous_auth: bool, ) { - let result = self.login_chatgpt_response(codex_streamlined_login).await; + let result = self + .login_chatgpt_response(codex_streamlined_login, revoke_previous_auth) + .await; self.outgoing.send_result(request_id, result).await; } async fn login_chatgpt_response( &self, codex_streamlined_login: bool, + revoke_previous_auth: bool, ) -> Result { - let opts = self.login_chatgpt_common(codex_streamlined_login).await?; + let opts = self + .login_chatgpt_common(codex_streamlined_login, revoke_previous_auth) + .await?; let server = run_login_server(opts) .map_err(|err| internal_error(format!("failed to start login server: {err}")))?; let login_id = Uuid::new_v4(); @@ -517,16 +535,23 @@ impl AccountRequestProcessor { }) } - async fn login_chatgpt_device_code_v2(&self, request_id: ConnectionRequestId) { - let result = self.login_chatgpt_device_code_response().await; + async fn login_chatgpt_device_code_v2( + &self, + request_id: ConnectionRequestId, + revoke_previous_auth: bool, + ) { + let result = self + .login_chatgpt_device_code_response(revoke_previous_auth) + .await; self.outgoing.send_result(request_id, result).await; } async fn login_chatgpt_device_code_response( &self, + revoke_previous_auth: bool, ) -> Result { let opts = self - .login_chatgpt_common(/*codex_streamlined_login*/ false) + .login_chatgpt_common(/*codex_streamlined_login*/ false, revoke_previous_auth) .await?; let device_code = request_device_code(&opts) .await @@ -653,8 +678,6 @@ impl AccountRequestProcessor { )); } - self.sync_active_account_session()?; - // Cancel any active login attempt to avoid persisting managed auth state. { let mut guard = self.active_login.lock().await; @@ -769,12 +792,6 @@ impl AccountRequestProcessor { } } - self.sync_active_account_session()?; - self.account_sessions_store() - .revoke_all_and_clear() - .await - .map_err(|err| internal_error(format!("failed to clear account sessions: {err}")))?; - match self.auth_manager.logout_with_revoke().await { Ok(_) => {} Err(err) => {