877 Commits

Author SHA1 Message Date
shaw
91da815993 feat(risk-control): 内容审计新增关键词拦截 2026-05-20 11:13:53 +08:00
Wesley Liddick
03730fbcf3
Merge pull request #2585 from Arron196/feature/channel-monitor-openai-detection
优化渠道监控 OpenAI 检测协议与内置模板
2026-05-20 08:50:44 +08:00
Wesley Liddick
74e35a0150
Merge pull request #2582 from wucm667/feat/channel-pricing-sync-models
feat(channels): 模型定价支持一键同步最新模型
2026-05-20 08:43:10 +08:00
Wesley Liddick
44c13e7a73
Merge pull request #2578 from wucm667/feat/payment-force-qrcode
feat(payment): 支持强制移动端统一使用二维码支付
2026-05-20 08:41:29 +08:00
benjamin
917bd877ae feat(channel-monitor): 暴露 API 模式接口字段
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-19 22:05:43 +08:00
wucm667
92ad68a314 feat(channels): 模型定价支持一键同步最新模型
从 LiteLLM 定价目录中读取指定平台的最新模型列表,
将尚未录入的模型以新定价条目(价格留空)的形式追加,
管理员只需点击同步最新模型按钮即可完成操作。

- backend/service: PricingService 新增 ListModelNamesByProvider
- backend/handler: ChannelHandler 新增 SyncPricingModels (GET /api/v1/admin/channels/pricing/sync-models)
- backend/routes: 注册新路由(在 /:id 通配符之前)
- backend/wire_gen: 手动更新 NewChannelHandler 调用
- frontend/api: channels.ts 新增 syncPricingModels
- frontend/i18n: zh.ts / en.ts 新增 5 个 key
- frontend/view: ChannelsView 定价区域标题行新增「同步最新模型」按钮
- tests: pricing_service_test + channel_handler_test 新增单元测试
2026-05-19 20:32:32 +08:00
name
2eb622f2f6 Remove ops retry replay storage 2026-05-19 19:37:41 +08:00
wucm667
e4c7927eff feat(payment): 支持强制移动端统一使用二维码支付 2026-05-19 18:22:12 +08:00
Wesley Liddick
21ae52c01f
Merge pull request #2571 from sherlockwhite/fix/openai-account-email-and-usage-refresh
fix(accounts): show email and fix usage refresh for OpenAI OAuth accounts
2026-05-19 16:56:26 +08:00
Wesley Liddick
2a242aec0f
Merge pull request #2573 from wucm667/feat/redeem-code-expiry
feat(redeem): 兑换码支持设置使用有效期
2026-05-19 16:25:12 +08:00
Wesley Liddick
66fca3d598
Merge pull request #2572 from wucm667/fix/openai-silent-refusal-failover
fix(openai): 识别上游静默拒绝(空流+finish_reason=stop)并触发 failover
2026-05-19 16:15:54 +08:00
Wesley Liddick
a929e285ce
Merge pull request #2271 from StarryKira/fix/redact-account-credentials
fix(security): 屏蔽 admin 账号接口返回的敏感凭证字段
2026-05-19 16:15:36 +08:00
Wesley Liddick
32037cb17b
Merge pull request #2570 from wucm667/fix/ops-sla-exclude-ip-denied
fix(ops): 用户 IP 限制导致的 ACCESS_DENIED 不计入 SLA 错误
2026-05-19 16:03:16 +08:00
wucm667
e4aaf0af29 feat(redeem): 兑换码支持设置使用有效期 2026-05-19 15:53:28 +08:00
wucm667
6381f9e37d fix(openai): 识别上游静默拒绝并触发 failover 2026-05-19 15:48:36 +08:00
chenjian
41e7ae534c fix(accounts): fix OpenAI OAuth usage quota never refreshing on manual refresh
The refresh button had no effect because two independent gates blocked
the Codex probe:

1. isOpenAICodexSnapshotStale returned false for non-WS-v2 accounts even
   when data was stale — this is correct for background auto-refresh (Codex
   quota is only auto-tracked for Codex CLI / WS v2 accounts), so this
   behavior is preserved.

2. shouldProbeOpenAICodexSnapshot had a 10-min in-memory rate limit with
   no bypass for explicit user requests.

