@voltro/plugin-auth 0.81.0 → 0.83.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/dist/index.js CHANGED
@@ -1,479 +1,89 @@
1
1
  import { PasswordEmptyError as e, PasswordHashError as t, hashPassword as n, needsRehash as r, parseScryptParams as i, verifyPassword as a, verifyPasswordWithRehash as o } from "./password.js";
2
- import { SESSION_COOKIE_NAME as s, clearSessionCookie as c, issueSession as l, readSession as u, readSessionKeyed as d, resolveSessionSecret as f, resolveSessionSecrets as p, sessionSecretsOf as m } from "./session.js";
3
- import { a as h, c as g, i as _, l as v, n as y, o as b, r as x, s as S, t as C } from "./strategy-MP_KxNuA.js";
4
- import { $ as w, A as T, B as E, C as D, D as O, E as k, F as A, G as j, H as M, I as N, J as P, K as F, L as I, M as L, N as R, O as z, P as B, Q as V, R as H, S as U, T as W, U as G, V as K, W as q, X as J, Y, Z as X, _ as Z, a as Q, at as ee, b as te, c as ne, ct as re, d as ie, et as ae, f as oe, g as se, h as ce, i as le, it as ue, j as de, k as fe, l as pe, lt as me, m as he, n as ge, nt as _e, o as ve, ot as ye, p as be, q as xe, r as Se, rt as Ce, s as we, st as Te, t as Ee, tt as De, u as Oe, ut as ke, v as Ae, w as je, x as Me, y as Ne, z as Pe } from "./plugin-DFQ8N52Q.js";
5
- import { EMAIL_VERIFY_TTL_S as Fe, MAGIC_LINK_TTL_S as Ie, MFA_PENDING_TTL_S as Le, PASSWORD_RESET_TTL_S as Re, hashToken as ze, mintSecret as Be, mintToken as Ve } from "./tokens.js";
6
- import { CSRF_COOKIE_NAME as He, CSRF_HEADER_NAME as Ue, isCsrfTokenWellFormed as We, issueCsrfToken as Ge, verifyCsrf as Ke } from "./csrf.js";
7
- import { generateChallenge as qe, verifyAssertion as Je, verifyRegistration as Ye } from "./webauthn.js";
8
- import { Effect as $ } from "effect";
9
- //#region src/memberships.ts
10
- var Xe = (e) => async (t) => t.type === "user" ? (await $.runPromise(e.listMemberships(t.id))).map((e) => ({
11
- tenantId: e.tenantId,
12
- role: e.role
13
- })) : [], Ze = (e) => {
14
- let t = e?.code;
15
- if (typeof t == "string") return t;
16
- let n = e?.cause?.code;
17
- return typeof n == "string" ? n : void 0;
18
- }, Qe = (e) => {
19
- let t = e?.columns ?? {};
20
- return {
21
- table: e?.table ?? "users",
22
- col: {
23
- id: t.id ?? "id",
24
- email: t.email ?? "email",
25
- tenantId: t.tenantId ?? "tenantId",
26
- createdAt: t.createdAt ?? "createdAt",
27
- passwordHash: t.passwordHash ?? "passwordHash",
28
- updatedAt: t.updatedAt ?? "updatedAt",
29
- mfaSecret: t.mfaSecret ?? "mfaSecret",
30
- mfaEnrolledAt: t.mfaEnrolledAt ?? "mfaEnrolledAt",
31
- emailVerifiedAt: t.emailVerifiedAt ?? "emailVerifiedAt",
32
- deactivatedAt: t.deactivatedAt ?? !1
33
- }
34
- };
35
- }, $e = (e, t = {}) => {
36
- let n = Qe(t.identity), { col: r } = n, i = (t) => e`${e(r[t])}`, a = [
37
- "id",
38
- "email",
39
- "passwordHash",
40
- "tenantId",
41
- "createdAt",
42
- "mfaSecret",
43
- "mfaEnrolledAt",
44
- "emailVerifiedAt",
45
- "deactivatedAt"
46
- ], o, s = () => o ??= {
47
- usersTable: e.join(".", !1)(n.table.split(".").map((t) => e`${e(t)}`)),
48
- selectList: e.csv(a.map((t) => r[t] === !1 ? e`NULL AS ${e(t)}` : e`${i(t)} AS ${e(t)}`))
49
- }, c = (e, t) => /* @__PURE__ */ Error(`postgresUserStore: ${t} needs the "${e}" column, and identity.columns.${e} is false — this table has none`), l = (t) => r.updatedAt === !1 ? e`` : e`, ${i("updatedAt")} = ${t}`, u = (e) => ({
50
- id: e.id,
51
- email: e.email,
52
- passwordHash: e.passwordHash,
53
- tenantId: e.tenantId,
54
- createdAt: e.createdAt,
55
- mfaSecret: e.mfaSecret,
56
- mfaEnrolledAt: e.mfaEnrolledAt,
57
- emailVerifiedAt: e.emailVerifiedAt,
58
- ...r.deactivatedAt === !1 ? {} : { deactivatedAt: e.deactivatedAt ?? null }
59
- }), d = (t) => $.gen(function* () {
60
- let n = yield* e`
61
- SELECT ${s().selectList} FROM ${s().usersTable}
62
- WHERE ${i("email")} = ${t.toLowerCase()}
63
- LIMIT 1
64
- `;
65
- return n[0] ? u(n[0]) : null;
66
- }).pipe($.orElseSucceed(() => null)), f = (t) => $.gen(function* () {
67
- let n = yield* e`
68
- SELECT ${s().selectList} FROM ${s().usersTable}
69
- WHERE ${i("id")} = ${t}
70
- LIMIT 1
71
- `;
72
- return n[0] ? u(n[0]) : null;
73
- }).pipe($.orElseSucceed(() => null)), p = (t) => $.gen(function* () {
74
- let n = t.email.toLowerCase(), a = /* @__PURE__ */ new Date(), o = [
75
- i("id"),
76
- i("email"),
77
- i("tenantId"),
78
- i("createdAt")
79
- ], c = [
80
- t.id,
81
- n,
82
- t.tenantId,
83
- a
84
- ];
85
- return r.passwordHash !== !1 && (o.push(i("passwordHash")), c.push(t.passwordHash ?? null)), r.updatedAt !== !1 && (o.push(i("updatedAt")), c.push(a)), yield* e`
86
- INSERT INTO ${s().usersTable} (${e.csv(o)})
87
- VALUES ${e.in(c)}
88
- `.pipe($.map(() => ({
89
- ...t,
90
- email: n,
91
- createdAt: a
92
- })), $.catchAll((e) => Ze(e) === "23505" ? $.fail(new y({ email: n })) : $.die(e)));
93
- }), m = (t) => $.gen(function* () {
94
- let n = (yield* e`
95
- SELECT ${s().selectList} FROM ${s().usersTable} WHERE ${i("id")} = ${t} LIMIT 1
96
- `)[0];
97
- return n ? u(n) : yield* $.fail(new x({ userId: t }));
98
- }).pipe($.catchTag("SqlError", (e) => $.die(e))), g = (t, n) => $.gen(function* () {
99
- return r.passwordHash === !1 ? yield* $.die(c("passwordHash", "updatePassword")) : (yield* e`
100
- UPDATE ${s().usersTable} SET ${i("passwordHash")} = ${n}${l(/* @__PURE__ */ new Date())}
101
- WHERE ${i("id")} = ${t}
102
- `.pipe($.catchTag("SqlError", (e) => $.die(e))), yield* m(t));
103
- }), _ = (t, n) => $.gen(function* () {
104
- return r.mfaSecret === !1 ? yield* $.die(c("mfaSecret", "setMfaSecret")) : r.mfaEnrolledAt === !1 ? yield* $.die(c("mfaEnrolledAt", "setMfaSecret")) : (yield* e`
105
- UPDATE ${s().usersTable}
106
- SET ${i("mfaSecret")} = ${n}, ${i("mfaEnrolledAt")} = ${null}
107
- WHERE ${i("id")} = ${t}
108
- `.pipe($.catchTag("SqlError", (e) => $.die(e))), yield* m(t));
109
- }), v = (t) => $.gen(function* () {
110
- return r.mfaEnrolledAt === !1 ? yield* $.die(c("mfaEnrolledAt", "markMfaEnrolled")) : (yield* e`
111
- UPDATE ${s().usersTable}
112
- SET ${i("mfaEnrolledAt")} = ${/* @__PURE__ */ new Date()}
113
- WHERE ${i("id")} = ${t}
114
- `.pipe($.catchTag("SqlError", (e) => $.die(e))), yield* m(t));
115
- }), b = (t) => $.gen(function* () {
116
- return r.mfaSecret === !1 ? yield* $.die(c("mfaSecret", "clearMfa")) : r.mfaEnrolledAt === !1 ? yield* $.die(c("mfaEnrolledAt", "clearMfa")) : (yield* e`
117
- UPDATE ${s().usersTable}
118
- SET ${i("mfaSecret")} = ${null}, ${i("mfaEnrolledAt")} = ${null}
119
- WHERE ${i("id")} = ${t}
120
- `.pipe($.catchTag("SqlError", (e) => $.die(e))), yield* m(t));
121
- }), S = (t) => $.gen(function* () {
122
- return r.emailVerifiedAt === !1 ? yield* $.die(c("emailVerifiedAt", "markEmailVerified")) : (yield* e`
123
- UPDATE ${s().usersTable}
124
- SET ${i("emailVerifiedAt")} = ${/* @__PURE__ */ new Date()}${l(/* @__PURE__ */ new Date())}
125
- WHERE ${i("id")} = ${t} AND ${i("emailVerifiedAt")} IS NULL
126
- `.pipe($.catchTag("SqlError", (e) => $.die(e))), yield* m(t));
127
- }), C = (t) => $.gen(function* () {
128
- return (yield* e`
129
- SELECT "userId", "tenantId", role, "joinedAt"
130
- FROM memberships WHERE "userId" = ${t}
131
- ORDER BY "joinedAt" ASC
132
- `).map((e) => ({ ...e }));
133
- }).pipe($.orElseSucceed(() => [])), w = (t) => $.gen(function* () {
134
- let n = /* @__PURE__ */ new Date();
135
- yield* e`
136
- UPDATE memberships SET role = ${t.role}
137
- WHERE "userId" = ${t.userId} AND "tenantId" = ${t.tenantId}
138
- `;
139
- let r = yield* e`
140
- SELECT "userId", "tenantId", role, "joinedAt"
141
- FROM memberships
142
- WHERE "userId" = ${t.userId} AND "tenantId" = ${t.tenantId}
143
- LIMIT 1
144
- `;
145
- return r[0] ? { ...r[0] } : (yield* e`
146
- INSERT INTO memberships (id, "userId", "tenantId", role, "joinedAt")
147
- VALUES (${h("mem")}, ${t.userId}, ${t.tenantId}, ${t.role}, ${n})
148
- `, {
149
- ...t,
150
- joinedAt: n
151
- });
152
- }).pipe($.catchAll(() => $.succeed({
153
- ...t,
154
- joinedAt: /* @__PURE__ */ new Date()
155
- }))), T = (t, n) => $.gen(function* () {
156
- return (yield* e`
157
- SELECT role FROM memberships
158
- WHERE "userId" = ${t} AND "tenantId" = ${n} LIMIT 1
159
- `)[0]?.role ?? null;
160
- }).pipe($.orElseSucceed(() => null)), E = (t) => $.gen(function* () {
161
- return (yield* e`
162
- SELECT id, "userId", "tenantId", "expiresAt", "ipAddress", "userAgent", "createdAt", "lastSeenAt"
163
- FROM sessions WHERE "userId" = ${t}
164
- ORDER BY "createdAt" DESC
165
- `).map((e) => ({ ...e }));
166
- }).pipe($.orElseSucceed(() => [])), D = (t) => $.gen(function* () {
167
- let n = /* @__PURE__ */ new Date();
168
- return yield* e`
169
- INSERT INTO sessions (id, "userId", "tenantId", "expiresAt", "ipAddress", "userAgent", "createdAt", "lastSeenAt")
170
- VALUES (
171
- ${t.id}, ${t.userId}, ${t.tenantId}, ${t.expiresAt},
172
- ${t.ipAddress ?? null}, ${t.userAgent ?? null}, ${n}, ${n}
173
- )
174
- `, {
2
+ import { SESSION_COOKIE_NAME as ee, clearSessionCookie as te, issueSession as s, readSession as c, readSessionFromHeaders as ne, readSessionKeyed as re, resolveSessionSecret as ie, resolveSessionSecrets as ae, sessionSecretsOf as oe } from "./session.js";
3
+ import { a as l, c as se, i as u, l as d, n as f, o as p, r as m, s as h, t as g } from "./strategy-XaGjSicX.js";
4
+ import { $ as _, A as v, B as y, C as b, D as x, E as S, F as C, G as w, H as T, I as E, J as D, K as O, L as k, M as A, N as j, O as M, P as N, Q as P, R as F, S as I, T as L, U as R, V as z, W as B, X as V, Y as H, Z as U, _ as W, _t as G, a as K, at as ce, b as le, c as ue, ct as de, d as fe, dt as pe, et as me, f as he, ft as ge, g as _e, gt as ve, h as ye, ht as be, i as xe, it as Se, j as Ce, k as we, l as Te, lt as Ee, m as De, mt as Oe, n as ke, nt as Ae, o as je, ot as Me, p as Ne, pt as Pe, q as Fe, r as Ie, rt as Le, s as Re, st as ze, t as Be, tt as Ve, u as He, ut as Ue, v as We, vt as Ge, w as Ke, x as qe, y as Je, z as Ye } from "./plugin-CNW-X70p.js";
5
+ import { EMAIL_VERIFY_TTL_S as Xe, MAGIC_LINK_TTL_S as Ze, MFA_PENDING_TTL_S as Qe, NATIVE_CODE_TTL_S as $e, PASSWORD_RESET_TTL_S as et, hashToken as tt, mintSecret as nt, mintToken as rt } from "./tokens.js";
6
+ import { CSRF_COOKIE_NAME as it, CSRF_HEADER_NAME as at, isCsrfTokenWellFormed as ot, issueCsrfToken as st, verifyCsrf as q } from "./csrf.js";
7
+ import { generateChallenge as ct, verifyAssertion as lt, verifyRegistration as ut } from "./webauthn.js";
8
+ import { Effect as J } from "effect";
9
+ import { eq as Y } from "@voltro/database";
10
+ //#region src/sessionRegistry.ts
11
+ var X = "sessions", dt = 604800, Z = (e) => ({
12
+ ...e,
13
+ expiresAt: new Date(e.expiresAt),
14
+ createdAt: new Date(e.createdAt),
15
+ lastSeenAt: new Date(e.lastSeenAt)
16
+ }), Q = async (e, t) => await e.query({
17
+ table: X,
18
+ predicate: t,
19
+ order: [],
20
+ take: void 0,
21
+ skip: void 0,
22
+ projection: void 0
23
+ }), ft = (e) => ({
24
+ listSessions: (t) => J.promise(async () => (await Q(e, Y("userId", t))).map(Z).sort((e, t) => t.createdAt.getTime() - e.createdAt.getTime())),
25
+ insertSession: (t) => J.promise(async () => {
26
+ let n = /* @__PURE__ */ new Date(), r = {
175
27
  ...t,
176
28
  createdAt: n,
177
29
  lastSeenAt: n
178
30
  };
179
- }).pipe($.catchAll(() => $.succeed({
180
- ...t,
181
- createdAt: /* @__PURE__ */ new Date(),
182
- lastSeenAt: /* @__PURE__ */ new Date()
183
- }))), O = (t) => $.gen(function* () {
184
- let n = yield* e`
185
- SELECT id, "userId", "tenantId", "expiresAt", "ipAddress", "userAgent", "createdAt", "lastSeenAt"
186
- FROM sessions WHERE id = ${t} LIMIT 1
187
- `;
188
- return n[0] ? { ...n[0] } : null;
189
- }).pipe($.orElseSucceed(() => null)), k = (t, n) => $.gen(function* () {
190
- yield* e`
191
- UPDATE sessions SET "expiresAt" = ${n}, "lastSeenAt" = ${/* @__PURE__ */ new Date()}
192
- WHERE id = ${t}
193
- `;
194
- }).pipe($.asVoid, $.orElseSucceed(() => void 0)), A = (t, n) => $.gen(function* () {
195
- return (yield* e`
196
- DELETE FROM sessions WHERE id = ${n} AND "userId" = ${t}
197
- RETURNING id
198
- `).length > 0;
199
- }).pipe($.orElseSucceed(() => !1)), j = (t, n) => $.gen(function* () {
200
- return (yield* e`
201
- DELETE FROM sessions WHERE "userId" = ${t} AND id <> ${n}
202
- RETURNING id
203
- `).length;
204
- }).pipe($.orElseSucceed(() => 0)), M = (t) => $.gen(function* () {
205
- let n = /* @__PURE__ */ new Date();
206
- return yield* e`
207
- INSERT INTO "authTokens" (id, "tokenHash", "userId", purpose, "expiresAt", "consumedAt", "createdAt")
208
- VALUES (${t.id}, ${t.tokenHash}, ${t.userId}, ${t.purpose}, ${t.expiresAt}, ${null}, ${n})
209
- `, {
210
- ...t,
211
- consumedAt: null,
212
- createdAt: n
213
- };
214
- }).pipe($.catchAll(() => $.succeed({
215
- ...t,
216
- consumedAt: null,
217
- createdAt: /* @__PURE__ */ new Date()
218
- }))), N = (t, n) => $.gen(function* () {
219
- let r = yield* e`
220
- UPDATE "authTokens"
221
- SET "consumedAt" = ${/* @__PURE__ */ new Date()}
222
- WHERE "tokenHash" = ${t}
223
- AND purpose = ${n}
224
- AND "consumedAt" IS NULL
225
- AND "expiresAt" > ${/* @__PURE__ */ new Date()}
226
- RETURNING id, "tokenHash", "userId", purpose, "expiresAt", "consumedAt", "createdAt"
227
- `;
228
- return r[0] ? { ...r[0] } : null;
229
- }).pipe($.orElseSucceed(() => null)), P = (t, n) => $.gen(function* () {
230
- let r = yield* e`
231
- SELECT id, "tokenHash", "userId", purpose, "expiresAt", "consumedAt", "createdAt"
232
- FROM "authTokens"
233
- WHERE "userId" = ${t} AND purpose = ${n}
234
- ORDER BY "createdAt" DESC
235
- LIMIT 1
236
- `;
237
- return r[0] ? { ...r[0] } : null;
238
- }).pipe($.orElseSucceed(() => null)), F = (t) => $.gen(function* () {
239
- let n = /* @__PURE__ */ new Date(), r = t.email.toLowerCase();
240
- return yield* e`
241
- INSERT INTO invitations (
242
- id, "tokenHash", email, "tenantId", role, "invitedByUserId",
243
- "expiresAt", "acceptedAt", "acceptedByUserId", "revokedAt", "revokedByUserId", "createdAt"
244
- ) VALUES (
245
- ${t.id}, ${t.tokenHash}, ${r}, ${t.tenantId},
246
- ${t.role}, ${t.invitedByUserId}, ${t.expiresAt},
247
- ${null}, ${null}, ${null}, ${null}, ${n}
248
- )
249
- `, {
250
- ...t,
251
- email: r,
252
- acceptedAt: null,
253
- acceptedByUserId: null,
254
- revokedAt: null,
255
- revokedByUserId: null,
256
- createdAt: n
257
- };
258
- }).pipe($.catchAll((e) => $.die(e))), I = (t) => $.gen(function* () {
259
- let n = yield* e`
260
- SELECT id, "tokenHash", email, "tenantId", role, "invitedByUserId", "expiresAt",
261
- "acceptedAt", "acceptedByUserId", "revokedAt", "revokedByUserId", "createdAt"
262
- FROM invitations WHERE "tokenHash" = ${t} LIMIT 1
263
- `;
264
- return n[0] ? { ...n[0] } : null;
265
- }).pipe($.orElseSucceed(() => null)), L = (t, n, r) => $.gen(function* () {
266
- let i = yield* e`
267
- UPDATE invitations
268
- SET "acceptedAt" = ${r}, "acceptedByUserId" = ${n}
269
- WHERE "tokenHash" = ${t}
270
- AND "acceptedAt" IS NULL
271
- AND "revokedAt" IS NULL
272
- AND "expiresAt" > ${r}
273
- RETURNING id, "tokenHash", email, "tenantId", role, "invitedByUserId", "expiresAt",
274
- "acceptedAt", "acceptedByUserId", "revokedAt", "revokedByUserId", "createdAt"
275
- `;
276
- return i[0] ? { ...i[0] } : null;
277
- }).pipe($.catchAll((e) => $.die(e))), R = (t, n, r, i) => $.gen(function* () {
278
- return (yield* e`
279
- UPDATE invitations
280
- SET "revokedAt" = ${i}, "revokedByUserId" = ${r}
281
- WHERE id = ${t}
282
- AND "tenantId" = ${n}
283
- AND "acceptedAt" IS NULL
284
- AND "revokedAt" IS NULL
285
- RETURNING id
286
- `).length > 0;
287
- }).pipe($.catchAll((e) => $.die(e))), z = (t) => $.gen(function* () {
288
- return (yield* e`
289
- SELECT id, "tokenHash", email, "tenantId", role, "invitedByUserId", "expiresAt",
290
- "acceptedAt", "acceptedByUserId", "revokedAt", "revokedByUserId", "createdAt"
291
- FROM invitations WHERE "tenantId" = ${t}
292
- ORDER BY "createdAt" DESC
293
- `).map((e) => ({ ...e }));
294
- }).pipe($.orElseSucceed(() => [])), B = (t, n) => $.gen(function* () {
295
- return (yield* e`
296
- SELECT COUNT(*)::int AS n FROM invitations
297
- WHERE "tenantId" = ${t}
298
- AND "acceptedAt" IS NULL AND "revokedAt" IS NULL AND "expiresAt" > ${n}
299
- `)[0]?.n ?? 0;
300
- }).pipe($.catchAll((e) => $.die(e))), V = (t, n, r, i) => $.gen(function* () {
301
- return (yield* e`
302
- UPDATE invitations
303
- SET "revokedAt" = ${i}, "revokedByUserId" = ${r}
304
- WHERE "tenantId" = ${t}
305
- AND email = ${n.toLowerCase()}
306
- AND "acceptedAt" IS NULL
307
- AND "revokedAt" IS NULL
308
- RETURNING id
309
- `).length;
310
- }).pipe($.catchAll((e) => $.die(e))), H = (t) => $.gen(function* () {
311
- let n = /* @__PURE__ */ new Date();
312
- return yield* e`
313
- INSERT INTO "impersonationGrants" (
314
- id, "sessionId", "actorUserId", "actorSessionId", "targetUserId", "tenantId",
315
- reason, "startedAt", "expiresAt", "endedAt", "endedReason", "ipAddress", "userAgent"
316
- ) VALUES (
317
- ${t.id}, ${t.sessionId}, ${t.actorUserId}, ${t.actorSessionId},
318
- ${t.targetUserId}, ${t.tenantId}, ${t.reason ?? null}, ${n},
319
- ${t.expiresAt}, ${null}, ${null}, ${t.ipAddress ?? null}, ${t.userAgent ?? null}
320
- )
321
- `, {
322
- ...t,
323
- startedAt: n,
324
- endedAt: null,
325
- endedReason: null
326
- };
327
- }).pipe($.catchAll((e) => $.die(e))), U = (t) => $.gen(function* () {
328
- let n = yield* e`
329
- SELECT id, "sessionId", "actorUserId", "actorSessionId", "targetUserId", "tenantId",
330
- reason, "startedAt", "expiresAt", "endedAt", "endedReason", "ipAddress", "userAgent"
331
- FROM "impersonationGrants" WHERE "sessionId" = ${t} LIMIT 1
332
- `;
333
- return n[0] ? { ...n[0] } : null;
334
- }).pipe($.orElseSucceed(() => null)), W = (t, n, r) => $.gen(function* () {
335
- return (yield* e`
336
- UPDATE "impersonationGrants"
337
- SET "endedAt" = ${r}, "endedReason" = ${n}
338
- WHERE "sessionId" = ${t} AND "endedAt" IS NULL
339
- RETURNING id
340
- `).length > 0;
341
- }).pipe($.catchAll((e) => $.die(e))), G = (t) => $.gen(function* () {
342
- return (yield* e`
343
- SELECT id, "credentialId", "userId", "publicKey", counter, transports, "createdAt", "lastUsedAt"
344
- FROM passkeys WHERE "userId" = ${t}
345
- `).map((e) => ({ ...e }));
346
- }).pipe($.orElseSucceed(() => [])), K = (t) => $.gen(function* () {
347
- let n = yield* e`
348
- SELECT id, "credentialId", "userId", "publicKey", counter, transports, "createdAt", "lastUsedAt"
349
- FROM passkeys WHERE "credentialId" = ${t} LIMIT 1
350
- `;
351
- return n[0] ? { ...n[0] } : null;
352
- }).pipe($.orElseSucceed(() => null)), q = (t) => $.gen(function* () {
353
- let n = /* @__PURE__ */ new Date();
354
- return yield* e`
355
- INSERT INTO passkeys (id, "credentialId", "userId", "publicKey", counter, transports, "createdAt", "lastUsedAt")
356
- VALUES (
357
- ${t.id}, ${t.credentialId}, ${t.userId}, ${t.publicKey},
358
- ${t.counter}, ${t.transports ?? null}, ${n}, ${null}
359
- )
360
- `, {
361
- ...t,
362
- createdAt: n,
363
- lastUsedAt: null
364
- };
365
- }).pipe($.catchAll(() => $.succeed({
366
- ...t,
367
- createdAt: /* @__PURE__ */ new Date(),
368
- lastUsedAt: null
369
- }))), J = (t, n) => $.gen(function* () {
370
- return (yield* e`
371
- UPDATE passkeys
372
- SET counter = ${n}, "lastUsedAt" = ${/* @__PURE__ */ new Date()}
373
- WHERE "credentialId" = ${t}
374
- AND counter < ${n}
375
- RETURNING id
376
- `).length > 0;
377
- }).pipe($.orElseSucceed(() => !1)), Y = (t, n) => $.gen(function* () {
378
- let r = /* @__PURE__ */ new Date();
379
- yield* e`DELETE FROM "recoveryCodes" WHERE "userId" = ${t}`;
380
- for (let i of n) yield* e`
381
- INSERT INTO "recoveryCodes" (id, "userId", "codeHash", "consumedAt", "createdAt")
382
- VALUES (${h("rc")}, ${t}, ${i}, ${null}, ${r})
383
- `;
384
- }).pipe($.asVoid, $.orElseSucceed(() => void 0)), X = (t, n) => $.gen(function* () {
385
- return (yield* e`
386
- UPDATE "recoveryCodes"
387
- SET "consumedAt" = ${/* @__PURE__ */ new Date()}
388
- WHERE "userId" = ${t}
389
- AND "codeHash" = ${n}
390
- AND "consumedAt" IS NULL
391
- RETURNING id
392
- `).length > 0;
393
- }).pipe($.orElseSucceed(() => !1)), Z = (t) => $.gen(function* () {
394
- return (yield* e`
395
- SELECT COUNT(*)::int AS n FROM "recoveryCodes"
396
- WHERE "userId" = ${t} AND "consumedAt" IS NULL
397
- `)[0]?.n ?? 0;
398
- }).pipe($.orElseSucceed(() => 0)), Q = (e, t) => $.catchAll((n) => $.logWarning(`[auth] lockout ${e} failed — brute-force protection is not counting`).pipe($.annotateLogs("cause", String(n)), $.as(t)));
31
+ return await e.insert(X, r), r;
32
+ }),
33
+ findSession: (t) => J.promise(async () => {
34
+ let n = (await Q(e, Y("id", t)))[0];
35
+ return n === void 0 ? null : Z(n);
36
+ }),
37
+ touchSession: (t, n) => J.promise(async () => {
38
+ await e.update(X, t, {
39
+ expiresAt: n,
40
+ lastSeenAt: /* @__PURE__ */ new Date()
41
+ });
42
+ }),
43
+ revokeSession: (t, n) => J.promise(async () => {
44
+ let r = (await Q(e, Y("id", n)))[0];
45
+ return r === void 0 || r.userId !== t ? !1 : e.delete(X, n);
46
+ }),
47
+ revokeAllOtherSessions: (t, n) => J.promise(async () => {
48
+ let r = 0;
49
+ for (let i of await Q(e, Y("userId", t))) i.id !== n && await e.delete(X, i.id) && (r += 1);
50
+ return r;
51
+ }),
52
+ revokeAllSessions: (t) => J.promise(async () => {
53
+ let n = 0;
54
+ for (let r of await Q(e, Y("userId", t))) await e.delete(X, r.id) && (n += 1);
55
+ return n;
56
+ })
57
+ }), $ = (e, t) => e.type === "user" ? {
58
+ ...e,
59
+ metadata: {
60
+ ...e.metadata ?? {},
61
+ sessionId: t
62
+ }
63
+ } : e, pt = async (e, t, n, r = {}) => {
64
+ if (t.type !== "user") throw Error("issueRegisteredSession: only a user subject has a session row");
65
+ let i = l("sess"), a = r.ttlSeconds ?? dt, o = (r.now ?? Date.now)();
66
+ await J.runPromise(e.insertSession({
67
+ id: i,
68
+ userId: t.id,
69
+ tenantId: t.tenantId ?? "",
70
+ expiresAt: new Date(o + a * 1e3),
71
+ ipAddress: r.ipAddress ?? null,
72
+ userAgent: r.userAgent ?? null
73
+ }));
74
+ let { ipAddress: ee, userAgent: te, ...c } = r;
399
75
  return {
400
- findByEmail: d,
401
- findById: f,
402
- insert: p,
403
- updatePassword: g,
404
- setMfaSecret: _,
405
- markMfaEnrolled: v,
406
- clearMfa: b,
407
- markEmailVerified: S,
408
- listMemberships: C,
409
- addMembership: w,
410
- membershipRole: T,
411
- listSessions: E,
412
- insertSession: D,
413
- findSession: O,
414
- touchSession: k,
415
- revokeSession: A,
416
- revokeAllOtherSessions: j,
417
- insertToken: M,
418
- consumeToken: N,
419
- latestToken: P,
420
- insertInvitation: F,
421
- findInvitationByHash: I,
422
- acceptInvitation: L,
423
- revokeInvitation: R,
424
- listInvitations: z,
425
- countPendingInvitations: B,
426
- supersedePendingInvitations: V,
427
- insertImpersonationGrant: H,
428
- findImpersonationGrantBySession: U,
429
- endImpersonationGrant: W,
430
- replaceRecoveryCodes: Y,
431
- consumeRecoveryCode: X,
432
- countRecoveryCodes: Z,
433
- listPasskeys: G,
434
- findPasskey: K,
435
- insertPasskey: q,
436
- advancePasskeyCounter: J,
437
- isLockedOut: (t, n) => $.gen(function* () {
438
- let r = (yield* e`
439
- SELECT "lockedUntil" FROM "loginAttempts"
440
- WHERE email = ${t.toLowerCase()} LIMIT 1
441
- `)[0]?.lockedUntil ?? null;
442
- return r != null && n < r.getTime() ? {
443
- locked: !0,
444
- retryAfterSeconds: Math.ceil((r.getTime() - n) / 1e3)
445
- } : {
446
- locked: !1,
447
- retryAfterSeconds: 0
448
- };
449
- }).pipe(Q("read", {
450
- locked: !1,
451
- retryAfterSeconds: 0
452
- })),
453
- recordLoginFailure: (t, n, r) => $.gen(function* () {
454
- let i = t.toLowerCase(), a = (yield* e`
455
- SELECT "failedCount", "windowStartedAt", "lockedUntil"
456
- FROM "loginAttempts" WHERE email = ${i} LIMIT 1
457
- `)[0], o = a?.windowStartedAt?.getTime() ?? null, s = a?.lockedUntil?.getTime() ?? null, c = o == null || n - o >= r.windowMs, l = !a || c || s != null && n >= s, u = l ? 1 : a.failedCount + 1, d = l ? new Date(n) : new Date(o), f = u >= r.maxAttempts ? new Date(n + r.lockMs) : null, p = new Date(n);
458
- yield* e`
459
- INSERT INTO "loginAttempts" (id, email, "failedCount", "windowStartedAt", "lockedUntil", "createdAt", "updatedAt")
460
- VALUES (${h("la")}, ${i}, ${u}, ${d}, ${f}, ${p}, ${p})
461
- ON CONFLICT (email) DO UPDATE SET
462
- "failedCount" = ${u},
463
- "windowStartedAt" = ${d},
464
- "lockedUntil" = ${f},
465
- "updatedAt" = ${p}
466
- `;
467
- }).pipe($.asVoid, Q("record", void 0)),
468
- clearLoginFailures: (t) => $.gen(function* () {
469
- yield* e`DELETE FROM "loginAttempts" WHERE email = ${t.toLowerCase()}`;
470
- }).pipe($.asVoid, Q("clear", void 0))
76
+ ...s($(t, i), n, c),
77
+ sessionId: i
471
78
  };
472
- }, et = (e) => (t) => $.runPromise(e.send({
79
+ }, mt = (e) => async (t) => t.type === "user" ? (await J.runPromise(e.listMemberships(t.id))).map((e) => ({
80
+ tenantId: e.tenantId,
81
+ role: e.role
82
+ })) : [], ht = (e) => (t) => J.runPromise(e.send({
473
83
  to: t.to,
474
84
  subject: t.subject,
475
85
  html: t.html,
476
86
  text: t.text
477
- }).pipe($.asVoid, $.orElseSucceed(() => void 0)));
87
+ }).pipe(J.asVoid, J.orElseSucceed(() => void 0)));
478
88
  //#endregion
479
- export { He as CSRF_COOKIE_NAME, Ue as CSRF_HEADER_NAME, Oe as DEFAULT_INVITER_ROLES, ie as DEFAULT_ROLE_RANK, P as EMAIL_NOT_VERIFIED_CODE, Y as EMAIL_VERIFIED_METADATA_KEY, J as EMAIL_VERIFY_RESEND_COOLDOWN_S, Fe as EMAIL_VERIFY_TTL_S, Se as IMPERSONATION_DEFAULT_DURATION_S, le as IMPERSONATION_FORBIDDEN_SUBPATHS, oe as INVITATION_MAX_PENDING, be as INVITATION_TTL_S, Ie as MAGIC_LINK_TTL_S, Le as MFA_PENDING_TTL_S, Re as PASSWORD_RESET_TTL_S, e as PasswordEmptyError, t as PasswordHashError, s as SESSION_COOKIE_NAME, ue as TotpVerifyError, y as UserAlreadyExistsError, x as UserNotFoundError, Xe as authMemberships, Ee as authRoutesPlugin, c as clearSessionCookie, O as configSessionSecrets, Me as dataStoreChallengeStore, he as defaultCanGrantRole, X as emailVerificationActive, V as emailVerificationGuard, qe as generateChallenge, ee as generateRecoveryCodes, ye as generateTotpCode, Te as generateTotpSecret, ge as getAuthSessionStrategy, z as guardSubject, ce as handleAcceptInvitation, se as handleAcceptInvitationWithSignUp, Z as handleCreateInvitation, fe as handleCsrf, w as handleEmailVerifyConfirm, ae as handleEmailVerifyRequest, Q as handleImpersonationStart, ve as handleImpersonationStop, Ae as handleListInvitations, T as handleListMemberships, de as handleListSessions, L as handleMagicLinkConsume, R as handleMagicLinkRequest, B as handleMfaEnrollStart, A as handleMfaEnrollVerify, N as handleMfaRegenerateRecoveryCodes, I as handleMfaUnenroll, H as handleMfaVerify, U as handlePasskeyAssertOptions, D as handlePasskeyAssertVerify, je as handlePasskeyRegisterOptions, W as handlePasskeyRegisterVerify, Pe as handlePasswordResetConfirm, E as handlePasswordResetRequest, Ne as handlePreviewInvitation, K as handleRevokeAllOtherSessions, te as handleRevokeInvitation, M as handleRevokeSession, G as handleSignIn, q as handleSignOut, j as handleSignUp, F as handleSwitchTenant, n as hashPassword, ze as hashToken, we as impersonationAuditRedactor, ne as impersonationOf, We as isCsrfTokenWellFormed, De as isEmailVerified, pe as isImpersonated, Ge as issueCsrfToken, l as issueSession, xe as issueUserSession, et as mailSender, v as makeSessionRevocationChecker, k as memoryChallengeStore, _ as memoryUserStore, Be as mintSecret, Ve as mintToken, r as needsRehash, h as newAuthId, re as otpauthUrl, i as parseScryptParams, $e as postgresUserStore, u as readSession, d as readSessionKeyed, f as resolveSessionSecret, p as resolveSessionSecrets, ke as runSubjectGuards, _e as sendEmailVerification, b as sessionIdOfSubject, m as sessionSecretsOf, S as subjectFromUser, g as subjectMemberships, Ce as userEmailVerified, Je as verifyAssertion, Ke as verifyCsrf, a as verifyPassword, o as verifyPasswordWithRehash, Ye as verifyRegistration, me as verifyTotpCode, C as voltroPasswordStrategy };
89
+ export { it as CSRF_COOKIE_NAME, at as CSRF_HEADER_NAME, _e as DEFAULT_INVITER_ROLES, W as DEFAULT_ROLE_RANK, me as EMAIL_NOT_VERIFIED_CODE, Ve as EMAIL_VERIFIED_METADATA_KEY, Ae as EMAIL_VERIFY_RESEND_COOLDOWN_S, Xe as EMAIL_VERIFY_TTL_S, Te as IMPERSONATION_DEFAULT_DURATION_S, He as IMPERSONATION_FORBIDDEN_SUBPATHS, We as INVITATION_MAX_PENDING, Je as INVITATION_TTL_S, Ze as MAGIC_LINK_TTL_S, Qe as MFA_PENDING_TTL_S, $e as NATIVE_CODE_TTL_S, Ie as NATIVE_PENDING_COOKIE, et as PASSWORD_RESET_TTL_S, e as PasswordEmptyError, t as PasswordHashError, ee as SESSION_COOKIE_NAME, Ue as TotpVerifyError, f as UserAlreadyExistsError, m as UserNotFoundError, G as appUserStore, mt as authMemberships, Be as authRoutesPlugin, te as clearSessionCookie, j as configSessionSecrets, x as dataStoreChallengeStore, ft as dataStoreSessionRegistry, le as defaultCanGrantRole, Le as emailVerificationActive, Se as emailVerificationGuard, ct as generateChallenge, pe as generateRecoveryCodes, ge as generateTotpCode, Pe as generateTotpSecret, ke as getAuthSessionStrategy, N as guardSubject, qe as handleAcceptInvitation, I as handleAcceptInvitationWithSignUp, b as handleCreateInvitation, C as handleCsrf, ce as handleEmailVerifyConfirm, Me as handleEmailVerifyRequest, fe as handleImpersonationStart, he as handleImpersonationStop, Ke as handleListInvitations, E as handleListMemberships, k as handleListSessions, F as handleMagicLinkConsume, Ye as handleMagicLinkRequest, y as handleMfaEnrollStart, z as handleMfaEnrollVerify, T as handleMfaRegenerateRecoveryCodes, R as handleMfaUnenroll, B as handleMfaVerify, xe as handleNativeAuthorize, K as handleNativeComplete, je as handleNativeExchange, M as handlePasskeyAssertOptions, we as handlePasskeyAssertVerify, v as handlePasskeyRegisterOptions, Ce as handlePasskeyRegisterVerify, w as handlePasswordResetConfirm, O as handlePasswordResetRequest, L as handlePreviewInvitation, Fe as handleRevokeAllOtherSessions, S as handleRevokeInvitation, D as handleRevokeSession, H as handleSignIn, V as handleSignOut, U as handleSignUp, P as handleSwitchTenant, n as hashPassword, tt as hashToken, Ne as impersonationAuditRedactor, De as impersonationOf, Re as isAllowedRedirectUri, ot as isCsrfTokenWellFormed, ze as isEmailVerified, ye as isImpersonated, st as issueCsrfToken, pt as issueRegisteredSession, s as issueSession, _ as issueUserSession, ht as mailSender, d as makeSessionRevocationChecker, A as memoryChallengeStore, u as memoryUserStore, nt as mintSecret, rt as mintToken, ue as nativeLoginRedirect, r as needsRehash, l as newAuthId, Oe as otpauthUrl, i as parseScryptParams, Ge as postgresUserStore, c as readSession, ne as readSessionFromHeaders, re as readSessionKeyed, ie as resolveSessionSecret, ae as resolveSessionSecrets, ve as runSubjectGuards, de as sendEmailVerification, p as sessionIdOfSubject, oe as sessionSecretsOf, h as subjectFromUser, se as subjectMemberships, Ee as userEmailVerified, lt as verifyAssertion, q as verifyCsrf, a as verifyPassword, o as verifyPasswordWithRehash, ut as verifyRegistration, be as verifyTotpCode, g as voltroPasswordStrategy, $ as withSessionId };