@opensaas/stack-auth 0.27.1 → 0.29.0
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +44 -0
- package/CLAUDE.md +35 -1
- package/dist/config/derive-auth-lists.d.ts +15 -5
- package/dist/config/derive-auth-lists.d.ts.map +1 -1
- package/dist/config/derive-auth-lists.js +59 -98
- package/dist/config/derive-auth-lists.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/plugin.d.ts.map +1 -1
- package/dist/config/plugin.js +31 -13
- package/dist/config/plugin.js.map +1 -1
- package/dist/config/types.d.ts +58 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/lists/index.d.ts +9 -4
- package/dist/lists/index.d.ts.map +1 -1
- package/dist/lists/index.js +3 -2
- package/dist/lists/index.js.map +1 -1
- package/dist/runtime/types.d.ts +7 -5
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/server/schema-converter.d.ts +34 -2
- package/dist/server/schema-converter.d.ts.map +1 -1
- package/dist/server/schema-converter.js +47 -163
- package/dist/server/schema-converter.js.map +1 -1
- package/package.json +2 -2
- package/src/config/derive-auth-lists.ts +61 -87
- package/src/config/index.ts +1 -0
- package/src/config/plugin.ts +36 -13
- package/src/config/types.ts +64 -0
- package/src/lists/index.ts +10 -4
- package/src/runtime/types.ts +7 -5
- package/src/server/schema-converter.ts +68 -158
- package/tests/config.test.ts +110 -0
- package/tests/derive-auth-lists.test.ts +54 -1
- package/tests/lists.test.ts +42 -145
- package/tests/plugin-derived-keys.test.ts +130 -18
- package/tests/schema-converter.test.ts +58 -21
- package/tsconfig.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# @opensaas/stack-auth
|
|
2
2
|
|
|
3
|
+
## 0.29.0
|
|
4
|
+
|
|
5
|
+
## 0.28.0
|
|
6
|
+
|
|
7
|
+
### Minor Changes
|
|
8
|
+
|
|
9
|
+
- [#696](https://github.com/OpenSaasAU/stack/pull/696) [`0bcfb4a`](https://github.com/OpenSaasAU/stack/commit/0bcfb4a6f1183ee75017bee73566f5aaa3b5408e) Thanks [@{](https://github.com/{)! - BREAKING: Auth-injected lists (User/Session/Account/Verification) now ship **closed** — no operation-level access — instead of shipping permissive defaults (`query: () => true`, self-only update/delete). Per ADR-0013, access control belongs to the application. With no access configured, `context.db` reads/writes against these lists return `null`/`[]` and they no longer appear in the admin UI. better-auth's own sign-in/sign-up/session flows are unaffected — they write through the raw Prisma client, bypassing access control entirely.
|
|
10
|
+
|
|
11
|
+
Grant access with the new `authPlugin({ access: { ... } })` passthrough, keyed by better-auth model name (`user`/`session`/`account`/`verification` — not the derived list key, so it stays correct if you rename a model via `modelName`). Each entry is a full list access config (operation and field-level):
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
authPlugin({
|
|
15
|
+
access: {
|
|
16
|
+
|
|
17
|
+
operation: {
|
|
18
|
+
query: ({ session }) => !!session,
|
|
19
|
+
update: ({ session, item }) => session?.userId === item.id,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
session: {
|
|
23
|
+
operation: {
|
|
24
|
+
query: ({ session }) => (session ? { user: { id: { equals: session.userId } } } : false),
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
For the User list specifically, `extendUserList.access` (unchanged) still works and takes precedence over `access.user` if both are set.
|
|
32
|
+
|
|
33
|
+
The runtime `getUser`/`getCurrentUser` helpers now resolve through the `sudo` helper `@opensaas/stack-core` passes to `plugin.runtime(context, sudo)`, so "who is this session" no longer depends on the application's User list access policy.
|
|
34
|
+
|
|
35
|
+
Migration: if you relied on the old permissive defaults, add the equivalent rules under `authPlugin({ access: { ... } })` for any Auth list your app reads or writes through `context.db` or the admin UI.
|
|
36
|
+
|
|
37
|
+
- [#698](https://github.com/OpenSaasAU/stack/pull/698) [`cf8b4bd`](https://github.com/OpenSaasAU/stack/commit/cf8b4bd17af15c5dadc898e76465913909c74c89) Thanks [@borisno2](https://github.com/borisno2)! - The derived `Session.user` and `Account.user` foreign keys now mirror a live better-auth database's shape: no `@@index([userId])` (better-auth carries no separate FK index) and `onDelete: Cascade` (Prisma's default was `Restrict`). This applies to both greenfield installs and adopted databases, so a generated Auth schema diffs clean against a standard better-auth Prisma schema.
|
|
38
|
+
|
|
39
|
+
Migration note: existing greenfield stack-auth apps will see a schema diff on next `pnpm generate` — a migration that drops the `userId` index on `Session`/`Account` and adds `onDelete: Cascade` to both foreign keys. Review the generated migration before applying it; deleting a user now cascades to their sessions and accounts instead of being blocked.
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- [#689](https://github.com/OpenSaasAU/stack/pull/689) [`8db2c57`](https://github.com/OpenSaasAU/stack/commit/8db2c57130f270b73a6a007312d743cac97a8743) Thanks [@borisno2](https://github.com/borisno2)! - Fix better-auth plugin schema extensions (e.g. `user`) resolving against a re-derived list key instead of the configured model-key remap, which could silently apply the extension's fields/access to an unrelated host list sharing the default key.
|
|
44
|
+
|
|
45
|
+
- [#695](https://github.com/OpenSaasAU/stack/pull/695) [`fd64913`](https://github.com/OpenSaasAU/stack/commit/fd64913ac65ed60440eaee210a34a6f8e3824c21) Thanks [@borisno2](https://github.com/borisno2)! - Fix a plugin's `extendList()` silently overwriting a pre-existing list's operation-level access. Per ADR-0013, an extension that carries `access.operation` for an existing list now throws a config-time error naming the plugin and the list; the auth plugin no longer forwards its own access when extending a list an app already declared.
|
|
46
|
+
|
|
3
47
|
## 0.27.1
|
|
4
48
|
|
|
5
49
|
## 0.27.0
|
package/CLAUDE.md
CHANGED
|
@@ -91,7 +91,39 @@ Because the plugin only ever adds/extends its **derived** keys, an app's own
|
|
|
91
91
|
domain `User` (a different model from the better-auth user) is never extended
|
|
92
92
|
or overwritten when the user model is renamed. The runtime `getUser`/
|
|
93
93
|
`getCurrentUser` helpers resolve the user list's `context.db` key from the
|
|
94
|
-
configured user `modelName
|
|
94
|
+
configured user `modelName`, and read through the `sudo` argument passed to
|
|
95
|
+
`runtime(context, sudo)` (see below).
|
|
96
|
+
|
|
97
|
+
### Access control on Auth lists (ADR-0013)
|
|
98
|
+
|
|
99
|
+
The four Auth lists ship **closed** — no operation-level access — per
|
|
100
|
+
[ADR-0013](../../docs/adr/0013-access-control-belongs-to-the-application-not-plugins.md).
|
|
101
|
+
Grant access via `authPlugin({ access: { user, session, account, verification } })`,
|
|
102
|
+
keyed by better-auth model name (not the derived list key, so it survives a
|
|
103
|
+
`modelName` remap). Each entry is applied on the plugin's own `addList` path
|
|
104
|
+
in `deriveAuthLists` (`src/config/derive-auth-lists.ts`), so it rides along
|
|
105
|
+
with the list's `@@map`/`@@schema`/fields — it is **not** forwarded on the
|
|
106
|
+
`extendList` path (an app-declared list of the same key keeps its own
|
|
107
|
+
access, unchanged since #678/ADR-0013).
|
|
108
|
+
|
|
109
|
+
`extendUserList.access` (the pre-existing User-only override) still works and
|
|
110
|
+
takes precedence over `access.user` when both are set — `createUserList` in
|
|
111
|
+
`derive-auth-lists.ts` resolves `userConfig.access || accessConfig.user`.
|
|
112
|
+
|
|
113
|
+
better-auth's own sign-in/sign-up/session flows are unaffected: they write
|
|
114
|
+
through the raw Prisma client (the driver adapter), bypassing access control
|
|
115
|
+
entirely. The runtime `getUser`/`getCurrentUser` helpers resolve through the
|
|
116
|
+
`sudo` argument core passes to `plugin.runtime(context, sudo)` for the same
|
|
117
|
+
reason — "who is this session" must not depend on the application's User
|
|
118
|
+
access policy. `sudo` is a plain second argument, not a method on `context`
|
|
119
|
+
(`AccessContext`) itself — see `packages/core/CLAUDE.md`.
|
|
120
|
+
|
|
121
|
+
`convertBetterAuthSchema`/`convertTableToList` (`src/server/schema-converter.ts`),
|
|
122
|
+
which handle additional tables a better-auth plugin's own schema declares
|
|
123
|
+
(e.g. OAuth client tables from the `mcp` plugin), also ship closed — there is
|
|
124
|
+
no `access` passthrough for them; an app that needs to grant access declares
|
|
125
|
+
the list itself under the same derived key so the plugin's field-only extend
|
|
126
|
+
path merges in (its own access then stands, same as any other `extendList`).
|
|
95
127
|
|
|
96
128
|
### Schema placement (relocatable Auth lists)
|
|
97
129
|
|
|
@@ -281,6 +313,8 @@ import { rawOpensaasContext } from '@/.opensaas/context'
|
|
|
281
313
|
export const auth = createAuth(config, rawOpensaasContext)
|
|
282
314
|
```
|
|
283
315
|
|
|
316
|
+
`createAuth()` returns a `Proxy` synchronously and defers the real `betterAuth()` construction (and the `context.prisma` it wraps) until `rawOpensaasContext` resolves — the sanctioned pattern for a module-init-time consumer that only needs to defer method calls, not obtain a resolved client value. See ADR-0014 and root `CLAUDE.md`'s "Getting the ORM client outside a request" for the full decision record and the synchronous-client alternative.
|
|
317
|
+
|
|
284
318
|
### With Better-auth
|
|
285
319
|
|
|
286
320
|
- Direct wrapper around Better-auth core
|
|
@@ -13,16 +13,19 @@
|
|
|
13
13
|
* - relationship refs between the auth lists wired to the *derived* keys
|
|
14
14
|
* (e.g. `Session.user → AuthUser.sessions`)
|
|
15
15
|
*
|
|
16
|
-
* When the developer supplies no `modelName`/`fields` overrides, the output
|
|
17
|
-
*
|
|
18
|
-
* `Verification`
|
|
16
|
+
* When the developer supplies no `modelName`/`fields` overrides, the output
|
|
17
|
+
* keeps the historical default keys (`User`/`Session`/`Account`/
|
|
18
|
+
* `Verification`) and field shapes — see the unit tests. Per ADR-0013, each
|
|
19
|
+
* list ships with **no** operation-level access unless the caller supplies it
|
|
20
|
+
* (`accessConfig`, or `userConfig.access` for the user list) — deny-by-default,
|
|
21
|
+
* not the plugin's former permissive defaults.
|
|
19
22
|
*
|
|
20
23
|
* `getAuthLists`/`convertBetterAuthSchema` (and the runtime user-key
|
|
21
24
|
* resolution) consume this module so derivation lives in exactly one place.
|
|
22
25
|
*/
|
|
23
26
|
import type { ListConfig } from '@opensaas/stack-core';
|
|
24
27
|
import type { ExtendUserListConfig } from '../lists/index.js';
|
|
25
|
-
import type { NormalizedAuthModels } from './types.js';
|
|
28
|
+
import type { AuthAccessConfig, NormalizedAuthModels } from './types.js';
|
|
26
29
|
/**
|
|
27
30
|
* The derived Auth list set together with the keys each list was placed under.
|
|
28
31
|
* Keys are surfaced separately so callers (plugin add-vs-extend logic, runtime
|
|
@@ -42,9 +45,16 @@ export type DerivedAuthLists = {
|
|
|
42
45
|
/**
|
|
43
46
|
* Derive the OpenSaaS Auth lists from the resolved better-auth model config.
|
|
44
47
|
*
|
|
48
|
+
* Per ADR-0013 the derived lists ship **closed** (no permissive operation
|
|
49
|
+
* access) unless the application supplies access via `accessConfig` (the
|
|
50
|
+
* `authPlugin({ access: … })` passthrough, keyed by better-auth model name) or,
|
|
51
|
+
* for the user list specifically, `userConfig.access` (`extendUserList.access`,
|
|
52
|
+
* which takes precedence — see {@link AuthAccessConfig}).
|
|
53
|
+
*
|
|
45
54
|
* @param models - Resolved better-auth per-model config (modelName + field column maps)
|
|
46
55
|
* @param userConfig - Extra User-list fields/access/hooks supplied via `extendUserList`
|
|
56
|
+
* @param accessConfig - App-authored access for each Auth list, keyed by better-auth model name
|
|
47
57
|
* @returns The derived list keys and the four Auth list configs keyed by those keys
|
|
48
58
|
*/
|
|
49
|
-
export declare function deriveAuthLists(models: NormalizedAuthModels, userConfig?: ExtendUserListConfig): DerivedAuthLists;
|
|
59
|
+
export declare function deriveAuthLists(models: NormalizedAuthModels, userConfig?: ExtendUserListConfig, accessConfig?: AuthAccessConfig): DerivedAuthLists;
|
|
50
60
|
//# sourceMappingURL=derive-auth-lists.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-auth-lists.d.ts","sourceRoot":"","sources":["../../src/config/derive-auth-lists.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"derive-auth-lists.d.ts","sourceRoot":"","sources":["../../src/config/derive-auth-lists.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAA6B,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAanG;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,oDAAoD;IACpD,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,YAAY,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,kEAAkE;IAElE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;CACvC,CAAA;AAyMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,oBAAoB,EAC5B,UAAU,GAAE,oBAAyB,EACrC,YAAY,GAAE,gBAAqB,GAClC,gBAAgB,CAiBlB"}
|
|
@@ -13,9 +13,12 @@
|
|
|
13
13
|
* - relationship refs between the auth lists wired to the *derived* keys
|
|
14
14
|
* (e.g. `Session.user → AuthUser.sessions`)
|
|
15
15
|
*
|
|
16
|
-
* When the developer supplies no `modelName`/`fields` overrides, the output
|
|
17
|
-
*
|
|
18
|
-
* `Verification`
|
|
16
|
+
* When the developer supplies no `modelName`/`fields` overrides, the output
|
|
17
|
+
* keeps the historical default keys (`User`/`Session`/`Account`/
|
|
18
|
+
* `Verification`) and field shapes — see the unit tests. Per ADR-0013, each
|
|
19
|
+
* list ships with **no** operation-level access unless the caller supplies it
|
|
20
|
+
* (`accessConfig`, or `userConfig.access` for the user list) — deny-by-default,
|
|
21
|
+
* not the plugin's former permissive defaults.
|
|
19
22
|
*
|
|
20
23
|
* `getAuthLists`/`convertBetterAuthSchema` (and the runtime user-key
|
|
21
24
|
* resolution) consume this module so derivation lives in exactly one place.
|
|
@@ -74,18 +77,34 @@ function fieldDb(fieldName, fields) {
|
|
|
74
77
|
return column ? { map: column } : undefined;
|
|
75
78
|
}
|
|
76
79
|
/**
|
|
77
|
-
* Build the
|
|
78
|
-
* `userId` column override from the better-auth
|
|
80
|
+
* Build the `db` config for a `user` relationship (`Session.user` /
|
|
81
|
+
* `Account.user`), honouring a `userId` column override from the better-auth
|
|
82
|
+
* `fields` map and mirroring better-auth's own FK shape: no separate FK index
|
|
83
|
+
* — the index is applied at the field level via `isIndexed: false` — and
|
|
84
|
+
* `onDelete: Cascade`, so a generated Auth schema diffs clean against a live
|
|
85
|
+
* better-auth database on both dimensions instead of showing a spurious index
|
|
86
|
+
* drop and a referential-action change (issue #679).
|
|
79
87
|
*/
|
|
80
|
-
function
|
|
88
|
+
function userRelationshipDb(fields) {
|
|
81
89
|
const column = fields.userId;
|
|
82
|
-
return
|
|
90
|
+
return {
|
|
91
|
+
...(column ? { foreignKey: { map: column } } : {}),
|
|
92
|
+
extendPrismaSchema: ({ fkLine, relationLine }) => ({
|
|
93
|
+
fkLine,
|
|
94
|
+
relationLine: relationLine.replace('@relation(', '@relation(onDelete: Cascade, '),
|
|
95
|
+
}),
|
|
96
|
+
};
|
|
83
97
|
}
|
|
84
98
|
/**
|
|
85
99
|
* Create the Auth user list, applying derived field column maps + table map and
|
|
86
100
|
* wiring the session/account relationships to the derived keys.
|
|
101
|
+
*
|
|
102
|
+
* Per ADR-0013, the plugin ships no permissive access default: the list is
|
|
103
|
+
* closed unless the application supplies access via `extendUserList.access`
|
|
104
|
+
* (takes precedence — it predates the keyed `access` passthrough and is
|
|
105
|
+
* User-specific) or the `access.user` passthrough.
|
|
87
106
|
*/
|
|
88
|
-
function createUserList(model, keys, userConfig) {
|
|
107
|
+
function createUserList(model, keys, userConfig, access) {
|
|
89
108
|
const f = model.fields;
|
|
90
109
|
return list({
|
|
91
110
|
fields: {
|
|
@@ -104,33 +123,17 @@ function createUserList(model, keys, userConfig) {
|
|
|
104
123
|
...(userConfig.fields || {}),
|
|
105
124
|
},
|
|
106
125
|
db: listDb(model, DEFAULT_MODEL_NAMES.user),
|
|
107
|
-
access: userConfig.access ||
|
|
108
|
-
operation: {
|
|
109
|
-
query: () => true,
|
|
110
|
-
create: () => true,
|
|
111
|
-
update: ({ session, item }) => {
|
|
112
|
-
if (!session)
|
|
113
|
-
return false;
|
|
114
|
-
const userId = session.userId;
|
|
115
|
-
const itemId = item?.id;
|
|
116
|
-
return userId === itemId;
|
|
117
|
-
},
|
|
118
|
-
delete: ({ session, item }) => {
|
|
119
|
-
if (!session)
|
|
120
|
-
return false;
|
|
121
|
-
const userId = session.userId;
|
|
122
|
-
const itemId = item?.id;
|
|
123
|
-
return userId === itemId;
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
},
|
|
126
|
+
access: userConfig.access || access,
|
|
127
127
|
hooks: userConfig.hooks,
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
131
|
* Create the Auth session list.
|
|
132
|
+
*
|
|
133
|
+
* Per ADR-0013, the plugin ships no permissive access default — closed unless
|
|
134
|
+
* the application supplies `access.session`.
|
|
132
135
|
*/
|
|
133
|
-
function createSessionList(model, keys) {
|
|
136
|
+
function createSessionList(model, keys, access) {
|
|
134
137
|
const f = model.fields;
|
|
135
138
|
return list({
|
|
136
139
|
fields: {
|
|
@@ -144,39 +147,21 @@ function createSessionList(model, keys) {
|
|
|
144
147
|
userAgent: text({ db: fieldDb('userAgent', f) }),
|
|
145
148
|
user: relationship({
|
|
146
149
|
ref: `${keys.user}.sessions`,
|
|
147
|
-
|
|
150
|
+
isIndexed: false,
|
|
151
|
+
db: userRelationshipDb(f),
|
|
148
152
|
}),
|
|
149
153
|
},
|
|
150
154
|
db: listDb(model, DEFAULT_MODEL_NAMES.session),
|
|
151
|
-
access
|
|
152
|
-
operation: {
|
|
153
|
-
query: ({ session }) => {
|
|
154
|
-
if (!session)
|
|
155
|
-
return false;
|
|
156
|
-
const userId = session.userId;
|
|
157
|
-
if (!userId)
|
|
158
|
-
return false;
|
|
159
|
-
return {
|
|
160
|
-
user: { id: { equals: userId } },
|
|
161
|
-
};
|
|
162
|
-
},
|
|
163
|
-
create: () => true,
|
|
164
|
-
update: () => false,
|
|
165
|
-
delete: ({ session, item }) => {
|
|
166
|
-
if (!session)
|
|
167
|
-
return false;
|
|
168
|
-
const userId = session.userId;
|
|
169
|
-
const itemUserId = item?.user?.id;
|
|
170
|
-
return userId === itemUserId;
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
},
|
|
155
|
+
access,
|
|
174
156
|
});
|
|
175
157
|
}
|
|
176
158
|
/**
|
|
177
159
|
* Create the Auth account list.
|
|
160
|
+
*
|
|
161
|
+
* Per ADR-0013, the plugin ships no permissive access default — closed unless
|
|
162
|
+
* the application supplies `access.account`.
|
|
178
163
|
*/
|
|
179
|
-
function createAccountList(model, keys) {
|
|
164
|
+
function createAccountList(model, keys, access) {
|
|
180
165
|
const f = model.fields;
|
|
181
166
|
return list({
|
|
182
167
|
fields: {
|
|
@@ -184,7 +169,8 @@ function createAccountList(model, keys) {
|
|
|
184
169
|
providerId: text({ validation: { isRequired: true }, db: fieldDb('providerId', f) }),
|
|
185
170
|
user: relationship({
|
|
186
171
|
ref: `${keys.user}.accounts`,
|
|
187
|
-
|
|
172
|
+
isIndexed: false,
|
|
173
|
+
db: userRelationshipDb(f),
|
|
188
174
|
}),
|
|
189
175
|
accessToken: text({ db: fieldDb('accessToken', f) }),
|
|
190
176
|
refreshToken: text({ db: fieldDb('refreshToken', f) }),
|
|
@@ -195,41 +181,16 @@ function createAccountList(model, keys) {
|
|
|
195
181
|
password: text({ db: fieldDb('password', f) }),
|
|
196
182
|
},
|
|
197
183
|
db: listDb(model, DEFAULT_MODEL_NAMES.account),
|
|
198
|
-
access
|
|
199
|
-
operation: {
|
|
200
|
-
query: ({ session }) => {
|
|
201
|
-
if (!session)
|
|
202
|
-
return false;
|
|
203
|
-
const userId = session.userId;
|
|
204
|
-
if (!userId)
|
|
205
|
-
return false;
|
|
206
|
-
return {
|
|
207
|
-
user: { id: { equals: userId } },
|
|
208
|
-
};
|
|
209
|
-
},
|
|
210
|
-
create: () => true,
|
|
211
|
-
update: ({ session, item }) => {
|
|
212
|
-
if (!session)
|
|
213
|
-
return false;
|
|
214
|
-
const userId = session.userId;
|
|
215
|
-
const itemUserId = item?.user?.id;
|
|
216
|
-
return userId === itemUserId;
|
|
217
|
-
},
|
|
218
|
-
delete: ({ session, item }) => {
|
|
219
|
-
if (!session)
|
|
220
|
-
return false;
|
|
221
|
-
const userId = session.userId;
|
|
222
|
-
const itemUserId = item?.user?.id;
|
|
223
|
-
return userId === itemUserId;
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
},
|
|
184
|
+
access,
|
|
227
185
|
});
|
|
228
186
|
}
|
|
229
187
|
/**
|
|
230
188
|
* Create the Auth verification list.
|
|
189
|
+
*
|
|
190
|
+
* Per ADR-0013, the plugin ships no permissive access default — closed unless
|
|
191
|
+
* the application supplies `access.verification`.
|
|
231
192
|
*/
|
|
232
|
-
function createVerificationList(model) {
|
|
193
|
+
function createVerificationList(model, access) {
|
|
233
194
|
const f = model.fields;
|
|
234
195
|
return list({
|
|
235
196
|
fields: {
|
|
@@ -238,24 +199,24 @@ function createVerificationList(model) {
|
|
|
238
199
|
expiresAt: timestamp({ db: fieldDb('expiresAt', f) }),
|
|
239
200
|
},
|
|
240
201
|
db: listDb(model, DEFAULT_MODEL_NAMES.verification),
|
|
241
|
-
access
|
|
242
|
-
operation: {
|
|
243
|
-
query: () => false,
|
|
244
|
-
create: () => true,
|
|
245
|
-
update: () => false,
|
|
246
|
-
delete: () => true,
|
|
247
|
-
},
|
|
248
|
-
},
|
|
202
|
+
access,
|
|
249
203
|
});
|
|
250
204
|
}
|
|
251
205
|
/**
|
|
252
206
|
* Derive the OpenSaaS Auth lists from the resolved better-auth model config.
|
|
253
207
|
*
|
|
208
|
+
* Per ADR-0013 the derived lists ship **closed** (no permissive operation
|
|
209
|
+
* access) unless the application supplies access via `accessConfig` (the
|
|
210
|
+
* `authPlugin({ access: … })` passthrough, keyed by better-auth model name) or,
|
|
211
|
+
* for the user list specifically, `userConfig.access` (`extendUserList.access`,
|
|
212
|
+
* which takes precedence — see {@link AuthAccessConfig}).
|
|
213
|
+
*
|
|
254
214
|
* @param models - Resolved better-auth per-model config (modelName + field column maps)
|
|
255
215
|
* @param userConfig - Extra User-list fields/access/hooks supplied via `extendUserList`
|
|
216
|
+
* @param accessConfig - App-authored access for each Auth list, keyed by better-auth model name
|
|
256
217
|
* @returns The derived list keys and the four Auth list configs keyed by those keys
|
|
257
218
|
*/
|
|
258
|
-
export function deriveAuthLists(models, userConfig = {}) {
|
|
219
|
+
export function deriveAuthLists(models, userConfig = {}, accessConfig = {}) {
|
|
259
220
|
const keys = {
|
|
260
221
|
user: models.user.modelName,
|
|
261
222
|
session: models.session.modelName,
|
|
@@ -264,10 +225,10 @@ export function deriveAuthLists(models, userConfig = {}) {
|
|
|
264
225
|
};
|
|
265
226
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ListConfig must accept any TypeInfo
|
|
266
227
|
const lists = {
|
|
267
|
-
[keys.user]: createUserList(models.user, keys, userConfig),
|
|
268
|
-
[keys.session]: createSessionList(models.session, keys),
|
|
269
|
-
[keys.account]: createAccountList(models.account, keys),
|
|
270
|
-
[keys.verification]: createVerificationList(models.verification),
|
|
228
|
+
[keys.user]: createUserList(models.user, keys, userConfig, accessConfig.user),
|
|
229
|
+
[keys.session]: createSessionList(models.session, keys, accessConfig.session),
|
|
230
|
+
[keys.account]: createAccountList(models.account, keys, accessConfig.account),
|
|
231
|
+
[keys.verification]: createVerificationList(models.verification, accessConfig.verification),
|
|
271
232
|
};
|
|
272
233
|
return { keys, lists };
|
|
273
234
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-auth-lists.js","sourceRoot":"","sources":["../../src/config/derive-auth-lists.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"derive-auth-lists.js","sourceRoot":"","sources":["../../src/config/derive-auth-lists.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,oBAAoB,EAMrB,MAAM,YAAY,CAAA;AAmDnB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,oBAAoB,EAMrB,MAAM,YAAY,CAAA;AAmDnB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,oBAAoB,CAgE5E;AAED,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAA;AAChD,cAAc,YAAY,CAAA"}
|
package/dist/config/index.js
CHANGED
|
@@ -83,6 +83,7 @@ export function normalizeAuthConfig(config) {
|
|
|
83
83
|
schema: config.schema,
|
|
84
84
|
sessionFields,
|
|
85
85
|
extendUserList: config.extendUserList || {},
|
|
86
|
+
access: config.access || {},
|
|
86
87
|
sendEmail: config.sendEmail ||
|
|
87
88
|
(async ({ to, subject, html }) => {
|
|
88
89
|
console.log('[Auth] Email not sent (no sendEmail configured):');
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAA;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,YAAY,CAAA;AAKlE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAA;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,YAAY,CAAA;AAKlE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA4KrD"}
|
package/dist/config/plugin.js
CHANGED
|
@@ -38,21 +38,34 @@ export function authPlugin(config) {
|
|
|
38
38
|
// User/Session/Account/Verification keys; with overrides (e.g.
|
|
39
39
|
// user.modelName: 'AuthUser') the lists are keyed and column-mapped to
|
|
40
40
|
// match the developer's live better-auth tables.
|
|
41
|
-
const authLists = getAuthLists(normalized.extendUserList, normalized.models);
|
|
41
|
+
const authLists = getAuthLists(normalized.extendUserList, normalized.models, normalized.access);
|
|
42
|
+
// The same base-model list keys the Auth lists above were derived under
|
|
43
|
+
// (e.g. `user.modelName: 'AuthUser'`). A provider plugin's schema
|
|
44
|
+
// extension of a base model (e.g. `user`) must resolve against this
|
|
45
|
+
// remap too, so it lands on the adopted Auth list rather than a
|
|
46
|
+
// re-derived key that can collide with an unrelated host list.
|
|
47
|
+
const baseModelKeys = {
|
|
48
|
+
user: normalized.models.user.modelName,
|
|
49
|
+
session: normalized.models.session.modelName,
|
|
50
|
+
account: normalized.models.account.modelName,
|
|
51
|
+
verification: normalized.models.verification.modelName,
|
|
52
|
+
};
|
|
42
53
|
// Extract additional lists from Better Auth plugins
|
|
43
54
|
for (const plugin of normalized.betterAuthPlugins) {
|
|
44
55
|
if (plugin && typeof plugin === 'object' && 'schema' in plugin) {
|
|
45
56
|
// Plugin has schema property - convert to OpenSaaS lists
|
|
46
57
|
const pluginSchema = plugin.schema;
|
|
47
|
-
const pluginLists = convertBetterAuthSchema(pluginSchema);
|
|
58
|
+
const pluginLists = convertBetterAuthSchema(pluginSchema, baseModelKeys);
|
|
48
59
|
// Add or extend lists from plugin
|
|
49
60
|
for (const [listName, listConfig] of Object.entries(pluginLists)) {
|
|
50
61
|
if (context.config.lists[listName]) {
|
|
51
|
-
// List exists
|
|
62
|
+
// List already exists — merge fields/hooks/mcp in only. Access
|
|
63
|
+
// control belongs to whoever owns the list; per ADR-0013 an
|
|
64
|
+
// extension must never carry operation-level access for a
|
|
65
|
+
// pre-existing list (the plugin engine throws if it does).
|
|
52
66
|
context.extendList(listName, {
|
|
53
67
|
fields: listConfig.fields,
|
|
54
68
|
hooks: listConfig.hooks,
|
|
55
|
-
access: listConfig.access,
|
|
56
69
|
mcp: listConfig.mcp,
|
|
57
70
|
});
|
|
58
71
|
}
|
|
@@ -74,11 +87,13 @@ export function authPlugin(config) {
|
|
|
74
87
|
// "merge auth fields into my User" behaviour.
|
|
75
88
|
for (const [listName, listConfig] of Object.entries(authLists)) {
|
|
76
89
|
if (context.config.lists[listName]) {
|
|
77
|
-
// A list already exists under this derived key — merge auth fields
|
|
90
|
+
// A list already exists under this derived key — merge auth fields
|
|
91
|
+
// in only. Access control belongs to whoever owns the list (the
|
|
92
|
+
// application declared it first), so the plugin never forwards its
|
|
93
|
+
// own access here — see ADR-0013.
|
|
78
94
|
context.extendList(listName, {
|
|
79
95
|
fields: listConfig.fields,
|
|
80
96
|
hooks: listConfig.hooks,
|
|
81
|
-
access: listConfig.access,
|
|
82
97
|
mcp: listConfig.mcp,
|
|
83
98
|
});
|
|
84
99
|
}
|
|
@@ -121,30 +136,33 @@ export function authPlugin(config) {
|
|
|
121
136
|
lists,
|
|
122
137
|
};
|
|
123
138
|
},
|
|
124
|
-
runtime: (context) => {
|
|
139
|
+
runtime: (context, sudo) => {
|
|
125
140
|
// Resolve the user list's context.db key from the configured user model.
|
|
126
141
|
// context.db is keyed camelCase, so 'User' -> 'user', 'AuthUser' -> 'authUser'.
|
|
127
142
|
const userDbKey = getDbKey(normalized.models.user.modelName);
|
|
128
143
|
// Provide auth-related utilities at runtime
|
|
129
144
|
return {
|
|
130
145
|
/**
|
|
131
|
-
* Get user by ID
|
|
132
|
-
*
|
|
146
|
+
* Get user by ID.
|
|
147
|
+
*
|
|
148
|
+
* Resolves through `sudo()` (per ADR-0013): the User list ships closed
|
|
149
|
+
* by default, and "who is this session" must not depend on the
|
|
150
|
+
* application's User access policy.
|
|
133
151
|
*/
|
|
134
152
|
getUser: async (userId) => {
|
|
135
|
-
return await
|
|
153
|
+
return await sudo().db[userDbKey].findUnique({
|
|
136
154
|
where: { id: userId },
|
|
137
155
|
});
|
|
138
156
|
},
|
|
139
157
|
/**
|
|
140
|
-
* Get current user from session
|
|
141
|
-
*
|
|
158
|
+
* Get current user from session. Extracts userId from session and
|
|
159
|
+
* fetches user data via `sudo()` — see {@link getUser}.
|
|
142
160
|
*/
|
|
143
161
|
getCurrentUser: async () => {
|
|
144
162
|
if (!context.session?.userId) {
|
|
145
163
|
return null;
|
|
146
164
|
}
|
|
147
|
-
return await
|
|
165
|
+
return await sudo().db[userDbKey].findUnique({
|
|
148
166
|
where: { id: context.session.userId },
|
|
149
167
|
});
|
|
150
168
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA;AAEvE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,UAAU,CAAC,MAAkB;IAC3C,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAE9C,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,OAAO;QAEhB,mBAAmB,EAAE;YACnB,MAAM,EAAE,iEAAiE;YACzE,QAAQ,EAAE,qBAAqB;SAChC;QAED,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACtB,uEAAuE;YACvE,mEAAmE;YACnE,+DAA+D;YAC/D,uEAAuE;YACvE,iDAAiD;YACjD,MAAM,SAAS,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"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"}
|