Skip to content

fix(plugin-auth,platform-objects): close @better-auth/oauth-provider 1.7 schema drift — restore platform SSO#3080

Merged
os-zhuang merged 2 commits into
mainfrom
fix/oauth-provider-17-schema-drift
Jul 16, 2026
Merged

fix(plugin-auth,platform-objects): close @better-auth/oauth-provider 1.7 schema drift — restore platform SSO#3080
os-zhuang merged 2 commits into
mainfrom
fix/oauth-provider-17-schema-drift

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

问题

better-auth 1.7.0-rc.1 升级(4ab16f8 “pnpm upgrade”)改变了 @better-auth/oauth-provider 的模型 schema,但 sys_oauth_* 平台对象和 auth-schema-config.ts 里的 camelCase→snake_case 映射没有跟上。实测(cloud 本地 rig,三仓 main)平台 SSO token 交换 500:

table sys_oauth_access_token has no column named authorizationCodeId

新字段没有 fieldName 映射时 camelCase 直通(其它列都是 snake_case),列也不存在 —— SQLite 与 prod PG 同炸。这是「Continue with ObjectStack」全环境登录链路的断点之一(另两个在 cloud / objectui,见下)。

修复

补列(1.7 完整对齐):

  • sys_oauth_access_token / sys_oauth_refresh_token:authorization_code_id(带索引)、resourcesrequested_user_info_claimsconfirmation;access 另加 revoked;refresh 另加 rotated_atrotation_replay_responserotation_replay_expires_at
  • sys_oauth_consent:resourcesrequested_user_info_claims
  • sys_oauth_application:jwksjwks_uribackchannel_logout_uribackchannel_logout_session_requireddpop_bound_access_tokens(1.7 的 DCR 会写带默认值的 dpopBoundAccessTokens,同类炸点)

新表(1.7 新增的三个模型):

  • sys_oauth_resource / sys_oauth_client_resource — RFC 8707 resource indicators(MCP OAuth track 的 audience 绑定用)
  • sys_oauth_client_assertion — RFC 7523 client-assertion jti 防重放

已注册进 auth manifest、SystemObjectName、i18n extract config 与 buildOauthProviderPluginSchema();翻译 bundle 重新生成(纯新增,708 insertions / 0 deletions)。

防漂移门(新测试): oauth-provider-schema-parity.test.ts 遍历 已安装 插件声明的 schema(fieldName ?? key 与 better-auth adapter 同逻辑解析),任何对象缺列直接红 —— 下次 better-auth bump 新增字段会在测试期失败而不是 prod 500。这个测试就是本 PR 发现三张新表的来源。

测试

  • plugin-auth:19 files / 452 tests 全过(含新 parity 8/8)
  • platform-objects:5 files / 197 tests 全过(含 bundle-ownership 门)
  • spec:6883 tests 全过
  • turbo build --filter=@objectstack/plugin-auth:11/11 成功

三仓协调

  1. framework(本 PR) — schema 修复,先合
  2. cloudplatform-sso.ts 注册双格式 redirect_uri(新 /api/v1/auth/callback/<provider> + 旧 /oauth2/callback/ 过渡)
  3. objectui — OIDC 登录从 POST /sign-in/oauth2(1.7 已移除)迁到 POST /sign-in/social,带旧路由 fallback

⚠️ cloud 当前 .framework-sha(929efdf)已包含 better-auth 升级点 —— 如果 staging/prod 已滚过含该 pin 的镜像,平台 SSO 现在就是断的;三仓合并后需尽快一起 bump pin 部署。

🤖 Generated with Claude Code

…1.7 schema drift — restore platform SSO

