Skip to content

Commit 9f060e5

Browse files
authored
chore(deps)!: better-auth 1.7.0-rc.2 + the production-dependency batch (#3517) (#3632)
Replaces dependabot #3517 (stale base; its three red checks are fixed here) and carries the better-auth family from 1.7.0-rc.1 to 1.7.0-rc.2. BREAKING: rc.2 restructures account identity — `account.accountId` is now `providerAccountId`, `account.issuer` is required, and lookups key on (issuer, providerAccountId). The field mapping, sys_account schema, unlink endpoint body, and client SDK follow; a boot-time backfill stamps pre-1.7 rows and reports what it cannot derive rather than guessing. SecondaryStorage also gained required `getAndDelete` + `increment`, both now implemented over the kernel cache service. @better-auth/scim stays at 1.7.0-rc.1 — rc.2 replaces that plugin wholesale (code-defined connections, six new models, no generate-token endpoint), an ADR-0071 feature migration rather than a version bump.
1 parent 9ab7f1b commit 9f060e5

29 files changed

Lines changed: 1214 additions & 509 deletions
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
"@objectstack/plugin-auth": major
3+
"@objectstack/platform-objects": major
4+
"@objectstack/client": major
5+
"@objectstack/cli": patch
6+
"@objectstack/create-objectstack": patch
7+
"@objectstack/plugin-hono-server": patch
8+
"@objectstack/plugin-pinyin-search": patch
9+
"@objectstack/hono": patch
10+
---
11+
12+
chore(deps)!: better-auth 1.7.0-rc.2 (account identity restructuring) + the
13+
production-dependency batch from #3517
14+
15+
**better-auth 1.7.0-rc.1 → 1.7.0-rc.2** across the family (`better-auth`,
16+
`@better-auth/core`, `@better-auth/oauth-provider`, `@better-auth/sso`, and the
17+
adapter/telemetry overrides). `@better-auth/scim` deliberately stays on
18+
1.7.0-rc.1 — rc.2 replaces its whole model (code-defined connections; the
19+
`scimProvider` model and the generate-token endpoint are gone), which is a
20+
feature migration, not a version bump. Its peer range accepts rc.2 core, and the
21+
advisory that forced the original pin (GHSA-j8v8-g9cx-5qf4) is still fixed.
22+
23+
**BREAKING — account identity.** better-auth renamed `account.accountId` to
24+
`account.providerAccountId` and added a REQUIRED `account.issuer`; sign-in now
25+
resolves accounts by `(issuer, providerAccountId)`.
26+
27+
- FROM `fields: { accountId: 'account_id' }` → TO
28+
`fields: { issuer: 'issuer', providerAccountId: 'account_id' }`. The provider
29+
account id keeps its `account_id` column — only the better-auth-side name
30+
moved — and `sys_account` gains an `issuer` column.
31+
- FROM `internalAdapter.createAccount({ providerId, accountId, … })` → TO
32+
`createAccount({ providerId, issuer, providerAccountId, … })`. A local
33+
password account carries the issuer better-auth mints for itself,
34+
`local:credential`.
35+
- FROM `client.auth.accounts.unlink({ providerId, accountId })` → TO
36+
`unlink({ accountId })`, where `accountId` is now the account ROW id (the `id`
37+
from `accounts.list()`), matching better-auth's narrowed body.
38+
`accounts.list()` returns `issuer` + `providerAccountId` in place of
39+
`accountId`.
40+
41+
**Existing deployments:** rows written before 1.7 have no issuer and are
42+
invisible to sign-in until stamped. The auth plugin now runs an idempotent
43+
boot-time backfill that stamps what it can derive — `local:credential` for
44+
password accounts, `local:oauth:<providerId>` for configured social providers,
45+
and the registered IdP's real `iss` from `sys_sso_provider` for federated ones.
46+
Accounts from a federated IdP that is no longer registered cannot be derived;
47+
they are logged with their provider id and row count rather than guessed, and
48+
those users cannot sign in through that provider until the row is stamped with
49+
the IdP's issuer or removed so a fresh login re-links it.
50+
51+
**Also required by 1.7:** `SecondaryStorage` gained two mandatory methods, both
52+
now implemented over the kernel cache service — `getAndDelete` (single-use
53+
verification values) and `increment` (fixed-window rate-limit counter;
54+
`rateLimit.storage: 'secondary-storage'` throws at boot without it).
55+
56+
The rest of #3517's production-dependency batch rides along: `@oclif/core`
57+
4.13.0, `@hono/node-server` 2.0.12, `hono` 4.12.32, `tar` 7.5.22, `jose` 6.2.4,
58+
`pinyin-pro` 3.28.2, plus the private docs app's fumadocs/next/react bumps.

apps/docs/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
"postinstall": "fumadocs-mdx"
1414
},
1515
"dependencies": {
16-
"fumadocs-core": "16.11.5",
16+
"fumadocs-core": "16.12.1",
1717
"fumadocs-mdx": "15.2.0",
18-
"fumadocs-ui": "16.11.5",
19-
"lucide-react": "^1.25.0",
18+
"fumadocs-ui": "16.12.1",
19+
"lucide-react": "^1.27.0",
2020
"mermaid": "^11.16.0",
21-
"next": "16.2.11",
21+
"next": "16.2.12",
2222
"next-themes": "^0.4.6",
23-
"react": "^19.2.7",
24-
"react-dom": "^19.2.7",
23+
"react": "^19.2.8",
24+
"react-dom": "^19.2.8",
2525
"tailwind-merge": "^3.6.0",
2626
"unist-util-visit": "^5.1.0"
2727
},

