Commit Graph

3128 Commits

Author SHA1 Message Date
IanShaw027 0fa47f18ed feat: complete pending oauth account creation UI 2026-04-21 00:02:51 +08:00
erio a1425b457d feat(channel-monitor): redesign user dashboard as card grid
Reference check-cx UI: INTELLIGENCE MONITOR hero + 3-column card grid
with 60-point timeline bars.

Backend:
- Add PrimaryPingLatencyMs + Timeline[60] to UserMonitorView
- ListRecentHistoryForMonitors: batch CTE + ROW_NUMBER() window query
- indexLatestByModel / indexAvailabilityByModel helpers

Frontend:
- 7 new components: ProviderIcon, MonitorMetricPair, MonitorAvailabilityRow,
  MonitorTimeline, MonitorHero, MonitorCard, MonitorCardGrid
- ChannelStatusView 381→~180 lines (delegated to subcomponents)
- AbortController reload concurrency protection
- HSL 0-120° availability color mapping
- Replace emoji with Icon component (bolt / globe)
- i18n: monitorCommon.* shared namespace, channelStatus.hero.*

Bump VERSION to 0.1.114.24
2026-04-20 23:38:59 +08:00
IanShaw027 7ef7fd19e7 fix: restore wechat payment oauth and jsapi flow 2026-04-20 23:34:57 +08:00
IanShaw027 6f00efa350 fix: support legacy payment method aliases 2026-04-20 23:05:29 +08:00
IanShaw027 e1a28848fa fix: clarify wechat existing account binding 2026-04-20 22:54:47 +08:00
IanShaw027 7fdede579a fix: preserve wechat bind resume state 2026-04-20 22:52:56 +08:00
IanShaw027 4d10ba4297 fix: complete wechat pending auth callback flows 2026-04-20 22:50:41 +08:00
IanShaw027 bffcc2042e fix: complete oidc pending auth callback flows 2026-04-20 22:37:25 +08:00
IanShaw027 724f8e89a1 feat: resolve auth identity migration reports 2026-04-20 22:29:21 +08:00
IanShaw027 452e55a53c feat: add admin auth identity repair binding 2026-04-20 22:22:14 +08:00
IanShaw027 3bd3027251 feat: expose auth identity migration reports 2026-04-20 22:05:33 +08:00
erio bbc4aed3d9 fix(openai): 移除已下线 Codex 模型并修复归一化兜底副作用
- backend: 删除 gpt-5 / 5.1 / 5.1-codex / 5.1-codex-max / 5.1-codex-mini / 5.2-codex / 5.4-nano 的内置映射与 DefaultModels 条目
- backend: normalizeCodexModel 默认兜底由 gpt-5.1 改为 gpt-5.4,gpt-5.3-codex-spark 独立保留映射
- backend: 修复 isOpenAIGPT54Model 与 shouldAutoInjectPromptCacheKeyForCompat 对 claude / gpt-4o 的误判(之前依赖 gpt-5.1 作为非 GPT 族的隐式 sentinel,改后需要显式前缀守卫)
- backend: 清理 billing_service 中已不可达的 fallback 价格与 switch 分支
- frontend: 从白名单、OpenCode 配置、预设映射中移除已下线模型
- 同步更新所有相关单测

Refs: #1758, parallels upstream #1759 but adds downstream guard fixes
2026-04-20 22:01:41 +08:00
IanShaw027 aaf4946b27 fix: normalize pending oauth email lookups 2026-04-20 21:59:03 +08:00
IanShaw027 31d0183d45 fix: normalize repository email lookups 2026-04-20 21:51:57 +08:00
IanShaw027 b309822199 fix: tighten legacy payment provider resolution 2026-04-20 21:46:24 +08:00
IanShaw027 422f60a145 fix: normalize legacy wechat auth identity keys 2026-04-20 21:42:35 +08:00
IanShaw027 f65429145e fix: route legacy linuxdo users to account binding 2026-04-20 21:31:05 +08:00
IanShaw027 5adefb466b fix: finalize oauth identity bindings 2026-04-20 21:24:33 +08:00
IanShaw027 bdcd3d87e5 fix: resolve unique legacy payment providers 2026-04-20 21:09:38 +08:00
IanShaw027 32059ae9d5 fix: backfill email identities on successful login 2026-04-20 20:58:19 +08:00
IanShaw027 9bebf1c1a6 feat: resolve payment results by resume token 2026-04-20 20:53:46 +08:00
IanShaw027 c0b24aefba feat: snapshot payment provider keys on orders 2026-04-20 20:47:14 +08:00
IanShaw027 e3f69e0246 fix: tighten webhook provider resolution 2026-04-20 20:42:01 +08:00
IanShaw027 7c7924e9fa fix: guard payment fulfillment provider mismatch 2026-04-20 20:31:19 +08:00
IanShaw027 97c9b992cb fix: require wechat unionid for oauth identity 2026-04-20 20:27:15 +08:00
erio 40d4e167cd feat(payment): i18n payment error codes and label localization
Pairs with the backend structured payment errors (reason + metadata). The
frontend now maps reason codes to localized messages with metadata as
interpolation variables, and automatically localizes raw config-field names
(e.g. "certSerial" → "证书序列号") using the existing UI-label i18n
namespace.

