feat: Add OIDC user monthly quota reset feature - #2722
Conversation
- Add UI controls in Operation Settings for OIDC quota reset - Support enable/disable monthly auto reset - Support configurable reset quota amount - Add manual reset button with confirmation - Add Chinese and English translations Configuration keys: - oidc_quota_reset.enabled: Enable/disable monthly auto reset - oidc_quota_reset.amount: Quota value to reset Note: This feature requires sync_service.py updates (not in this repo) and nginx proxy configuration for /api/sync/ endpoint. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WalkthroughThis change introduces OIDC user quota reset functionality, enabling administrators to automatically reset quotas monthly or manually trigger quota resets for all OIDC users. It adds configuration fields, a new API endpoint integration, UI components with confirmation dialogs, and translations in English and Chinese. Changes
Sequence DiagramsequenceDiagram
actor Admin
participant UI as SettingsCreditLimit<br/>Component
participant API as Frontend API<br/>Client
participant Backend as Backend<br/>Service
Admin->>UI: Click "Reset All OIDC<br/>Users Quota Now"
UI->>UI: Show Popconfirm<br/>Dialog
Admin->>UI: Confirm Reset
UI->>UI: Set resetting = true
UI->>API: POST /api/sync/<br/>reset-oidc-quota
API->>Backend: Forward Reset<br/>Request
Backend->>Backend: Reset quotas for<br/>all OIDC users
Backend-->>API: Return {status,<br/>count, quota}
API-->>UI: Response with<br/>reset details
UI->>UI: Show Success<br/>Message
UI->>UI: Set resetting = false
Admin->>Admin: View confirmation<br/>with user count
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@web/src/pages/Setting/Operation/SettingsCreditLimit.jsx`:
- Around line 84-107: In handleManualReset replace the raw fetch call with the
shared API helper (use API.post('/api/sync/reset-oidc-quota')) so the request
gets the standard headers (including New-API-User) and consistent behavior; keep
the same success/error handling (parse response, call showSuccess/showError,
setResetting(true/false) in try/finally) and ensure you await API.post and read
the returned data shape (data.success, data.affected, data.quota, data.message)
just like the current fetch-based logic.
| async function handleManualReset() { | ||
| setResetting(true); | ||
| try { | ||
| const response = await fetch(`${SYNC_SERVICE_URL}/reset-oidc-quota`, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| }); | ||
| const data = await response.json(); | ||
| if (data.success) { | ||
| showSuccess(t('重置成功,已重置 {{count}} 个用户的额度为 {{quota}}', { | ||
| count: data.affected, | ||
| quota: data.quota, | ||
| })); | ||
| } else { | ||
| showError(data.message || t('重置失败')); | ||
| } | ||
| } catch (error) { | ||
| showError(t('重置失败:') + error.message); | ||
| } finally { | ||
| setResetting(false); | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for API helper definitions and auth/interceptor patterns
rg -n "API\s*=\s*|export\s+const\s+API|axios\.create" web/src --type js --type jsxRepository: QuantumNous/new-api
Length of output: 90
🏁 Script executed:
# Search for Authorization headers and auth interceptors
rg -n "Authorization|token|interceptor|Bearer" web/src --type js --type jsx | head -30Repository: QuantumNous/new-api
Length of output: 90
🏁 Script executed:
# Find where SYNC_SERVICE_URL is defined and used
rg -n "SYNC_SERVICE_URL" web/src --type js --type jsxRepository: QuantumNous/new-api
Length of output: 90
🏁 Script executed:
# Check other API call patterns in the codebase
rg -n "fetch\(" web/src --type js --type jsx -A 2 | head -40Repository: QuantumNous/new-api
Length of output: 90
🏁 Script executed:
# Look for API helper usage patterns (API.post, API.get, etc.)
rg -n "API\.(post|get|put|delete|request)" web/src --type js --type jsx | head -30Repository: QuantumNous/new-api
Length of output: 90
🏁 Script executed:
# Search for API helper definitions (broader search)
rg -n "API\s*=\s*|export\s+const\s+API|axios\.create" web/srcRepository: QuantumNous/new-api
Length of output: 519
🏁 Script executed:
# Search for Authorization and interceptor patterns
rg -n "Authorization|interceptor|Bearer" web/srcRepository: QuantumNous/new-api
Length of output: 4987
🏁 Script executed:
# Find SYNC_SERVICE_URL definition
rg -n "SYNC_SERVICE_URL" web/srcRepository: QuantumNous/new-api
Length of output: 295
🏁 Script executed:
# Look at the actual file in question
cat -n web/src/pages/Setting/Operation/SettingsCreditLimit.jsx | head -120Repository: QuantumNous/new-api
Length of output: 4539
🏁 Script executed:
# Find API-related imports and usage patterns
rg -n "import.*API|from.*api" web/src | head -20Repository: QuantumNous/new-api
Length of output: 2351
🏁 Script executed:
# Examine the API helper setup and interceptors
cat -n web/src/helpers/api.js | head -100Repository: QuantumNous/new-api
Length of output: 3373
🏁 Script executed:
# Check auth helper setup
cat -n web/src/helpers/auth.jsx | head -50Repository: QuantumNous/new-api
Length of output: 1866
🏁 Script executed:
# Check if there's a request interceptor that adds auth headers
rg -n "interceptors\.request|setAuthHeader" web/src --context 5Repository: QuantumNous/new-api
Length of output: 45
🏁 Script executed:
# Look at how other components use API for POST requests
rg -n "API\.post" web/src -A 3 | head -40Repository: QuantumNous/new-api
Length of output: 2630
🏁 Script executed:
# Check if auth headers are being injected via request interceptor
cat -n web/src/helpers/api.js | tail -50Repository: QuantumNous/new-api
Length of output: 1704
🏁 Script executed:
# Check helpers/index.js to see what's exported
cat -n web/src/helpers/index.jsRepository: QuantumNous/new-api
Length of output: 1322
🏁 Script executed:
# Look for any middleware or setup that adds auth to requests
rg -n "authHeader|Authorization" web/src/helpers --context 3Repository: QuantumNous/new-api
Length of output: 728
🏁 Script executed:
# Check if there's a request interceptor we may have missed
rg -n "interceptors\.request" web/src/helpers/api.js -A 10Repository: QuantumNous/new-api
Length of output: 45
🏁 Script executed:
# Verify if authHeader is actually used anywhere as a request interceptor
rg -n "authHeader\(" web/src --context 2Repository: QuantumNous/new-api
Length of output: 854
🏁 Script executed:
# Check the complete setup of the API instance one more time - look for where auth is configured
sed -n '29,93p' web/src/helpers/api.jsRepository: QuantumNous/new-api
Length of output: 1641
Use API.post() instead of fetch() for consistency and to include necessary request headers.
The current fetch() call bypasses the API helper entirely, missing the New-API-User header that is automatically injected by the API instance. Use API.post('/api/sync/reset-oidc-quota') to align with the existing API pattern (as used on line 59 of this file with API.put()) and ensure proper request headers are included.
🤖 Prompt for AI Agents
In `@web/src/pages/Setting/Operation/SettingsCreditLimit.jsx` around lines 84 -
107, In handleManualReset replace the raw fetch call with the shared API helper
(use API.post('/api/sync/reset-oidc-quota')) so the request gets the standard
headers (including New-API-User) and consistent behavior; keep the same
success/error handling (parse response, call showSuccess/showError,
setResetting(true/false) in try/finally) and ensure you await API.post and read
the returned data shape (data.success, data.affected, data.quota, data.message)
just like the current fetch-based logic.
Summary
Configuration Keys
Files Changed
Backend Service ReferenceThis feature requires a companion backend service. Below is a reference implementation: Click to expand: Backend implementation referenceRead config from options tabledef get_oidc_quota_reset_config():
"""从 options 表读取 OIDC 额度重置配置"""
conn = get_pg_connection()
cur = conn.cursor()
config = {'enabled': False, 'amount': 500000}
cur.execute("""
SELECT key, value FROM options
WHERE key IN ('oidc_quota_reset.enabled', 'oidc_quota_reset.amount')
""")
for row in cur.fetchall():
if row['key'] == 'oidc_quota_reset.enabled':
config['enabled'] = row['value'].lower() == 'true'
elif row['key'] == 'oidc_quota_reset.amount':
try:
config['amount'] = int(row['value'])
except (ValueError, TypeError):
pass
cur.close()
conn.close()
return configReset OIDC users quotadef reset_all_users_quota(quota_amount=None):
"""重置所有 OIDC 用户的配额 (排除 oidc_id 为空或 NULL 的用户)"""
if quota_amount is None:
config = get_oidc_quota_reset_config()
quota_amount = config['amount'] if config['amount'] > 0 else 500000
conn = get_pg_connection()
cur = conn.cursor()
cur.execute("""
UPDATE users
SET quota = %s, used_quota = 0
WHERE oidc_id IS NOT NULL
AND oidc_id != ''
AND deleted_at IS NULL
""", (quota_amount,))
affected = cur.rowcount
conn.commit()
cur.close()
conn.close()
return affected, quota_amountAPI endpoint for manual reset@app.route('/api/reset-oidc-quota', methods=['POST'])
def reset_oidc_quota():
try:
config = get_oidc_quota_reset_config()
affected, quota_amount = reset_all_users_quota(config['amount'])
return jsonify({
'success': True,
'affected': affected,
'quota': quota_amount
})
except Exception as e:
return jsonify({'success': False, 'message': str(e)}), 500Nginx Proxy Configurationlocation /api/sync/ {
proxy_pass http://localhost:3001/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}Test Plan
🤖 Generated with Claude Code |
|
看起来不是一个通用功能 |
|
仔细一看怎么还是一个外挂的服务呢,提交的内容就加几个配置项。。。这种自用脚本还是自己用吧 |
Summary
Configuration Keys
oidc_quota_reset.enabledoidc_quota_reset.amountFiles Changed
web/src/components/settings/OperationSetting.jsx- Add config keys to inputs stateweb/src/i18n/locales/zh.json- Add Chinese translationsweb/src/i18n/locales/en.json- Add English translationsweb/src/pages/Setting/Operation/SettingsCreditLimit.jsx- Add UI componentsBackend Service Reference
This feature requires a companion backend service. Below is a reference implementation:
Click to expand: Backend implementation reference
Read config from options table
Reset OIDC users quota
API endpoint for manual reset
Nginx Proxy Configuration
Test Plan
🤖 Generated with Claude Code