@robelest/convex-auth 0.0.2-preview.1 → 0.0.2
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/dist/bin.cjs +466 -63
- package/dist/client/index.d.ts +211 -30
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +673 -59
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +56 -1
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +93 -3
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/convex.config.d.ts.map +1 -1
- package/dist/component/convex.config.js +2 -0
- package/dist/component/convex.config.js.map +1 -1
- package/dist/component/index.d.ts +5 -3
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/index.js +5 -3
- package/dist/component/index.js.map +1 -1
- package/dist/component/portalBridge.d.ts +80 -0
- package/dist/component/portalBridge.d.ts.map +1 -0
- package/dist/component/portalBridge.js +102 -0
- package/dist/component/portalBridge.js.map +1 -0
- package/dist/component/public.d.ts +193 -9
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +204 -33
- package/dist/component/public.js.map +1 -1
- package/dist/component/schema.d.ts +89 -9
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +68 -7
- package/dist/component/schema.js.map +1 -1
- package/dist/providers/{Anonymous.d.ts → anonymous.d.ts} +8 -8
- package/dist/providers/{Anonymous.d.ts.map → anonymous.d.ts.map} +1 -1
- package/dist/providers/{Anonymous.js → anonymous.js} +9 -10
- package/dist/providers/anonymous.js.map +1 -0
- package/dist/providers/{ConvexCredentials.d.ts → credentials.d.ts} +11 -11
- package/dist/providers/credentials.d.ts.map +1 -0
- package/dist/providers/{ConvexCredentials.js → credentials.js} +8 -8
- package/dist/providers/credentials.js.map +1 -0
- package/dist/providers/{Email.d.ts → email.d.ts} +6 -6
- package/dist/providers/email.d.ts.map +1 -0
- package/dist/providers/{Email.js → email.js} +6 -6
- package/dist/providers/email.js.map +1 -0
- package/dist/providers/passkey.d.ts +20 -0
- package/dist/providers/passkey.d.ts.map +1 -0
- package/dist/providers/passkey.js +32 -0
- package/dist/providers/passkey.js.map +1 -0
- package/dist/providers/{Password.d.ts → password.d.ts} +10 -10
- package/dist/providers/{Password.d.ts.map → password.d.ts.map} +1 -1
- package/dist/providers/{Password.js → password.js} +19 -20
- package/dist/providers/password.js.map +1 -0
- package/dist/providers/{Phone.d.ts → phone.d.ts} +3 -3
- package/dist/providers/{Phone.d.ts.map → phone.d.ts.map} +1 -1
- package/dist/providers/{Phone.js → phone.js} +3 -3
- package/dist/providers/{Phone.js.map → phone.js.map} +1 -1
- package/dist/providers/totp.d.ts +14 -0
- package/dist/providers/totp.d.ts.map +1 -0
- package/dist/providers/totp.js +23 -0
- package/dist/providers/totp.js.map +1 -0
- package/dist/server/convex-auth.d.ts +243 -0
- package/dist/server/convex-auth.d.ts.map +1 -0
- package/dist/server/convex-auth.js +365 -0
- package/dist/server/convex-auth.js.map +1 -0
- package/dist/server/implementation/index.d.ts +153 -166
- package/dist/server/implementation/index.d.ts.map +1 -1
- package/dist/server/implementation/index.js +162 -105
- package/dist/server/implementation/index.js.map +1 -1
- package/dist/server/implementation/passkey.d.ts +33 -0
- package/dist/server/implementation/passkey.d.ts.map +1 -0
- package/dist/server/implementation/passkey.js +450 -0
- package/dist/server/implementation/passkey.js.map +1 -0
- package/dist/server/implementation/redirects.d.ts.map +1 -1
- package/dist/server/implementation/redirects.js +4 -9
- package/dist/server/implementation/redirects.js.map +1 -1
- package/dist/server/implementation/sessions.d.ts +2 -20
- package/dist/server/implementation/sessions.d.ts.map +1 -1
- package/dist/server/implementation/sessions.js +2 -20
- package/dist/server/implementation/sessions.js.map +1 -1
- package/dist/server/implementation/signIn.d.ts +13 -0
- package/dist/server/implementation/signIn.d.ts.map +1 -1
- package/dist/server/implementation/signIn.js +26 -1
- package/dist/server/implementation/signIn.js.map +1 -1
- package/dist/server/implementation/totp.d.ts +40 -0
- package/dist/server/implementation/totp.d.ts.map +1 -0
- package/dist/server/implementation/totp.js +211 -0
- package/dist/server/implementation/totp.js.map +1 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +255 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/portal-email.d.ts +19 -0
- package/dist/server/portal-email.d.ts.map +1 -0
- package/dist/server/portal-email.js +89 -0
- package/dist/server/portal-email.js.map +1 -0
- package/dist/server/portal.d.ts +116 -0
- package/dist/server/portal.d.ts.map +1 -0
- package/dist/server/portal.js +294 -0
- package/dist/server/portal.js.map +1 -0
- package/dist/server/provider_utils.d.ts +1 -1
- package/dist/server/provider_utils.d.ts.map +1 -1
- package/dist/server/provider_utils.js +39 -1
- package/dist/server/provider_utils.js.map +1 -1
- package/dist/server/types.d.ts +128 -11
- package/dist/server/types.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/cli/index.ts +48 -6
- package/src/cli/portal-link.ts +112 -0
- package/src/cli/portal-upload.ts +411 -0
- package/src/client/index.ts +823 -109
- package/src/component/_generated/api.ts +72 -1
- package/src/component/_generated/component.ts +180 -4
- package/src/component/convex.config.ts +3 -0
- package/src/component/index.ts +5 -10
- package/src/component/portalBridge.ts +116 -0
- package/src/component/public.ts +231 -37
- package/src/component/schema.ts +70 -7
- package/src/providers/{Anonymous.ts → anonymous.ts} +10 -11
- package/src/providers/{ConvexCredentials.ts → credentials.ts} +11 -11
- package/src/providers/{Email.ts → email.ts} +5 -5
- package/src/providers/passkey.ts +35 -0
- package/src/providers/{Password.ts → password.ts} +22 -27
- package/src/providers/{Phone.ts → phone.ts} +2 -2
- package/src/providers/totp.ts +26 -0
- package/src/server/convex-auth.ts +470 -0
- package/src/server/implementation/index.ts +228 -239
- package/src/server/implementation/passkey.ts +650 -0
- package/src/server/implementation/redirects.ts +4 -11
- package/src/server/implementation/sessions.ts +2 -20
- package/src/server/implementation/signIn.ts +39 -1
- package/src/server/implementation/totp.ts +366 -0
- package/src/server/index.ts +373 -0
- package/src/server/portal-email.ts +95 -0
- package/src/server/portal.ts +375 -0
- package/src/server/provider_utils.ts +42 -1
- package/src/server/types.ts +161 -10
- package/dist/providers/Anonymous.js.map +0 -1
- package/dist/providers/ConvexCredentials.d.ts.map +0 -1
- package/dist/providers/ConvexCredentials.js.map +0 -1
- package/dist/providers/Email.d.ts.map +0 -1
- package/dist/providers/Email.js.map +0 -1
- package/dist/providers/Password.js.map +0 -1
- package/providers/Anonymous/package.json +0 -6
- package/providers/ConvexCredentials/package.json +0 -6
- package/providers/Email/package.json +0 -6
- package/providers/Password/package.json +0 -6
- package/providers/Phone/package.json +0 -6
- package/server/package.json +0 -6
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import {
|
|
2
|
+
queryGeneric,
|
|
3
|
+
mutationGeneric,
|
|
4
|
+
internalMutationGeneric,
|
|
5
|
+
} from "convex/server";
|
|
6
|
+
import type { HttpRouter } from "convex/server";
|
|
7
|
+
import { v } from "convex/values";
|
|
8
|
+
import type { ComponentApi as AuthComponentApi } from "../component/_generated/component.js";
|
|
9
|
+
import { registerStaticRoutes } from "@convex-dev/self-hosting";
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Helpers
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if the authenticated user is a portal admin.
|
|
17
|
+
* Portal admins are identified by having an accepted invite
|
|
18
|
+
* with `role: "portalAdmin"`.
|
|
19
|
+
*/
|
|
20
|
+
async function requirePortalAdmin(
|
|
21
|
+
ctx: any,
|
|
22
|
+
authComponent: AuthComponentApi,
|
|
23
|
+
userId: string,
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
const invites = await ctx.runQuery(authComponent.public.inviteList, {
|
|
26
|
+
status: "accepted",
|
|
27
|
+
});
|
|
28
|
+
const isAdmin = invites.some(
|
|
29
|
+
(invite: any) =>
|
|
30
|
+
invite.role === "portalAdmin" && invite.acceptedByUserId === userId,
|
|
31
|
+
);
|
|
32
|
+
if (!isAdmin) {
|
|
33
|
+
throw new Error("Not authorized: portal admin access required");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Portal() factory
|
|
39
|
+
// ============================================================================
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Configure the Convex Auth Portal. Returns all the functions needed to
|
|
43
|
+
* serve the portal admin UI, manage invite links, and query auth data.
|
|
44
|
+
*
|
|
45
|
+
* The portal dogfoods the same `Auth()` instance as your app. Portal admins
|
|
46
|
+
* sign in via email magic link and are identified by accepted invites with
|
|
47
|
+
* `role: "portalAdmin"`.
|
|
48
|
+
*
|
|
49
|
+
* ```ts filename="convex/portal.ts"
|
|
50
|
+
* import { Portal } from "@robelest/convex-auth/component";
|
|
51
|
+
* import { auth } from "./auth";
|
|
52
|
+
* import { components } from "./_generated/api";
|
|
53
|
+
*
|
|
54
|
+
* export const {
|
|
55
|
+
* hosting, getCurrentDeployment,
|
|
56
|
+
* portalQuery, portalMutation,
|
|
57
|
+
* validateInvite, acceptInvite, createPortalInvite,
|
|
58
|
+
* portal,
|
|
59
|
+
* } = Portal(components.auth, components.selfHosting, auth);
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* ## Setup
|
|
63
|
+
*
|
|
64
|
+
* 1. Configure an email provider in your `Auth()` config (e.g. Resend).
|
|
65
|
+
* 2. Generate an admin invite link:
|
|
66
|
+
* `npx @robelest/convex-auth portal link [--prod]`
|
|
67
|
+
* 3. Visit the link, enter your email, click the magic link, and you're in.
|
|
68
|
+
*
|
|
69
|
+
* The portal URL is auto-derived from `CONVEX_SITE_URL` (always set by Convex).
|
|
70
|
+
* Override with `options.portalUrl` if you need a custom URL.
|
|
71
|
+
*/
|
|
72
|
+
export function Portal(
|
|
73
|
+
authComponent: AuthComponentApi,
|
|
74
|
+
selfHostingComponent: any,
|
|
75
|
+
auth: any,
|
|
76
|
+
options?: { portalUrl?: string },
|
|
77
|
+
) {
|
|
78
|
+
const portalUrl =
|
|
79
|
+
options?.portalUrl ??
|
|
80
|
+
(process.env.CONVEX_SITE_URL
|
|
81
|
+
? `${process.env.CONVEX_SITE_URL.replace(/\/$/, "")}/portal`
|
|
82
|
+
: "/portal");
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
// ---- Self-hosting: combined internal mutation for CLI ----
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Combined internal mutation for self-hosting operations.
|
|
89
|
+
* Used by the CLI (`@robelest/convex-auth portal upload`) to
|
|
90
|
+
* upload static assets and manage deployments.
|
|
91
|
+
*/
|
|
92
|
+
hosting: internalMutationGeneric({
|
|
93
|
+
args: {
|
|
94
|
+
action: v.string(),
|
|
95
|
+
path: v.optional(v.string()),
|
|
96
|
+
storageId: v.optional(v.string()),
|
|
97
|
+
blobId: v.optional(v.string()),
|
|
98
|
+
contentType: v.optional(v.string()),
|
|
99
|
+
deploymentId: v.optional(v.string()),
|
|
100
|
+
currentDeploymentId: v.optional(v.string()),
|
|
101
|
+
limit: v.optional(v.number()),
|
|
102
|
+
},
|
|
103
|
+
handler: async (ctx: any, args: any) => {
|
|
104
|
+
switch (args.action) {
|
|
105
|
+
case "generateUploadUrl": {
|
|
106
|
+
return await ctx.storage.generateUploadUrl();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
case "recordAsset": {
|
|
110
|
+
const { oldStorageId, oldBlobId } = await ctx.runMutation(
|
|
111
|
+
selfHostingComponent.lib.recordAsset,
|
|
112
|
+
{
|
|
113
|
+
path: args.path,
|
|
114
|
+
...(args.storageId ? { storageId: args.storageId } : {}),
|
|
115
|
+
...(args.blobId ? { blobId: args.blobId } : {}),
|
|
116
|
+
contentType: args.contentType,
|
|
117
|
+
deploymentId: args.deploymentId,
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
if (oldStorageId) {
|
|
121
|
+
try {
|
|
122
|
+
await ctx.storage.delete(oldStorageId);
|
|
123
|
+
} catch {
|
|
124
|
+
// Ignore — old file may have been in different storage
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return oldBlobId ?? null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
case "gcOldAssets": {
|
|
131
|
+
const { storageIds, blobIds } = await ctx.runMutation(
|
|
132
|
+
selfHostingComponent.lib.gcOldAssets,
|
|
133
|
+
{ currentDeploymentId: args.currentDeploymentId },
|
|
134
|
+
);
|
|
135
|
+
for (const storageId of storageIds) {
|
|
136
|
+
try {
|
|
137
|
+
await ctx.storage.delete(storageId);
|
|
138
|
+
} catch {
|
|
139
|
+
// Ignore
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
await ctx.runMutation(
|
|
143
|
+
selfHostingComponent.lib.setCurrentDeployment,
|
|
144
|
+
{ deploymentId: args.currentDeploymentId },
|
|
145
|
+
);
|
|
146
|
+
return { deleted: storageIds.length, blobIds };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
case "listAssets": {
|
|
150
|
+
return await ctx.runQuery(selfHostingComponent.lib.listAssets, {
|
|
151
|
+
limit: args.limit,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
default:
|
|
156
|
+
throw new Error(`Unknown hosting action: ${args.action}`);
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
}),
|
|
160
|
+
|
|
161
|
+
// ---- Deployment query (public, for client live-reload) ----
|
|
162
|
+
|
|
163
|
+
getCurrentDeployment: queryGeneric({
|
|
164
|
+
args: {},
|
|
165
|
+
handler: async (ctx: any) => {
|
|
166
|
+
return await ctx.runQuery(
|
|
167
|
+
selfHostingComponent.lib.getCurrentDeployment,
|
|
168
|
+
{},
|
|
169
|
+
);
|
|
170
|
+
},
|
|
171
|
+
}),
|
|
172
|
+
|
|
173
|
+
// ---- Invite management ----
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Validate an invite token. Returns the invite if valid and pending,
|
|
177
|
+
* or `null` otherwise. Used by the portal UI to check if an invite
|
|
178
|
+
* link is valid before showing the registration form.
|
|
179
|
+
*/
|
|
180
|
+
validateInvite: queryGeneric({
|
|
181
|
+
args: { tokenHash: v.string() },
|
|
182
|
+
handler: async (ctx: any, { tokenHash }: { tokenHash: string }) => {
|
|
183
|
+
const invite = await ctx.runQuery(
|
|
184
|
+
authComponent.public.inviteGetByTokenHash,
|
|
185
|
+
{ tokenHash },
|
|
186
|
+
);
|
|
187
|
+
if (!invite || invite.status !== "pending") {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
if (invite.expiresTime && invite.expiresTime < Date.now()) {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
return { _id: invite._id, role: invite.role };
|
|
194
|
+
},
|
|
195
|
+
}),
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Accept a portal invite. Must be called by an authenticated user.
|
|
199
|
+
* Marks the invite as accepted and records the accepting user's ID.
|
|
200
|
+
*
|
|
201
|
+
* The portal UI calls this after the user has signed in via magic link
|
|
202
|
+
* following an invite link.
|
|
203
|
+
*/
|
|
204
|
+
acceptInvite: mutationGeneric({
|
|
205
|
+
args: { tokenHash: v.string() },
|
|
206
|
+
handler: async (ctx: any, { tokenHash }: { tokenHash: string }) => {
|
|
207
|
+
const userId = await auth.user.require(ctx);
|
|
208
|
+
|
|
209
|
+
const invite = await ctx.runQuery(
|
|
210
|
+
authComponent.public.inviteGetByTokenHash,
|
|
211
|
+
{ tokenHash },
|
|
212
|
+
);
|
|
213
|
+
if (!invite) {
|
|
214
|
+
throw new Error("Invalid invite token");
|
|
215
|
+
}
|
|
216
|
+
if (invite.status !== "pending") {
|
|
217
|
+
throw new Error(`Invite already ${invite.status}`);
|
|
218
|
+
}
|
|
219
|
+
if (invite.expiresTime && invite.expiresTime < Date.now()) {
|
|
220
|
+
throw new Error("Invite has expired");
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
await ctx.runMutation(authComponent.public.inviteAccept, {
|
|
224
|
+
inviteId: invite._id,
|
|
225
|
+
acceptedByUserId: userId,
|
|
226
|
+
});
|
|
227
|
+
},
|
|
228
|
+
}),
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Create a portal admin invite. Internal mutation called by the CLI
|
|
232
|
+
* (`npx @robelest/convex-auth portal link`).
|
|
233
|
+
*/
|
|
234
|
+
createPortalInvite: internalMutationGeneric({
|
|
235
|
+
args: { tokenHash: v.string() },
|
|
236
|
+
handler: async (ctx: any, { tokenHash }: { tokenHash: string }) => {
|
|
237
|
+
await ctx.runMutation(authComponent.public.inviteCreate, {
|
|
238
|
+
tokenHash,
|
|
239
|
+
role: "portalAdmin",
|
|
240
|
+
status: "pending" as const,
|
|
241
|
+
});
|
|
242
|
+
return { portalUrl };
|
|
243
|
+
},
|
|
244
|
+
}),
|
|
245
|
+
|
|
246
|
+
// ---- Portal data query (auth-gated) ----
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Combined portal query for all auth data reads.
|
|
250
|
+
* Requires the caller to be an authenticated portal admin.
|
|
251
|
+
*
|
|
252
|
+
* Actions:
|
|
253
|
+
* - `listUsers` — List all users
|
|
254
|
+
* - `listSessions` — List all sessions
|
|
255
|
+
* - `getUser` — Get a single user by ID (requires `userId`)
|
|
256
|
+
* - `getUserSessions` — List sessions for a user (requires `userId`)
|
|
257
|
+
* - `getUserAccounts` — List auth accounts for a user (requires `userId`)
|
|
258
|
+
* - `isAdmin` — Check if the current user is a portal admin
|
|
259
|
+
*/
|
|
260
|
+
portalQuery: queryGeneric({
|
|
261
|
+
args: {
|
|
262
|
+
action: v.string(),
|
|
263
|
+
userId: v.optional(v.string()),
|
|
264
|
+
},
|
|
265
|
+
handler: async (
|
|
266
|
+
ctx: any,
|
|
267
|
+
{ action, userId }: { action: string; userId?: string },
|
|
268
|
+
) => {
|
|
269
|
+
const currentUserId = await auth.user.require(ctx);
|
|
270
|
+
|
|
271
|
+
// Allow isAdmin check without admin requirement
|
|
272
|
+
if (action === "isAdmin") {
|
|
273
|
+
try {
|
|
274
|
+
await requirePortalAdmin(ctx, authComponent, currentUserId);
|
|
275
|
+
return true;
|
|
276
|
+
} catch {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
await requirePortalAdmin(ctx, authComponent, currentUserId);
|
|
282
|
+
|
|
283
|
+
switch (action) {
|
|
284
|
+
case "listUsers":
|
|
285
|
+
return await ctx.runQuery(authComponent.public.userList);
|
|
286
|
+
|
|
287
|
+
case "listSessions":
|
|
288
|
+
return await ctx.runQuery(authComponent.public.sessionList);
|
|
289
|
+
|
|
290
|
+
case "getUser":
|
|
291
|
+
return await ctx.runQuery(authComponent.public.userGetById, {
|
|
292
|
+
userId: userId!,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
case "getUserSessions":
|
|
296
|
+
return await ctx.runQuery(authComponent.public.sessionListByUser, {
|
|
297
|
+
userId: userId!,
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
case "getUserAccounts": {
|
|
301
|
+
const accounts = await ctx.runQuery(
|
|
302
|
+
authComponent.public.accountListByUser,
|
|
303
|
+
{ userId: userId! },
|
|
304
|
+
);
|
|
305
|
+
// Strip secrets — never send password hashes to the frontend
|
|
306
|
+
return accounts.map(({ secret: _, ...rest }: any) => rest);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
default:
|
|
310
|
+
throw new Error(`Unknown portal query action: ${action}`);
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
}),
|
|
314
|
+
|
|
315
|
+
// ---- Portal mutation (auth-gated) ----
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Combined portal mutation for all auth data writes.
|
|
319
|
+
* Requires the caller to be an authenticated portal admin.
|
|
320
|
+
*
|
|
321
|
+
* Actions:
|
|
322
|
+
* - `revokeSession` — Revoke (delete) a session (requires `sessionId`)
|
|
323
|
+
*/
|
|
324
|
+
portalMutation: mutationGeneric({
|
|
325
|
+
args: {
|
|
326
|
+
action: v.string(),
|
|
327
|
+
sessionId: v.optional(v.string()),
|
|
328
|
+
},
|
|
329
|
+
handler: async (
|
|
330
|
+
ctx: any,
|
|
331
|
+
{ action, sessionId }: { action: string; sessionId?: string },
|
|
332
|
+
) => {
|
|
333
|
+
const currentUserId = await auth.user.require(ctx);
|
|
334
|
+
await requirePortalAdmin(ctx, authComponent, currentUserId);
|
|
335
|
+
|
|
336
|
+
switch (action) {
|
|
337
|
+
case "revokeSession":
|
|
338
|
+
await ctx.runMutation(authComponent.public.sessionDelete, {
|
|
339
|
+
sessionId: sessionId!,
|
|
340
|
+
});
|
|
341
|
+
return;
|
|
342
|
+
|
|
343
|
+
default:
|
|
344
|
+
throw new Error(`Unknown portal mutation action: ${action}`);
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
}),
|
|
348
|
+
|
|
349
|
+
// ---- Portal namespace ----
|
|
350
|
+
|
|
351
|
+
portal: {
|
|
352
|
+
/**
|
|
353
|
+
* The URL where the portal is served. Used by the Svelte client
|
|
354
|
+
* as the `redirectTo` for magic link sign-in.
|
|
355
|
+
*/
|
|
356
|
+
portalUrl,
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Register HTTP routes that serve the portal static UI.
|
|
360
|
+
*/
|
|
361
|
+
addHttpRoutes: (
|
|
362
|
+
http: HttpRouter,
|
|
363
|
+
opts?: { pathPrefix?: string; spaFallback?: boolean },
|
|
364
|
+
) => {
|
|
365
|
+
const prefix = opts?.pathPrefix ?? "/portal";
|
|
366
|
+
|
|
367
|
+
// Static file serving
|
|
368
|
+
registerStaticRoutes(http, selfHostingComponent, {
|
|
369
|
+
pathPrefix: prefix,
|
|
370
|
+
spaFallback: opts?.spaFallback ?? true,
|
|
371
|
+
});
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
};
|
|
375
|
+
}
|
|
@@ -79,8 +79,41 @@ function materializeAndDefaultProviders(config_: ConvexAuthConfig) {
|
|
|
79
79
|
);
|
|
80
80
|
const config = { ...config_, providers };
|
|
81
81
|
|
|
82
|
+
// setEnvDefaults is from Auth.js and only works with Auth.js provider types.
|
|
83
|
+
// Filter out passkey and TOTP providers before passing to setEnvDefaults,
|
|
84
|
+
// then reinsert them at their original positions.
|
|
85
|
+
const passkeyIndices: number[] = [];
|
|
86
|
+
const passkeyProviders: AuthProviderMaterializedConfig[] = [];
|
|
87
|
+
const totpIndices: number[] = [];
|
|
88
|
+
const totpProviders: AuthProviderMaterializedConfig[] = [];
|
|
89
|
+
const filteredProviders = config.providers.filter((p, i) => {
|
|
90
|
+
if (p.type === "passkey") {
|
|
91
|
+
passkeyIndices.push(i);
|
|
92
|
+
passkeyProviders.push(p);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (p.type === "totp") {
|
|
96
|
+
totpIndices.push(i);
|
|
97
|
+
totpProviders.push(p);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
|
|
82
103
|
// Unfortunately mutates its argument
|
|
83
|
-
|
|
104
|
+
const tempConfig = { ...config, providers: filteredProviders };
|
|
105
|
+
setEnvDefaults(process.env, tempConfig as any);
|
|
106
|
+
|
|
107
|
+
// Reinsert passkey and TOTP providers at their original positions
|
|
108
|
+
const merged = [...tempConfig.providers];
|
|
109
|
+
for (let i = 0; i < passkeyIndices.length; i++) {
|
|
110
|
+
merged.splice(passkeyIndices[i]!, 0, passkeyProviders[i]!);
|
|
111
|
+
}
|
|
112
|
+
for (let i = 0; i < totpIndices.length; i++) {
|
|
113
|
+
merged.splice(totpIndices[i]!, 0, totpProviders[i]!);
|
|
114
|
+
}
|
|
115
|
+
config.providers = merged;
|
|
116
|
+
|
|
84
117
|
// Manually do this for new provider type
|
|
85
118
|
config.providers.forEach((provider) => {
|
|
86
119
|
if (provider.type === "phone") {
|
|
@@ -94,6 +127,14 @@ function materializeAndDefaultProviders(config_: ConvexAuthConfig) {
|
|
|
94
127
|
}
|
|
95
128
|
|
|
96
129
|
function providerDefaults(provider: AuthProviderMaterializedConfig) {
|
|
130
|
+
// Passkey providers don't use Auth.js options merge or OAuth normalization
|
|
131
|
+
if (provider.type === "passkey") {
|
|
132
|
+
return provider;
|
|
133
|
+
}
|
|
134
|
+
// TOTP providers don't use Auth.js options merge or OAuth normalization
|
|
135
|
+
if (provider.type === "totp") {
|
|
136
|
+
return provider;
|
|
137
|
+
}
|
|
97
138
|
// TODO: Add `redirectProxyUrl` to oauth providers
|
|
98
139
|
const merged = merge(
|
|
99
140
|
provider,
|
package/src/server/types.ts
CHANGED
|
@@ -14,11 +14,11 @@ import {
|
|
|
14
14
|
GenericMutationCtx,
|
|
15
15
|
} from "convex/server";
|
|
16
16
|
import { GenericId, Value } from "convex/values";
|
|
17
|
-
import {
|
|
17
|
+
import { CredentialsUserConfig } from "../providers/credentials.js";
|
|
18
18
|
import { GenericDoc } from "./convex_types.js";
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* The config for the Convex Auth library, passed to `
|
|
21
|
+
* The config for the Convex Auth library, passed to `Auth`.
|
|
22
22
|
*/
|
|
23
23
|
export type ConvexAuthConfig = {
|
|
24
24
|
/**
|
|
@@ -89,9 +89,9 @@ export type ConvexAuthConfig = {
|
|
|
89
89
|
*
|
|
90
90
|
* ```ts
|
|
91
91
|
* import GitHub from "@auth/core/providers/github";
|
|
92
|
-
* import {
|
|
92
|
+
* import { Auth } from "@robelest/convex-auth/component";
|
|
93
93
|
*
|
|
94
|
-
* export const { auth, signIn, signOut, store } =
|
|
94
|
+
* export const { auth, signIn, signOut, store } = Auth({
|
|
95
95
|
* providers: [GitHub],
|
|
96
96
|
* callbacks: {
|
|
97
97
|
* async redirect({ redirectTo }) {
|
|
@@ -245,7 +245,11 @@ export type AuthProviderConfig =
|
|
|
245
245
|
| ConvexCredentialsConfig
|
|
246
246
|
| ((...args: any) => ConvexCredentialsConfig)
|
|
247
247
|
| PhoneConfig
|
|
248
|
-
| ((...args: any) => PhoneConfig)
|
|
248
|
+
| ((...args: any) => PhoneConfig)
|
|
249
|
+
| PasskeyProviderConfig
|
|
250
|
+
| ((...args: any) => PasskeyProviderConfig)
|
|
251
|
+
| TotpProviderConfig
|
|
252
|
+
| ((...args: any) => TotpProviderConfig);
|
|
249
253
|
|
|
250
254
|
/**
|
|
251
255
|
* Extends the standard Auth.js email provider config
|
|
@@ -349,22 +353,153 @@ export type PhoneUserConfig<
|
|
|
349
353
|
/**
|
|
350
354
|
* Similar to Auth.js Credentials config.
|
|
351
355
|
*/
|
|
352
|
-
export type ConvexCredentialsConfig =
|
|
356
|
+
export type ConvexCredentialsConfig = CredentialsUserConfig<any> & {
|
|
353
357
|
type: "credentials";
|
|
354
358
|
id: string;
|
|
355
359
|
};
|
|
356
360
|
|
|
361
|
+
/**
|
|
362
|
+
* Configuration for the passkey (WebAuthn) provider.
|
|
363
|
+
*/
|
|
364
|
+
export interface PasskeyProviderConfig {
|
|
365
|
+
id: string;
|
|
366
|
+
type: "passkey";
|
|
367
|
+
options: {
|
|
368
|
+
/** Relying Party display name. Defaults to SITE_URL hostname. */
|
|
369
|
+
rpName?: string;
|
|
370
|
+
/** Relying Party ID (hostname). Defaults to SITE_URL hostname. */
|
|
371
|
+
rpId?: string;
|
|
372
|
+
/** Allowed origins for credential verification. Defaults to SITE_URL. */
|
|
373
|
+
origin?: string | string[];
|
|
374
|
+
/** Attestation conveyance preference. Defaults to "none". */
|
|
375
|
+
attestation?: "none" | "direct";
|
|
376
|
+
/** User verification requirement. Defaults to "required". */
|
|
377
|
+
userVerification?: "required" | "preferred" | "discouraged";
|
|
378
|
+
/** Resident key (discoverable credential) preference. Defaults to "preferred". */
|
|
379
|
+
residentKey?: "required" | "preferred" | "discouraged";
|
|
380
|
+
/** Restrict to platform or cross-platform authenticators. */
|
|
381
|
+
authenticatorAttachment?: "platform" | "cross-platform";
|
|
382
|
+
/** Supported COSE algorithms. Defaults to [-7 (ES256), -257 (RS256)]. */
|
|
383
|
+
algorithms?: number[];
|
|
384
|
+
/** Challenge expiration in ms. Defaults to 300_000 (5 minutes). */
|
|
385
|
+
challengeExpirationMs?: number;
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Configuration for the TOTP two-factor authentication provider.
|
|
391
|
+
*/
|
|
392
|
+
export interface TotpProviderConfig {
|
|
393
|
+
id: string;
|
|
394
|
+
type: "totp";
|
|
395
|
+
options: {
|
|
396
|
+
/** Issuer name shown in authenticator apps (e.g. "My App"). */
|
|
397
|
+
issuer: string;
|
|
398
|
+
/** Number of digits in each code (default: 6). */
|
|
399
|
+
digits: number;
|
|
400
|
+
/** Time period in seconds for code rotation (default: 30). */
|
|
401
|
+
period: number;
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export type AuthAccountCredentials = {
|
|
406
|
+
id: string;
|
|
407
|
+
secret?: string;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
export type AuthCreateAccountArgs = {
|
|
411
|
+
provider: string;
|
|
412
|
+
account: AuthAccountCredentials;
|
|
413
|
+
profile: Record<string, unknown> & {
|
|
414
|
+
email?: string;
|
|
415
|
+
phone?: string;
|
|
416
|
+
emailVerified?: boolean;
|
|
417
|
+
phoneVerified?: boolean;
|
|
418
|
+
};
|
|
419
|
+
shouldLinkViaEmail?: boolean;
|
|
420
|
+
shouldLinkViaPhone?: boolean;
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
export type AuthRetrieveAccountArgs = {
|
|
424
|
+
provider: string;
|
|
425
|
+
account: AuthAccountCredentials;
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
export type AuthUpdateAccountCredentialsArgs = {
|
|
429
|
+
provider: string;
|
|
430
|
+
account: {
|
|
431
|
+
id: string;
|
|
432
|
+
secret: string;
|
|
433
|
+
};
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
export type AuthInvalidateSessionsArgs = {
|
|
437
|
+
userId: GenericId<"user">;
|
|
438
|
+
except?: GenericId<"session">[];
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
export type AuthProviderSignInArgs = {
|
|
442
|
+
accountId?: GenericId<"account">;
|
|
443
|
+
params?: Record<string, Value | undefined>;
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
export type AuthProviderSignInResult = {
|
|
447
|
+
userId: GenericId<"user">;
|
|
448
|
+
sessionId: GenericId<"session">;
|
|
449
|
+
} | null;
|
|
450
|
+
|
|
451
|
+
export type AuthServerHelpers = {
|
|
452
|
+
account: {
|
|
453
|
+
create: (
|
|
454
|
+
ctx: GenericActionCtx<any>,
|
|
455
|
+
args: AuthCreateAccountArgs,
|
|
456
|
+
) => Promise<{
|
|
457
|
+
account: GenericDoc<GenericDataModel, "account">;
|
|
458
|
+
user: GenericDoc<GenericDataModel, "user">;
|
|
459
|
+
}>;
|
|
460
|
+
get: (
|
|
461
|
+
ctx: GenericActionCtx<any>,
|
|
462
|
+
args: AuthRetrieveAccountArgs,
|
|
463
|
+
) => Promise<{
|
|
464
|
+
account: GenericDoc<GenericDataModel, "account">;
|
|
465
|
+
user: GenericDoc<GenericDataModel, "user">;
|
|
466
|
+
}>;
|
|
467
|
+
updateCredentials: (
|
|
468
|
+
ctx: GenericActionCtx<any>,
|
|
469
|
+
args: AuthUpdateAccountCredentialsArgs,
|
|
470
|
+
) => Promise<void>;
|
|
471
|
+
};
|
|
472
|
+
session: {
|
|
473
|
+
current: (
|
|
474
|
+
ctx: { auth: GenericActionCtx<GenericDataModel>["auth"] },
|
|
475
|
+
) => Promise<GenericId<"session"> | null>;
|
|
476
|
+
invalidate: (
|
|
477
|
+
ctx: GenericActionCtx<any>,
|
|
478
|
+
args: AuthInvalidateSessionsArgs,
|
|
479
|
+
) => Promise<void>;
|
|
480
|
+
};
|
|
481
|
+
provider: {
|
|
482
|
+
signIn: (
|
|
483
|
+
ctx: GenericActionCtx<any>,
|
|
484
|
+
provider: AuthProviderConfig,
|
|
485
|
+
args: AuthProviderSignInArgs,
|
|
486
|
+
) => Promise<AuthProviderSignInResult>;
|
|
487
|
+
};
|
|
488
|
+
};
|
|
489
|
+
|
|
357
490
|
/**
|
|
358
491
|
* Your `ActionCtx` enriched with `ctx.auth.config` field with
|
|
359
|
-
* the config passed to `
|
|
492
|
+
* the config passed to `Auth`.
|
|
360
493
|
*/
|
|
361
494
|
export type GenericActionCtxWithAuthConfig<DataModel extends GenericDataModel> =
|
|
362
495
|
GenericActionCtx<DataModel> & {
|
|
363
|
-
auth:
|
|
496
|
+
auth: GenericActionCtx<DataModel>["auth"] & {
|
|
497
|
+
config: ConvexAuthMaterializedConfig;
|
|
498
|
+
} & AuthServerHelpers;
|
|
364
499
|
};
|
|
365
500
|
|
|
366
501
|
/**
|
|
367
|
-
* The config for the Convex Auth library, passed to `
|
|
502
|
+
* The config for the Convex Auth library, passed to `Auth`,
|
|
368
503
|
* with defaults and initialized providers.
|
|
369
504
|
*
|
|
370
505
|
* See {@link ConvexAuthConfig}
|
|
@@ -385,7 +520,9 @@ export type AuthProviderMaterializedConfig =
|
|
|
385
520
|
| OAuth2Config<any>
|
|
386
521
|
| EmailConfig
|
|
387
522
|
| PhoneConfig
|
|
388
|
-
| ConvexCredentialsConfig
|
|
523
|
+
| ConvexCredentialsConfig
|
|
524
|
+
| PasskeyProviderConfig
|
|
525
|
+
| TotpProviderConfig;
|
|
389
526
|
|
|
390
527
|
/**
|
|
391
528
|
* Component function references required by core auth runtime.
|
|
@@ -441,8 +578,22 @@ export type AuthComponentApi = {
|
|
|
441
578
|
memberUpdate: FunctionReference<"mutation", "internal">;
|
|
442
579
|
inviteCreate: FunctionReference<"mutation", "internal">;
|
|
443
580
|
inviteGet: FunctionReference<"query", "internal">;
|
|
581
|
+
inviteGetByTokenHash: FunctionReference<"query", "internal">;
|
|
444
582
|
inviteList: FunctionReference<"query", "internal">;
|
|
445
583
|
inviteAccept: FunctionReference<"mutation", "internal">;
|
|
446
584
|
inviteRevoke: FunctionReference<"mutation", "internal">;
|
|
585
|
+
passkeyInsert: FunctionReference<"mutation", "internal">;
|
|
586
|
+
passkeyGetByCredentialId: FunctionReference<"query", "internal">;
|
|
587
|
+
passkeyListByUserId: FunctionReference<"query", "internal">;
|
|
588
|
+
passkeyUpdateCounter: FunctionReference<"mutation", "internal">;
|
|
589
|
+
passkeyUpdateMeta: FunctionReference<"mutation", "internal">;
|
|
590
|
+
passkeyDelete: FunctionReference<"mutation", "internal">;
|
|
591
|
+
totpInsert: FunctionReference<"mutation", "internal", any, any>;
|
|
592
|
+
totpGetVerifiedByUserId: FunctionReference<"query", "internal", any, any>;
|
|
593
|
+
totpListByUserId: FunctionReference<"query", "internal", any, any>;
|
|
594
|
+
totpGetById: FunctionReference<"query", "internal", any, any>;
|
|
595
|
+
totpMarkVerified: FunctionReference<"mutation", "internal", any, any>;
|
|
596
|
+
totpUpdateLastUsed: FunctionReference<"mutation", "internal", any, any>;
|
|
597
|
+
totpDelete: FunctionReference<"mutation", "internal", any, any>;
|
|
447
598
|
};
|
|
448
599
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Anonymous.js","sourceRoot":"","sources":["../../src/providers/Anonymous.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,iBAAiB,MAAM,mDAAmD,CAAC;AAClF,OAAO,EAEL,aAAa,GACd,MAAM,iCAAiC,CAAC;AAoCzC;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,SAAqC,EAAE;IAEvC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,IAAI,WAAW,CAAC;IAC1C,OAAO,iBAAiB,CAAY;QAClC,EAAE,EAAE,WAAW;QACf,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YACvE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE;gBACxC,QAAQ;gBACR,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE;gBACpC,OAAO,EAAE,OAAc;aACxB,CAAC,CAAC;YACH,MAAM;YACN,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,CAAC;QACD,GAAG,MAAM;KACV,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ConvexCredentials.d.ts","sourceRoot":"","sources":["../../src/providers/ConvexCredentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,8BAA8B,EAC/B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,2BAA2B,CAC1C,SAAS,SAAS,gBAAgB,GAAG,gBAAgB;IAErD;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,SAAS,EAAE;IACT;;;;;;OAMG;IACH,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC,EACvD,GAAG,EAAE,8BAA8B,CAAC,SAAS,CAAC,KAC3C,OAAO,CAAC;QACX,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1B,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAClC,GAAG,IAAI,CAAC,CAAC;IACV;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAChD;;;WAGG;QACH,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KAClE,CAAC;IACF;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,kBAAkB,GAAG,SAAS,CAAC,EAAE,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,SAAS,SAAS,gBAAgB,EAC1E,MAAM,EAAE,2BAA2B,CAAC,SAAS,CAAC,GAC7C,uBAAuB,CAQzB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ConvexCredentials.js","sourceRoot":"","sources":["../../src/providers/ConvexCredentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAuEH;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,MAA8C;IAE9C,OAAO;QACL,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,aAAa;QACnB,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QAC3B,4BAA4B;QAC5B,OAAO,EAAE,MAAM;KAChB,CAAC;AACJ,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Email.d.ts","sourceRoot":"","sources":["../../src/providers/Email.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,KAAK,CAAC,SAAS,SAAS,gBAAgB,EACtD,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,GAChC,IAAI,CAAC,WAAW,EAAE,yBAAyB,CAAC,GAC7C,WAAW,CAAC,SAAS,CAAC,CAuBxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Email.js","sourceRoot":"","sources":["../../src/providers/Email.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,KAAK,CACnB,MAC8C;IAE9C,OAAO;QACL,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,+BAA+B;QACrC,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,SAAS;QAC1B,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;YACnC,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;YACJ,CAAC;YACD,IAAI,OAAO,CAAC,iBAAiB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC/C,MAAM,IAAI,KAAK,CACb,sDAAsD;oBACpD,wBAAwB,CAC3B,CAAC;YACJ,CAAC;QACH,CAAC;QACD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB;QACvD,OAAO,EAAE,MAAM;KAChB,CAAC;AACJ,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Password.js","sourceRoot":"","sources":["../../src/providers/Password.ts"],"names":[],"mappings":"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"}
|