yangjianbo
1d0872e7ca
feat(openai-ws): 合并 WS v2 透传模式与前端 ws mode
...
新增 OpenAI WebSocket v2 passthrough relay 数据面与服务适配层,
支持按账号 ws mode 在 ctx_pool 与 passthrough 间路由。
同步调整前端 OpenAI ws mode 选项为 off/ctx_pool/passthrough,
并补充 i18n 文案与对应单测。
新增 Caddyfile.dmit 与 docker-compose-aicodex.yml 部署配置,
用于宿主机场景下的反向代理与服务编排。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-05 11:50:58 +08:00
shaw
078fefed03
fix: 修复账号管理页面容量列显示为0的bug
2026-03-05 09:48:00 +08:00
Wesley Liddick
4caf95e5dd
Merge pull request #767 from litianc/fix/rewrite-userid-regex-match-account-uuid
...
fix: extend RewriteUserID regex to match user_id containing account_uuid
2026-03-05 08:56:03 +08:00
litianc
8e1bcf53bb
fix: extend RewriteUserID regex to match user_id containing account_uuid
...
The existing regex only matched the old format where account_uuid is
empty (account__session_). Real Claude Code clients and newer sub2api
generated user_ids use account_{uuid}_session_ which was silently
skipped, causing the original metadata.user_id to leak to upstream
when User-Agent is rewritten by an intermediate gateway.
Closes #766
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-04 23:13:17 +08:00
kyx236
3d79773ba2
Merge branch 'main' of https://github.com/james-6-23/sub2api
2026-03-04 20:25:39 +08:00
kyx236
6aa8cbbf20
feat: 二次 401 直接升级为错误状态,添加 DB 回退确保生效
...
账号首次 401 仅临时不可调度,给予 token 刷新窗口;若恢复后再次 401
说明凭证确实失效,直接升级为错误状态以避免反复无效调度。
- 缓存中 reason 为空时从 DB 回退读取,防止升级判断失效
- ClearError 同时清除临时不可调度状态,管理员恢复后重新给予一次机会
- 管理后台账号列表添加"临时不可调度"状态筛选
- 补充 DB 回退场景单元测试
2026-03-04 20:25:15 +08:00
Wesley Liddick
27abae21b8
Merge pull request #724 from PMExtra/feat/registration-email-domain-whitelist
...
feat(registration): add email domain whitelist policy
2026-03-04 15:51:51 +08:00
shaw
0819c8a51a
refactor: 消除重复的 normalizeAccountIDList,补充 PR#754 新增组件的单元测试
...
- 删除 account_today_stats_cache.go 中重复的 normalizeAccountIDList,统一使用 id_list_utils.go 的 normalizeInt64IDList
- 新增 snapshot_cache_test.go:覆盖 snapshotCache、buildETagFromAny、parseBoolQueryWithDefault
- 新增 id_list_utils_test.go:覆盖 normalizeInt64IDList、buildAccountTodayStatsBatchCacheKey
- 新增 ops_query_mode_test.go:覆盖 shouldFallbackOpsPreagg、cloneOpsFilterWithMode
2026-03-04 15:22:46 +08:00
Wesley Liddick
9dcd3cd491
Merge pull request #754 from xvhuan/perf/admin-core-large-dataset
...
perf(admin): 优化后台大数据场景加载性能(仪表盘/用户/账号/Ops)
2026-03-04 15:15:13 +08:00
Wesley Liddick
49767cccd2
Merge pull request #755 from xvhuan/perf/admin-usage-fast-pagination-main
...
perf(admin-usage): 优化 usage 大表分页,默认避免全量 COUNT(*)
2026-03-04 14:15:57 +08:00
xvhuan
f6fe5b552d
fix(admin): resolve CI lint and user subscriptions regression
2026-03-04 14:07:17 +08:00
PMExtra
bd0801a887
feat(registration): add email domain whitelist policy
2026-03-04 13:54:18 +08:00
xvhuan
05b1c66aa8
perf(admin-usage): avoid expensive count on large usage_logs pagination
2026-03-04 13:51:27 +08:00
xvhuan
80ae592c23
perf(admin): optimize large-dataset loading for dashboard/users/accounts/ops
2026-03-04 13:45:49 +08:00
shaw
ba6de4c4d4
feat: /keys页面支持表单筛选
2026-03-04 11:29:31 +08:00
shaw
0aa3cf677a
chore: 清理一些无用的文件
2026-03-04 10:15:42 +08:00
shaw
72961c5858
fix: Anthropic 平台无限流重置时间的 429 不再误标记账号限流
2026-03-04 09:36:24 +08:00
Wesley Liddick
a11ac188c2
Merge pull request #738 from DaydreamCoding/feat/ungrouped-key-setting
...
feat(gateway): 系统设置控制未分组 Key 调度 — Handler 层中间件拦截
2026-03-03 21:03:31 +08:00
Wesley Liddick
60350d298a
Merge pull request #735 from alfadb/fix/count-tokens-default-ignore
...
fix(ops): 默认忽略 count_tokens 404 错误
2026-03-03 21:02:46 +08:00
shaw
838dad8759
feat: 重构 /v1/usage 端点,支持 quota_limited 和 unrestricted 双模式
...
- quota_limited 模式:返回 Key 级别的总额度、速率限制窗口用量和过期时间
- unrestricted 模式:返回订阅限额或钱包余额信息(向后兼容)
- 新增 model_stats 字段,支持 start_date/end_date 参数查询按模型用量统计
- 提取 buildUsageData/parseUsageDateRange 等辅助方法,减少主函数复杂度
- 新增 APIKeyService.GetRateLimitData 和 UsageService.GetAPIKeyModelStats
2026-03-03 20:59:12 +08:00
shaw
a728dfe0c6
refactor: 重构 api_key_auth 中间件,用 skipBilling 替代 7 处散落的 isUsageQuery
...
将中间件职责拆分为鉴权(Authentication)和计费执行(Billing Enforcement)两层:
- 鉴权层(disabled/IP/用户状态)始终执行
- 计费层(过期/配额/订阅/余额)用单一 skipBilling 守卫整块控制
/v1/usage 端点只需鉴权不需计费,skipBilling 仅出现 2 处(订阅加载错误处理 + 计费块守卫),
取代了之前 isUsageQuery 散布在 7 个 if 分支中的控制流。
2026-03-03 20:58:00 +08:00
QTom
0c7cbe3566
feat(gateway): 系统设置控制未分组 Key 调度 — Handler 层中间件拦截
...
新增系统设置 allow_ungrouped_key_scheduling(默认关闭),
未分组的 API Key 在网关请求时直接返回 403,
由 RequireGroupAssignment 中间件统一拦截,
支持 Anthropic / Google 两种错误格式响应。
全栈实现:常量 → 结构体 → 解析/更新/初始化 → DTO → 管理接口 →
中间件 → 路由注册 → 前端设置界面 + i18n。
2026-03-03 19:56:27 +08:00
alfadb
832b0185c7
style: fix gofmt formatting in ops_settings.go
...
Remove extra space before inline comment to pass golangci-lint gofmt check.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-03 18:00:49 +08:00
alfadb
b1719b26d1
fix(ops): 默认忽略 count_tokens 404 错误
...
将 IgnoreCountTokensErrors 默认值从 false 改为 true。
count_tokens 返回 404 是预期业务行为(上游不支持 endpoint,
客户端应 fallback 到本地 tokenizer 估算),不应被视为错误。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-03 16:50:13 +08:00
shaw
ccf6a921c7
fix: 修复 PR #723 引入的 CI lint 和 test 编译错误
...
- wire_gen_test.go: 补充 NewTokenRefreshService 缺失的 tempUnschedCache 参数
- config.go, token_refresh_service.go: 修复 gofmt 格式问题
2026-03-03 16:45:29 +08:00
Wesley Liddick
197c570baa
Merge pull request #723 from zqq-nuli/fix/oauth-401-temp-unschedulable
...
fix: OAuth 401 不再永久锁死账号,改用临时不可调度实现自动恢复
2026-03-03 16:33:07 +08:00
shaw
0fe09f1d40
fix: 恢复 PR #682 中被误替换为占位符的 OAuth client_secret
...
PR #682 (release → main 全量同步) 将 Antigravity 和 Gemini CLI 的
OAuth client_secret 硬编码值替换为了 "GOCSPX-your-client-secret" 占位符,
导致未配置环境变量的部署环境中 token 刷新失败。
恢复内容:
- antigravity/oauth.go: 恢复真实 client_secret
- antigravity/oauth_test.go: 恢复测试断言中的真实值
- geminicli/constants.go: 恢复真实 client_secret
2026-03-03 16:27:28 +08:00
shaw
4a91954532
fix: correct migration 061 checksum and add missing BillingCache mock methods
...
- Fix fileChecksum for 061 migration: use TrimSpace hash (66207e7a) instead
of raw sha256sum (97bdd9a3), matching the actual runtime computation
- Add 222b4a09 as accepted DB checksum for 061 migration
- Add missing GetAPIKeyRateLimit/SetAPIKeyRateLimit/UpdateAPIKeyRateLimitUsage/
InvalidateAPIKeyRateLimit methods to mock BillingCache in test stubs
- Fix NewBillingCacheService call in singleflight test (add apiKeyRepo param)
2026-03-03 16:11:05 +08:00
shaw
b8b5cec35c
fix: resolve CI lint errors and test compilation failures for rate limit feature
...
- Fix errcheck: properly handle rows.Close() error via named return + defer closure
- Fix gofmt: auto-format billing_cache.go, api_key_service.go, billing_cache_service.go
- Add missing rate limit interface methods to 4 test stubs (GetRateLimitData, IncrementRateLimitUsage, ResetRateLimitWindows)
- Fix NewBillingCacheService calls missing the new apiKeyRepo parameter
2026-03-03 15:43:08 +08:00
Wesley Liddick
43c203333e
Merge pull request #733 from DaydreamCoding/fix/group-isolation
...
fix(gateway): 分组隔离 — 禁止未分组账号被跨组调度
2026-03-03 15:10:30 +08:00
Wesley Liddick
1c6393b131
Merge pull request #732 from xvhuan/perf/admin-dashboard-preagg
...
perf(admin): 优化 Dashboard 大数据量加载(预聚合趋势+异步用户趋势)
2026-03-03 15:10:20 +08:00
Wesley Liddick
22f04e72e5
Merge pull request #731 from xvhuan/fix/061-bounded-backfill-startup
...
fix(migrations): 061 迁移改为限时分批回填,避免启动阻塞导致 502
2026-03-03 15:08:18 +08:00
shaw
5f3debf65b
chore: add migration for api key rate limit fields
2026-03-03 15:05:15 +08:00
shaw
a80ec5d8bb
feat: apikey支持5h/1d/7d速率控制
2026-03-03 15:01:10 +08:00
QTom
530a16291c
fix(gateway): 分组隔离 — 禁止未分组账号被跨组调度
...
当 API Key 无分组时,调度仅从未分组账号池中选取。
修复 isAccountInGroup 在 groupID==nil 时的逻辑,
同时补全 scheduler_snapshot_service 和 gemini_compat_service
中的 SimpleMode 保护,确保分组隔离在所有调度路径生效。
新增 ListSchedulableUngroupedByPlatform/s 方法,
使用 Ent 的 Not(HasAccountGroups()) 谓词实现未分组账号隔离。
新增 17 个单元和端到端隔离测试,覆盖所有分支和边界条件。
2026-03-03 13:20:58 +08:00
xvhuan
7be8f4dc6e
perf(admin-dashboard): accelerate trend load with pre-aggregation and async user trend
2026-03-03 11:53:54 +08:00
ius
99f1e3ff35
fix(migrations): avoid startup outage from 061 full-table backfill
2026-03-03 11:01:22 +08:00
Wesley Liddick
b7df7ce5d5
Merge pull request #726 from DaydreamCoding/feat/dual-mode-umq
...
feat(gateway): 双模式用户消息队列 — 串行队列 + 软性限速
2026-03-03 08:41:34 +08:00
erio
451a851118
fix: remove unused sanitizeCustomMenuItemsJSON function
...
Replaced by filterUserVisibleMenuItems which includes both array
validation and admin-item filtering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-03 07:13:08 +08:00
erio
e97c376681
fix: security hardening and architectural improvements for custom menu
...
1. (Critical) Filter admin-only menu items from public API responses -
both GetPublicSettings handler and GetPublicSettingsForInjection now
exclude visibility=admin items, preventing unauthorized access to
admin menu URLs.
2. (Medium) Validate JSON array structure in sanitizeCustomMenuItemsJSON -
use json.Unmarshal into []json.RawMessage instead of json.Valid to
reject non-array JSON values that would cause frontend runtime errors.
3. (Medium) Decouple router from business JSON parsing - move origin
extraction logic from router.go to SettingService.GetFrameSrcOrigins,
eliminating direct JSON parsing of custom_menu_items in the routing
layer.
4. (Low) Restrict custom menu item ID charset to [a-zA-Z0-9_-] via
regex validation, preventing route-breaking characters like / ? # or
spaces.
5. (Low) Handle crypto/rand error in generateMenuItemID - return error
instead of silently ignoring, preventing potential duplicate IDs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-03 07:05:01 +08:00
erio
7541e243bc
style: fix gofmt alignment in setting_service.go
2026-03-03 06:38:04 +08:00
erio
50a8116ae9
fix: update SecurityHeaders call sites to match new signature
2026-03-03 06:37:50 +08:00
erio
bf6fe5e962
fix: custom menu security hardening and code quality improvements
...
- Add admin menu permission check in CustomPageView (visibility + role)
- Sanitize SVG content with DOMPurify before v-html rendering (XSS prevention)
- Decouple router.go from dto package using anonymous struct
- Consolidate duplicate parseCustomMenuItems into dto.ParseCustomMenuItems
- Enhance menu item validation (count, length, ID uniqueness limits)
- Add audit logging for purchase_subscription and custom_menu_items changes
- Update API contract test to include custom_menu_items field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-03 06:23:56 +08:00
erio
e4f8799323
fix: include custom_menu_items in GetPublicSettingsForInjection
2026-03-03 06:21:23 +08:00
erio
a50d5d351b
fix: replace curly quotes with straight quotes in domain_constants.go
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-03 06:18:35 +08:00
erio
067810fa98
feat: custom menu pages with iframe embedding and CSP injection
...
Add configurable custom menu items that appear in sidebar, each rendering
an iframe-embedded external page. Includes shared URL builder with
src_host/src_url tracking, CSP frame-src multi-origin deduplication,
admin settings UI, and i18n support.
chore: bump version to 0.1.87.19
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-03 06:18:20 +08:00
QTom
a9285b8a94
feat(gateway): 双模式用户消息队列 — 串行队列 + 软性限速
...
新增 UMQ (User Message Queue) 双模式支持:
- serialize: 账号级分布式串行锁 + RPM 自适应延迟(严格限流)
- throttle: 仅 RPM 自适应前置延迟,不阻塞并发(软性限速)
后端:
- config: 新增 Mode 字段,保留 Enabled 向后兼容
- service: 新增 UserMessageQueueService(Lua 锁/延迟算法/清理 worker)
- repository: 新增 UserMsgQueueCache(Redis Lua acquire/release/force-release)
- handler: 新增 UserMsgQueueHelper(SSE ping + 等待循环 + throttle)
- gateway: 按 mode 分支集成 serialize/throttle 逻辑
- lint: 修复 gofmt rewrite rules、errcheck 类型断言、staticcheck QF1012
前端:
- 三态选择器 UI(关闭/软性限速/串行队列)替代 toggle 开关
- BulkEdit 支持 null 语义(不修改)
- i18n 中英文文案
通过 6 轮专家评审(42 次 review)、golangci-lint、单元测试、集成测试。
2026-03-03 01:05:11 +08:00
zqq61
ec6bcfeb83
fix: OAuth 401 不再永久锁死账号,改用临时不可调度实现自动恢复
...
OAuth 账号收到 401 时,原逻辑同时设置 expires_at=now() 和 SetError(),
但刷新服务只查询 status=active 的账号,导致 error 状态的账号永远无法
被刷新服务拾取,expires_at=now() 实际上是死代码。
修复:
- OAuth 401 使用 SetTempUnschedulable 替代 SetError,保持 status=active
- 新增 oauth_401_cooldown_minutes 配置项(默认 10 分钟)
- 刷新成功后同步清除 DB 和 Redis 中的临时不可调度状态
- 不可重试错误检查(invalid_grant 等)从 Antigravity 推广到所有平台
- 可重试错误耗尽后不再标记 error,下个刷新周期继续重试
恢复流程:
OAuth 401 → temp_unschedulable + expires_at=now → 刷新服务拾取
→ 成功: 清除 temp_unschedulable → 自动恢复
→ invalid_grant: SetError → 永久禁用
→ 网络错误: 仅记日志 → 下周期重试
2026-03-02 22:54:38 +08:00
QTom
fdcbf7aacf
feat(proxy): 集中代理 URL 验证并实现全局 fail-fast
...
提取 proxyurl.Parse() 公共包,将分散在 6 处的代理 URL 验证逻辑
统一收敛,确保无效代理配置在创建时立即失败,永不静默回退直连。
主要变更:
- 新增 proxyurl 包:统一 TrimSpace → url.Parse → Host 校验 → Scheme 白名单
- socks5:// 自动升级为 socks5h://,防止 DNS 泄漏(大小写不敏感)
- antigravity: http.ProxyURL → proxyutil.ConfigureTransportProxy 支持 SOCKS5
- openai_oauth: 删除 newOpenAIOAuthHTTPClient,收编至 httpclient.GetClient
- 移除未使用的 ProxyStrict 字段(fail-fast 已是全局默认行为)
- 补充 15 个 proxyurl 测试 + pricing/usage fail-fast 测试
2026-03-02 16:04:20 +08:00
Wesley Liddick
445bfdf242
Merge pull request #706 from PMExtra/feat/default-subscriptions-on-user-create
...
feat(settings): add default subscriptions for new users
2026-03-02 11:38:26 +08:00