content/docs/permissions/authentication.mdx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,10 +945,17 @@ The plugin bridges this gap using better-auth's official **`modelName` / `fields
945945
// Declared in the betterAuth() config via AUTH_*_CONFIG constants:
946946
user: { modelName: 'sys_user', fields: { emailVerified: 'email_verified', … } },
947947
session: { modelName: 'sys_session', fields: { userId: 'user_id', expiresAt: 'expires_at', … } },
948-
account: { modelName: 'sys_account', fields: { providerId: 'provider_id', accountId: 'account_id', … } },
948+
account: { modelName: 'sys_account', fields: { providerId: 'provider_id', issuer: 'issuer', providerAccountId: 'account_id', … } },
949949
verification: { modelName: 'sys_verification', fields: { expiresAt: 'expires_at', … } },
950950
```
951951

952+
better-auth 1.7 identifies an account by `(issuer, providerAccountId)``providerAccountId` is
953+
the field formerly called `accountId` (same `account_id` column) and `issuer` names the authority
954+
that vouched for it: an OIDC `iss` for federated logins, or a synthetic `local:credential` /
955+
`local:oauth:<providerId>` for providers that carry none. Rows written before 1.7 have no issuer,
956+
so the auth plugin stamps them once at boot; accounts from a federated IdP that is no longer
957+
registered cannot be derived and are reported in the boot log instead of guessed.
958+
952959
The ObjectQL adapter factory (`createObjectQLAdapterFactory`) then uses better-auth's `createAdapterFactory`
953960
which automatically transforms all data and where-clauses using these mappings — no manual
954961
camelCase ↔ snake_case conversion is needed in the adapter.

packages/adapters/hono/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"devDependencies": {
2828
"@objectstack/runtime": "workspace:*",
29-
"hono": "^4.12.31",
29+
"hono": "^4.12.32",
3030
"typescript": "^6.0.3",
3131
"vitest": "^4.1.10"
3232
},

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
"@objectstack/trigger-schedule": "workspace:*",
9090
"@objectstack/types": "workspace:*",
9191
"@objectstack/verify": "workspace:*",
92-
"@oclif/core": "^4.11.14",
92+
"@oclif/core": "^4.13.0",
9393
"bundle-require": "^5.1.0",
9494
"chalk": "^5.6.2",
9595
"chokidar": "^5.0.0",

packages/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"@objectstack/spec": "workspace:*"
2323
},
2424
"devDependencies": {
25-
"@hono/node-server": "^2.0.10",
25+
"@hono/node-server": "^2.0.12",
2626
"@objectstack/driver-memory": "workspace:*",
2727
"@objectstack/hono": "workspace:*",
2828
"@objectstack/objectql": "workspace:*",

packages/client/src/index.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,19 +2233,23 @@ export class ObjectStackClient {
22332233
return { accounts: accounts as Array<{
22342234
id: string;
22352235
providerId: string;
2236-
accountId: string;
2236+
/** Authority that vouched for `providerAccountId` — an OIDC issuer, or `local:…`. */
2237+
issuer: string;
2238+
/** The user's id at the provider — better-auth 1.7 renamed this from `accountId`. */
2239+
providerAccountId: string;
22372240
createdAt?: string;
22382241
updatedAt?: string;
22392242
}> };
22402243
},
22412244

22422245
/**
22432246
* Unlink a provider connection.
2244-
* better-auth: POST /unlink-account — `{ providerId, accountId? }`.
2245-
* `accountId` is required when the user has more than one account
2246-
* for the same provider.
2247+
* better-auth: POST /unlink-account — `{ accountId }`, where `accountId`
2248+
* is the account ROW id (the `id` from `accounts.list()`), NOT the user's
2249+
* id at the provider. 1.7 narrowed the body from the old
2250+
* `{ providerId, accountId? }` pair; the row id implies the provider.
22472251
*/
2248-
unlink: async (req: { providerId: string; accountId?: string }) => {
2252+
unlink: async (req: { accountId: string }) => {
22492253
const route = this.getRoute('auth');
22502254
const res = await this.fetch(`${this.baseUrl}${route}/unlink-account`, {
22512255
method: 'POST',

packages/create-objectstack/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"dependencies": {
2323
"chalk": "^5.6.2",
2424
"commander": "^15.0.0",
25-
"tar": "^7.5.21"
25+
"tar": "^7.5.22"
2626
},
2727
"devDependencies": {
2828
"@types/node": "^26.1.1",

packages/platform-objects/src/apps/translations/en.objects.generated.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ export const enObjects: NonNullable<TranslationData['objects']> = {
382382
label: "Provider ID",
383383
help: "OAuth provider identifier (google, github, etc.)"
384384
},
385+
issuer: {
386+
label: "Issuer",
387+
help: "Authority that vouched for the provider account id — an OIDC issuer, or local:… for providers without one"
388+
},
385389
account_id: {
386390
label: "Provider Account ID",
387391
help: "User's ID in the provider's system"

packages/platform-objects/src/apps/translations/es-ES.objects.generated.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ export const esESObjects: NonNullable<TranslationData['objects']> = {
382382
label: "ID del proveedor",
383383
help: "Identificador del proveedor OAuth (google, github, etc.)."
384384
},
385+
issuer: {
386+
label: "Emisor",
387+
help: "Autoridad que avaló el id de cuenta del proveedor: un emisor OIDC, o local:… para proveedores que no tienen uno"
388+
},
385389
account_id: {
386390
label: "ID de cuenta del proveedor",
387391
help: "ID del usuario en el sistema del proveedor."

0 commit comments

Comments
 (0)