@cairs-npm/express-auth-2fa 0.1.2 → 0.1.3

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 CHANGED
@@ -185,6 +185,12 @@ var configSchema = import_zod.z.object({
185
185
  (v) => typeof v === "function"
186
186
  )
187
187
  ]).default(false),
188
+ /**
189
+ * Project-wide 2-Step Verification switch. False: password sign-in never asks for a code
190
+ * (whatever each user chose) and the two-step setting can't be turned on. Passwordless
191
+ * sign-in still sends a code — it's the only factor there.
192
+ */
193
+ twoStepEnabled: import_zod.z.boolean().default(true),
188
194
  /** 2-Step Verification state for users who have not chosen one yet. */
189
195
  twoStepDefault: import_zod.z.boolean().default(false),
190
196
  limits: limitSchema.default({}),
@@ -647,11 +653,16 @@ var MethodService = class {
647
653
  const cred = await this.cols.credentials.findOne({ userId });
648
654
  const docs = await this.cols.methods.find({ userId, status: "active" }).toArray();
649
655
  const methods = docs.sort((a, b) => Number(b.isDefault) - Number(a.isDefault) || a.createdAt.getTime() - b.createdAt.getTime()).map(toApiMethod);
650
- return { twoStepEnabled: cred?.twoStepEnabled ?? this.config.twoStepDefault, methods };
656
+ const available = this.config.twoStepEnabled;
657
+ const twoStepEnabled = available && (cred?.twoStepEnabled ?? this.config.twoStepDefault);
658
+ return { twoStepEnabled, twoStepAvailable: available, methods };
651
659
  }
652
660
  /** BR-15 — enable needs ≥1 active method; disable needs step-up + revokes trusted devices. */
653
661
  async setTwoStep(userId, sid, enabled, stepUpToken) {
654
662
  const now = this.config.clock();
663
+ if (enabled && !this.config.twoStepEnabled) {
664
+ throw apiError(409, "VALIDATION_ERROR", "2-Step Verification is turned off for this application.");
665
+ }
655
666
  if (enabled) {
656
667
  await ensureEmailMethod(this.config, this.cols, userId);
657
668
  const count = await this.cols.methods.countDocuments({ userId, status: "active" });
@@ -891,8 +902,9 @@ var AuthService = class {
891
902
  throw apiError(423, "LOCKED", "Too many attempts. Try again later.", { retryAt: cred.lockedUntil });
892
903
  }
893
904
  await this.resetFailedLogins(cred, now);
894
- const trustedOk = cred.twoStepEnabled && await this.checkTrustedDevice(req, user.id);
895
- if (!cred.twoStepEnabled || trustedOk) {
905
+ const twoStep = this.config.twoStepEnabled && cred.twoStepEnabled;
906
+ const trustedOk = twoStep && await this.checkTrustedDevice(req, user.id);
907
+ if (!twoStep || trustedOk) {
896
908
  await this.audit.record(user.id, "login_success", ctx);
897
909
  return this.authenticate(user.id, req, res, ["pwd"], { rememberMe: input.rememberMe });
898
910
  }