Fix: add a force parameter threaded from handler → GetUsage → getOpenAIUsage
→ shouldProbeOpenAICodexSnapshot. When force=true (manual refresh button),
both gates are bypassed and the probe always runs. Background auto-loads
continue to respect the original WS v2 logic and 10-min rate limit.
2026-05-19 15:43:21 +08:00
wucm667
271aba1abe fix(ops): exclude IP-denied access from SLA 2026-05-19 15:41:54 +08:00
Wesley Liddick
1b6ed24c33
Merge pull request #2492 from DaydreamCoding/feat/dingtalk-login
feat(dingtalk): 钉钉 OAuth 登录接入 + internal_only 用户属性同步
2026-05-19 15:36:13 +08:00
DaydreamCoding
b19da9c7fe feat(dingtalk): 钉钉 OAuth 登录接入与 internal_only 用户属性同步
⚠️ 应用类型约束:当前实现仅支持「钉钉登录-企业内部应用」(DingTalk 开放平台
internal_app 类型)。第三方个人应用、第三方企业应用类型暂不支持——OAuth 流程
相同但 corp 校验、跨企业行为不同。backend 通过 DingTalkAppKind 校验对非
internal_app 类型 fail-closed(硬约束)。

钉钉 OAuth 登录主链
- 4 步 OAuth 链:ExchangeCodeForUserToken / GetUnionIdByUserToken /
  GetUserIdByUnionId / GetStaffInfoByUserId;app token 缓存
- pending session 机制持久化 OAuth 中间态;cookie-only token 持久化
- 三种分流:bind_login_required / email_completion / choose_account_action
- corp_restriction_policy 支持 none + internal_only;stale "whitelist" 在
  加载层与写入层均静默 coerce 为 none + slog.Warn
- bypass_registration 开关:企业内部模式豁免全局 REGISTRATION_DISABLED
- isReservedEmail / signup_source / canUnbindProvider / OAuth pending flow
  等横切点支持 dingtalk provider
- migration 136:4 表 CHECK 约束加入 'dingtalk' provider 值

internal_only 模式同步企业邮箱/姓名/部门到用户属性
- SyncCorpEmail / SyncDisplayName / SyncDept 三个独立开关 + 对应
  SyncXxxAttrKey 目标属性 key(默认 dingtalk_email / dingtalk_name /
  dingtalk_department);非 internal_only policy 在写入层与加载层均
  coerce 为 false,admin handler 与 setting_service 双层兜底
- 同步语义:首次注册写 users.username(昵称优先 → 企业姓名 fallback),
  之后每次登录刷新 3 个属性;空值也写入以覆盖旧值
- 邮箱三级 fallback:org_email > email > extension["企业邮箱"]
  (钉钉自定义字段 JSON)
- 部门路径递归向上拼接,跳过 dept_id=1 选首个真实子部门,剥离根组织名
- GetUnionIdByUserToken 同时返回 OIDC /contact/users/me 的 nick 字段;
  新增 GetDeptInfo 调用 OAPI /topapi/v2/department/get
- AuthHandler 注入 UserAttributeService;OAuth pending flow 在
  createPendingOAuthAccount / bindPendingOAuthLogin 分别派发到
  AfterRegistration(syncUsername=true)/ AfterLogin
- migration 137 seed dingtalk_email/name/department 三个用户属性定义

附带修复(同集成路径暴露的两个 OAuth 注册回归)
- LoginOrRegisterOAuthWithTokenPair 新建用户分支用 inferLegacySignupSource
  覆写 caller 显式传入的 signupSource,导致 dingtalk/linuxdo/oidc/wechat
  渠道授权按 email 渠道读取;改为只在 caller 未显式传入时回退邮箱推断
- mergeProviderDefaultGrantSettings 把 parse fallback 默认值
  (Concurrency=5 / Balance=0) 当作"未配置"哨兵,admin 显式设 5 时被误判
  退回全局默认(复现:全局默认 1 + 渠道默认并发 5 + grant_on_signup → 新
  用户实际 concurrency=1);去掉哨兵,admin 任何 >=0 值都覆盖 globalDefaults

前端
- DingTalk Login / Callback / EmailCompletion / ChoiceAccount / Error
  视图;router + auth API client
