-
Notifications
You must be signed in to change notification settings - Fork 635
feat(providers): display account subscription / plan expiration date in dashboard (#1060) #1081
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -328,7 +328,8 @@ export const de: Record<TKey, string> = { | |
| "prov.removeConfirm": "Anbieter \"{name}\" entfernen? Seine Modelle verschwinden aus Codex’ Auswahl.", | ||
| "prov.hasApiKey": "API-Schlüssel konfiguriert", | ||
| "prov.hasHeaders": "benutzerdefinierte Header konfiguriert", | ||
| "prov.accounts": "Konten ({n})", | ||
| "prov.accounts": | ||
| "prov.expiresAt": "Läuft ab: {date}", "Konten ({n})", | ||
|
Comment on lines
+331
to
+332
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Fix broken Lines 331-332 have the same invalid object-literal shape as "prov.accounts":
"prov.expiresAt": "Läuft ab: {date}", "Konten ({n})",Biome confirms a parse error at line 332. Restore 🧰 Tools🪛 Biome (2.5.6)[error] 332-332: expected (parse) [error] 332-332: expected (parse) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| "prov.accountsAria": "{name}-Konten umschalten", | ||
| "prov.accountActive": "Aktiv", | ||
| "prov.accountReauth": "Erneut anmelden", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -345,7 +345,8 @@ export const en = { | |
| "prov.removeConfirm": "Remove provider \"{name}\"? Its models disappear from Codex's picker.", | ||
| "prov.hasApiKey": "api key configured", | ||
| "prov.hasHeaders": "custom headers configured", | ||
| "prov.accounts": "Accounts ({n})", | ||
| "prov.accounts": | ||
| "prov.expiresAt": "Expires: {date}", "Accounts ({n})", | ||
|
Comment on lines
+348
to
+349
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Fix broken Lines 348-349 read: "prov.accounts":
"prov.expiresAt": "Expires: {date}", "Accounts ({n})",This is invalid JavaScript/TypeScript object syntax. Restore the original 🐛 Proposed fix- "prov.accounts":
- "prov.expiresAt": "Expires: {date}", "Accounts ({n})",
+ "prov.accounts": "Accounts ({n})",
+ "prov.expiresAt": "Expires: {date}",🧰 Tools🪛 Biome (2.5.6)[error] 349-349: expected (parse) [error] 349-349: expected (parse) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| "prov.accountsAria": "Toggle {name} accounts", | ||
| "prov.accountActive": "Active", | ||
| "prov.accountReauth": "Re-login", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -334,7 +334,8 @@ export const ja: Record<TKey, string> = { | |
| "prov.removeConfirm": "プロバイダー \"{name}\" を削除しますか? そのモデルは Codex のピッカーから消えます。", | ||
| "prov.hasApiKey": "API キー設定済み", | ||
| "prov.hasHeaders": "カスタムヘッダー設定済み", | ||
| "prov.accounts": "アカウント ({n})", | ||
| "prov.accounts": | ||
| "prov.expiresAt": "有効期限: {date}", "アカウント ({n})", | ||
|
Comment on lines
+337
to
+338
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Fix broken Lines 337-338 have the same invalid object-literal shape as "prov.accounts":
"prov.expiresAt": "有効期限: {date}", "アカウント ({n})",Biome confirms a parse error at line 338. Restore 🧰 Tools🪛 Biome (2.5.6)[error] 338-338: expected (parse) [error] 338-338: expected (parse) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| "prov.accountsAria": "{name} のアカウントを切り替え", | ||
| "prov.accountActive": "アクティブ", | ||
| "prov.accountReauth": "再ログイン", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -337,7 +337,8 @@ export const ko: Record<TKey, string> = { | |
| "prov.removeConfirm": "프로바이더 \"{name}\" 을(를) 삭제할까요? 해당 모델이 Codex 선택기에서 사라집니다.", | ||
| "prov.hasApiKey": "API 키 설정됨", | ||
| "prov.hasHeaders": "커스텀 헤더 설정됨", | ||
| "prov.accounts": "계정 ({n})", | ||
| "prov.accounts": | ||
| "prov.expiresAt": "만료일: {date}", "계정 ({n})", | ||
|
Comment on lines
+340
to
+341
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Fix broken Lines 340-341 have the same invalid object-literal shape as "prov.accounts":
"prov.expiresAt": "만료일: {date}", "계정 ({n})",Biome confirms a parse error at line 341. Restore 🧰 Tools🪛 Biome (2.5.6)[error] 341-341: expected (parse) [error] 341-341: expected (parse) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| "prov.accountsAria": "{name} 계정 목록 열기/닫기", | ||
| "prov.accountActive": "활성", | ||
| "prov.accountReauth": "재로그인", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -339,7 +339,8 @@ export const ru: Record<TKey, string> = { | |
| "prov.removeConfirm": "Удалить провайдера \"{name}\"? Его модели исчезнут из селектора моделей Codex.", | ||
| "prov.hasApiKey": "API-ключ настроен", | ||
| "prov.hasHeaders": "настроены пользовательские заголовки", | ||
| "prov.accounts": "Аккаунты ({n})", | ||
| "prov.accounts": | ||
| "prov.expiresAt": "Истекает: {date}", "Аккаунты ({n})", | ||
|
Comment on lines
+342
to
+343
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Fix broken Lines 342-343 have the same invalid object-literal shape as "prov.accounts":
"prov.expiresAt": "Истекает: {date}", "Аккаунты ({n})",Biome confirms a parse error at line 343. Restore 🧰 Tools🪛 Biome (2.5.6)[error] 343-343: expected (parse) [error] 343-343: expected (parse) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| "prov.accountsAria": "Показать или скрыть аккаунты {name}", | ||
| "prov.accountActive": "Активен", | ||
| "prov.accountReauth": "Повторный вход", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -334,7 +334,8 @@ export const zh: Record<TKey, string> = { | |
| "prov.removeConfirm": "移除提供方 \"{name}\"?其模型将从 Codex 选择器中消失。", | ||
| "prov.hasApiKey": "已配置 API 密钥", | ||
| "prov.hasHeaders": "已配置自定义请求头", | ||
| "prov.accounts": "账户({n})", | ||
| "prov.accounts": | ||
| "prov.expiresAt": "到期时间: {date}", "账户({n})", | ||
|
Comment on lines
+337
to
+338
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Fix broken Lines 337-338 have the same invalid object-literal shape as "prov.accounts":
"prov.expiresAt": "到期时间: {date}", "账户({n})",Biome confirms a parse error at line 338. Restore 🧰 Tools🪛 Biome (2.5.6)[error] 338-338: expected (parse) [error] 338-338: expected (parse) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| "prov.accountsAria": "展开/收起 {name} 账户", | ||
| "prov.accountActive": "使用中", | ||
| "prov.accountReauth": "需重新登录", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -195,6 +195,7 @@ function poolAccountDto( | |
| const quota = quotaForPlan(quotaResult.quota, account.plan); | ||
| const needsReauth = !hasCredential || quotaResult.needsReauth || isAccountNeedsReauth(account.id); | ||
| const health = projectCodexAccountHealth({ accountId: account.id, needsReauth }); | ||
| const cred = getCodexAccountCredential(account.id); | ||
| return { | ||
| id: account.id, | ||
| email: maskEmail(account.email) ?? account.email, | ||
|
|
@@ -206,6 +207,7 @@ function poolAccountDto( | |
| quota: quota ? { ...quota } : null, | ||
| needsReauth, | ||
| hasCredential, | ||
| ...(cred?.expiresAt ? { expiresAt: cred.expiresAt } : {}), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the dashboard uses the default Codex App login, this field is never returned: Useful? React with 👍 / 👎. |
||
| ...(quotaResult.quotaProbeSkipped ? { quotaProbeSkipped: true as const } : {}), | ||
| ...oauthAccountHealthFields("codex", account.id, health), | ||
| }; | ||
|
|
@@ -647,6 +649,7 @@ export interface CodexAuthAccountDto { | |
| quota: (StoredAccountQuota | (Omit<StoredAccountQuota, "updatedAt"> & { updatedAt: number })) | null; | ||
| needsReauth?: boolean; | ||
| hasCredential: boolean; | ||
| expiresAt?: number; | ||
| health: OAuthAccountHealth; | ||
| healthLabel: OAuthHealthLabel; | ||
| healthSummary: string; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When an OAuth credential is refreshed by ordinary proxy traffic or the optional token guardian while the Providers page remains mounted, this date stays at the old token's expiration.
useProviderAccountPoolsfetches account sets only on initial provider-list discovery and explicit account actions (useProviderAccountPools.ts:244-256), unlike the Codex pool's 30-second polling, so a valid refreshed account can indefinitely display a past expiration date. Poll the account summaries or invalidate this state when credentials rotate.Useful? React with 👍 / 👎.