@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.cjs
CHANGED
|
@@ -186,23 +186,27 @@ var configSchema = import_zod.z.object({
|
|
|
186
186
|
)
|
|
187
187
|
]).default(false),
|
|
188
188
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
189
|
+
* 2-Step Verification switch above each user's own choice. False: password sign-in never
|
|
190
|
+
* asks for a code and the two-step setting can't be turned on. Passwordless sign-in still
|
|
191
|
+
* sends a code — it's the only factor there. Pass a function to decide per user, e.g. from
|
|
192
|
+
* an organization setting.
|
|
192
193
|
*/
|
|
193
|
-
twoStepEnabled: import_zod.z.
|
|
194
|
+
twoStepEnabled: import_zod.z.union([
|
|
195
|
+
import_zod.z.boolean(),
|
|
196
|
+
import_zod.z.custom((v) => typeof v === "function")
|
|
197
|
+
]).default(true),
|
|
194
198
|
/** 2-Step Verification state for users who have not chosen one yet. */
|
|
195
199
|
twoStepDefault: import_zod.z.boolean().default(false),
|
|
196
|
-
limits: limitSchema.
|
|
200
|
+
limits: limitSchema.prefault({}),
|
|
197
201
|
/**
|
|
198
202
|
* Set false to turn off every RATE_LIMITED check: the per-IP limits on login / code
|
|
199
203
|
* verify / send / step-up and the code-send cooldown and caps. Account lockouts after
|
|
200
204
|
* failed passwords or codes (LOCKED) still apply.
|
|
201
205
|
*/
|
|
202
206
|
rateLimits: import_zod.z.boolean().default(true),
|
|
203
|
-
argon2: argon2Schema.
|
|
204
|
-
cookies: cookieSchema.
|
|
205
|
-
ttl: ttlSchema.
|
|
207
|
+
argon2: argon2Schema.prefault({}),
|
|
208
|
+
cookies: cookieSchema.prefault({}),
|
|
209
|
+
ttl: ttlSchema.prefault({}),
|
|
206
210
|
/** Serve GET /auth/openapi.json (A.7 docs). */
|
|
207
211
|
exposeDocs: import_zod.z.boolean().default(false)
|
|
208
212
|
});
|
|
@@ -391,6 +395,12 @@ async function migrate(db, prefix = "auth_", auditDays = 365) {
|
|
|
391
395
|
return c;
|
|
392
396
|
}
|
|
393
397
|
|
|
398
|
+
// src/config/twoStep.ts
|
|
399
|
+
async function twoStepAvailableFor(config, userId) {
|
|
400
|
+
const v = config.twoStepEnabled;
|
|
401
|
+
return typeof v === "function" ? Boolean(await v({ userId })) : v;
|
|
402
|
+
}
|
|
403
|
+
|
|
394
404
|
// src/services/auth.service.ts
|
|
395
405
|
init_hash();
|
|
396
406
|
|
|
@@ -653,14 +663,14 @@ var MethodService = class {
|
|
|
653
663
|
const cred = await this.cols.credentials.findOne({ userId });
|
|
654
664
|
const docs = await this.cols.methods.find({ userId, status: "active" }).toArray();
|
|
655
665
|
const methods = docs.sort((a, b) => Number(b.isDefault) - Number(a.isDefault) || a.createdAt.getTime() - b.createdAt.getTime()).map(toApiMethod);
|
|
656
|
-
const available = this.config
|
|
666
|
+
const available = await twoStepAvailableFor(this.config, userId);
|
|
657
667
|
const twoStepEnabled = available && (cred?.twoStepEnabled ?? this.config.twoStepDefault);
|
|
658
668
|
return { twoStepEnabled, twoStepAvailable: available, methods };
|
|
659
669
|
}
|
|
660
670
|
/** BR-15 — enable needs ≥1 active method; disable needs step-up + revokes trusted devices. */
|
|
661
671
|
async setTwoStep(userId, sid, enabled, stepUpToken) {
|
|
662
672
|
const now = this.config.clock();
|
|
663
|
-
if (enabled && !this.config
|
|
673
|
+
if (enabled && !await twoStepAvailableFor(this.config, userId)) {
|
|
664
674
|
throw apiError(409, "VALIDATION_ERROR", "2-Step Verification is turned off for this application.");
|
|
665
675
|
}
|
|
666
676
|
if (enabled) {
|
|
@@ -902,7 +912,7 @@ var AuthService = class {
|
|
|
902
912
|
throw apiError(423, "LOCKED", "Too many attempts. Try again later.", { retryAt: cred.lockedUntil });
|
|
903
913
|
}
|
|
904
914
|
await this.resetFailedLogins(cred, now);
|
|
905
|
-
const twoStep =
|
|
915
|
+
const twoStep = cred.twoStepEnabled && await twoStepAvailableFor(this.config, user.id);
|
|
906
916
|
const trustedOk = twoStep && await this.checkTrustedDevice(req, user.id);
|
|
907
917
|
if (!twoStep || trustedOk) {
|
|
908
918
|
await this.audit.record(user.id, "login_success", ctx);
|