@robelest/convex-auth 0.0.4-preview.23 → 0.0.4-preview.24
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/README.md +10 -11
- package/dist/component/index.js +2 -2
- package/dist/component/model.d.ts.map +1 -1
- package/dist/component/schema.d.ts +5 -5
- package/dist/component/server/auth.d.ts +103 -103
- package/dist/component/server/auth.d.ts.map +1 -1
- package/dist/component/server/auth.js +70 -68
- package/dist/component/server/auth.js.map +1 -1
- package/dist/component/server/context.js +53 -0
- package/dist/component/server/context.js.map +1 -0
- package/dist/component/server/core.js +2 -20
- package/dist/component/server/core.js.map +1 -1
- package/dist/component/server/device.js +1 -1
- package/dist/component/server/http.d.ts +85 -0
- package/dist/component/server/http.d.ts.map +1 -0
- package/dist/component/server/http.js +59 -1
- package/dist/component/server/http.js.map +1 -1
- package/dist/component/server/runtime.d.ts +4 -4
- package/dist/component/server/runtime.d.ts.map +1 -1
- package/dist/component/server/runtime.js +110 -109
- package/dist/component/server/runtime.js.map +1 -1
- package/dist/server/auth.d.ts +103 -103
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +70 -68
- package/dist/server/auth.js.map +1 -1
- package/dist/server/context.d.ts +1 -0
- package/dist/server/context.js +53 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/core.d.ts +3 -36
- package/dist/server/core.d.ts.map +1 -1
- package/dist/server/core.js +2 -20
- package/dist/server/core.js.map +1 -1
- package/dist/server/device.js +1 -1
- package/dist/server/http.d.ts +81 -3
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +59 -1
- package/dist/server/http.js.map +1 -1
- package/dist/server/index.d.ts +3 -2
- package/dist/server/index.js +2 -2
- package/dist/server/mounts.d.ts +7 -7
- package/dist/server/mounts.d.ts.map +1 -1
- package/dist/server/mounts.js +1 -1
- package/dist/server/mounts.js.map +1 -1
- package/dist/server/mutations/account.d.ts +6 -6
- package/dist/server/mutations/account.d.ts.map +1 -1
- package/dist/server/mutations/code.d.ts +12 -12
- package/dist/server/mutations/invalidate.d.ts +4 -4
- package/dist/server/mutations/invalidate.d.ts.map +1 -1
- package/dist/server/mutations/oauth.d.ts +7 -7
- package/dist/server/mutations/oauth.d.ts.map +1 -1
- package/dist/server/mutations/refresh.d.ts +3 -3
- package/dist/server/mutations/register.d.ts +9 -9
- package/dist/server/mutations/register.d.ts.map +1 -1
- package/dist/server/mutations/retrieve.d.ts +6 -6
- package/dist/server/mutations/signature.d.ts +4 -4
- package/dist/server/mutations/signin.d.ts +5 -5
- package/dist/server/mutations/signin.d.ts.map +1 -1
- package/dist/server/mutations/store.d.ts +77 -77
- package/dist/server/mutations/verify.d.ts +7 -7
- package/dist/server/runtime.d.ts +9 -9
- package/dist/server/runtime.d.ts.map +1 -1
- package/dist/server/runtime.js +110 -109
- package/dist/server/runtime.js.map +1 -1
- package/package.json +1 -1
- package/src/component/index.ts +8 -2
- package/src/server/auth.ts +183 -147
- package/src/server/context.ts +90 -0
- package/src/server/core.ts +5 -60
- package/src/server/http.ts +253 -0
- package/src/server/index.ts +8 -2
- package/src/server/mounts.ts +9 -6
- package/src/server/runtime.ts +287 -264
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ one setup API, full TypeScript support.
|
|
|
20
20
|
- **Groups, memberships, invites** — hierarchical multi-tenancy with roles.
|
|
21
21
|
- **SSR support** — framework-agnostic httpOnly cookie API (SvelteKit, TanStack
|
|
22
22
|
Start, Next.js).
|
|
23
|
-
- **Context enrichment** — zero-boilerplate `ctx.auth.userId` via `
|
|
23
|
+
- **Context enrichment** — zero-boilerplate `ctx.auth.userId` via `auth.ctx()`.
|
|
24
24
|
|
|
25
25
|
## Install
|
|
26
26
|
|
|
@@ -105,11 +105,11 @@ import { auth } from "./auth";
|
|
|
105
105
|
|
|
106
106
|
const convex = createBuilder<DataModel>();
|
|
107
107
|
|
|
108
|
+
// `auth.context(ctx)` resolves { userId, user, groupId, role, grants }
|
|
109
|
+
// and throws before the handler runs when unauthenticated.
|
|
108
110
|
const withRequiredAuth = convex.createMiddleware<any, { auth: any }>(
|
|
109
111
|
async (ctx, next) => {
|
|
110
|
-
|
|
111
|
-
const user = await auth.user.get(ctx, userId);
|
|
112
|
-
return next({ ...ctx, auth: { ...ctx.auth, userId, user } });
|
|
112
|
+
return next({ ...ctx, auth: await auth.context(ctx) });
|
|
113
113
|
},
|
|
114
114
|
);
|
|
115
115
|
|
|
@@ -117,19 +117,18 @@ export const query = convex.query().use(withRequiredAuth).extend(WithZod);
|
|
|
117
117
|
export const mutation = convex.mutation().use(withRequiredAuth).extend(WithZod);
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
`
|
|
121
|
-
project already uses `convex-helpers`.
|
|
120
|
+
`auth.ctx()` works with `convex-helpers` and other custom builder setups.
|
|
122
121
|
|
|
123
122
|
## Providers
|
|
124
123
|
|
|
125
124
|
| Provider | Import |
|
|
126
125
|
| ----------------- | ----------------------------------------------------------------------- |
|
|
127
126
|
| OAuth (Arctic) | `import { OAuth } from "@robelest/convex-auth/providers"` |
|
|
128
|
-
| Password | `import { Password } from "@robelest/convex-auth/providers
|
|
129
|
-
| Passkey | `import { Passkey } from "@robelest/convex-auth/providers
|
|
130
|
-
| TOTP | `import { Totp } from "@robelest/convex-auth/providers
|
|
131
|
-
| Phone/SMS | `import {
|
|
132
|
-
| Anonymous | `import { Anonymous } from "@robelest/convex-auth/providers
|
|
127
|
+
| Password | `import { Password } from "@robelest/convex-auth/providers"` |
|
|
128
|
+
| Passkey | `import { Passkey } from "@robelest/convex-auth/providers"` |
|
|
129
|
+
| TOTP | `import { Totp } from "@robelest/convex-auth/providers"` |
|
|
130
|
+
| Phone/SMS | `import { Phone } from "@robelest/convex-auth/providers"` |
|
|
131
|
+
| Anonymous | `import { Anonymous } from "@robelest/convex-auth/providers"` |
|
|
133
132
|
| Device (RFC 8628) | `import { Device } from "@robelest/convex-auth/providers"` |
|
|
134
133
|
|
|
135
134
|
## Enterprise
|
package/dist/component/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createAuth } from "./server/auth.js";
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { createAuth };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","names":[],"sources":["../../src/component/model.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"model.d.ts","names":[],"sources":["../../src/component/model.ts"],"mappings":";;;;;;cAEa,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;cA2BA,IAAA,iBAAI,OAAA;;;;OAAmD,cAAA,CAAA,OAAA;;;cAEvD,UAAA,GAAc,IAAA,yBAAS,OAAA;;;;SAIhC,cAAA,CAAA,MAAA;;;cAES,aAAA,EAAa,cAAA,CAAA,MAAA,kDAKzB,cAAA,CALyB,QAAA,yBAAA,cAAA,CAAA,QAAA,0BAAA,cAAA,CAAA,QAAA,yBAAA,cAAA,CAAA,QAAA;AAAA,cAOb,aAAA,EAAa,cAAA,CAAA,MAAA,uCAIzB,cAAA,CAJyB,QAAA,yBAAA,cAAA,CAAA,QAAA,4BAAA,cAAA,CAAA,QAAA;AAAA,cAMb,+BAAA,EAA+B,cAAA,CAAA,MAAA,4BAG3C,cAAA,CAH2C,QAAA,+BAAA,cAAA,CAAA,QAAA;AAAA,cAK/B,8BAAA,EAA8B,cAAA,CAAA,MAAA,yBAG1C,cAAA,CAH0C,QAAA,4BAAA,cAAA,CAAA,QAAA;AAAA,cAK9B,8BAAA,EAA8B,cAAA,CAAA,MAAA,oDAI1C,cAAA,CAJ0C,QAAA,qBAAA,cAAA,CAAA,QAAA,4BAAA,cAAA,CAAA,QAAA;AAAA,cAM9B,0BAAA,EAA0B,cAAA,CAAA,MAAA,mBAGtC,cAAA,CAHsC,QAAA,sBAAA,cAAA,CAAA,QAAA;AAAA,cAK1B,iBAAA,EAAiB,cAAA,CAAA,MAAA,mCAI7B,cAAA,CAJ6B,QAAA,uBAAA,cAAA,CAAA,QAAA,wBAAA,cAAA,CAAA,QAAA;AAAA,cAMjB,iBAAA,iBAAiB,OAAA;;;;;;;;;;;;;;;;;;;;;;;WAsB5B,cAAA,CAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,WAAA,EAAW,cAAA,CAAA,MAAA,mCAIvB,cAAA,CAJuB,QAAA,uBAAA,cAAA,CAAA,QAAA,wBAAA,cAAA,CAAA,QAAA;AAAA,cAMX,iBAAA,EAAiB,cAAA,CAAA,MAAA,oBAAiD,cAAA,CAAjD,QAAA,sBAAA,cAAA,CAAA,QAAA;AAAA,cAEjB,eAAA,EAAe,cAAA,CAAA,MAAA,sDAM3B,cAAA,CAN2B,QAAA,sBAAA,cAAA,CAAA,QAAA,wBAAA,cAAA,CAAA,QAAA,sBAAA,cAAA,CAAA,QAAA,yBAAA,cAAA,CAAA,QAAA;AAAA,cAQf,YAAA,EAAY,cAAA,CAAA,MAAA,yBAAsD,cAAA,CAAtD,QAAA,yBAAA,cAAA,CAAA,QAAA;AAAA,cAEZ,sBAAA,EAAsB,cAAA,CAAA,MAAA,yBAGlC,cAAA,CAHkC,QAAA,wBAAA,cAAA,CAAA,QAAA;AAAA,cAKtB,sBAAA,EAAsB,cAAA,CAAA,MAAA,qDAKlC,cAAA,CALkC,QAAA,yBAAA,cAAA,CAAA,QAAA,4BAAA,cAAA,CAAA,QAAA,2BAAA,cAAA,CAAA,QAAA;AAAA,cAOtB,wBAAA,EAAwB,cAAA,CAAA,MAAA,mCAGpC,cAAA,CAHoC,QAAA,0BAAA,cAAA,CAAA,QAAA;AAAA,cAKxB,iBAAA,EAAiB,cAAA,CAAA,MAAA,kDAI7B,cAAA,CAJ6B,QAAA,wBAAA,cAAA,CAAA,QAAA,gCAAA,cAAA,CAAA,QAAA;AAAA,cAMjB,YAAA,iBAAY,OAAA;;;;YAGvB,cAAA,CAAA,OAAA;;;cAEW,gBAAA,iBAAgB,OAAA;;;;eAG3B,cAAA,CAAA,QAAA;;;cAEW,qBAAA,iBAAqB,OAAA;;;;gBAGhC,cAAA,CAAA,QAAA;;;cAEW,qBAAA,EAAqB,cAAA,CAAA,MAAA,wBAA2C,cAAA,CAA3C,QAAA;AAAA,cAWrB,QAAA,iBAAQ,OAAA;;;;;;;;;OAUnB,cAAA,CAAA,SAAA;;;;;;;;;;;;;;cAEW,WAAA,iBAAW,OAAA;OAItB,cAAA,CAAA,SAAA;;;;;;;;;;cAEW,WAAA,iBAAW,OAAA;;;;;OAStB,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;cAEW,gBAAA,iBAAgB,OAAA;cAI3B,cAAA,CAAA,SAAA;;;;;;;;;;cAEW,oBAAA,iBAAoB,OAAA;;;;OAS/B,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;cAEW,gBAAA,iBAAgB,OAAA;;yBAM3B,cAAA,CAAA,SAAA;;;;;;;;;;;;;cAEW,WAAA,iBAAW,OAAA;;;;OAatB,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,cAAA,iBAAc,OAAA;;;OAUzB,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;cAEW,aAAA,iBAAa,OAAA;OAKxB,cAAA,CAAA,SAAA;;;;;;;;;;;;cAEW,SAAA,iBAAS,OAAA;;;;kBAUpB,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,eAAA,iBAAe,OAAA;;;;;OAQ1B,cAAA,CAAA,SAAA;;;;;;;;;;;;;;cAEW,eAAA,iBAAe,OAAA;;;YAa1B,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,UAAA,iBAAU,OAAA;;;;;;;;;;;;;;OAcrB,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,cAAA,iBAAc,OAAA;WAUzB,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;cAEW,cAAA,iBAAc,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;OASzB,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,oBAAA,iBAAoB,OAAA;;OAO/B,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;cAEW,gCAAA,iBAAgC,OAAA;OAW3C,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;cAEW,oBAAA,iBAAoB,OAAA;OAO/B,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;cAEW,wBAAA,iBAAwB,OAAA;;;OASnC,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;cAEW,0BAAA,iBAA0B,OAAA;;WAWrC,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;cAEW,wBAAA,iBAAwB,OAAA;;;;;;OAcnC,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,6BAAA,iBAA6B,OAAA;;oBAaxC,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,6BAAA,iBAA6B,OAAA;iBAaxC,cAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,gBAAA,iBAAgB,OAAA;;;OAO3B,cAAA,CAAA,SAAA;;;;;;;;;;;;;;cAEW,0BAAA,iBAA0B,OAAA;aAMrC,cAAA,CAAA,SAAA"}
|
|
@@ -15,10 +15,10 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
15
15
|
* and multiple concurrent sessions.
|
|
16
16
|
*/
|
|
17
17
|
User: convex_server66.TableDefinition<convex_values121.VObject<{
|
|
18
|
-
|
|
18
|
+
email?: string | undefined;
|
|
19
19
|
extend?: any;
|
|
20
20
|
name?: string | undefined;
|
|
21
|
-
|
|
21
|
+
phone?: string | undefined;
|
|
22
22
|
image?: string | undefined;
|
|
23
23
|
emailVerificationTime?: number | undefined;
|
|
24
24
|
phoneVerificationTime?: number | undefined;
|
|
@@ -32,7 +32,7 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
32
32
|
phoneVerificationTime: convex_values121.VFloat64<number | undefined, "optional">;
|
|
33
33
|
isAnonymous: convex_values121.VBoolean<boolean | undefined, "optional">;
|
|
34
34
|
extend: convex_values121.VAny<any, "optional", string>;
|
|
35
|
-
}, "required", "
|
|
35
|
+
}, "required", "email" | "extend" | "name" | "phone" | "image" | "emailVerificationTime" | "phoneVerificationTime" | "isAnonymous" | `extend.${string}`>, {
|
|
36
36
|
email: ["email", "_creationTime"];
|
|
37
37
|
email_verified: ["email", "emailVerificationTime", "_creationTime"];
|
|
38
38
|
phone: ["phone", "_creationTime"];
|
|
@@ -336,9 +336,9 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
336
336
|
* invite links where neither is known upfront.
|
|
337
337
|
*/
|
|
338
338
|
GroupInvite: convex_server66.TableDefinition<convex_values121.VObject<{
|
|
339
|
+
email?: string | undefined;
|
|
339
340
|
groupId?: convex_values121.GenericId<"Group"> | undefined;
|
|
340
341
|
extend?: any;
|
|
341
|
-
email?: string | undefined;
|
|
342
342
|
role?: string | undefined;
|
|
343
343
|
roleIds?: string[] | undefined;
|
|
344
344
|
invitedByUserId?: convex_values121.GenericId<"User"> | undefined;
|
|
@@ -359,7 +359,7 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
359
359
|
acceptedByUserId: convex_values121.VId<convex_values121.GenericId<"User"> | undefined, "optional">;
|
|
360
360
|
acceptedTime: convex_values121.VFloat64<number | undefined, "optional">;
|
|
361
361
|
extend: convex_values121.VAny<any, "optional", string>;
|
|
362
|
-
}, "required", "
|
|
362
|
+
}, "required", "email" | "groupId" | "extend" | "status" | `extend.${string}` | "role" | "roleIds" | "invitedByUserId" | "tokenHash" | "expiresTime" | "acceptedByUserId" | "acceptedTime">, {
|
|
363
363
|
token_hash: ["tokenHash", "_creationTime"];
|
|
364
364
|
status: ["status", "_creationTime"];
|
|
365
365
|
email_status: ["email", "status", "_creationTime"];
|
|
@@ -87,9 +87,12 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
|
|
|
87
87
|
* this in fluent-convex middleware, custom wrappers, or anywhere you
|
|
88
88
|
* need the current `{ userId, user, groupId, role, grants }` object.
|
|
89
89
|
*
|
|
90
|
-
* Throws a structured `ConvexError` when unauthenticated.
|
|
90
|
+
* Throws a structured `ConvexError` when unauthenticated by default.
|
|
91
|
+
* Pass `{ optional: true }` to get a null-shaped auth object instead.
|
|
91
92
|
*
|
|
92
93
|
* @param ctx - Convex query, mutation, or action context.
|
|
94
|
+
* @param config - Optional auth resolution config. Supports `optional`,
|
|
95
|
+
* `resolve`, and `authResolve`.
|
|
93
96
|
* @returns The current auth context.
|
|
94
97
|
*
|
|
95
98
|
* @example fluent-convex middleware
|
|
@@ -100,12 +103,20 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
|
|
|
100
103
|
* ```
|
|
101
104
|
*
|
|
102
105
|
* @example Direct usage in a handler
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
* ```ts
|
|
107
|
+
* const authContext = await auth.context(ctx);
|
|
108
|
+
* const { userId, grants } = authContext;
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @example Optional usage
|
|
112
|
+
* ```ts
|
|
113
|
+
* const authContext = await auth.context(ctx, { optional: true });
|
|
114
|
+
* if (authContext.userId === null) {
|
|
115
|
+
* return null;
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
context: AuthContextResolver;
|
|
109
120
|
/**
|
|
110
121
|
* Context enrichment for convex-helpers `customQuery` / `customMutation` /
|
|
111
122
|
* `customAction`.
|
|
@@ -144,21 +155,13 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
|
|
|
144
155
|
* });
|
|
145
156
|
* ```
|
|
146
157
|
*/
|
|
147
|
-
ctx:
|
|
148
|
-
args: Record<string, never>;
|
|
149
|
-
input: (ctx: any) => Promise<{
|
|
150
|
-
ctx: {
|
|
151
|
-
auth: AuthContext;
|
|
152
|
-
};
|
|
153
|
-
args: Record<string, never>;
|
|
154
|
-
}>;
|
|
155
|
-
};
|
|
158
|
+
ctx: AuthContextFactory;
|
|
156
159
|
};
|
|
157
160
|
/**
|
|
158
|
-
* Current request auth context injected into `ctx.auth` by `auth.ctx()
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
161
|
+
* Current request auth context injected into `ctx.auth` by `auth.ctx()`. This
|
|
162
|
+
* is the authenticated auth shape returned by {@link createAuth().context}.
|
|
163
|
+
* Optional context builders may still surface nullable fields when
|
|
164
|
+
* `optional: true` is used.
|
|
162
165
|
*
|
|
163
166
|
* - `groupId` is `null` when the user has no active group set.
|
|
164
167
|
* - `role` is `null` when no active group or no membership is resolved.
|
|
@@ -184,16 +187,59 @@ type AuthContext = {
|
|
|
184
187
|
role: string | null; /** Resolved grant strings from the user's role definitions. */
|
|
185
188
|
grants: string[];
|
|
186
189
|
};
|
|
187
|
-
|
|
190
|
+
/**
|
|
191
|
+
* Nullable auth context returned by `auth.context(ctx, { optional: true })`
|
|
192
|
+
* and injected by `auth.ctx({ optional: true })`.
|
|
193
|
+
*
|
|
194
|
+
* Use this when callers may be unauthenticated but you still want a stable
|
|
195
|
+
* auth-shaped object.
|
|
196
|
+
*
|
|
197
|
+
* - `userId` and `user` are `null` when unauthenticated.
|
|
198
|
+
* - `groupId` and `role` are `null` when no active group is resolved.
|
|
199
|
+
* - `grants` is `[]` when no membership is resolved.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* const authContext = await auth.context(ctx, { optional: true });
|
|
204
|
+
* if (authContext.userId === null) {
|
|
205
|
+
* return null;
|
|
206
|
+
* }
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
type OptionalAuthContext = {
|
|
210
|
+
/** The authenticated user's document ID, or `null` when unauthenticated. */userId: GenericId<"User"> | null; /** The authenticated user's full document, or `null` when unauthenticated. */
|
|
211
|
+
user: UserDoc | null; /** The user's active group ID, or `null` if none is set. */
|
|
212
|
+
groupId: string | null; /** The user's primary role in the active group, or `null`. */
|
|
213
|
+
role: string | null; /** Resolved grant strings for the active membership, or `[]`. */
|
|
214
|
+
grants: string[];
|
|
215
|
+
};
|
|
216
|
+
type AuthContextBase = {
|
|
188
217
|
getUserIdentity: () => Promise<UserIdentity | null>;
|
|
189
218
|
};
|
|
190
|
-
type
|
|
191
|
-
type
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
219
|
+
type RequiredAuthContextState = AuthContextBase & AuthContext;
|
|
220
|
+
type OptionalAuthContextState = AuthContextBase & OptionalAuthContext;
|
|
221
|
+
type ResolvedAuthContext<TResolve> = AuthContext & TResolve;
|
|
222
|
+
type ResolvedOptionalAuthContext<TResolve> = OptionalAuthContext & TResolve;
|
|
223
|
+
type AuthContextResolver = {
|
|
224
|
+
<TResolve extends Record<string, unknown> = Record<string, never>>(ctx: any, config: AuthContextConfig<TResolve> & {
|
|
225
|
+
optional: true;
|
|
226
|
+
}): Promise<ResolvedOptionalAuthContext<TResolve>>;
|
|
227
|
+
<TResolve extends Record<string, unknown> = Record<string, never>>(ctx: any, config?: AuthContextConfig<TResolve>): Promise<ResolvedAuthContext<TResolve>>;
|
|
228
|
+
};
|
|
229
|
+
type AuthContextCustomization<TAuth> = {
|
|
230
|
+
args: {};
|
|
231
|
+
input: (ctx: any, _args: any, _extra?: any) => Promise<{
|
|
232
|
+
ctx: {
|
|
233
|
+
auth: TAuth;
|
|
234
|
+
};
|
|
235
|
+
args: {};
|
|
236
|
+
}>;
|
|
237
|
+
};
|
|
238
|
+
type AuthContextFactory = {
|
|
239
|
+
<TResolve extends Record<string, unknown> = Record<string, never>>(config: AuthContextConfig<TResolve> & {
|
|
240
|
+
optional: true;
|
|
241
|
+
}): AuthContextCustomization<OptionalAuthContextState & TResolve>;
|
|
242
|
+
<TResolve extends Record<string, unknown> = Record<string, never>>(config?: AuthContextConfig<TResolve>): AuthContextCustomization<RequiredAuthContextState & TResolve>;
|
|
197
243
|
};
|
|
198
244
|
type InternalSsoApi = ReturnType<typeof Auth>["auth"]["sso"];
|
|
199
245
|
type PublicSsoAdminApi = {
|
|
@@ -309,20 +355,38 @@ declare function createAuth<P extends AuthProviderConfig[], TAuthorization exten
|
|
|
309
355
|
authorization?: TAuthorization;
|
|
310
356
|
}): ConvexAuthResult<P, TAuthorization>;
|
|
311
357
|
/**
|
|
312
|
-
* Configuration for {@link
|
|
358
|
+
* Configuration for {@link createAuth().ctx} context enrichment.
|
|
359
|
+
*
|
|
360
|
+
* The same config shape is also used by {@link createAuth().context}.
|
|
313
361
|
*
|
|
314
362
|
* @typeParam TResolve - Extra fields returned from `resolve()` and merged into
|
|
315
363
|
* the resulting `ctx.auth` object.
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```ts
|
|
367
|
+
* const authContext = await auth.context(ctx, {
|
|
368
|
+
* resolve: async (_ctx, user, authState) => ({
|
|
369
|
+
* email: user.email,
|
|
370
|
+
* canWrite: authState.grants.includes("posts.write"),
|
|
371
|
+
* }),
|
|
372
|
+
* });
|
|
373
|
+
* ```
|
|
316
374
|
*/
|
|
317
|
-
type
|
|
318
|
-
/**
|
|
375
|
+
type AuthContextConfig<TResolve extends Record<string, unknown> = Record<string, never>> = {
|
|
376
|
+
/**
|
|
377
|
+
* Allow unauthenticated callers and return a null-shaped auth object instead
|
|
378
|
+
* of throwing `NOT_SIGNED_IN`.
|
|
379
|
+
*/
|
|
380
|
+
optional?: boolean;
|
|
319
381
|
/**
|
|
320
382
|
* Attach additional derived fields to the auth context after the base auth
|
|
321
383
|
* context is resolved.
|
|
384
|
+
*
|
|
385
|
+
* This callback runs only when a user is authenticated.
|
|
322
386
|
*/
|
|
323
387
|
resolve?: (ctx: any, user: UserDoc, auth: AuthContext) => Promise<TResolve> | TResolve;
|
|
324
388
|
/**
|
|
325
|
-
* Override or wrap the base auth resolution used by {@link
|
|
389
|
+
* Override or wrap the base auth resolution used by {@link createAuth().ctx}.
|
|
326
390
|
*
|
|
327
391
|
* Return `undefined` to fall back to the built-in resolver,
|
|
328
392
|
* `null` for an explicit unauthenticated state, or an
|
|
@@ -332,12 +396,12 @@ type AuthCtxConfig<TResolve extends Record<string, unknown> = Record<string, nev
|
|
|
332
396
|
* Convex auth tables.
|
|
333
397
|
*
|
|
334
398
|
* @param ctx - The Convex function context.
|
|
335
|
-
* @param fallback - The built-in auth resolver used by {@link
|
|
399
|
+
* @param fallback - The built-in auth resolver used by {@link createAuth().ctx}.
|
|
336
400
|
* @returns Resolved auth state, `null`, or `undefined` to use the fallback.
|
|
337
401
|
*
|
|
338
402
|
* @example
|
|
339
403
|
* ```ts
|
|
340
|
-
* const authCtx =
|
|
404
|
+
* const authCtx = auth.ctx({
|
|
341
405
|
* authResolve: async (ctx, fallback) => {
|
|
342
406
|
* const injected = getInjectedAuth(ctx);
|
|
343
407
|
* return injected ?? (await fallback());
|
|
@@ -348,85 +412,21 @@ type AuthCtxConfig<TResolve extends Record<string, unknown> = Record<string, nev
|
|
|
348
412
|
authResolve?: (ctx: any, fallback: () => Promise<AuthContext | null>) => Promise<AuthContext | null | undefined> | AuthContext | null | undefined;
|
|
349
413
|
};
|
|
350
414
|
/**
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
* When `optional: true` is set, unauthenticated requests are allowed.
|
|
354
|
-
* The enriched `ctx.auth` will have `userId: null`, `user: null`,
|
|
355
|
-
* `groupId: null`, `role: null`, and `grants: []` for unauthenticated callers.
|
|
356
|
-
*
|
|
357
|
-
* @param auth - The auth API object returned by {@link createAuth}.
|
|
358
|
-
* @param config - Configuration with `optional: true` and an optional
|
|
359
|
-
* `resolve` callback for attaching extra fields to the auth context.
|
|
360
|
-
* @returns An object with `args` and `input` compatible with Convex
|
|
361
|
-
* custom function builders.
|
|
362
|
-
*
|
|
363
|
-
* @example
|
|
364
|
-
* ```ts
|
|
365
|
-
* const authCtx = AuthCtx(auth, {
|
|
366
|
-
* optional: true,
|
|
367
|
-
* resolve: async (_ctx, user) => ({ plan: user?.extend?.plan ?? null }),
|
|
368
|
-
* });
|
|
369
|
-
* ```
|
|
370
|
-
*
|
|
371
|
-
* @see {@link createAuth}
|
|
372
|
-
*/
|
|
373
|
-
declare function AuthCtx<TResolve extends Record<string, unknown> = Record<string, never>>(auth: AuthLike, config: AuthCtxConfig<TResolve> & {
|
|
374
|
-
optional: true;
|
|
375
|
-
}): {
|
|
376
|
-
args: {};
|
|
377
|
-
input: (ctx: any, _args: any, _extra?: any) => Promise<{
|
|
378
|
-
ctx: {
|
|
379
|
-
auth: OptionalAuthCtxState & TResolve;
|
|
380
|
-
};
|
|
381
|
-
args: {};
|
|
382
|
-
}>;
|
|
383
|
-
};
|
|
384
|
-
/**
|
|
385
|
-
* Create a context enrichment for `customQuery` / `customMutation` — required auth (default).
|
|
386
|
-
*
|
|
387
|
-
* When `optional` is omitted or `false`, unauthenticated requests throw a
|
|
388
|
-
* structured `ConvexError` before your handler runs.
|
|
389
|
-
*
|
|
390
|
-
* @param auth - The auth API object returned by {@link createAuth}.
|
|
391
|
-
* @param config - Optional configuration with a `resolve` callback
|
|
392
|
-
* for attaching extra fields to the auth context.
|
|
393
|
-
* @returns An object with `args` and `input` compatible with Convex
|
|
394
|
-
* custom function builders.
|
|
395
|
-
*
|
|
396
|
-
* @example
|
|
397
|
-
* ```ts
|
|
398
|
-
* const authCtx = AuthCtx(auth, {
|
|
399
|
-
* resolve: async (_ctx, user) => ({ email: user.email }),
|
|
400
|
-
* });
|
|
401
|
-
* ```
|
|
402
|
-
*
|
|
403
|
-
* @see {@link createAuth}
|
|
404
|
-
*/
|
|
405
|
-
declare function AuthCtx<TResolve extends Record<string, unknown> = Record<string, never>>(auth: AuthLike, config?: AuthCtxConfig<TResolve>): {
|
|
406
|
-
args: {};
|
|
407
|
-
input: (ctx: any, _args: any, _extra?: any) => Promise<{
|
|
408
|
-
ctx: {
|
|
409
|
-
auth: RequiredAuthCtxState & TResolve;
|
|
410
|
-
};
|
|
411
|
-
args: {};
|
|
412
|
-
}>;
|
|
413
|
-
};
|
|
414
|
-
/**
|
|
415
|
-
* Extract the resolved `auth` context type from an {@link AuthCtx} instance.
|
|
415
|
+
* Extract the resolved `auth` context type from an `auth.ctx()` customization.
|
|
416
416
|
*
|
|
417
417
|
* Use this to type function parameters or variables that receive the
|
|
418
|
-
* enriched auth context produced by `
|
|
418
|
+
* enriched auth context produced by `auth.ctx()`. The inferred type includes
|
|
419
419
|
* `userId`, `user`, `groupId`, `role`, `grants`, `getUserIdentity`, and any
|
|
420
420
|
* additional fields added by the `resolve` callback. This is the generic
|
|
421
421
|
* utility for reusing the enriched auth shape without manually duplicating
|
|
422
422
|
* conditional auth types.
|
|
423
423
|
*
|
|
424
|
-
* @typeParam T - An `
|
|
424
|
+
* @typeParam T - An `auth.ctx()` return value (must have an `input` method
|
|
425
425
|
* that returns `{ ctx: { auth: ... } }`).
|
|
426
426
|
*
|
|
427
427
|
* @example
|
|
428
428
|
* ```ts
|
|
429
|
-
* const authCtx =
|
|
429
|
+
* const authCtx = auth.ctx({
|
|
430
430
|
* resolve: async (ctx, user) => ({ orgId: user.orgId }),
|
|
431
431
|
* });
|
|
432
432
|
* type Auth = InferAuth<typeof authCtx>;
|
|
@@ -443,5 +443,5 @@ type InferAuth<T extends {
|
|
|
443
443
|
}>;
|
|
444
444
|
}> = Awaited<ReturnType<T["input"]>>["ctx"]["auth"];
|
|
445
445
|
//#endregion
|
|
446
|
-
export { AuthApi, AuthConfig, AuthContext,
|
|
446
|
+
export { AuthApi, AuthConfig, AuthContext, AuthContextConfig, InferAuth, OptionalAuthContext, UserDoc, createAuth };
|
|
447
447
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/server/auth.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/server/auth.ts"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createUnauthenticatedAuthContext, getAuthContext } from "./context.js";
|
|
1
2
|
import { Auth } from "./runtime.js";
|
|
2
3
|
import { Cv } from "@robelest/fx/convex";
|
|
3
4
|
|
|
@@ -31,41 +32,29 @@ import { Cv } from "@robelest/fx/convex";
|
|
|
31
32
|
* });
|
|
32
33
|
* ```
|
|
33
34
|
*
|
|
34
|
-
* @see {@link
|
|
35
|
+
* @see {@link AuthContextConfig}
|
|
35
36
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
let grants = [];
|
|
53
|
-
if (groupId) {
|
|
54
|
-
const resolved = await auth.member.inspect(ctx, {
|
|
55
|
-
userId,
|
|
56
|
-
groupId
|
|
57
|
-
});
|
|
58
|
-
if (resolved.membership) {
|
|
59
|
-
role = resolved.roleIds[0] ?? null;
|
|
60
|
-
grants = resolved.grants;
|
|
61
|
-
}
|
|
37
|
+
async function resolveConfiguredAuthContext(auth, ctx, config) {
|
|
38
|
+
const fallback = () => getAuthContext(auth, ctx);
|
|
39
|
+
const authOverride = config?.authResolve ? await config.authResolve(ctx, fallback) : void 0;
|
|
40
|
+
return authOverride === void 0 ? await fallback() : authOverride;
|
|
41
|
+
}
|
|
42
|
+
function createNotSignedInError() {
|
|
43
|
+
return Cv.error({
|
|
44
|
+
code: "NOT_SIGNED_IN",
|
|
45
|
+
message: "Authentication required."
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function createPublicAuthContext(auth, ctx, config) {
|
|
49
|
+
const resolved = await resolveConfiguredAuthContext(auth, ctx, config);
|
|
50
|
+
if (resolved === null) {
|
|
51
|
+
if (config?.optional !== true) throw createNotSignedInError();
|
|
52
|
+
return createUnauthenticatedAuthContext();
|
|
62
53
|
}
|
|
54
|
+
const extra = config?.resolve ? await config.resolve(ctx, resolved.user, resolved) : {};
|
|
63
55
|
return {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
groupId,
|
|
67
|
-
role,
|
|
68
|
-
grants
|
|
56
|
+
...resolved,
|
|
57
|
+
...extra
|
|
69
58
|
};
|
|
70
59
|
}
|
|
71
60
|
function createAuth(component, config) {
|
|
@@ -184,52 +173,65 @@ function createAuth(component, config) {
|
|
|
184
173
|
validate: scimApi.validate
|
|
185
174
|
} },
|
|
186
175
|
http: authResult.auth.http,
|
|
187
|
-
context:
|
|
188
|
-
|
|
189
|
-
if (authContext === null) throw Cv.error({
|
|
190
|
-
code: "NOT_SIGNED_IN",
|
|
191
|
-
message: "Authentication required."
|
|
192
|
-
});
|
|
193
|
-
return authContext;
|
|
194
|
-
},
|
|
195
|
-
ctx: () => ({
|
|
196
|
-
args: {},
|
|
197
|
-
input: async (ctx) => {
|
|
198
|
-
const authCtx = await getAuthContext(authResult.auth, ctx);
|
|
199
|
-
if (authCtx === null) throw Cv.error({
|
|
200
|
-
code: "NOT_SIGNED_IN",
|
|
201
|
-
message: "Authentication required."
|
|
202
|
-
});
|
|
203
|
-
return {
|
|
204
|
-
ctx: { auth: authCtx },
|
|
205
|
-
args: {}
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
})
|
|
176
|
+
context: ((ctx, config$1) => createPublicAuthContext(authResult.auth, ctx, config$1)),
|
|
177
|
+
ctx: ((config$1) => createAuthContextCustomization(authResult.auth, config$1))
|
|
209
178
|
};
|
|
210
179
|
}
|
|
211
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Create a context enrichment for `customQuery` / `customMutation` — optional auth.
|
|
182
|
+
*
|
|
183
|
+
* When `optional: true` is set, unauthenticated requests are allowed.
|
|
184
|
+
* The enriched `ctx.auth` will have `userId: null`, `user: null`,
|
|
185
|
+
* `groupId: null`, `role: null`, and `grants: []` for unauthenticated callers.
|
|
186
|
+
*
|
|
187
|
+
* @param config - Configuration with `optional: true` and an optional
|
|
188
|
+
* `resolve` callback for attaching extra fields to the auth context.
|
|
189
|
+
* @returns An object with `args` and `input` compatible with Convex
|
|
190
|
+
* custom function builders.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* const authCtx = auth.ctx({
|
|
195
|
+
* optional: true,
|
|
196
|
+
* resolve: async (_ctx, user) => ({ plan: user.extend?.plan ?? null }),
|
|
197
|
+
* });
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* @see {@link createAuth}
|
|
201
|
+
*/
|
|
202
|
+
/**
|
|
203
|
+
* Create a context enrichment for `customQuery` / `customMutation` — required auth (default).
|
|
204
|
+
*
|
|
205
|
+
* When `optional` is omitted or `false`, unauthenticated requests throw a
|
|
206
|
+
* structured `ConvexError` before your handler runs.
|
|
207
|
+
*
|
|
208
|
+
* @param config - Optional configuration with a `resolve` callback
|
|
209
|
+
* for attaching extra fields to the auth context.
|
|
210
|
+
* @returns An object with `args` and `input` compatible with Convex
|
|
211
|
+
* custom function builders.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```ts
|
|
215
|
+
* const authCtx = auth.ctx({
|
|
216
|
+
* resolve: async (_ctx, user) => ({ email: user.email }),
|
|
217
|
+
* });
|
|
218
|
+
* ```
|
|
219
|
+
*
|
|
220
|
+
* @see {@link createAuth}
|
|
221
|
+
*/
|
|
222
|
+
function createAuthContextCustomization(auth, config) {
|
|
212
223
|
return {
|
|
213
224
|
args: {},
|
|
214
225
|
input: async (ctx, _args, _extra) => {
|
|
215
226
|
const nativeAuth = ctx.auth;
|
|
216
227
|
const getUserIdentity = nativeAuth.getUserIdentity.bind(nativeAuth);
|
|
217
|
-
const
|
|
218
|
-
const authOverride = config?.authResolve ? await config.authResolve(ctx, fallback) : void 0;
|
|
219
|
-
const resolved = authOverride === void 0 ? await fallback() : authOverride;
|
|
228
|
+
const resolved = await resolveConfiguredAuthContext(auth, ctx, config);
|
|
220
229
|
if (resolved === null) {
|
|
221
|
-
if (config?.optional !== true) throw
|
|
222
|
-
code: "NOT_SIGNED_IN",
|
|
223
|
-
message: "Authentication required."
|
|
224
|
-
});
|
|
230
|
+
if (config?.optional !== true) throw createNotSignedInError();
|
|
225
231
|
return {
|
|
226
232
|
ctx: { auth: {
|
|
227
233
|
getUserIdentity,
|
|
228
|
-
|
|
229
|
-
user: null,
|
|
230
|
-
groupId: null,
|
|
231
|
-
role: null,
|
|
232
|
-
grants: []
|
|
234
|
+
...createUnauthenticatedAuthContext()
|
|
233
235
|
} },
|
|
234
236
|
args: {}
|
|
235
237
|
};
|
|
@@ -248,5 +250,5 @@ function AuthCtx(auth, config) {
|
|
|
248
250
|
}
|
|
249
251
|
|
|
250
252
|
//#endregion
|
|
251
|
-
export {
|
|
253
|
+
export { createAuth };
|
|
252
254
|
//# sourceMappingURL=auth.js.map
|