@cairs-npm/express-auth-2fa 0.1.3 → 0.1.4
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.cjs +17 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -6
- package/dist/index.d.ts +15 -6
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -209,11 +209,16 @@ declare const configSchema: z.ZodObject<{
|
|
|
209
209
|
type?: string;
|
|
210
210
|
}) => boolean | Promise<boolean>>]>>;
|
|
211
211
|
/**
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
212
|
+
* 2-Step Verification switch above each user's own choice. False: password sign-in never
|
|
213
|
+
* asks for a code and the two-step setting can't be turned on. Passwordless sign-in still
|
|
214
|
+
* sends a code — it's the only factor there. Pass a function to decide per user, e.g. from
|
|
215
|
+
* an organization setting.
|
|
215
216
|
*/
|
|
216
|
-
twoStepEnabled: z.ZodDefault<z.ZodBoolean
|
|
217
|
+
twoStepEnabled: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodType<(input: {
|
|
218
|
+
userId: string;
|
|
219
|
+
}) => boolean | Promise<boolean>, z.ZodTypeDef, (input: {
|
|
220
|
+
userId: string;
|
|
221
|
+
}) => boolean | Promise<boolean>>]>>;
|
|
217
222
|
/** 2-Step Verification state for users who have not chosen one yet. */
|
|
218
223
|
twoStepDefault: z.ZodDefault<z.ZodBoolean>;
|
|
219
224
|
limits: z.ZodDefault<z.ZodObject<{
|
|
@@ -339,7 +344,9 @@ declare const configSchema: z.ZodObject<{
|
|
|
339
344
|
username: string;
|
|
340
345
|
type?: string;
|
|
341
346
|
}) => boolean | Promise<boolean>);
|
|
342
|
-
twoStepEnabled: boolean
|
|
347
|
+
twoStepEnabled: boolean | ((input: {
|
|
348
|
+
userId: string;
|
|
349
|
+
}) => boolean | Promise<boolean>);
|
|
343
350
|
twoStepDefault: boolean;
|
|
344
351
|
limits: {
|
|
345
352
|
loginMaxAttempts: number;
|
|
@@ -409,7 +416,9 @@ declare const configSchema: z.ZodObject<{
|
|
|
409
416
|
username: string;
|
|
410
417
|
type?: string;
|
|
411
418
|
}) => boolean | Promise<boolean>) | undefined;
|
|
412
|
-
twoStepEnabled?: boolean |
|
|
419
|
+
twoStepEnabled?: boolean | ((input: {
|
|
420
|
+
userId: string;
|
|
421
|
+
}) => boolean | Promise<boolean>) | undefined;
|
|
413
422
|
twoStepDefault?: boolean | undefined;
|
|
414
423
|
limits?: {
|
|
415
424
|
loginMaxAttempts?: number | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -209,11 +209,16 @@ declare const configSchema: z.ZodObject<{
|
|
|
209
209
|
type?: string;
|
|
210
210
|
}) => boolean | Promise<boolean>>]>>;
|
|
211
211
|
/**
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
212
|
+
* 2-Step Verification switch above each user's own choice. False: password sign-in never
|
|
213
|
+
* asks for a code and the two-step setting can't be turned on. Passwordless sign-in still
|
|
214
|
+
* sends a code — it's the only factor there. Pass a function to decide per user, e.g. from
|
|
215
|
+
* an organization setting.
|
|
215
216
|
*/
|
|
216
|
-
twoStepEnabled: z.ZodDefault<z.ZodBoolean
|
|
217
|
+
twoStepEnabled: z.ZodDefault<z.ZodUnion<[z.ZodBoolean, z.ZodType<(input: {
|
|
218
|
+
userId: string;
|
|
219
|
+
}) => boolean | Promise<boolean>, z.ZodTypeDef, (input: {
|
|
220
|
+
userId: string;
|
|
221
|
+
}) => boolean | Promise<boolean>>]>>;
|
|
217
222
|
/** 2-Step Verification state for users who have not chosen one yet. */
|
|
218
223
|
twoStepDefault: z.ZodDefault<z.ZodBoolean>;
|
|
219
224
|
limits: z.ZodDefault<z.ZodObject<{
|
|
@@ -339,7 +344,9 @@ declare const configSchema: z.ZodObject<{
|
|
|
339
344
|
username: string;
|
|
340
345
|
type?: string;
|
|
341
346
|
}) => boolean | Promise<boolean>);
|
|
342
|
-
twoStepEnabled: boolean
|
|
347
|
+
twoStepEnabled: boolean | ((input: {
|
|
348
|
+
userId: string;
|
|
349
|
+
}) => boolean | Promise<boolean>);
|
|
343
350
|
twoStepDefault: boolean;
|
|
344
351
|
limits: {
|
|
345
352
|
loginMaxAttempts: number;
|
|
@@ -409,7 +416,9 @@ declare const configSchema: z.ZodObject<{
|
|
|
409
416
|
username: string;
|
|
410
417
|
type?: string;
|
|
411
418
|
}) => boolean | Promise<boolean>) | undefined;
|
|
412
|
-
twoStepEnabled?: boolean |
|
|
419
|
+
twoStepEnabled?: boolean | ((input: {
|
|
420
|
+
userId: string;
|
|
421
|
+
}) => boolean | Promise<boolean>) | undefined;
|
|
413
422
|
twoStepDefault?: boolean | undefined;
|
|
414
423
|
limits?: {
|
|
415
424
|
loginMaxAttempts?: number | undefined;
|
package/dist/index.js
CHANGED
|
@@ -100,11 +100,15 @@ var configSchema = z.object({
|
|
|
100
100
|
)
|
|
101
101
|
]).default(false),
|
|
102
102
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
103
|
+
* 2-Step Verification switch above each user's own choice. False: password sign-in never
|
|
104
|
+
* asks for a code and the two-step setting can't be turned on. Passwordless sign-in still
|
|
105
|
+
* sends a code — it's the only factor there. Pass a function to decide per user, e.g. from
|
|
106
|
+
* an organization setting.
|
|
106
107
|
*/
|
|
107
|
-
twoStepEnabled: z.
|
|
108
|
+
twoStepEnabled: z.union([
|
|
109
|
+
z.boolean(),
|
|
110
|
+
z.custom((v) => typeof v === "function")
|
|
111
|
+
]).default(true),
|
|
108
112
|
/** 2-Step Verification state for users who have not chosen one yet. */
|
|
109
113
|
twoStepDefault: z.boolean().default(false),
|
|
110
114
|
limits: limitSchema.default({}),
|
|
@@ -305,6 +309,12 @@ async function migrate(db, prefix = "auth_", auditDays = 365) {
|
|
|
305
309
|
return c;
|
|
306
310
|
}
|
|
307
311
|
|
|
312
|
+
// src/config/twoStep.ts
|
|
313
|
+
async function twoStepAvailableFor(config, userId) {
|
|
314
|
+
const v = config.twoStepEnabled;
|
|
315
|
+
return typeof v === "function" ? Boolean(await v({ userId })) : v;
|
|
316
|
+
}
|
|
317
|
+
|
|
308
318
|
// src/middleware/errors.ts
|
|
309
319
|
import { ZodError } from "zod";
|
|
310
320
|
var ApiErrorException = class extends Error {
|
|
@@ -561,14 +571,14 @@ var MethodService = class {
|
|
|
561
571
|
const cred = await this.cols.credentials.findOne({ userId });
|
|
562
572
|
const docs = await this.cols.methods.find({ userId, status: "active" }).toArray();
|
|
563
573
|
const methods = docs.sort((a, b) => Number(b.isDefault) - Number(a.isDefault) || a.createdAt.getTime() - b.createdAt.getTime()).map(toApiMethod);
|
|
564
|
-
const available = this.config
|
|
574
|
+
const available = await twoStepAvailableFor(this.config, userId);
|
|
565
575
|
const twoStepEnabled = available && (cred?.twoStepEnabled ?? this.config.twoStepDefault);
|
|
566
576
|
return { twoStepEnabled, twoStepAvailable: available, methods };
|
|
567
577
|
}
|
|
568
578
|
/** BR-15 — enable needs ≥1 active method; disable needs step-up + revokes trusted devices. */
|
|
569
579
|
async setTwoStep(userId, sid, enabled, stepUpToken) {
|
|
570
580
|
const now = this.config.clock();
|
|
571
|
-
if (enabled && !this.config
|
|
581
|
+
if (enabled && !await twoStepAvailableFor(this.config, userId)) {
|
|
572
582
|
throw apiError(409, "VALIDATION_ERROR", "2-Step Verification is turned off for this application.");
|
|
573
583
|
}
|
|
574
584
|
if (enabled) {
|
|
@@ -810,7 +820,7 @@ var AuthService = class {
|
|
|
810
820
|
throw apiError(423, "LOCKED", "Too many attempts. Try again later.", { retryAt: cred.lockedUntil });
|
|
811
821
|
}
|
|
812
822
|
await this.resetFailedLogins(cred, now);
|
|
813
|
-
const twoStep =
|
|
823
|
+
const twoStep = cred.twoStepEnabled && await twoStepAvailableFor(this.config, user.id);
|
|
814
824
|
const trustedOk = twoStep && await this.checkTrustedDevice(req, user.id);
|
|
815
825
|
if (!twoStep || trustedOk) {
|
|
816
826
|
await this.audit.record(user.id, "login_success", ctx);
|