@cairs-npm/express-auth-2fa 0.1.3 → 0.1.5
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 +21 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -246
- package/dist/index.d.ts +31 -246
- package/dist/index.js +21 -11
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -100,23 +100,27 @@ 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
|
-
limits: limitSchema.
|
|
114
|
+
limits: limitSchema.prefault({}),
|
|
111
115
|
/**
|
|
112
116
|
* Set false to turn off every RATE_LIMITED check: the per-IP limits on login / code
|
|
113
117
|
* verify / send / step-up and the code-send cooldown and caps. Account lockouts after
|
|
114
118
|
* failed passwords or codes (LOCKED) still apply.
|
|
115
119
|
*/
|
|
116
120
|
rateLimits: z.boolean().default(true),
|
|
117
|
-
argon2: argon2Schema.
|
|
118
|
-
cookies: cookieSchema.
|
|
119
|
-
ttl: ttlSchema.
|
|
121
|
+
argon2: argon2Schema.prefault({}),
|
|
122
|
+
cookies: cookieSchema.prefault({}),
|
|
123
|
+
ttl: ttlSchema.prefault({}),
|
|
120
124
|
/** Serve GET /auth/openapi.json (A.7 docs). */
|
|
121
125
|
exposeDocs: z.boolean().default(false)
|
|
122
126
|
});
|
|
@@ -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);
|