- admin SettingsView:corp policy radio(none / internal_only)+ bypass
  注册开关 + i18n;internal_only 下展示三同步开关 + 目标 attr key 下拉
  (拉取 user attribute definitions),展示 fieldEmail /
  qyapi_get_department_list 钉钉权限申请提示
- Profile:S1 主动绑定 / S5 解绑钉钉按钮 + 合成邮箱防自锁

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 15:27:47 +08:00
DaydreamCoding
664e9fdcd4 feat(usage): 用户用量按平台拆分 + UsersView 列设置可配置 + 用量列排序
后端
- BatchUserUsageStats / UserDashboardStats 新增 ByPlatform 字段
  复用 ops 路径 COALESCE(g.platform, a.platform) 语义,不冗余 DB 字段
- 抽出 usageLogEffectivePlatformExpr 常量供管理员与用户两路径共用
- GetBatchUsersUsage cacheKey 加 v=2 + 当日日期,修复跨午夜旧缓存兼容新字段

前端
- 新建 PlatformUsageBreakdown:管理员用量列 hover tooltip 展示各平台 today/total
- 新建 PlatformCostCell:单平台 today/total 紧凑单元格
- UsersView 列设置新增 Claude/OpenAI/Gemini/Antigravity 四个平台子列,默认隐藏可手动启用
- 普通用户 Dashboard 新增 Row 3 平台拆分卡片,受 isSimple 控制
- 平台之和 < 总值时显式展示"其他"行,避免数字对不齐
- last_active_at 从 FORCED_VISIBLE_COLUMNS 移除,允许用户隐藏并持久化
- 列设置加 schema 版本号 + 迁移机制,老用户升级时新增默认隐藏列自动应用
- UsersView 用量列(汇总 + 4 平台子列)加入前端单页排序:列头单按钮 + 弹出菜单
  切换"今日 / 近30天",三态循环 desc → asc → off;菜单底部备注"仅对本页数据排序"
- sortedUsers computed 在 server-side-sort 结果之上叠加本地排序,缺失值按 0 处理;
  usageSort 状态独立 localStorage 持久化,互不干扰后端 sort_by
- i18n 新增 admin.users.sortBy / sortCurrentPageOnly

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:25:34 +08:00
Wesley Liddick
8a4ee578cb
Merge pull request #2451 from wucm667/codex/issue-2237-gemini-chat-completions
fix(gateway): 修复 Gemini 组 Chat Completions 路由
2026-05-19 14:47:52 +08:00
Wesley Liddick
e365aae450
Merge pull request #2450 from wucm667/codex/issue-2431-responses-api-support
feat: 支持后台配置 OpenAI Responses API 路由
2026-05-19 14:47:10 +08:00
Wesley Liddick
03473d3ee8
Merge pull request #2554 from Arron196/feature/sync-upstream-models-pr
feat: 支持从上游同步账号可用模型列表
2026-05-19 14:42:47 +08:00
Wesley Liddick
a340002c6d
Merge pull request #2401 from 2ue/fix/normalize-image-billing-size
修复图片计费尺寸归一化与使用记录展示
2026-05-19 14:00:24 +08:00
benjamin
36c00374d3 feat: expose upstream model sync admin API
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 19:01:33 +08:00
benjamin
6acb46c113 fix: 标记通用网关本地调度容量错误
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 16:52:32 +08:00
benjamin
429adbc721 fix: 标记 OpenAI 本地调度容量错误
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 16:52:20 +08:00
benjamin
ae6ee23e2e fix: 调整 Ops 错误分类的 SLA 排除逻辑
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 16:52:06 +08:00
wucm667
2ec1d331e0 fix(gateway): return Gemini models for Gemini groups 2026-05-15 11:33:26 +08:00
wucm667
041d138f76 fix(gateway): route Gemini chat completions upstream 2026-05-14 11:48:00 +08:00
wucm667
862819042c feat(openai): 支持后台配置 Responses API 路由 2026-05-14 11:46:24 +08:00
2ue
bb4c1abe28 Fix image billing size normalization 2026-05-12 15:21:31 +08:00
shaw
a07a0dac63 feat: add configurable Antigravity user agent version 2026-05-11 22:25:20 +08:00
shaw
9377c96746 fix: 让消息 cache_control 改写默认关闭 2026-05-11 21:26:41 +08:00
ZeroDeng
37ec21e1a5
Merge branch 'main' into dev 2026-05-11 11:48:55 +08:00
ZeroDeng
f788e6bdba fix(service): handle unexpected default transport type, simplify warning append 2026-05-11 11:43:44 +08:00
shaw
b23055af5b feat: add Airwallex payments and multi-currency support 2026-05-11 11:17:26 +08:00
shaw
33db04fb75 chore: 修复 CI 安全与 lint 检查 2026-05-08 14:42:20 +08:00
shaw
fda1ed459d feat: 优化 OAuth 账号导入流程 2026-05-08 11:36:09 +08:00
haruka
0f8e2d0934 fix(security): 屏蔽 admin 账号接口返回的敏感凭证字段
Account.Credentials 是 JSONB map,混合存放可编辑的非敏感配置(base_url、
model_mapping、project_id 等)与敏感秘钥(OAuth access/refresh/id token、
API key、AWS secret、Vertex private key 等)。当前所有 admin 账号接口直接
透传该 map,token 经由浏览器 DevTools、抓包、日志等途径泄漏。

