@riffdb/better-auth 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +90 -14
- package/README.md +157 -25
- package/dist/adapter.d.ts +7 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +385 -47
- package/dist/adapter.js.map +1 -1
- package/dist/generated/client.d.ts +267 -26
- package/dist/generated/client.d.ts.map +1 -1
- package/dist/generated/client.js +479 -69
- package/dist/generated/client.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin-dispatch.d.ts +37 -0
- package/dist/plugin-dispatch.d.ts.map +1 -0
- package/dist/plugin-dispatch.js +293 -0
- package/dist/plugin-dispatch.js.map +1 -0
- package/dist/profile-contract.d.ts +3 -0
- package/dist/profile-contract.d.ts.map +1 -1
- package/dist/profile-contract.js +8 -0
- package/dist/profile-contract.js.map +1 -1
- package/dist/profile-plan.js +1 -1
- package/dist/profile-plan.js.map +1 -1
- package/dist/profile.d.ts +2 -1
- package/dist/profile.d.ts.map +1 -1
- package/dist/profile.js +2 -1
- package/dist/profile.js.map +1 -1
- package/dist/profiles/custom-fields/profile.d.ts +3 -0
- package/dist/profiles/custom-fields/profile.d.ts.map +1 -0
- package/dist/profiles/custom-fields/profile.js +475 -0
- package/dist/profiles/custom-fields/profile.js.map +1 -0
- package/dist/profiles/custom-fields/src/generated/client.d.ts +2710 -0
- package/dist/profiles/custom-fields/src/generated/client.d.ts.map +1 -0
- package/dist/profiles/custom-fields/src/generated/client.js +2663 -0
- package/dist/profiles/custom-fields/src/generated/client.js.map +1 -0
- package/dist/profiles/runtime/profile.d.ts +3 -0
- package/dist/profiles/runtime/profile.d.ts.map +1 -0
- package/dist/profiles/runtime/profile.js +1065 -0
- package/dist/profiles/runtime/profile.js.map +1 -0
- package/dist/profiles/runtime/src/generated/client.d.ts +4274 -0
- package/dist/profiles/runtime/src/generated/client.d.ts.map +1 -0
- package/dist/profiles/runtime/src/generated/client.js +4607 -0
- package/dist/profiles/runtime/src/generated/client.js.map +1 -0
- package/dist/runtime-materialize.d.ts +10 -0
- package/dist/runtime-materialize.d.ts.map +1 -0
- package/dist/runtime-materialize.js +344 -0
- package/dist/runtime-materialize.js.map +1 -0
- package/dist/runtime-profile.d.ts +34 -0
- package/dist/runtime-profile.d.ts.map +1 -0
- package/dist/runtime-profile.js +203 -0
- package/dist/runtime-profile.js.map +1 -0
- package/generated/go/client.go +350 -96
- package/generated/mcp/tools.json +3338 -1768
- package/generated/python/client.py +603 -26
- package/generated/riffdb.application.exact.json +1 -1
- package/generated/riffdb.contract.bundle +0 -0
- package/generated/rust/client.rs +522 -26
- package/package.json +34 -13
- package/profiles/custom-fields/generated/go/client.go +2578 -0
- package/profiles/custom-fields/generated/mcp/tools.json +15998 -0
- package/profiles/custom-fields/generated/python/client.py +5141 -0
- package/profiles/custom-fields/generated/riffdb.application.exact.json +1 -0
- package/profiles/custom-fields/generated/riffdb.contract.bundle +0 -0
- package/profiles/custom-fields/generated/rust/client.rs +7980 -0
- package/profiles/custom-fields/profile.ts +474 -0
- package/profiles/custom-fields/riffdb/contract.riff +568 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_all_email_asc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_contains_asc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_contains_desc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_email_contains_created_desc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_email_contains_image_asc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_ends_with_asc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_ends_with_desc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_starts_with_asc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/admin_users_starts_with_desc.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/find_account_by_id.riffq +24 -0
- package/profiles/custom-fields/riffdb/queries/find_account_by_provider.riffq +26 -0
- package/profiles/custom-fields/riffdb/queries/find_accounts_by_user_id.riffq +25 -0
- package/profiles/custom-fields/riffdb/queries/find_accounts_by_user_provider.riffq +27 -0
- package/profiles/custom-fields/riffdb/queries/find_active_sessions_by_user_id.riffq +23 -0
- package/profiles/custom-fields/riffdb/queries/find_credential_account.riffq +25 -0
- package/profiles/custom-fields/riffdb/queries/find_expired_verification_ids.riffq +17 -0
- package/profiles/custom-fields/riffdb/queries/find_latest_verification.riffq +20 -0
- package/profiles/custom-fields/riffdb/queries/find_session_by_id.riffq +20 -0
- package/profiles/custom-fields/riffdb/queries/find_session_by_token.riffq +20 -0
- package/profiles/custom-fields/riffdb/queries/find_sessions_by_token_set.riffq +20 -0
- package/profiles/custom-fields/riffdb/queries/find_sessions_by_user_id.riffq +21 -0
- package/profiles/custom-fields/riffdb/queries/find_user_by_email.riffq +16 -0
- package/profiles/custom-fields/riffdb/queries/find_user_by_id.riffq +15 -0
- package/profiles/custom-fields/riffdb/queries/find_verification_by_id.riffq +19 -0
- package/profiles/custom-fields/riffdb/queries/find_verifications_by_identifier.riffq +21 -0
- package/profiles/custom-fields/riffdb/queries/profile_account_with_user_by_provider.riffq +31 -0
- package/profiles/custom-fields/riffdb/queries/profile_session_with_user_by_id.riffq +14 -0
- package/profiles/custom-fields/riffdb/queries/profile_session_with_user_by_token.riffq +14 -0
- package/profiles/custom-fields/riffdb/queries/profile_sessions_with_users_by_token_set.riffq +25 -0
- package/profiles/custom-fields/riffdb/queries/profile_user_with_accounts_by_email.riffq +19 -0
- package/profiles/custom-fields/riffdb/queries/profile_user_with_accounts_by_id.riffq +19 -0
- package/profiles/custom-fields/riffdb.application.json +217 -0
- package/profiles/custom-fields/riffdb.application.lock.json +1 -0
- package/profiles/custom-fields/riffdb.toml +3 -0
- package/profiles/custom-fields/src/generated/client.ts +3096 -0
- package/profiles/organization-security/materialization.json +3 -0
- package/profiles/organization-security/riffdb/contract.riff +12 -0
- package/profiles/organization-security/riffdb/queries/find_team_by_id.riffq +1 -1
- package/profiles/organization-security/riffdb/queries/find_team_member_by_id.riffq +1 -1
- package/profiles/organization-security/riffdb/queries/find_team_member_by_membership_key.riffq +16 -0
- package/profiles/organization-security/riffdb/queries/find_team_member_by_team_id.riffq +1 -1
- package/profiles/organization-security/riffdb.application.json +5 -0
- package/profiles/organization-security.profile.json +27 -1
- package/profiles/runtime/generated/go/client.go +4511 -0
- package/profiles/runtime/generated/mcp/tools.json +30004 -0
- package/profiles/runtime/generated/python/client.py +9337 -0
- package/profiles/runtime/generated/riffdb.application.exact.json +1 -0
- package/profiles/runtime/generated/riffdb.contract.bundle +0 -0
- package/profiles/runtime/generated/rust/client.rs +13297 -0
- package/profiles/runtime/profile.ts +1064 -0
- package/profiles/runtime/riffdb/contract.riff +1053 -0
- package/profiles/runtime/riffdb/queries/admin_users_all_email_asc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/admin_users_contains_asc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/admin_users_contains_desc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/admin_users_email_contains_created_desc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/admin_users_email_contains_image_asc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/admin_users_ends_with_asc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/admin_users_ends_with_desc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/admin_users_starts_with_asc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/admin_users_starts_with_desc.riffq +24 -0
- package/profiles/runtime/riffdb/queries/find_account_by_id.riffq +24 -0
- package/profiles/runtime/riffdb/queries/find_account_by_provider.riffq +26 -0
- package/profiles/runtime/riffdb/queries/find_accounts_by_user_id.riffq +25 -0
- package/profiles/runtime/riffdb/queries/find_accounts_by_user_provider.riffq +27 -0
- package/profiles/runtime/riffdb/queries/find_active_sessions_by_user_id.riffq +23 -0
- package/profiles/runtime/riffdb/queries/find_credential_account.riffq +25 -0
- package/profiles/runtime/riffdb/queries/find_expired_verification_ids.riffq +17 -0
- package/profiles/runtime/riffdb/queries/find_latest_verification.riffq +20 -0
- package/profiles/runtime/riffdb/queries/find_session_by_id.riffq +20 -0
- package/profiles/runtime/riffdb/queries/find_session_by_token.riffq +20 -0
- package/profiles/runtime/riffdb/queries/find_sessions_by_token_set.riffq +20 -0
- package/profiles/runtime/riffdb/queries/find_sessions_by_user_id.riffq +21 -0
- package/profiles/runtime/riffdb/queries/find_user_by_email.riffq +16 -0
- package/profiles/runtime/riffdb/queries/find_user_by_id.riffq +15 -0
- package/profiles/runtime/riffdb/queries/find_verification_by_id.riffq +19 -0
- package/profiles/runtime/riffdb/queries/find_verifications_by_identifier.riffq +21 -0
- package/profiles/runtime/riffdb/queries/profile_account_with_user_by_provider.riffq +31 -0
- package/profiles/runtime/riffdb/queries/profile_invitation_by_email.riffq +17 -0
- package/profiles/runtime/riffdb/queries/profile_invitation_by_id.riffq +17 -0
- package/profiles/runtime/riffdb/queries/profile_invitation_by_organization_email_status.riffq +19 -0
- package/profiles/runtime/riffdb/queries/profile_invitation_by_organization_id.riffq +17 -0
- package/profiles/runtime/riffdb/queries/profile_invitation_by_organization_status.riffq +18 -0
- package/profiles/runtime/riffdb/queries/profile_member_by_id.riffq +27 -0
- package/profiles/runtime/riffdb/queries/profile_member_by_organization.riffq +20 -0
- package/profiles/runtime/riffdb/queries/profile_member_by_organization_created_at_asc.riffq +20 -0
- package/profiles/runtime/riffdb/queries/profile_member_by_organization_created_at_desc.riffq +20 -0
- package/profiles/runtime/riffdb/queries/profile_member_by_organization_role_asc.riffq +20 -0
- package/profiles/runtime/riffdb/queries/profile_member_by_organization_role_desc.riffq +20 -0
- package/profiles/runtime/riffdb/queries/profile_member_by_organization_user.riffq +28 -0
- package/profiles/runtime/riffdb/queries/profile_member_by_user.riffq +27 -0
- package/profiles/runtime/riffdb/queries/profile_organization_by_id.riffq +27 -0
- package/profiles/runtime/riffdb/queries/profile_organization_by_slug.riffq +27 -0
- package/profiles/runtime/riffdb/queries/profile_session_with_user_by_id.riffq +14 -0
- package/profiles/runtime/riffdb/queries/profile_session_with_user_by_token.riffq +14 -0
- package/profiles/runtime/riffdb/queries/profile_sessions_with_users_by_token_set.riffq +25 -0
- package/profiles/runtime/riffdb/queries/profile_two_factor_by_id.riffq +17 -0
- package/profiles/runtime/riffdb/queries/profile_two_factor_by_user.riffq +17 -0
- package/profiles/runtime/riffdb/queries/profile_user_with_accounts_by_email.riffq +19 -0
- package/profiles/runtime/riffdb/queries/profile_user_with_accounts_by_id.riffq +19 -0
- package/profiles/runtime/riffdb/queries/profile_users_by_id_set.riffq +8 -0
- package/profiles/runtime/riffdb.application.json +324 -0
- package/profiles/runtime/riffdb.application.lock.json +1 -0
- package/profiles/runtime/riffdb.toml +3 -0
- package/profiles/runtime/src/generated/client.ts +5186 -0
- package/riffdb/contract.riff +58 -0
- package/riffdb/queries/find_credential_account.riffq +25 -0
- package/riffdb.application.json +106 -26
- package/riffdb.application.lock.json +1 -1
- package/src/generated/client.ts +2746 -0
package/DESIGN.md
CHANGED
|
@@ -7,7 +7,7 @@ generation, adapter method mapping, and Better Auth conformance tests. RiffDB
|
|
|
7
7
|
owns database semantics, compiled operations, authorization, durability,
|
|
8
8
|
idempotency, and the Rust-backed TypeScript transport.
|
|
9
9
|
|
|
10
|
-
## Better Auth 1.
|
|
10
|
+
## Better Auth 1.7.18 method inventory
|
|
11
11
|
|
|
12
12
|
The adapter project must cover the current `createAdapterFactory` interface:
|
|
13
13
|
|
|
@@ -34,13 +34,22 @@ matching, independent order, and nullable order are declared in the compiled
|
|
|
34
34
|
query. The result page and total therefore share one provider epoch; the
|
|
35
35
|
adapter neither drains pages nor recounts client-side.
|
|
36
36
|
|
|
37
|
-
`consumeOne` maps to one atomic delete-and-return compiled command.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
`consumeOne` maps to one atomic delete-and-return compiled command. In a
|
|
38
|
+
recognized Better Auth verification transaction, the adapter records a bounded
|
|
39
|
+
candidate and its internal revision, then commits `ConsumeVerificationSnapshot`.
|
|
40
|
+
The database validates that revision while deleting; a losing delete racer
|
|
41
|
+
returns `null`, and a changed snapshot fails explicitly. Remaining identifier-
|
|
42
|
+
scoped rows use the separate bounded cleanup command.
|
|
43
|
+
|
|
44
|
+
Better Auth 1.7.18 wraps password reset in a larger transaction. For the
|
|
45
|
+
supported existing-credential graph, `ResetCredentialPassword` consumes the
|
|
46
|
+
recorded verification row and revision-guards the credential password write
|
|
47
|
+
in one compiled command. A stale or missing account leaves the token and
|
|
48
|
+
password unchanged. Basic password changes use the native
|
|
49
|
+
`UpdateCredentialPassword` command with its current credential selector.
|
|
50
|
+
Additional verification rows, credential-account creation,
|
|
51
|
+
and session-revoking reset graphs are unsupported. Signup and OAuth creation
|
|
52
|
+
also remain single-command graphs; unknown callback shapes fail closed.
|
|
44
53
|
|
|
45
54
|
Mutable core records carry internal monotonically increasing revisions. The
|
|
46
55
|
adapter reads that compiler-owned revision, sends it to an exact update
|
|
@@ -92,7 +101,7 @@ tests. This separation makes the profile customizable without turning schema
|
|
|
92
101
|
generation into a generic database or weakening the application-facing safety
|
|
93
102
|
boundary. The generation adapter rejects every runtime method.
|
|
94
103
|
|
|
95
|
-
##
|
|
104
|
+
## Planning materialization
|
|
96
105
|
|
|
97
106
|
`materializeRiffDBBetterAuthProfile` turns a reviewed plan into the first two
|
|
98
107
|
of those artifacts: one contract and one named query per accepted call shape,
|
|
@@ -133,7 +142,7 @@ needs one of them enforced changes the aggregate assignment by hand.
|
|
|
133
142
|
representative plan, regenerated by `npm run profiles:materialize` and verified
|
|
134
143
|
byte-for-byte by `npm run profiles:check`. It ships its own `riffdb.toml`, so
|
|
135
144
|
the claim made about it is checkable directly: `riffdb application check` in
|
|
136
|
-
that directory compiles the contract and all
|
|
145
|
+
that directory compiles the contract and all twenty queries.
|
|
137
146
|
|
|
138
147
|
References:
|
|
139
148
|
|
|
@@ -143,7 +152,73 @@ References:
|
|
|
143
152
|
- <https://github.com/yultyyev/better-auth-firestore>
|
|
144
153
|
- <https://github.com/datar-platform/better-auth-dynamodb>
|
|
145
154
|
|
|
146
|
-
##
|
|
155
|
+
## Executable runtime profiles
|
|
156
|
+
|
|
157
|
+
`materializeRiffDBBetterAuthRuntimeProfile` extends the reviewed core sources
|
|
158
|
+
with a finite operation catalogue and emits `profile.ts`. After source review,
|
|
159
|
+
`riffdb application lock --write` generates its named client and exact immutable
|
|
160
|
+
identity. The adapter accepts that bound module, compares its schema plan with
|
|
161
|
+
the resolved Better Auth schema, and instantiates the generated client. It never
|
|
162
|
+
accepts a JSON schema as executable storage or a caller-supplied CRUD callback.
|
|
163
|
+
|
|
164
|
+
The runtime generator currently accepts scalar custom user fields and the
|
|
165
|
+
reviewed default organization and two-factor schemas. Baseline fields,
|
|
166
|
+
references, requiredness, and secret classification cannot be overridden.
|
|
167
|
+
Organization teams, dynamic access control, and mutation hooks are rejected.
|
|
168
|
+
Additional plugins and call shapes need a reviewed compiler implementation.
|
|
169
|
+
`nextCookies` is a reviewed integration plugin and adds no storage schema; its
|
|
170
|
+
ID is excluded from storage plans while runtime validation checks its version.
|
|
171
|
+
|
|
172
|
+
The sample applications live in `profiles/custom-fields/` and `profiles/runtime/`.
|
|
173
|
+
They have separate locks and generated clients. Source freshness, compilation,
|
|
174
|
+
package contents, and official real-service authentication conformance are
|
|
175
|
+
checked for all advertised profiles. The custom-field profile runs the official
|
|
176
|
+
additional-fields test against a contract already carrying that field.
|
|
177
|
+
|
|
178
|
+
Runtime profiles place all entities under one tenant aggregate. This intentionally
|
|
179
|
+
serializes same-tenant commands and lets member and invitation rows retain both
|
|
180
|
+
user and organization references. Compiled reads hydrate related rows through
|
|
181
|
+
bounded dependent batches in the same snapshot; the adapter only associates
|
|
182
|
+
those returned identities. It enables native joins for these profiles and
|
|
183
|
+
rejects unmatched joins before querying, rather than invoking factory fallback
|
|
184
|
+
join queries.
|
|
185
|
+
|
|
186
|
+
The current compiler refuses a command binding two entities carrying cascade
|
|
187
|
+
policies, even when they are read parents. Therefore the organization profile
|
|
188
|
+
omits user deletion and rejects `user.deleteUser.enabled`; organization deletion
|
|
189
|
+
cascades both memberships and invitations atomically. This is a limitation of
|
|
190
|
+
this layout and compiler surface, not permission to remove either reference.
|
|
191
|
+
The core and custom-field profiles retain their compiled user cascade.
|
|
192
|
+
|
|
193
|
+
Organization capacity is authoritative: member and invitation creation mutate
|
|
194
|
+
the organization's internal counters with a guard below 100, and individual
|
|
195
|
+
deletions release capacity atomically. The organization delete graph has at most
|
|
196
|
+
201 rows. Membership creation plus session activation during invitation
|
|
197
|
+
acceptance is another single compiled graph. Invitation status guards admit
|
|
198
|
+
one racer; upstream Better Auth owns its higher-level acceptance and compensation
|
|
199
|
+
flow around that graph.
|
|
200
|
+
|
|
201
|
+
Native 2FA commands increment failure counters, set locks under a threshold
|
|
202
|
+
guard, reset expired locks, and replace backup codes under an exact old-value
|
|
203
|
+
guard. An internal millisecond field tracks the optional lock timestamp in the
|
|
204
|
+
same commands, so the expiry comparison stays a native scalar predicate. Every
|
|
205
|
+
secret result leaf has an explicit `reveals` declaration. No counter or backup-
|
|
206
|
+
code path invokes Better Auth's generic mutation fallback.
|
|
207
|
+
|
|
208
|
+
Profile changes require explicit data migration review. The shared tenant
|
|
209
|
+
aggregate and plugin fields cannot reinterpret an installed core profile.
|
|
210
|
+
Internal revisions, capacity counters, required fields, reference targets, and
|
|
211
|
+
secret authority must be initialized and verified before adopting a new lock.
|
|
212
|
+
No automatic migration or mixed-profile runtime is supplied.
|
|
213
|
+
|
|
214
|
+
The broader planning materializer still supports schema exploration for teams.
|
|
215
|
+
Better Auth 1.7's optional unique `teamMember.membershipKey` needs an explicit
|
|
216
|
+
`requireUniqueValues` review: RiffDB cannot enforce a nullable unique field.
|
|
217
|
+
The planning fixture requires a non-null key on every row and reports that
|
|
218
|
+
stronger storage requirement. It cannot accept legacy null-key rows and is not
|
|
219
|
+
an advertised runtime profile.
|
|
220
|
+
|
|
221
|
+
## Default core profile exclusions
|
|
147
222
|
|
|
148
223
|
- renamed models or fields;
|
|
149
224
|
- additional user/session fields;
|
|
@@ -154,11 +229,14 @@ References:
|
|
|
154
229
|
- Better Auth database hooks that imply additional database mutations; and
|
|
155
230
|
- secondary storage implemented by RiffDB.
|
|
156
231
|
|
|
232
|
+
These exclusions describe the default core profile; the executable profiles
|
|
233
|
+
above provide reviewed extensions. Each addition needs an explicit bounded contract and semantic tests.
|
|
234
|
+
|
|
157
235
|
## Closed RiffDB blockers
|
|
158
236
|
|
|
159
237
|
The loopback conformance run deploys the exact contract and role and connects
|
|
160
238
|
through `riffdb-driverd`. The initial empty `FindUserByEmail` result carries the
|
|
161
|
-
valid application head `0`; `@riffdb/client@0.2.
|
|
239
|
+
valid application head `0`; `@riffdb/client@0.2.1` preserves it
|
|
162
240
|
as `0n`. The adapter does not issue an unrelated warmup write, so the first
|
|
163
241
|
application-visible mutation remains the compiled signup graph.
|
|
164
242
|
|
|
@@ -181,8 +259,6 @@ independent ordering, and explicit null placement. The generated TypeScript
|
|
|
181
259
|
client also emits only reachable compact decoders, so it compiles under strict
|
|
182
260
|
consumer `noUnusedLocals` settings without generated-source suppressions.
|
|
183
261
|
|
|
184
|
-
These exclusions describe the first profile, not permanent product limits.
|
|
185
|
-
Each addition needs an explicit bounded contract and semantic tests.
|
|
186
262
|
|
|
187
263
|
## Secrets and authority
|
|
188
264
|
|
package/README.md
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
An external Better Auth database adapter for RiffDB.
|
|
4
4
|
|
|
5
|
-
Status:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
Status: core and compiled runtime profiles are implemented for Better Auth
|
|
6
|
+
`1.7.18`. The default core profile, a custom-field profile, and an organization
|
|
7
|
+
plus 2FA profile run through Better Auth's official authentication-flow suite
|
|
8
|
+
against a real TLS loopback RiffDB service. The custom-field profile also runs
|
|
9
|
+
the official additional-fields test.
|
|
10
|
+
|
|
11
|
+
`nextCookies()` is supported with each profile. Organizations and 2FA require
|
|
12
|
+
an explicitly selected, deployed compiled profile. Teams and dynamic access
|
|
13
|
+
control remain unsupported. The organization profile also rejects user deletion;
|
|
14
|
+
its stored member and invitation references remain enforced.
|
|
12
15
|
|
|
13
16
|
## Architecture boundary
|
|
14
17
|
|
|
@@ -18,19 +21,20 @@ reviewed compiled profile. It does not expose generic CRUD, accept arbitrary
|
|
|
18
21
|
transaction callbacks, perform client-side authorization filtering, or
|
|
19
22
|
silently fall back for unknown models, fields, joins, predicates, or plugins.
|
|
20
23
|
|
|
21
|
-
The
|
|
24
|
+
The default core runtime profile is deliberately exact:
|
|
22
25
|
|
|
23
|
-
- Better Auth `1.
|
|
26
|
+
- Better Auth `1.7.18`;
|
|
24
27
|
- the four default core models and their default field names;
|
|
25
28
|
- UUID identifiers for every model;
|
|
26
|
-
- no
|
|
29
|
+
- the reviewed `nextCookies()` integration, with no storage plugins or additional fields; and
|
|
27
30
|
- the bundled `RiffDBBetterAuthCore` contract and `BetterAuthServer` role.
|
|
28
31
|
|
|
29
32
|
Unsupported configuration fails before any RiffDB request. A custom or plugin
|
|
30
33
|
profile requires its own generated contract, named operations, client facade,
|
|
31
|
-
and conformance tests
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
and conformance tests. `materializeRiffDBBetterAuthRuntimeProfile` emits the
|
|
35
|
+
reviewable runtime sources and binding; RiffDB compiles and locks their client.
|
|
36
|
+
Adapter construction also verifies that the resolved
|
|
37
|
+
`better-auth` installation is exactly `1.7.18`; package-manager overrides do
|
|
34
38
|
not bypass that runtime check. Secret-bearing Better Auth debug logging is
|
|
35
39
|
rejected rather than forwarded to the factory logger.
|
|
36
40
|
|
|
@@ -60,7 +64,80 @@ The caller owns the RiffDB driver connection and application-defined
|
|
|
60
64
|
organization ID. Better Auth continues to own users, sessions, passwords,
|
|
61
65
|
sign-in, OAuth, and reset flows. The package contains the exact RiffDB
|
|
62
66
|
application source, lock, contract bundle, and generated artifacts required to
|
|
63
|
-
deploy the core profile.
|
|
67
|
+
deploy the core profile. Better Auth development dependencies stay exactly
|
|
68
|
+
pinned. Supported versions are explicit; a scheduled registry check flags new
|
|
69
|
+
stable releases for schema, call-shape, and conformance review.
|
|
70
|
+
|
|
71
|
+
For Next.js Server Actions, import `nextCookies` from `better-auth/next-js`
|
|
72
|
+
and add `nextCookies()` as the last plugin in the Better Auth configuration.
|
|
73
|
+
It can accompany the default core profile or the compiled profiles below.
|
|
74
|
+
Cookie propagation, RSC refresh suppression, and Server Action refresh behavior
|
|
75
|
+
are covered by integration tests using the official plugin and mocked Next.js
|
|
76
|
+
request helpers.
|
|
77
|
+
|
|
78
|
+
## Organization and 2FA runtime profile
|
|
79
|
+
|
|
80
|
+
Deploy `profiles/runtime/riffdb.application.json` and its exact lock before
|
|
81
|
+
connecting the driver. Select its binding explicitly:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import profile from "@riffdb/better-auth/profiles/organization-security";
|
|
85
|
+
import { organization, twoFactor } from "better-auth/plugins";
|
|
86
|
+
|
|
87
|
+
const auth = betterAuth({
|
|
88
|
+
database: riffdbAdapter({ driver, organizationId: tenantId, profile }),
|
|
89
|
+
advanced: { database: { generateId: "uuid" } },
|
|
90
|
+
emailAndPassword: { enabled: true },
|
|
91
|
+
user: {
|
|
92
|
+
additionalFields: {
|
|
93
|
+
locale: { type: "string", required: false },
|
|
94
|
+
dateField: { type: "date", required: false },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
plugins: [
|
|
98
|
+
organization({ membershipLimit: 100, invitationLimit: 100 }),
|
|
99
|
+
twoFactor(),
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
These are example profile fields; `dateField` also serves the upstream
|
|
105
|
+
conformance test. Generate a separate reviewed profile to use a different field
|
|
106
|
+
inventory. The standalone custom-field example is available at
|
|
107
|
+
`@riffdb/better-auth/profiles/custom-fields` and deploys from
|
|
108
|
+
`profiles/custom-fields/` without storage plugins.
|
|
109
|
+
|
|
110
|
+
The adapter's `organizationId` is the application's RiffDB tenant partition.
|
|
111
|
+
The organization plugin's `organizationId` identifies an auth organization
|
|
112
|
+
inside that partition. They are separate identifiers.
|
|
113
|
+
|
|
114
|
+
The organization profile supports organization creation/update/listing, active
|
|
115
|
+
organization sessions, membership listing/counts/roles/removal, invitations and
|
|
116
|
+
guarded status transitions, and atomic organization/dependent deletion.
|
|
117
|
+
Membership creation and session activation during invitation acceptance share
|
|
118
|
+
one compiled command. Native capacity guards admit at most 100 live memberships
|
|
119
|
+
and 100 retained invitations per organization; deleting an individual record
|
|
120
|
+
releases its capacity. Lists are bounded at 100, membership offsets at 4096,
|
|
121
|
+
and user hydration sets at 32. Member pages support the compiled default role
|
|
122
|
+
order, role ascending/descending, and creation-time ascending/descending.
|
|
123
|
+
Other member filters and sorts are rejected.
|
|
124
|
+
|
|
125
|
+
2FA supports TOTP enrollment/verification, OTP challenges, backup codes,
|
|
126
|
+
challenge consumption, and account lockout. Failure increments, expired-lock
|
|
127
|
+
reset, backup-code replacement, and invitation status transitions use native
|
|
128
|
+
compiled commands. Tests cover TOTP enrollment, backup-code and invitation
|
|
129
|
+
races, challenge replay, lockout counters, capacity contention, and reset rollback.
|
|
130
|
+
|
|
131
|
+
Teams, dynamic access control, organization mutation hooks, renamed storage,
|
|
132
|
+
plugin-model custom fields, user deletion in organization profiles, and
|
|
133
|
+
`revokeSessionsOnPasswordReset` are rejected. Password changes that request
|
|
134
|
+
`revokeOtherSessions` also require a separately compiled transaction graph.
|
|
135
|
+
Organization limits must be integers from 1 through 100. Custom runtime fields
|
|
136
|
+
currently support scalar strings, booleans, safe integers, and dates on `user`;
|
|
137
|
+
custom indexes, uniqueness,
|
|
138
|
+
and references require a separately implemented profile. Credential password
|
|
139
|
+
reset supports an existing credential account and one verification row per
|
|
140
|
+
identifier. Additional transaction graphs fail closed.
|
|
64
141
|
|
|
65
142
|
## Implemented core surface
|
|
66
143
|
|
|
@@ -128,7 +205,7 @@ With that generation-only config, run the Better Auth CLI version matching the
|
|
|
128
205
|
pinned runtime:
|
|
129
206
|
|
|
130
207
|
```bash
|
|
131
|
-
npx auth@1.
|
|
208
|
+
npx auth@1.7.18 generate --config ./auth.profile.ts --yes
|
|
132
209
|
```
|
|
133
210
|
|
|
134
211
|
The output records resolved storage names, field types, required/unique/index
|
|
@@ -147,31 +224,84 @@ npm run profiles:write
|
|
|
147
224
|
npm run profiles:check
|
|
148
225
|
```
|
|
149
226
|
|
|
227
|
+
## Materializing an executable profile
|
|
228
|
+
|
|
229
|
+
Pass the reviewed plan to `materializeRiffDBBetterAuthRuntimeProfile(plan)`.
|
|
230
|
+
Write the returned `files` under a new application directory, review the
|
|
231
|
+
contract, queries, and `profile.ts`, then run `riffdb application lock --write`
|
|
232
|
+
in that directory. Compile `profile.ts` and the generated TypeScript client
|
|
233
|
+
with your application and pass its default export as `riffdbAdapter({ profile,
|
|
234
|
+
driver, organizationId })`. A JSON plan alone cannot be passed to the adapter.
|
|
235
|
+
Runtime construction compares the resolved schema and reviewed plugins with
|
|
236
|
+
the bound plan before requests. Binding also checks compiler-owned command and
|
|
237
|
+
result schemas, so a stale client cannot silently omit a new optional field.
|
|
238
|
+
The generated client and driver enforce the exact compiled application and
|
|
239
|
+
operation identities.
|
|
240
|
+
|
|
241
|
+
The planning fixture also reports its explicit non-null requirement for the
|
|
242
|
+
optional unique team membership key; it cannot accept legacy null-key rows.
|
|
243
|
+
|
|
244
|
+
The executable generator accepts the core schema plus the reviewed organization
|
|
245
|
+
and 2FA schemas. The broader `materializeRiffDBBetterAuthProfile` remains a
|
|
246
|
+
planning tool: its teams example reports unenforced references and is not an
|
|
247
|
+
executable runtime profile.
|
|
248
|
+
|
|
249
|
+
Regenerate the executable examples with `npm run profiles:runtime`, review
|
|
250
|
+
the source diff, and write each application's lock explicitly. `npm run
|
|
251
|
+
profiles:check` verifies source freshness, compiler locks, and generated clients.
|
|
252
|
+
|
|
253
|
+
A different profile is a different compiled application identity. There is no
|
|
254
|
+
automatic switch or reinterpretation of existing core data. For existing
|
|
255
|
+
installations, plan and review an explicit data migration, including identifier
|
|
256
|
+
mapping, required/default fields, references, secrets, and capacity counts.
|
|
257
|
+
Deploy the matching contract, operations, role, and client together. Never point
|
|
258
|
+
a new binding at an old lock. Runtime profile examples are intended for fresh
|
|
259
|
+
installations until an application-specific migration has been reviewed.
|
|
260
|
+
|
|
150
261
|
## Local development
|
|
151
262
|
|
|
152
263
|
```bash
|
|
153
|
-
npm
|
|
264
|
+
npm ci --ignore-scripts
|
|
154
265
|
npm run check
|
|
155
266
|
```
|
|
156
267
|
|
|
157
|
-
The lock is pinned to `@riffdb/client@0.2.
|
|
268
|
+
The lock is pinned to `@riffdb/client@0.2.1` and `@riffdb/cli@0.2.1`.
|
|
158
269
|
|
|
159
270
|
`npm run check` performs strict type checking, semantic and upstream tests,
|
|
160
271
|
profile-artifact freshness, a production build, and a package dry run.
|
|
161
272
|
|
|
162
273
|
## Real loopback conformance
|
|
163
274
|
|
|
164
|
-
Run the
|
|
275
|
+
Run the official suite against isolated TLS services and Rust driver hosts:
|
|
165
276
|
|
|
166
277
|
```bash
|
|
167
|
-
|
|
278
|
+
npm run test:loopback
|
|
168
279
|
```
|
|
169
280
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
driver host.
|
|
281
|
+
This runs the core, custom-field, and organization/2FA profiles. It requires
|
|
282
|
+
`riffdbd` and `riffdb-driverd` from the immutable RiffDB build in
|
|
283
|
+
`.github/riffdb-revision` on PATH. `RIFFDB_CLI`, `RIFFDB_SERVER_BIN`, and
|
|
284
|
+
`RIFFDB_DRIVERD` can select exact local binaries. The published RiffDB `0.2.1`
|
|
285
|
+
release bundle includes the CLI and service, but omits the driver host. Build
|
|
286
|
+
that host from a separate RiffDB checkout at the full revision recorded in
|
|
287
|
+
`.github/riffdb-revision`:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# In that separate, pinned RiffDB checkout:
|
|
291
|
+
RUSTC_WRAPPER= cargo build --locked --release -p riffdb-driver-host --bin riffdb-driverd
|
|
292
|
+
|
|
293
|
+
# Back in this adapter checkout, with riffdbd on PATH:
|
|
294
|
+
RIFFDB_DRIVERD=/path/to/riffdb/target/release/riffdb-driverd npm run test:loopback
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Release CI verifies the bundle checksum and revision, then builds the driver
|
|
298
|
+
from that same revision. Certificates, capabilities, sockets, and databases
|
|
299
|
+
are disposable and removed at the end. The official
|
|
300
|
+
harness's cleanup hook is scoped to that disposable service; it is never a
|
|
301
|
+
public delete-all operation.
|
|
302
|
+
|
|
303
|
+
The original `scripts/real-riffdb-runner.mjs` also remains available to an
|
|
304
|
+
external harness supplying its ten exact driver-identity arguments.
|
|
175
305
|
|
|
176
306
|
See [DESIGN.md](./DESIGN.md) for the method and safety inventory. The adapter
|
|
177
307
|
follows Better Auth's
|
|
@@ -185,7 +315,9 @@ This adapter owns its RiffDB compatibility checks. Pull requests compile the
|
|
|
185
315
|
application sources and verify existing locks and generated artifacts against
|
|
186
316
|
the full commit in `.github/riffdb-revision`. Scheduled checks use RiffDB
|
|
187
317
|
`main`; manual dispatch accepts a full commit or `main`. Failures are reported
|
|
188
|
-
here and do not block RiffDB itself.
|
|
318
|
+
here and do not block RiffDB itself. The job also runs `npm run check` and
|
|
319
|
+
`npm run test:loopback`, including the official Better Auth suite for every
|
|
320
|
+
advertised runtime profile.
|
|
189
321
|
|
|
190
322
|
To upgrade, update the pin, migrate sources as needed, review the result of
|
|
191
323
|
`riffdb application lock --write`, and verify with `riffdb application check`.
|
package/dist/adapter.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type DriverApplicationTransport } from "@riffdb/client";
|
|
|
2
2
|
import { type AdapterFactory, type DBAdapterDebugLogOption } from "better-auth/adapters";
|
|
3
3
|
import type { BetterAuthOptions } from "better-auth";
|
|
4
4
|
import { RiffDBBetterAuthCoreClient } from "./generated/client.js";
|
|
5
|
+
import { type RiffDBCompiledProfile } from "./runtime-profile.js";
|
|
5
6
|
export type RiffDBBetterAuthCallErrorCode = "invalid_configuration" | "unsupported_model" | "unsupported_call_shape" | "unsupported_transaction_shape" | "result_bound_exceeded" | "invalid_record_shape" | "declared_outcome";
|
|
6
7
|
export declare class RiffDBBetterAuthCallError extends Error {
|
|
7
8
|
readonly code: RiffDBBetterAuthCallErrorCode;
|
|
@@ -14,12 +15,17 @@ export interface RiffDBBetterAuthAdapterConfig {
|
|
|
14
15
|
readonly organizationId: string;
|
|
15
16
|
readonly commandAttemptBudget?: number;
|
|
16
17
|
readonly debugLogs?: DBAdapterDebugLogOption;
|
|
18
|
+
readonly profile?: RiffDBCompiledProfile;
|
|
17
19
|
}
|
|
20
|
+
type CoreClient = Omit<RiffDBBetterAuthCoreClient, "causalSession" | "withReadAfterCommit"> & {
|
|
21
|
+
causalSession(): CoreClient;
|
|
22
|
+
};
|
|
18
23
|
interface InternalAdapterConfig {
|
|
19
|
-
readonly client:
|
|
24
|
+
readonly client: CoreClient;
|
|
20
25
|
readonly organizationId: string;
|
|
21
26
|
readonly debugLogs?: DBAdapterDebugLogOption;
|
|
22
27
|
readonly resetModelForTesting?: (model: string) => number | Promise<number>;
|
|
28
|
+
readonly profile?: RiffDBCompiledProfile;
|
|
23
29
|
}
|
|
24
30
|
export declare function assertSupportedBetterAuthInstallation(installedVersion?: string): void;
|
|
25
31
|
export declare function buildRiffDBBetterAuthAdapter(config: InternalAdapterConfig): AdapterFactory<BetterAuthOptions>;
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,KAAK,cAAc,EAInB,KAAK,uBAAuB,EAE7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EACL,0BAA0B,EAe3B,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,KAAK,cAAc,EAInB,KAAK,uBAAuB,EAE7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EACL,0BAA0B,EAe3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAkD3D,MAAM,MAAM,6BAA6B,GACrC,uBAAuB,GACvB,mBAAmB,GACnB,wBAAwB,GACxB,+BAA+B,GAC/B,uBAAuB,GACvB,sBAAsB,GACtB,kBAAkB,CAAC;AAEvB,qBAAa,yBAA0B,SAAQ,KAAK;aAEhC,IAAI,EAAE,6BAA6B;aACnC,SAAS,EAAE,MAAM;aACjB,OAAO,CAAC,EAAE,MAAM;IAHlC,YACkB,IAAI,EAAE,6BAA6B,EACnC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,YAAA,EAQjC;CACF;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,uBAAuB,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAED,KAAK,UAAU,GAAG,IAAI,CAAC,0BAA0B,EAAE,eAAe,GAAG,qBAAqB,CAAC,GAAG;IAC5F,aAAa,IAAI,UAAU,CAAC;CAC7B,CAAC;AAEF,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,uBAAuB,CAAC;IAC7C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAuBD,wBAAgB,qCAAqC,CACnD,gBAAgB,SAAsC,GACrD,IAAI,CAIN;AAqnDD,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,qBAAqB,GAC5B,cAAc,CAAC,iBAAiB,CAAC,CA2CnC;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,6BAA6B,GACpC,cAAc,CAAC,iBAAiB,CAAC,CAanC"}
|