diff --git a/docs-site/src/content/docs/guides/claude-code.md b/docs-site/src/content/docs/guides/claude-code.md index d3e46fbbd37..d1f12866b13 100644 --- a/docs-site/src/content/docs/guides/claude-code.md +++ b/docs-site/src/content/docs/guides/claude-code.md @@ -79,7 +79,9 @@ The dashboard shows Pro, Max 5x, or Ultra beside Claude account quotas, using su metadata from the authenticated profile. Both `ultra` and `claude_max_20x` display as Ultra (the existing `ultra` and `max_20x` tier aliases are retained). Unfamiliar validated tiers retain their original name without failing the usage read. Claude account rows prefer your alias, then a masked email, and -fall back to a numbered label when no safe identity is available. +fall back to a numbered label when no safe identity is available. The provider Overview shows the +same label as a separate current-account field when its account list is verified. Email labels stay +masked even when `privacy.maskEmails` is false. You can log in multiple Claude accounts via the Providers dashboard (`ocx login anthropic` / add-account). By default every request uses the **active** account only. diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index d28873ac404..1984840870c 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -13,6 +13,9 @@ These links preserve the preset's referral parameters. Sponsor information is sh the configured provider name, adapter and endpoint match the preset; it never changes routing, account selection or defaults. +While a provider login is in progress, its Accounts panel offers **Cancel** once sign-in +instructions appear. + ## OpenAI account modes | Provider id | Use | Credential/account rule | diff --git a/docs-site/src/content/docs/guides/web-dashboard.md b/docs-site/src/content/docs/guides/web-dashboard.md index 5dd7a99df8f..818d52692a6 100644 --- a/docs-site/src/content/docs/guides/web-dashboard.md +++ b/docs-site/src/content/docs/guides/web-dashboard.md @@ -164,6 +164,10 @@ to save an incomplete snapshot; choose another order or repair the history befor ### Account selection +For a provider's OAuth accounts, finish the current sign-in or account removal before starting +the other operation. If the account list and sign-in status cannot be refreshed, the status remains +unverified and **Log out** is available to explicitly retry recovery. + Account selection is shared with request routing. Selecting an OAuth account takes effect on the next request even when a pool is enabled. A healthy selection is not replaced merely because another generic OAuth account has more unused quota. If the account returns 429, automatic @@ -539,6 +543,8 @@ them. Both switches apply immediately; **Save** never changes them. When interce Claude/Anthropic accounts are managed only on **Providers > Anthropic > Accounts**: login and the browser option, the account roster with switch, pause, remove, and reauthentication, the paste-code field, account pool settings, and quota. Claude no longer has an Account sub-tab. Provider-level controls such as the default provider, removal, and the enabled switch stay on Providers. +If an account change is still in progress, wait for it to finish before retrying logout. After an account removal, the dashboard rechecks the provider's login status; if it cannot verify the result, refresh the account list before retrying the removal. + The bookmarks `#claude` and `#claude/code` open this page, and the former `#claude/settings` redirects to `#claude/code`; `#claude/desktop` selects the separate Claude Desktop tab. The old `#claude/account` bookmark redirects to `#providers?provider=anthropic&tab=accounts`. Legacy `#integrations/claude` and `#integrations/claude/desktop` bookmarks still redirect to `#claude/code` and `#claude/desktop`, respectively. Arrow keys move between tabs; Home and End select the first and last tab. diff --git a/docs-site/src/content/docs/reference/configuration/server.md b/docs-site/src/content/docs/reference/configuration/server.md index 7c435e2b08e..f1c809e3352 100644 --- a/docs-site/src/content/docs/reference/configuration/server.md +++ b/docs-site/src/content/docs/reference/configuration/server.md @@ -463,13 +463,16 @@ use `ssh -g -L`, broad container publishing, or forwarding modes that expose the ## Account email masking (`privacy`) -Stored account emails are masked everywhere they leave the proxy — the dashboard account lists, +Stored account emails are masked by default wherever they leave the proxy — the dashboard account lists, `GET /api/codex-auth/accounts`, `GET /api/oauth/status`, and the `ocx status` logins section all show `p***n@example.com` rather than the address on file. | Field | Type | Default | Meaning | | --- | --- | --- | --- | -| `privacy.maskEmails?` | `boolean` | `true` | Set to `false` to show stored account emails in full. Absent, `true`, and any malformed value all keep masking, so only a deliberate `false` reveals an address. | +| `privacy.maskEmails?` | `boolean` | `true` | Set to `false` to reveal stored account emails in projected email fields. Absent, `true`, and any malformed value keep masking, so only a deliberate `false` reveals an address. | + +Claude dashboard account labels remain masked even when this flag is `false`; an account alias +takes precedence over the masked label. The active account uses the same label in Overview. Turn it off when you run many accounts on a machine you control and cannot tell them apart from masked forms. Read the flag as a disclosure decision rather than a display preference: management diff --git a/gui/src/components/provider-workspace/ProviderAuthPanel.tsx b/gui/src/components/provider-workspace/ProviderAuthPanel.tsx index 4ee68d79c16..298002dc44e 100644 --- a/gui/src/components/provider-workspace/ProviderAuthPanel.tsx +++ b/gui/src/components/provider-workspace/ProviderAuthPanel.tsx @@ -331,7 +331,8 @@ export default function ProviderAuthPanel({ setManualCodeBusy(false); } }; - const loggedIn = accounts.length > 0 || oauth?.loggedIn === true; + const loggedIn = (accountLoadState === "ready" && accounts.length > 0) || oauth?.loggedIn === true; + const canLogout = loggedIn || (accountLoadState === "error" && oauth?.loggedIn !== false); const activeReauthAccount = accounts.find(a => a.active && a.needsReauth); const activeNeedsReauth = Boolean(activeReauthAccount); const quotaRows = isOauth ? accounts : keys; @@ -488,7 +489,7 @@ export default function ProviderAuthPanel({ {loggedIn ? t("pws.loggedInTitle") - : (oauth?.error || t("pws.notLoggedInTitle"))} + : (oauth?.error || (oauth?.loggedIn === false ? t("pws.notLoggedInTitle") : t("startup.unverified")))} {activeReauthAccount && ( @@ -496,7 +497,7 @@ export default function ProviderAuthPanel({ {t("pws.reauthenticate")} )} - {loggedIn ? ( + {canLogout ? ( ) : (