- frontend/src/utils/apiError.ts
  - extractApiErrorCode now prefers the string `reason` over the numeric HTTP
    `code`; reason is granular enough to drive i18n lookup, HTTP code is not.
  - New extractApiErrorMetadata to pull interpolation params off the error.
  - New extractI18nErrorMessage(err, t, namespace, fallback): looks up
    `<namespace>.<REASON>` in i18n and substitutes metadata. Before
    substitution, `metadata.key` and `metadata.keys` (slash-joined) are
    re-translated through `admin.settings.payment.field_<key>` so users see
    "缺少必填项:证书序列号" instead of "缺少必填项:certSerial".

- frontend/src/i18n/locales/{zh,en}.ts
  - Add payment.errors entries for every structured reason code returned by
    the backend (PAYMENT_DISABLED, INVALID_AMOUNT, TOO_MANY_PENDING,
    DAILY_LIMIT_EXCEEDED, NO_AVAILABLE_INSTANCE, PAYMENT_PROVIDER_MISCONFIGURED,
    WXPAY_CONFIG_MISSING_KEY / INVALID_KEY_LENGTH / INVALID_KEY, NOT_FOUND,
    FORBIDDEN, CONFLICT, INVALID_ORDER_TYPE, INVALID_STATUS,
    BALANCE_NOT_ENOUGH, REFUND_AMOUNT_EXCEEDED, REFUND_FAILED, and more),
    with placeholders for template variables.

- 13 payment-related Vue files
  - Migrate catch-block error reporting from extractApiErrorMessage to
    extractI18nErrorMessage(err, t, 'payment.errors', fallback).
  - Remove the ad-hoc paymentErrorMap computed in SettingsView.vue, which the
    new helper supersedes (it reads i18n directly via t).

- frontend/src/components/payment/providerConfig.ts
  - wxpay: publicKey and publicKeyId are now required (was optional), matching
    the pubkey-only verifier direction; certSerial is already required.

This PR is drop-in safe: reason-preferring extractApiErrorCode is backward
compatible with callers that pass their own i18nMap, and error codes missing
from i18n fall back to the existing message-based path.
2026-04-20 20:23:16 +08:00
IanShaw027 58b2cc380f test: harden payment result resume flow 2026-04-20 20:22:00 +08:00
erio 20a4e41872 feat(monitor): admin channel monitor MVP with SSRF protection and batch aggregation
新增 admin「渠道监控」模块(参考 BingZi-233/check-cx),独立于现有 Channel 体系。
admin 配置 + 后台定时调用上游 LLM chat completions 健康检查 + 所有登录用户只读可见。

后端:
- ent: channel_monitor + channel_monitor_history(AES-256-GCM 加密 api_key)
- service 按职责拆分:service/aggregator/validate/checker/runner/ssrf
- provider strategy map 替代 switch(openai/anthropic/gemini)
- repository batch 聚合(ListLatestForMonitorIDs + ComputeAvailabilityForMonitors)消除 N+1
- runner: ticker(5s) + pond worker pool(5) + inFlight 防并发 + TrySubmit 防雪崩
  + 凌晨 3 点 cron 清理 30 天历史
- SSRF 防护:强制 https + 私网/loopback/云元数据 IP 拒绝(127/8、10/8、172.16/12、
  192.168/16、169.254/16、100.64/10、::1、fc00::/7、fe80::/10)+ DialContext
  在 socket 层防 DNS rebinding
- API key sanitize:擦除 url.Error 与上游响应 body 中的 sk-/sk-ant-/AIza/JWT 模式
- APIKeyDecryptFailed 标志位 + 单 monitor 路径检测,避免空 key 调用上游

handler:
- admin: CRUD + 手动触发 + 历史接口(api_key 脱敏)
- user: 只读列表 + 状态详情(去除 api_key/endpoint)
- ParseChannelMonitorID 共用 + dto.ChannelMonitorExtraModelStatus 共用

前端:
- 路由 /admin/channels/{pricing,monitor} + /monitor(用户只读)
- AppSidebar 父项 expandOnly 支持
- ChannelMonitorView 拆为 8 个子组件 + ChannelStatusView 拆出 detail dialog
- composables/useChannelMonitorFormat + constants/channelMonitor 共享
- i18n monitorCommon namespace 消除 admin/user 两 view 重复

