@voltro/plugin-auth 0.33.0 → 0.34.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/CHANGELOG.md +1801 -0
- package/dist/index.d.ts +830 -26
- package/dist/index.js +182 -52
- package/dist/password.d.ts +2 -1
- package/dist/password.js +44 -35
- package/dist/plugin-BZm5Semm.js +1330 -0
- package/dist/plugin.d.ts +315 -44
- package/dist/plugin.js +2 -1
- package/dist/schema.d.ts +46 -1
- package/dist/schema.js +33 -3
- package/dist/session.d.ts +13 -5
- package/dist/{strategy-Ce4FlGi4.js → strategy-Bty6_XUj.js} +84 -12
- package/dist/strategy.d.ts +111 -1
- package/dist/strategy.js +1 -1
- package/dist/tokens.d.ts +36 -1
- package/dist/tokens.js +15 -8
- package/package.json +3 -3
- package/dist/plugin-ZXs8LFn0.js +0 -820
package/dist/index.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
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
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-
|
|
4
|
-
import {
|
|
5
|
-
import { MAGIC_LINK_TTL_S as
|
|
6
|
-
import { CSRF_COOKIE_NAME as
|
|
7
|
-
import { generateChallenge as
|
|
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-Bty6_XUj.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 ee, T as te, U as ne, V as U, W, X as G, Y as K, Z as q, _ as J, a as Y, at as X, b as Z, c as re, ct as ie, d as ae, dt as oe, et as se, f as ce, g as le, h as ue, i as de, it as fe, j as pe, k as me, l as he, lt as ge, m as _e, n as ve, nt as ye, o as be, ot as xe, p as Se, q as Ce, r as we, rt as Te, s as Ee, st as De, t as Oe, tt as ke, u as Ae, ut as je, v as Me, w as Ne, x as Pe, y as Fe, z as Ie } from "./plugin-BZm5Semm.js";
|
|
5
|
+
import { EMAIL_VERIFY_TTL_S as Le, MAGIC_LINK_TTL_S as Re, MFA_PENDING_TTL_S as ze, PASSWORD_RESET_TTL_S as Be, hashToken as Ve, mintSecret as He, mintToken as Q } from "./tokens.js";
|
|
6
|
+
import { CSRF_COOKIE_NAME as Ue, CSRF_HEADER_NAME as We, isCsrfTokenWellFormed as Ge, issueCsrfToken as Ke, verifyCsrf as qe } from "./csrf.js";
|
|
7
|
+
import { generateChallenge as Je, verifyAssertion as Ye, verifyRegistration as Xe } from "./webauthn.js";
|
|
8
8
|
import { Effect as $ } from "effect";
|
|
9
9
|
//#region src/postgresUserStore.ts
|
|
10
|
-
var
|
|
10
|
+
var Ze = (e) => {
|
|
11
11
|
let t = e?.code;
|
|
12
12
|
if (typeof t == "string") return t;
|
|
13
13
|
let n = e?.cause?.code;
|
|
14
14
|
return typeof n == "string" ? n : void 0;
|
|
15
|
-
},
|
|
15
|
+
}, Qe = (e) => {
|
|
16
16
|
let t = (t) => $.gen(function* () {
|
|
17
17
|
return (yield* e`
|
|
18
|
-
SELECT id, email, "passwordHash", "tenantId", "createdAt", "mfaSecret", "mfaEnrolledAt"
|
|
18
|
+
SELECT id, email, "passwordHash", "tenantId", "createdAt", "mfaSecret", "mfaEnrolledAt", "emailVerifiedAt"
|
|
19
19
|
FROM users
|
|
20
20
|
WHERE email = ${t.toLowerCase()}
|
|
21
21
|
LIMIT 1
|
|
22
22
|
`)[0] ?? null;
|
|
23
23
|
}).pipe($.orElseSucceed(() => null)), n = (t) => $.gen(function* () {
|
|
24
24
|
return (yield* e`
|
|
25
|
-
SELECT id, email, "passwordHash", "tenantId", "createdAt", "mfaSecret", "mfaEnrolledAt"
|
|
25
|
+
SELECT id, email, "passwordHash", "tenantId", "createdAt", "mfaSecret", "mfaEnrolledAt", "emailVerifiedAt"
|
|
26
26
|
FROM users
|
|
27
27
|
WHERE id = ${t}
|
|
28
28
|
LIMIT 1
|
|
@@ -36,10 +36,10 @@ var be = (e) => {
|
|
|
36
36
|
...t,
|
|
37
37
|
email: n,
|
|
38
38
|
createdAt: r
|
|
39
|
-
})), $.catchAll((e) =>
|
|
39
|
+
})), $.catchAll((e) => Ze(e) === "23505" ? $.fail(new y({ email: n })) : $.die(e)));
|
|
40
40
|
}), i = (t) => $.gen(function* () {
|
|
41
41
|
return (yield* e`
|
|
42
|
-
SELECT id, email, "passwordHash", "tenantId", "createdAt", "mfaSecret", "mfaEnrolledAt"
|
|
42
|
+
SELECT id, email, "passwordHash", "tenantId", "createdAt", "mfaSecret", "mfaEnrolledAt", "emailVerifiedAt"
|
|
43
43
|
FROM users WHERE id = ${t} LIMIT 1
|
|
44
44
|
`)[0] || (yield* $.fail(new x({ userId: t })));
|
|
45
45
|
}).pipe($.catchTag("SqlError", (e) => $.die(e))), a = (t, n) => $.gen(function* () {
|
|
@@ -66,12 +66,18 @@ var be = (e) => {
|
|
|
66
66
|
WHERE id = ${t}
|
|
67
67
|
`.pipe($.catchTag("SqlError", (e) => $.die(e))), yield* i(t);
|
|
68
68
|
}), l = (t) => $.gen(function* () {
|
|
69
|
+
return yield* e`
|
|
70
|
+
UPDATE users
|
|
71
|
+
SET "emailVerifiedAt" = ${/* @__PURE__ */ new Date()}, "updatedAt" = ${/* @__PURE__ */ new Date()}
|
|
72
|
+
WHERE id = ${t} AND "emailVerifiedAt" IS NULL
|
|
73
|
+
`.pipe($.catchTag("SqlError", (e) => $.die(e))), yield* i(t);
|
|
74
|
+
}), u = (t) => $.gen(function* () {
|
|
69
75
|
return (yield* e`
|
|
70
76
|
SELECT "userId", "tenantId", role, "joinedAt"
|
|
71
77
|
FROM memberships WHERE "userId" = ${t}
|
|
72
78
|
ORDER BY "joinedAt" ASC
|
|
73
79
|
`).map((e) => ({ ...e }));
|
|
74
|
-
}).pipe($.orElseSucceed(() => [])),
|
|
80
|
+
}).pipe($.orElseSucceed(() => [])), d = (t) => $.gen(function* () {
|
|
75
81
|
let n = /* @__PURE__ */ new Date();
|
|
76
82
|
yield* e`
|
|
77
83
|
UPDATE memberships SET role = ${t.role}
|
|
@@ -93,18 +99,18 @@ var be = (e) => {
|
|
|
93
99
|
}).pipe($.catchAll(() => $.succeed({
|
|
94
100
|
...t,
|
|
95
101
|
joinedAt: /* @__PURE__ */ new Date()
|
|
96
|
-
}))),
|
|
102
|
+
}))), f = (t, n) => $.gen(function* () {
|
|
97
103
|
return (yield* e`
|
|
98
104
|
SELECT role FROM memberships
|
|
99
105
|
WHERE "userId" = ${t} AND "tenantId" = ${n} LIMIT 1
|
|
100
106
|
`)[0]?.role ?? null;
|
|
101
|
-
}).pipe($.orElseSucceed(() => null)),
|
|
107
|
+
}).pipe($.orElseSucceed(() => null)), p = (t) => $.gen(function* () {
|
|
102
108
|
return (yield* e`
|
|
103
109
|
SELECT id, "userId", "tenantId", "expiresAt", "ipAddress", "userAgent", "createdAt", "lastSeenAt"
|
|
104
110
|
FROM sessions WHERE "userId" = ${t}
|
|
105
111
|
ORDER BY "createdAt" DESC
|
|
106
112
|
`).map((e) => ({ ...e }));
|
|
107
|
-
}).pipe($.orElseSucceed(() => [])),
|
|
113
|
+
}).pipe($.orElseSucceed(() => [])), m = (t) => $.gen(function* () {
|
|
108
114
|
let n = /* @__PURE__ */ new Date();
|
|
109
115
|
return yield* e`
|
|
110
116
|
INSERT INTO sessions (id, "userId", "tenantId", "expiresAt", "ipAddress", "userAgent", "createdAt", "lastSeenAt")
|
|
@@ -121,28 +127,28 @@ var be = (e) => {
|
|
|
121
127
|
...t,
|
|
122
128
|
createdAt: /* @__PURE__ */ new Date(),
|
|
123
129
|
lastSeenAt: /* @__PURE__ */ new Date()
|
|
124
|
-
}))),
|
|
130
|
+
}))), g = (t) => $.gen(function* () {
|
|
125
131
|
let n = yield* e`
|
|
126
132
|
SELECT id, "userId", "tenantId", "expiresAt", "ipAddress", "userAgent", "createdAt", "lastSeenAt"
|
|
127
133
|
FROM sessions WHERE id = ${t} LIMIT 1
|
|
128
134
|
`;
|
|
129
135
|
return n[0] ? { ...n[0] } : null;
|
|
130
|
-
}).pipe($.orElseSucceed(() => null)),
|
|
136
|
+
}).pipe($.orElseSucceed(() => null)), _ = (t, n) => $.gen(function* () {
|
|
131
137
|
yield* e`
|
|
132
138
|
UPDATE sessions SET "expiresAt" = ${n}, "lastSeenAt" = ${/* @__PURE__ */ new Date()}
|
|
133
139
|
WHERE id = ${t}
|
|
134
140
|
`;
|
|
135
|
-
}).pipe($.asVoid, $.orElseSucceed(() => void 0)),
|
|
141
|
+
}).pipe($.asVoid, $.orElseSucceed(() => void 0)), v = (t, n) => $.gen(function* () {
|
|
136
142
|
return (yield* e`
|
|
137
143
|
DELETE FROM sessions WHERE id = ${n} AND "userId" = ${t}
|
|
138
144
|
RETURNING id
|
|
139
145
|
`).length > 0;
|
|
140
|
-
}).pipe($.orElseSucceed(() => !1)),
|
|
146
|
+
}).pipe($.orElseSucceed(() => !1)), b = (t, n) => $.gen(function* () {
|
|
141
147
|
return (yield* e`
|
|
142
148
|
DELETE FROM sessions WHERE "userId" = ${t} AND id <> ${n}
|
|
143
149
|
RETURNING id
|
|
144
150
|
`).length;
|
|
145
|
-
}).pipe($.orElseSucceed(() => 0)),
|
|
151
|
+
}).pipe($.orElseSucceed(() => 0)), S = (t) => $.gen(function* () {
|
|
146
152
|
let n = /* @__PURE__ */ new Date();
|
|
147
153
|
return yield* e`
|
|
148
154
|
INSERT INTO "authTokens" (id, "tokenHash", "userId", purpose, "expiresAt", "consumedAt", "createdAt")
|
|
@@ -156,7 +162,7 @@ var be = (e) => {
|
|
|
156
162
|
...t,
|
|
157
163
|
consumedAt: null,
|
|
158
164
|
createdAt: /* @__PURE__ */ new Date()
|
|
159
|
-
}))),
|
|
165
|
+
}))), C = (t, n) => $.gen(function* () {
|
|
160
166
|
let r = yield* e`
|
|
161
167
|
UPDATE "authTokens"
|
|
162
168
|
SET "consumedAt" = ${/* @__PURE__ */ new Date()}
|
|
@@ -167,18 +173,130 @@ var be = (e) => {
|
|
|
167
173
|
RETURNING id, "tokenHash", "userId", purpose, "expiresAt", "consumedAt", "createdAt"
|
|
168
174
|
`;
|
|
169
175
|
return r[0] ? { ...r[0] } : null;
|
|
170
|
-
}).pipe($.orElseSucceed(() => null)),
|
|
176
|
+
}).pipe($.orElseSucceed(() => null)), w = (t, n) => $.gen(function* () {
|
|
177
|
+
let r = yield* e`
|
|
178
|
+
SELECT id, "tokenHash", "userId", purpose, "expiresAt", "consumedAt", "createdAt"
|
|
179
|
+
FROM "authTokens"
|
|
180
|
+
WHERE "userId" = ${t} AND purpose = ${n}
|
|
181
|
+
ORDER BY "createdAt" DESC
|
|
182
|
+
LIMIT 1
|
|
183
|
+
`;
|
|
184
|
+
return r[0] ? { ...r[0] } : null;
|
|
185
|
+
}).pipe($.orElseSucceed(() => null)), T = (t) => $.gen(function* () {
|
|
186
|
+
let n = /* @__PURE__ */ new Date(), r = t.email.toLowerCase();
|
|
187
|
+
return yield* e`
|
|
188
|
+
INSERT INTO invitations (
|
|
189
|
+
id, "tokenHash", email, "tenantId", role, "invitedByUserId",
|
|
190
|
+
"expiresAt", "acceptedAt", "acceptedByUserId", "revokedAt", "revokedByUserId", "createdAt"
|
|
191
|
+
) VALUES (
|
|
192
|
+
${t.id}, ${t.tokenHash}, ${r}, ${t.tenantId},
|
|
193
|
+
${t.role}, ${t.invitedByUserId}, ${t.expiresAt},
|
|
194
|
+
${null}, ${null}, ${null}, ${null}, ${n}
|
|
195
|
+
)
|
|
196
|
+
`, {
|
|
197
|
+
...t,
|
|
198
|
+
email: r,
|
|
199
|
+
acceptedAt: null,
|
|
200
|
+
acceptedByUserId: null,
|
|
201
|
+
revokedAt: null,
|
|
202
|
+
revokedByUserId: null,
|
|
203
|
+
createdAt: n
|
|
204
|
+
};
|
|
205
|
+
}).pipe($.catchAll((e) => $.die(e))), E = (t) => $.gen(function* () {
|
|
206
|
+
let n = yield* e`
|
|
207
|
+
SELECT id, "tokenHash", email, "tenantId", role, "invitedByUserId", "expiresAt",
|
|
208
|
+
"acceptedAt", "acceptedByUserId", "revokedAt", "revokedByUserId", "createdAt"
|
|
209
|
+
FROM invitations WHERE "tokenHash" = ${t} LIMIT 1
|
|
210
|
+
`;
|
|
211
|
+
return n[0] ? { ...n[0] } : null;
|
|
212
|
+
}).pipe($.orElseSucceed(() => null)), D = (t, n, r) => $.gen(function* () {
|
|
213
|
+
let i = yield* e`
|
|
214
|
+
UPDATE invitations
|
|
215
|
+
SET "acceptedAt" = ${r}, "acceptedByUserId" = ${n}
|
|
216
|
+
WHERE "tokenHash" = ${t}
|
|
217
|
+
AND "acceptedAt" IS NULL
|
|
218
|
+
AND "revokedAt" IS NULL
|
|
219
|
+
AND "expiresAt" > ${r}
|
|
220
|
+
RETURNING id, "tokenHash", email, "tenantId", role, "invitedByUserId", "expiresAt",
|
|
221
|
+
"acceptedAt", "acceptedByUserId", "revokedAt", "revokedByUserId", "createdAt"
|
|
222
|
+
`;
|
|
223
|
+
return i[0] ? { ...i[0] } : null;
|
|
224
|
+
}).pipe($.catchAll((e) => $.die(e))), O = (t, n, r, i) => $.gen(function* () {
|
|
225
|
+
return (yield* e`
|
|
226
|
+
UPDATE invitations
|
|
227
|
+
SET "revokedAt" = ${i}, "revokedByUserId" = ${r}
|
|
228
|
+
WHERE id = ${t}
|
|
229
|
+
AND "tenantId" = ${n}
|
|
230
|
+
AND "acceptedAt" IS NULL
|
|
231
|
+
AND "revokedAt" IS NULL
|
|
232
|
+
RETURNING id
|
|
233
|
+
`).length > 0;
|
|
234
|
+
}).pipe($.catchAll((e) => $.die(e))), k = (t) => $.gen(function* () {
|
|
235
|
+
return (yield* e`
|
|
236
|
+
SELECT id, "tokenHash", email, "tenantId", role, "invitedByUserId", "expiresAt",
|
|
237
|
+
"acceptedAt", "acceptedByUserId", "revokedAt", "revokedByUserId", "createdAt"
|
|
238
|
+
FROM invitations WHERE "tenantId" = ${t}
|
|
239
|
+
ORDER BY "createdAt" DESC
|
|
240
|
+
`).map((e) => ({ ...e }));
|
|
241
|
+
}).pipe($.orElseSucceed(() => [])), A = (t, n) => $.gen(function* () {
|
|
242
|
+
return (yield* e`
|
|
243
|
+
SELECT COUNT(*)::int AS n FROM invitations
|
|
244
|
+
WHERE "tenantId" = ${t}
|
|
245
|
+
AND "acceptedAt" IS NULL AND "revokedAt" IS NULL AND "expiresAt" > ${n}
|
|
246
|
+
`)[0]?.n ?? 0;
|
|
247
|
+
}).pipe($.catchAll((e) => $.die(e))), j = (t, n, r, i) => $.gen(function* () {
|
|
248
|
+
return (yield* e`
|
|
249
|
+
UPDATE invitations
|
|
250
|
+
SET "revokedAt" = ${i}, "revokedByUserId" = ${r}
|
|
251
|
+
WHERE "tenantId" = ${t}
|
|
252
|
+
AND email = ${n.toLowerCase()}
|
|
253
|
+
AND "acceptedAt" IS NULL
|
|
254
|
+
AND "revokedAt" IS NULL
|
|
255
|
+
RETURNING id
|
|
256
|
+
`).length;
|
|
257
|
+
}).pipe($.catchAll((e) => $.die(e))), M = (t) => $.gen(function* () {
|
|
258
|
+
let n = /* @__PURE__ */ new Date();
|
|
259
|
+
return yield* e`
|
|
260
|
+
INSERT INTO "impersonationGrants" (
|
|
261
|
+
id, "sessionId", "actorUserId", "actorSessionId", "targetUserId", "tenantId",
|
|
262
|
+
reason, "startedAt", "expiresAt", "endedAt", "endedReason", "ipAddress", "userAgent"
|
|
263
|
+
) VALUES (
|
|
264
|
+
${t.id}, ${t.sessionId}, ${t.actorUserId}, ${t.actorSessionId},
|
|
265
|
+
${t.targetUserId}, ${t.tenantId}, ${t.reason ?? null}, ${n},
|
|
266
|
+
${t.expiresAt}, ${null}, ${null}, ${t.ipAddress ?? null}, ${t.userAgent ?? null}
|
|
267
|
+
)
|
|
268
|
+
`, {
|
|
269
|
+
...t,
|
|
270
|
+
startedAt: n,
|
|
271
|
+
endedAt: null,
|
|
272
|
+
endedReason: null
|
|
273
|
+
};
|
|
274
|
+
}).pipe($.catchAll((e) => $.die(e))), N = (t) => $.gen(function* () {
|
|
275
|
+
let n = yield* e`
|
|
276
|
+
SELECT id, "sessionId", "actorUserId", "actorSessionId", "targetUserId", "tenantId",
|
|
277
|
+
reason, "startedAt", "expiresAt", "endedAt", "endedReason", "ipAddress", "userAgent"
|
|
278
|
+
FROM "impersonationGrants" WHERE "sessionId" = ${t} LIMIT 1
|
|
279
|
+
`;
|
|
280
|
+
return n[0] ? { ...n[0] } : null;
|
|
281
|
+
}).pipe($.orElseSucceed(() => null)), P = (t, n, r) => $.gen(function* () {
|
|
282
|
+
return (yield* e`
|
|
283
|
+
UPDATE "impersonationGrants"
|
|
284
|
+
SET "endedAt" = ${r}, "endedReason" = ${n}
|
|
285
|
+
WHERE "sessionId" = ${t} AND "endedAt" IS NULL
|
|
286
|
+
RETURNING id
|
|
287
|
+
`).length > 0;
|
|
288
|
+
}).pipe($.catchAll((e) => $.die(e))), F = (t) => $.gen(function* () {
|
|
171
289
|
return (yield* e`
|
|
172
290
|
SELECT id, "credentialId", "userId", "publicKey", counter, transports, "createdAt", "lastUsedAt"
|
|
173
291
|
FROM passkeys WHERE "userId" = ${t}
|
|
174
292
|
`).map((e) => ({ ...e }));
|
|
175
|
-
}).pipe($.orElseSucceed(() => [])),
|
|
293
|
+
}).pipe($.orElseSucceed(() => [])), I = (t) => $.gen(function* () {
|
|
176
294
|
let n = yield* e`
|
|
177
295
|
SELECT id, "credentialId", "userId", "publicKey", counter, transports, "createdAt", "lastUsedAt"
|
|
178
296
|
FROM passkeys WHERE "credentialId" = ${t} LIMIT 1
|
|
179
297
|
`;
|
|
180
298
|
return n[0] ? { ...n[0] } : null;
|
|
181
|
-
}).pipe($.orElseSucceed(() => null)),
|
|
299
|
+
}).pipe($.orElseSucceed(() => null)), L = (t) => $.gen(function* () {
|
|
182
300
|
let n = /* @__PURE__ */ new Date();
|
|
183
301
|
return yield* e`
|
|
184
302
|
INSERT INTO passkeys (id, "credentialId", "userId", "publicKey", counter, transports, "createdAt", "lastUsedAt")
|
|
@@ -195,7 +313,7 @@ var be = (e) => {
|
|
|
195
313
|
...t,
|
|
196
314
|
createdAt: /* @__PURE__ */ new Date(),
|
|
197
315
|
lastUsedAt: null
|
|
198
|
-
}))),
|
|
316
|
+
}))), R = (t, n) => $.gen(function* () {
|
|
199
317
|
return (yield* e`
|
|
200
318
|
UPDATE passkeys
|
|
201
319
|
SET counter = ${n}, "lastUsedAt" = ${/* @__PURE__ */ new Date()}
|
|
@@ -203,14 +321,14 @@ var be = (e) => {
|
|
|
203
321
|
AND counter < ${n}
|
|
204
322
|
RETURNING id
|
|
205
323
|
`).length > 0;
|
|
206
|
-
}).pipe($.orElseSucceed(() => !1)),
|
|
324
|
+
}).pipe($.orElseSucceed(() => !1)), z = (t, n) => $.gen(function* () {
|
|
207
325
|
let r = /* @__PURE__ */ new Date();
|
|
208
326
|
yield* e`DELETE FROM "recoveryCodes" WHERE "userId" = ${t}`;
|
|
209
327
|
for (let i of n) yield* e`
|
|
210
328
|
INSERT INTO "recoveryCodes" (id, "userId", "codeHash", "consumedAt", "createdAt")
|
|
211
329
|
VALUES (${h("rc")}, ${t}, ${i}, ${null}, ${r})
|
|
212
330
|
`;
|
|
213
|
-
}).pipe($.asVoid, $.orElseSucceed(() => void 0)),
|
|
331
|
+
}).pipe($.asVoid, $.orElseSucceed(() => void 0)), B = (t, n) => $.gen(function* () {
|
|
214
332
|
return (yield* e`
|
|
215
333
|
UPDATE "recoveryCodes"
|
|
216
334
|
SET "consumedAt" = ${/* @__PURE__ */ new Date()}
|
|
@@ -219,12 +337,12 @@ var be = (e) => {
|
|
|
219
337
|
AND "consumedAt" IS NULL
|
|
220
338
|
RETURNING id
|
|
221
339
|
`).length > 0;
|
|
222
|
-
}).pipe($.orElseSucceed(() => !1)),
|
|
340
|
+
}).pipe($.orElseSucceed(() => !1)), V = (t) => $.gen(function* () {
|
|
223
341
|
return (yield* e`
|
|
224
342
|
SELECT COUNT(*)::int AS n FROM "recoveryCodes"
|
|
225
343
|
WHERE "userId" = ${t} AND "consumedAt" IS NULL
|
|
226
344
|
`)[0]?.n ?? 0;
|
|
227
|
-
}).pipe($.orElseSucceed(() => 0)),
|
|
345
|
+
}).pipe($.orElseSucceed(() => 0)), H = (e, t) => $.catchAll((n) => $.logWarning(`[auth] lockout ${e} failed — brute-force protection is not counting`).pipe($.annotateLogs("cause", String(n)), $.as(t)));
|
|
228
346
|
return {
|
|
229
347
|
findByEmail: t,
|
|
230
348
|
findById: n,
|
|
@@ -233,24 +351,36 @@ var be = (e) => {
|
|
|
233
351
|
setMfaSecret: o,
|
|
234
352
|
markMfaEnrolled: s,
|
|
235
353
|
clearMfa: c,
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
354
|
+
markEmailVerified: l,
|
|
355
|
+
listMemberships: u,
|
|
356
|
+
addMembership: d,
|
|
357
|
+
membershipRole: f,
|
|
358
|
+
listSessions: p,
|
|
359
|
+
insertSession: m,
|
|
360
|
+
findSession: g,
|
|
361
|
+
touchSession: _,
|
|
362
|
+
revokeSession: v,
|
|
363
|
+
revokeAllOtherSessions: b,
|
|
364
|
+
insertToken: S,
|
|
365
|
+
consumeToken: C,
|
|
366
|
+
latestToken: w,
|
|
367
|
+
insertInvitation: T,
|
|
368
|
+
findInvitationByHash: E,
|
|
369
|
+
acceptInvitation: D,
|
|
370
|
+
revokeInvitation: O,
|
|
371
|
+
listInvitations: k,
|
|
372
|
+
countPendingInvitations: A,
|
|
373
|
+
supersedePendingInvitations: j,
|
|
374
|
+
insertImpersonationGrant: M,
|
|
375
|
+
findImpersonationGrantBySession: N,
|
|
376
|
+
endImpersonationGrant: P,
|
|
377
|
+
replaceRecoveryCodes: z,
|
|
378
|
+
consumeRecoveryCode: B,
|
|
379
|
+
countRecoveryCodes: V,
|
|
380
|
+
listPasskeys: F,
|
|
381
|
+
findPasskey: I,
|
|
382
|
+
insertPasskey: L,
|
|
383
|
+
advancePasskeyCounter: R,
|
|
254
384
|
isLockedOut: (t, n) => $.gen(function* () {
|
|
255
385
|
let r = (yield* e`
|
|
256
386
|
SELECT "lockedUntil" FROM "loginAttempts"
|
|
@@ -263,7 +393,7 @@ var be = (e) => {
|
|
|
263
393
|
locked: !1,
|
|
264
394
|
retryAfterSeconds: 0
|
|
265
395
|
};
|
|
266
|
-
}).pipe(
|
|
396
|
+
}).pipe(H("read", {
|
|
267
397
|
locked: !1,
|
|
268
398
|
retryAfterSeconds: 0
|
|
269
399
|
})),
|
|
@@ -281,16 +411,16 @@ var be = (e) => {
|
|
|
281
411
|
"lockedUntil" = ${f},
|
|
282
412
|
"updatedAt" = ${p}
|
|
283
413
|
`;
|
|
284
|
-
}).pipe($.asVoid,
|
|
414
|
+
}).pipe($.asVoid, H("record", void 0)),
|
|
285
415
|
clearLoginFailures: (t) => $.gen(function* () {
|
|
286
416
|
yield* e`DELETE FROM "loginAttempts" WHERE email = ${t.toLowerCase()}`;
|
|
287
|
-
}).pipe($.asVoid,
|
|
417
|
+
}).pipe($.asVoid, H("clear", void 0))
|
|
288
418
|
};
|
|
289
|
-
},
|
|
419
|
+
}, $e = (e) => (t) => $.runPromise(e.send({
|
|
290
420
|
to: t.to,
|
|
291
421
|
subject: t.subject,
|
|
292
422
|
html: t.html,
|
|
293
423
|
text: t.text
|
|
294
424
|
}).pipe($.asVoid, $.orElseSucceed(() => void 0)));
|
|
295
425
|
//#endregion
|
|
296
|
-
export {
|
|
426
|
+
export { Ue as CSRF_COOKIE_NAME, We as CSRF_HEADER_NAME, ae as DEFAULT_INVITER_ROLES, ce as DEFAULT_ROLE_RANK, K as EMAIL_NOT_VERIFIED_CODE, G as EMAIL_VERIFIED_METADATA_KEY, q as EMAIL_VERIFY_RESEND_COOLDOWN_S, Le as EMAIL_VERIFY_TTL_S, we as IMPERSONATION_DEFAULT_DURATION_S, de as IMPERSONATION_FORBIDDEN_SUBPATHS, Y as IMPERSONATION_METADATA_KEY, Se as INVITATION_MAX_PENDING, _e as INVITATION_TTL_S, Re as MAGIC_LINK_TTL_S, ze as MFA_PENDING_TTL_S, Be as PASSWORD_RESET_TTL_S, e as PasswordEmptyError, t as PasswordHashError, s as SESSION_COOKIE_NAME, X as TotpVerifyError, y as UserAlreadyExistsError, x as UserNotFoundError, Oe as authRoutesPlugin, c as clearSessionCookie, z as configSessionSecrets, ee as dataStoreChallengeStore, ue as defaultCanGrantRole, V as emailVerificationActive, w as emailVerificationGuard, Je as generateChallenge, xe as generateRecoveryCodes, De as generateTotpCode, ie as generateTotpSecret, ve as getAuthSessionStrategy, me as guardSubject, le as handleAcceptInvitation, J as handleAcceptInvitationWithSignUp, Me as handleCreateInvitation, T as handleCsrf, se as handleEmailVerifyConfirm, ke as handleEmailVerifyRequest, be as handleImpersonationStart, Ee as handleImpersonationStop, Fe as handleListInvitations, pe as handleListMemberships, L as handleListSessions, R as handleMagicLinkConsume, B as handleMagicLinkRequest, A as handleMfaEnrollStart, N as handleMfaEnrollVerify, I as handleMfaRegenerateRecoveryCodes, H as handleMfaUnenroll, Ie as handleMfaVerify, D as handlePasskeyAssertOptions, Ne as handlePasskeyAssertVerify, te as handlePasskeyRegisterOptions, k as handlePasskeyRegisterVerify, E as handlePasswordResetConfirm, U as handlePasswordResetRequest, Z as handlePreviewInvitation, M as handleRevokeAllOtherSessions, Pe as handleRevokeInvitation, ne as handleRevokeSession, W as handleSignIn, j as handleSignOut, F as handleSignUp, Ce as handleSwitchTenant, n as hashPassword, Ve as hashToken, re as impersonationAuditRedactor, he as impersonationOf, Ge as isCsrfTokenWellFormed, ye as isEmailVerified, Ae as isImpersonated, Ke as issueCsrfToken, l as issueSession, P as issueUserSession, $e as mailSender, v as makeSessionRevocationChecker, O as memoryChallengeStore, _ as memoryUserStore, He as mintSecret, Q as mintToken, r as needsRehash, h as newAuthId, ge as otpauthUrl, i as parseScryptParams, Qe as postgresUserStore, u as readSession, d as readSessionKeyed, f as resolveSessionSecret, p as resolveSessionSecrets, oe as runSubjectGuards, Te as sendEmailVerification, b as sessionIdOfSubject, m as sessionSecretsOf, S as subjectFromUser, g as subjectMemberships, fe as userEmailVerified, Ye as verifyAssertion, qe as verifyCsrf, a as verifyPassword, o as verifyPasswordWithRehash, Xe as verifyRegistration, je as verifyTotpCode, C as voltroPasswordStrategy };
|
package/dist/password.d.ts
CHANGED
|
@@ -24,7 +24,8 @@ declare interface ParsedHash {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/** Parse the scrypt parameters out of a stored hash. Returns null when the
|
|
27
|
-
* string isn't a well-formed `scrypt$N$r$p$salt$derived
|
|
27
|
+
* string isn't a well-formed `scrypt$N$r$p$salt$derived`, or when its
|
|
28
|
+
* parameters exceed the derivation ceiling. */
|
|
28
29
|
export declare const parseScryptParams: (stored: string) => ParsedHash | null;
|
|
29
30
|
|
|
30
31
|
export declare class PasswordEmptyError extends PasswordEmptyError_base<{
|
package/dist/password.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { randomBytes as e, scrypt as t, timingSafeEqual as n } from "node:crypto";
|
|
2
2
|
import { Data as r, Effect as i } from "effect";
|
|
3
3
|
//#region src/password.ts
|
|
4
|
-
var a =
|
|
5
|
-
t(e, n, r,
|
|
6
|
-
|
|
4
|
+
var a = 32768, o = 8, s = 1, c = 32, l = 16, u = (e, t) => 128 * e * t * 2, d = 256 * 1024 * 1024, f = class extends r.TaggedError("PasswordEmptyError") {}, p = class extends r.TaggedError("PasswordHashError") {}, m = (e, n, r, a) => i.async((o) => {
|
|
5
|
+
t(e, n, r, {
|
|
6
|
+
...a,
|
|
7
|
+
maxmem: u(a.N, a.r)
|
|
8
|
+
}, (e, t) => {
|
|
9
|
+
o(e ? i.fail(new p({
|
|
7
10
|
message: e.message,
|
|
8
11
|
cause: e
|
|
9
12
|
})) : i.succeed(t));
|
|
10
13
|
});
|
|
11
|
-
}),
|
|
12
|
-
if (t.length === 0) return yield* i.fail(new
|
|
13
|
-
let n = e(l), r = yield*
|
|
14
|
+
}), h = (t) => i.gen(function* () {
|
|
15
|
+
if (t.length === 0) return yield* i.fail(new f({ message: "password must be non-empty" }));
|
|
16
|
+
let n = e(l), r = yield* m(t, n, c, {
|
|
14
17
|
N: a,
|
|
15
18
|
r: o,
|
|
16
19
|
p: s
|
|
@@ -23,44 +26,50 @@ var a = 16384, o = 8, s = 1, c = 32, l = 16, u = class extends r.TaggedError("Pa
|
|
|
23
26
|
n.toString("base64"),
|
|
24
27
|
r.toString("base64")
|
|
25
28
|
].join("$");
|
|
26
|
-
}),
|
|
27
|
-
let r = t
|
|
28
|
-
if (r
|
|
29
|
-
let
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
let m = Buffer.from(c, "base64"), h = Buffer.from(l, "base64"), g = yield* f(e, m, h.length, {
|
|
34
|
-
N: u,
|
|
35
|
-
r: d,
|
|
36
|
-
p
|
|
29
|
+
}), g = (e, t) => i.gen(function* () {
|
|
30
|
+
let r = _(t);
|
|
31
|
+
if (!r) return !1;
|
|
32
|
+
let { N: i, r: a, p: o, salt: s, expected: c } = r, l = yield* m(e, s, c.length, {
|
|
33
|
+
N: i,
|
|
34
|
+
r: a,
|
|
35
|
+
p: o
|
|
37
36
|
});
|
|
38
|
-
return
|
|
39
|
-
}).pipe(i.catchAll(() => i.succeed(!1))),
|
|
37
|
+
return l.length === c.length && n(l, c);
|
|
38
|
+
}).pipe(i.catchAll(() => i.succeed(!1))), _ = (e) => {
|
|
40
39
|
let t = e.split("$");
|
|
41
40
|
if (t.length !== 6) return null;
|
|
42
|
-
let [n, r, i, a, ,
|
|
41
|
+
let [n, r, i, a, o, s] = t;
|
|
43
42
|
if (n !== "scrypt") return null;
|
|
44
|
-
let
|
|
45
|
-
if (!Number.
|
|
46
|
-
let
|
|
47
|
-
return
|
|
48
|
-
N:
|
|
49
|
-
r:
|
|
50
|
-
p:
|
|
51
|
-
keyLen:
|
|
43
|
+
let c = Number(r), l = Number(i), u = Number(a);
|
|
44
|
+
if (!Number.isInteger(c) || !Number.isInteger(l) || !Number.isInteger(u) || c < 2 || l < 1 || u < 1 || 128 * c * l > d) return null;
|
|
45
|
+
let f = Buffer.from(s, "base64");
|
|
46
|
+
return f.length === 0 ? null : {
|
|
47
|
+
N: c,
|
|
48
|
+
r: l,
|
|
49
|
+
p: u,
|
|
50
|
+
keyLen: f.length,
|
|
51
|
+
salt: Buffer.from(o, "base64"),
|
|
52
|
+
expected: f
|
|
52
53
|
};
|
|
53
|
-
},
|
|
54
|
-
let t =
|
|
54
|
+
}, v = (e) => {
|
|
55
|
+
let t = _(e);
|
|
56
|
+
return t ? {
|
|
57
|
+
N: t.N,
|
|
58
|
+
r: t.r,
|
|
59
|
+
p: t.p,
|
|
60
|
+
keyLen: t.keyLen
|
|
61
|
+
} : null;
|
|
62
|
+
}, y = (e) => {
|
|
63
|
+
let t = v(e);
|
|
55
64
|
return !t || t.N !== a || t.r !== o || t.p !== s || t.keyLen !== c;
|
|
56
|
-
},
|
|
57
|
-
if (!(yield*
|
|
58
|
-
if (!
|
|
59
|
-
let n = yield*
|
|
65
|
+
}, b = (e, t) => i.gen(function* () {
|
|
66
|
+
if (!(yield* g(e, t))) return { valid: !1 };
|
|
67
|
+
if (!y(t)) return { valid: !0 };
|
|
68
|
+
let n = yield* h(e).pipe(i.orElseSucceed(() => ""));
|
|
60
69
|
return n ? {
|
|
61
70
|
valid: !0,
|
|
62
71
|
rehash: n
|
|
63
72
|
} : { valid: !0 };
|
|
64
73
|
});
|
|
65
74
|
//#endregion
|
|
66
|
-
export {
|
|
75
|
+
export { f as PasswordEmptyError, p as PasswordHashError, h as hashPassword, y as needsRehash, v as parseScryptParams, g as verifyPassword, b as verifyPasswordWithRehash };
|