Commit 366f895
* chore(deps): move the @better-auth/scim pin off the rc onto the stable line (measurement base, #3653)
Part of #3653. NOT a proposed landing: leg 2' stopped on a scope fork before
the provisioning half could be written, so this branch carries the pin move
alone as the reproducible base every measurement in the report was taken on.
A pin-move-only tree is red by construction (7 failed | 21 passed on the
parity gate) and must never be landed on its own.
- packages/plugins/plugin-auth/package.json 1.7.0-rc.1 -> ^1.7.1
- pnpm-workspace.yaml '@better-auth/scim@<1.7.0-rc.1': '1.7.0-rc.1'
-> '@better-auth/scim@<2.0.0': '^1.7.1'
(major-boundary bound, matching the rest of the family per this file's
own doctrine; the old bound sat AT the rc precisely so a <2.0.0 bound
could not rewrite the stable release down onto it.)
Measured consequences, all reproducible from this commit:
- '^1.7.1' resolves to 1.7.2, not 1.7.1. Every prior measurement on this
epic was taken against 1.7.1. Re-measured on 1.7.2: same seven models,
same three-way constructor predicate, same absent scimProvider.
- scim lands on 1.7.2 while the rest of the family stays 1.7.1. 1.7.2 peers
'@better-auth/core': '^1.7.2' and 'better-auth': '^1.7.2', which 1.7.1
does not satisfy; this repo's existing overrides rewrite those peer ranges
down to '^1.7.1' in the lockfile, so nothing reports the mismatch. One
copy each of better-auth and @better-auth/core remain in the store.
- check:prerelease-pins retires itself: "No prerelease pin left in
pnpm-workspace.yaml overrides - nothing to watch", exit 0.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194kbQJxUvv2yvsGRtuXpP5
* feat(auth,platform-objects,spec): migrate @better-auth/scim to stable 1.7.1 — provision the seven models, app-owned bearer verification (#3653)
Part of #3653 (leg 2' of epic #11632). The pin resolves to 1.7.1 EXACTLY
(not ^1.7.1, which resolves to 1.7.2 whose better-auth/core ^1.7.2 peers
only the workspace overrides' silencing would 'satisfy'; floating is its
own follow-up card).
- pnpm-workspace.yaml + plugin-auth: exact 1.7.1 pin, stale rc-hold
comment blocks rewritten to the landed state.
- packages/platform-objects/src/identity/: the seven stable models
provisioned as platform objects (scimConnectionBinding, scimGroup,
scimGroupMember, scimIdentityTombstone, scimProjectionGrant,
scimSubject, scimUser) plus sys_scim_connection_credential, the
ObjectStack-owned credential store for the app-owned verifyBearerToken
route (stable upstream stores no credential at all). Translation
bundles regenerated with pnpm i18n:extract only.
- packages/spec platform-object-names.ts: eight additive registry names
(the measured-unsplittable spec edit; sys_scim_provider stays — its
retirement is #11757's).
- plugin-security BETTER_AUTH_MANAGED_OBJECTS: the seven library-managed
names, forced additively by the bidirectional drift pin
(default-permission-sets.test.ts) the moment the objects declare
managedBy: 'better-auth'.
- plugin-auth scim-connection-service.ts: mint + digest + verify owned
outright; at rest only HMAC-SHA-256(secret, domain-separated bearer),
base64url — at parity or better than the rc.1 unsalted SHA-256.
- auth-manager.ts: stable constructor shape — connections: [] plus
authentication.verifyBearerToken resolving the connection from a
sys_scim_connection_credential row at request time; auth secret
resolved once (memoized) so digests and better-auth share key material.
- objectql-adapter.ts: seven AUTH_MODEL_TO_PROTOCOL bridge entries, and
NATIVE adapter transactions over engine.transaction({ require: true })
— stable scim refuses the sequential fallback by assertion.
- better-auth-schema-parity.test.ts: KNOWN_UNMAPPED_MODELS shrinks to
the empty set (exact-set assertion kept, both directions).
- credential-at-rest-posture.test.ts: restructured honestly — the
upstream-cleartext control arm is no longer measurable (upstream
stores nothing); its successor pins that vacating fact plus the keyed
digest relationship, negatives for the unkeyed/wrong-key/undomained
shapes, and live 200/401 rejection paths incl. revocation and expiry.
Co-authored-by: Claude <noreply@anthropic.com>
* feat(cli,create-objectstack): retire the @better-auth/scim>better-call suppression with the pin; adapter transaction degrades declared (#3653)
Epic item 7, same stroke as the pin move: stable 1.7.1 peers
better-call@1.4.0 exactly, so the rc-era allowedVersions key retires in
its two declared places (SCAFFOLD_ALLOWED_PEER_VERSIONS and the blank
template) and both presence ratchets flip to absence pins. The
better-auth>better-sqlite3 and four @better-auth/utils entries stay —
re-derived from the tree, their conditions are separate and unmet; the
separation pin now guards that they survived the retirement.
Adapter transactions: better-auth routes its own multi-writes (sign-up
included) through adapter.transaction — measured: a fail-closed
require:true 500'd every sign-up on the memory engine — so the
implementation keeps the two declared degrades those flows always had
(no-transaction-API engines run the callback directly; drivers without
beginTransaction follow the engine's ADR-0119 D1 warn-once degrade).
SQL drivers get real atomic transactions.
Also: changeset (minor across the six touched published packages, level
argued in the body), and two stale-prose corrections where files
described the retired rc.1 storeSCIMToken wiring as current.
Co-authored-by: Claude <noreply@anthropic.com>
* fix(scripts): retire check-prerelease-pin-watch's repo-anchored self-test with the pin (#3653)
The watch script promised to retire itself when the last prerelease pin
went stable, and its CLI does (empty watch list is the success state) —
but its --self-test kept an anti-vacuity assertion that the repo's own
pnpm-workspace.yaml parses to a NON-empty watch list, so the 'Stable
release watch for prerelease pins' job went red on the very commit that
redeemed the pin. Flip the pair to the retired state without opening the
hole the old check guarded: the overrides block must still parse
non-empty (a parser break cannot masquerade as retirement), and the
derived watch list must be empty, with the failure text instructing how
to flip back if a prerelease pin ever reappears.
Reproduced the CI failure locally before the fix (self-test exit 1, same
failing line) and measured exit 0 after; check-self-test-workflow-commands
green (140 scripts scanned).
Co-authored-by: Claude <noreply@anthropic.com>
* fix(auth): scope the adapter's native transactions to SCIM protocol requests (#3653)
Measured twice on the unscoped variant: better-auth wraps whole request
flows in adapter.transaction (runWithTransaction), so opening a real
driver transaction around every sign-in/sign-up starved the
single-connection sqlite pools — the dogfood showcase boot deadlocked on
'Acquire connection error' until the 180s hook timeout, in CI and
reproduced locally on this branch, with 337 sibling dogfood tests green.
The scim verifier now marks its request's async chain (AsyncLocalStorage
enterWith), and config.transaction opens a real engine.transaction only
inside that scope — exactly where assertNativeSCIMTransactions demands
atomicity. Every other better-auth flow keeps the sequential behaviour
it has always had under the factory's as-is fallback, so nothing existing
weakens. Re-measured after the fix: the deadlocked dogfood file passes in
19s (13/13), the credential-at-rest suite (which drives a real SCIM 2.0
request through the scoped transaction over better-sqlite3) stays green,
and the full plugin-auth suite is 81 files / 1660 tests green.
Co-authored-by: Claude <noreply@anthropic.com>
---------
Co-authored-by: os-litant <litant.dev@proton.me>
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 340c5e5 commit 366f895
39 files changed
Lines changed: 4240 additions & 448 deletions
File tree
- .changeset
- packages
- cli
- src/commands
- test
- create-objectstack/src
- templates/blank
- platform-objects
- scripts
- src
- apps/translations
- identity
- plugins
- plugin-auth
- src
- plugin-security/src/objects
- spec/src/system/constants
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
121 | 117 | | |
122 | 118 | | |
123 | 119 | | |
| |||
167 | 163 | | |
168 | 164 | | |
169 | 165 | | |
170 | | - | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
171 | 169 | | |
172 | 170 | | |
173 | 171 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
333 | 333 | | |
334 | 334 | | |
335 | 335 | | |
336 | | - | |
337 | | - | |
338 | | - | |
339 | | - | |
340 | | - | |
341 | | - | |
342 | | - | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
343 | 345 | | |
344 | 346 | | |
345 | 347 | | |
| |||
384 | 386 | | |
385 | 387 | | |
386 | 388 | | |
387 | | - | |
388 | | - | |
389 | | - | |
390 | | - | |
391 | | - | |
392 | | - | |
393 | | - | |
394 | | - | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
395 | 399 | | |
396 | 400 | | |
397 | 401 | | |
| |||
Lines changed: 10 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
502 | 502 | | |
503 | 503 | | |
504 | 504 | | |
505 | | - | |
506 | | - | |
507 | | - | |
508 | | - | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
509 | 512 | | |
510 | | - | |
511 | | - | |
512 | | - | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
513 | 516 | | |
514 | 517 | | |
515 | 518 | | |
| |||
Lines changed: 3 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
53 | 50 | | |
54 | 51 | | |
55 | 52 | | |
| |||
75 | 72 | | |
76 | 73 | | |
77 | 74 | | |
78 | | - | |
79 | 75 | | |
80 | 76 | | |
81 | 77 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
104 | 104 | | |
105 | 105 | | |
106 | 106 | | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
107 | 115 | | |
108 | 116 | | |
109 | 117 | | |
| |||
241 | 249 | | |
242 | 250 | | |
243 | 251 | | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
244 | 262 | | |
245 | 263 | | |
246 | 264 | | |
| |||
Lines changed: 5 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
29 | 34 | | |
30 | 35 | | |
31 | 36 | | |
| |||
0 commit comments