合规:所有文件符合 CLAUDE.md(Go ≤ 500 行 / Vue ≤ 300 行 / 函数 ≤ 30 行)
CI: go build / gofmt / golangci-lint(0 issues) / make test-unit / pnpm build 全绿
2026-04-20 20:21:02 +08:00
IanShaw027 b51bc7ee24 feat: wire payment return url payloads 2026-04-20 20:19:23 +08:00
IanShaw027 7826e9880c feat: support linuxdo pending bind 2fa callback 2026-04-20 19:53:22 +08:00
IanShaw027 fb6204ea8b feat: apply oauth first-bind defaults and pending bind 2fa 2026-04-20 19:53:22 +08:00
erio 79192cf65b feat(payment): harden wxpay config validation with structured errors
Motivation: platform-certificate mode is being phased out by WeChat (2024-10+,
newly-provisioned merchants already cannot download platform certificates at
all), and wxpay config errors currently surface only when an order is being
created — admins have no feedback at save time. Also, errors were returned as
natural-language strings, leaving the frontend no way to localize them.

Changes:

- backend/internal/payment/provider/wxpay.go
  - Replace fmt.Errorf with structured infraerrors.BadRequest errors:
    - WXPAY_CONFIG_MISSING_KEY    (metadata: key)
    - WXPAY_CONFIG_INVALID_KEY_LENGTH  (metadata: key, expected, actual)
    - WXPAY_CONFIG_INVALID_KEY    (metadata: key) for malformed PEMs
  - Parse privateKey and publicKey PEMs in NewWxpay so malformed keys fail
    at save time instead of at order creation.
  - Keep the pubkey verifier (NewSHA256WithRSAPubkeyVerifier) as the single
    supported verifier; no more loadKeyPair helper.

- backend/internal/service/payment_order.go invokeProvider
  - If CreateProvider or CreatePayment returns a structured ApplicationError,
    pass it through (optionally enriching metadata with provider/instance_id)
    instead of wrapping it as generic PAYMENT_GATEWAY_ERROR — so clients see
    the actual reason code (e.g. WXPAY_CONFIG_MISSING_KEY) and can localize.
  - Simplify a few messages (TOO_MANY_PENDING, DAILY_LIMIT_EXCEEDED,
    PAYMENT_GATEWAY_ERROR, NO_AVAILABLE_INSTANCE) to keyword form with
    metadata for template variables.

- backend/internal/service/payment_config_providers.go
  - New helper validateProviderConfig calls provider.CreateProvider at save
    time. Enabled instances are validated on both Create and Update so admins
    see config errors immediately in the dialog, not later at order creation.
  - Disabled instances are not validated (half-filled drafts are allowed).

- backend/internal/payment/provider/wxpay_test.go
  - Add generateTestKeyPair helper that produces valid RSA-2048 PKCS8/PKIX
    PEMs per test, used by the valid-config baseline (prior fake strings no
    longer pass the eager PEM check).
  - Cover each structured-error branch (missing/invalid-length/malformed PEM).
2026-04-20 19:49:45 +08:00
IanShaw027 6ea3f42e2f feat: add oauth callback email binding ui 2026-04-20 19:30:19 +08:00
IanShaw027 6a75bd77e3 feat: add pending oauth email onboarding flow 2026-04-20 19:30:09 +08:00
IanShaw027 d47580a144 test: pin email signup defaults in register tests 2026-04-20 18:42:28 +08:00
IanShaw027 0353c3870f test: update user service stubs for identity summaries 2026-04-20 18:40:34 +08:00
IanShaw027 4e0e691546 feat: apply auth source signup defaults 2026-04-20 18:39:53 +08:00
IanShaw027 c6d8592484 feat: add profile auth identity binding flow 2026-04-20 18:28:44 +08:00
IanShaw027 13d9780df4 feat: expose user activity timestamps in admin list 2026-04-20 17:48:30 +08:00
IanShaw027 e9de839d87 feat: rebuild auth identity foundation flow 2026-04-20 17:39:57 +08:00
IanShaw027 fbd0a2e3c4 feat: carry suggested third-party profile through pending oauth 2026-04-20 16:27:23 +08:00
IanShaw027 d3d4267731 fix: harden oidc callback security 2026-04-20 16:23:42 +08:00
IanShaw027 584ded2182 docs: harden auth identity payment design 2026-04-20 14:41:12 +08:00
IanShaw027 b6751f7ebc docs: add auth identity implementation plan 2026-04-20 13:47:00 +08:00
IanShaw027 721d7ab3ab docs: add audit synthesis to auth identity spec 2026-04-20 13:40:31 +08:00
IanShaw027 e01c1eaceb docs: add auth identity payment foundation design spec 2026-04-20 13:18:30 +08:00
shaw 23def40bc5 chore: change license from MIT to LGPL v3.0 2026-04-19 22:06:04 +08:00
Wesley Liddick f5ee93796d Merge pull request #1753 from touwaeriol/feat/fix-orphaned-scheduled-tests
fix: delete scheduled test plans when account is deleted
2026-04-19 21:14:23 +08:00
Wesley Liddick e8be434498 Merge pull request #1752 from touwaeriol/fix/quota-exceeded-scheduling
fix(account): prevent quota-exceeded API key/Bedrock accounts from being scheduled
2026-04-19 21:14:06 +08:00
Wesley Liddick 061fd48df7 Merge pull request #1749 from touwaeriol/fix/xhigh-reasoning-effort
fix: support xhigh reasoning effort in usage records
2026-04-19 21:13:45 +08:00