The better-auth 1.7.0-rc.1 bump (4ab16f8 "pnpm upgrade") changed the
oauth-provider model schemas, but the sys_oauth_* platform objects and the
camelCase→snake_case fieldName mappings in auth-schema-config.ts were never
updated. Token exchange then 500s with `table sys_oauth_access_token has no
column named authorizationCodeId`, breaking platform SSO ("Continue with
ObjectStack") end-to-end for every environment login — on SQLite AND
Postgres control planes alike.

- sys_oauth_access_token / sys_oauth_refresh_token: add
  authorization_code_id (indexed), resources, requested_user_info_claims,
  confirmation; access adds revoked; refresh adds rotated_at,
  rotation_replay_response, rotation_replay_expires_at.
- sys_oauth_consent: add resources, requested_user_info_claims.
- sys_oauth_application: add jwks, jwks_uri, backchannel_logout_uri,
  backchannel_logout_session_required, dpop_bound_access_tokens (1.7 DCR
  writes dpopBoundAccessTokens with a default — same crash class).
- New objects for the three models 1.7 introduced: sys_oauth_resource,
  sys_oauth_client_resource (RFC 8707 resource indicators, used by the MCP
  OAuth track), sys_oauth_client_assertion (RFC 7523 jti replay
  prevention); registered in the auth manifest, SystemObjectName, i18n
  extract config, and buildOauthProviderPluginSchema().
- Mappings extended for every camelCase field; regenerated the
  platform-objects translation bundles (additive only).
- NEW oauth-provider-schema-parity.test.ts: iterates the INSTALLED
  plugin's declared schema and fails when any writable column is missing
  from the platform objects — the next better-auth bump that adds fields
  breaks at test time, not in production. (This test is what surfaced the
  three brand-new 1.7 models above.)

Companion changes: cloud registers the ≥1.7 social-flow callback format
(/api/v1/auth/callback/<provider>) alongside the legacy one, and
@object-ui/auth signs OIDC providers in via POST /sign-in/social.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 16, 2026 5:06pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:system tests tooling size/xl labels Jul 16, 2026
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/platform-objects, @objectstack/plugin-auth, packages/qa, @objectstack/spec.

102 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via packages/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/plugin-auth)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-auth, @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/plugin-auth, @objectstack/spec)
  • content/docs/permissions/authentication.mdx (via @objectstack/plugin-auth)
  • content/docs/permissions/authorization.mdx (via packages/qa, @objectstack/spec)
  • content/docs/permissions/delegated-administration.mdx (via packages/qa)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/permissions/sso.mdx (via @objectstack/plugin-auth)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/plugin-auth, @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/platform-objects, @objectstack/plugin-auth, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-auth, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-auth, @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/platform-objects, @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…oken exchange

Drives authorize → code → token → userinfo against a bootStack kernel with
OS_OIDC_PROVIDER_ENABLED, seeding the client row exactly the way cloud's
seedPlatformSsoClient does (hashed secret, skip_consent, client_secret_basic,
≥1.7 /api/v1/auth/callback/<provider> redirect_uri). The token-exchange step
is the hop that 500'd in production on the 1.7 schema drift; verified the
test fails (2/3) when the authorization_code_id column is removed and passes
(3/3) with the fix. Complements the static parity gate in plugin-auth.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
os-zhuang added a commit to objectstack-ai/objectui that referenced this pull request Jul 16, 2026
…h ≥ 1.7) (#2621)

better-auth 1.7 restructured the genericOAuth plugin: generic OAuth/OIDC
providers are injected into the core social sign-in flow and the dedicated
POST /sign-in/oauth2 endpoint no longer exists. `signInWithProvider` with
`type: 'oidc'` therefore 404'd on every click — "Continue with ObjectStack"
(platform SSO) was dead against a current framework server.

Sign in through `signIn.social` first; when the social route rejects the
provider AND the legacy `signIn.oauth2` client method succeeds (an older
< 1.7 server), fall back to it — the coordinated framework/cloud rollout
can't atomically flip every deployment. When both routes fail, surface the
social-route error: on a ≥ 1.7 server it is the real failure, the legacy
route only 404s.

Companion changes: framework adds the better-auth 1.7 sys_oauth_* columns
(objectstack-ai/framework#3080); cloud registers the new
/api/v1/auth/callback/<provider> redirect_uri format alongside the legacy
one.

Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@os-zhuang os-zhuang closed this Jul 16, 2026
@os-zhuang os-zhuang reopened this Jul 16, 2026
@os-zhuang
os-zhuang merged commit 4109153 into main Jul 16, 2026
29 of 31 checks passed
@os-zhuang
os-zhuang deleted the fix/oauth-provider-17-schema-drift branch July 16, 2026 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:system size/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant