@fonderie/auth 5.0.2 → 5.0.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.js CHANGED
@@ -292,7 +292,8 @@ function verifyToken(token, config) {
292
292
  }
293
293
 
294
294
  // src/services/mfa.ts
295
- import { createHmac, randomBytes, timingSafeEqual } from "crypto";
295
+ import { createHmac, randomBytes } from "crypto";
296
+ import { constantTimeEqual } from "@fonderie/core";
296
297
  var STEP = 30;
297
298
  var DRIFT = 1;
298
299
  var DIGITS = 6;
@@ -363,16 +364,10 @@ function generateTotpUri(email2, secret, issuer) {
363
364
  });
364
365
  return `otpauth://totp/${encodeURIComponent(issuer)}:${encodeURIComponent(email2)}?${params}`;
365
366
  }
366
- function safeCodeEqual(a, b) {
367
- const bufA = Buffer.from(a);
368
- const bufB = Buffer.from(b);
369
- if (bufA.length !== bufB.length) return false;
370
- return timingSafeEqual(bufA, bufB);
371
- }
372
367
  function verifyTotpToken(token, secret) {
373
368
  const t = timeCounter();
374
369
  for (let i = -DRIFT; i <= DRIFT; i++) {
375
- if (safeCodeEqual(hotp(secret, t + i), token)) {
370
+ if (constantTimeEqual(hotp(secret, t + i), token)) {
376
371
  return true;
377
372
  }
378
373
  }
@@ -421,7 +416,7 @@ function makeMfaCipher(keyHex) {
421
416
  }
422
417
 
423
418
  // src/dtos/user.ts
424
- import { stringOrEmpty, booleanOrFalse } from "@fonderie/core";
419
+ import { stringOrEmpty, booleanOrFalse, dateOrEmpty } from "@fonderie/core";
425
420
  var DEFAULT_PREFERENCES = {
426
421
  locale: "en-US",
427
422
  timezone: "UTC",
@@ -459,7 +454,7 @@ function toUserDTO(user, phoneVerified = false) {
459
454
  phone: stringOrEmpty(user.phone),
460
455
  profileImageUrl: stringOrEmpty(user.profileImageUrl),
461
456
  isActive: typeof user.isActive === "boolean" ? user.isActive : true,
462
- lastLogin: user.lastLogin instanceof Date ? user.lastLogin.toISOString() : "",
457
+ lastLogin: dateOrEmpty(user.lastLogin),
463
458
  preferences: {
464
459
  ...DEFAULT_PREFERENCES,
465
460
  ...cleaned,
@@ -476,8 +471,8 @@ function toUserDTO(user, phoneVerified = false) {
476
471
  suspended: booleanOrFalse(user.suspended),
477
472
  whitelist: booleanOrFalse(user.whitelist),
478
473
  ipWhitelist: Array.isArray(user.ipWhitelist) ? user.ipWhitelist : [],
479
- createdAt: user.createdAt instanceof Date ? user.createdAt.toISOString() : "",
480
- updatedAt: user.updatedAt instanceof Date ? user.updatedAt.toISOString() : ""
474
+ createdAt: dateOrEmpty(user.createdAt),
475
+ updatedAt: dateOrEmpty(user.updatedAt)
481
476
  };
482
477
  }
483
478
 
@@ -1715,7 +1710,7 @@ function authController(store, config, bus) {
1715
1710
 
1716
1711
  // src/controllers/user.controller.ts
1717
1712
  import { randomInt as randomInt2 } from "crypto";
1718
- import { setApiResponse as setApiResponse4, HTTP as HTTP4 } from "@fonderie/core";
1713
+ import { setApiResponse as setApiResponse4, HTTP as HTTP4, dateOrEmpty as dateOrEmpty2 } from "@fonderie/core";
1719
1714
  import { NOTIFICATION_EVENT as NOTIFICATION_EVENT3 } from "@fonderie/events";
1720
1715
  function normalizePhone2(phone2) {
1721
1716
  return phone2.trim().replace(/[\s()\-\.]/g, "");
@@ -1935,8 +1930,8 @@ function userController(store, config, bus) {
1935
1930
  id: s.id,
1936
1931
  userAgent: s.userAgent,
1937
1932
  ipAddress: s.ipAddress,
1938
- createdAt: s.createdAt instanceof Date ? s.createdAt.toISOString() : s.createdAt,
1939
- expiresAt: s.expiresAt instanceof Date ? s.expiresAt.toISOString() : s.expiresAt
1933
+ createdAt: dateOrEmpty2(s.createdAt),
1934
+ expiresAt: dateOrEmpty2(s.expiresAt)
1940
1935
  })),
1941
1936
  security: {
1942
1937
  mfaEnabled: user.mfaEnabled === true,
@@ -2120,19 +2115,19 @@ function buildAuthRoutes(store, config, bus) {
2120
2115
  }
2121
2116
 
2122
2117
  // src/services/config-guard.ts
2118
+ import { MIN_SECRET_LENGTH, PLACEHOLDER_SECRET, secretStrengthProblem } from "@fonderie/core";
2123
2119
  var MODULE = "@fonderie/auth";
2124
- var PLACEHOLDER_SECRET = /dev-secret|test-secret|changeme|change-me|your[-_]secret|placeholder|example|insecure|min-32-chars/i;
2125
- var MIN_SECRET_LENGTH = 32;
2126
2120
  function collectAuthConfigProblems(config) {
2127
2121
  const problems = [];
2128
2122
  const secret = config.jwtSecret ?? "";
2129
- if (secret.length < MIN_SECRET_LENGTH) {
2123
+ const secretProblem = secretStrengthProblem(secret);
2124
+ if (secretProblem === "too-short") {
2130
2125
  problems.push({
2131
2126
  module: MODULE,
2132
2127
  severity: "error",
2133
2128
  message: `jwtSecret must be at least ${MIN_SECRET_LENGTH} characters (got ${secret.length})`
2134
2129
  });
2135
- } else if (PLACEHOLDER_SECRET.test(secret)) {
2130
+ } else if (secretProblem === "placeholder") {
2136
2131
  problems.push({
2137
2132
  module: MODULE,
2138
2133
  severity: "error",