- service 包新增 SensitiveCredentialKeys 清单与 MergePreservingSensitiveCreds
  作为单一权威定义。
- dto 层 RedactCredentials 在响应里剥离敏感子键,输出 credentials_status
  (has_<key> 布尔标识)告知前端存在性,不暴露原值。
- AccountFromServiceShallow 接入脱敏,覆盖 list、get、create、update、
  refresh、batch、bulk-update、OAuth 创建等 9 个 handler。
- service.UpdateAccount 改为合并语义:incoming 没传敏感键则保留 existing,
  让前端"全对象 PUT"流程在脱敏后无感工作;显式提供新 token 仍会覆盖。
- 前端 EditAccountModal 修复脱敏后会崩的两处兜底:apikey 必填检查和
  Vertex SA JSON 存在性校验改读 credentials_status.has_*。
- 导出端点 /admin/accounts/data 走独立的 DataAccount 结构,按设计保留
  完整 credentials 作为管理员备份路径。

测试:RedactCredentials 单元测试、mapper 端到端 JSON 断言(确认序列化
后无 token 子串)、UpdateAccount 合并语义三种场景(保留 / 覆盖 / 空 map 跳过)。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 03:44:04 +08:00
shaw
e872cbec0b feat: 添加登录注册条款确认 2026-05-07 17:35:05 +08:00
shaw
0eca600ffa fix moderation key handling and key UI 2026-05-07 14:31:19 +08:00
Wesley Liddick
e69319e747
Merge pull request #2224 from lyen1688/feat-email-oauth-github-google
feat: 增加 GitHub 和 Google 邮箱快捷登录
2026-05-07 10:07:28 +08:00
shaw
989f87fe08 fix: harden markdown page image paths 2026-05-07 10:05:49 +08:00
Wesley Liddick
d52da45363
Merge pull request #2202 from Michael-Jetson/main
新增三大功能:兑换码邀请返利、批量修改用户并发数、Markdown页面渲染
2026-05-07 09:35:14 +08:00
shaw
fff4a300c6 feat(risk-control): add content moderation audit 2026-05-07 09:14:47 +08:00
lyen1688
e69256a706 fix: 完善邮箱快捷登录注册流程 2026-05-06 20:52:10 +08:00
lyen1688
93f884b719 fix: 优化 GitHub OAuth 邮箱验证赋值 2026-05-06 16:42:12 +08:00
lyen1688
af550fa64e feat: 增加 GitHub 和 Google 邮箱快捷登录 2026-05-06 16:06:11 +08:00
Michael-Jetson
cf2d5067c3 fix(security): add JWT auth + visibility check to pages API
- GET /pages/:slug now requires JWT + checks custom_menu_items visibility
- GET /pages (list) is admin-only
- GET /pages/:slug/images/* uses visibility check without JWT (browser
  img tags cannot carry auth headers), blocks admin-only page images
- Frontend fetch adds Authorization header from authStore.token
- settingService nil guard changed to fail-closed (deny access)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-05 07:00:08 -07:00