@fonderie/auth 2.0.0 → 3.0.0

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.d.cts CHANGED
@@ -2,8 +2,8 @@ export { IMfaChallenge, ISession, IUser } from './types.cjs';
2
2
  import { IFonderieModule, IFonderieApp } from '@fonderie/core';
3
3
  import { IStoreAdapter } from '@fonderie/store';
4
4
  import { EventBus } from '@fonderie/events';
5
- import { I as IAuthConfig } from './session-DbtCnbiG.cjs';
6
- export { A as AUTH_CONFIG_KEYS, a as AuthLimitedRoute, b as AuthMessageKey, c as IAuthRateLimitConfig, d as IAuthRuntimeConfig, e as IAuthSecrets, M as MESSAGE_KEYS, f as buildAuthAccountLimiter, g as buildAuthIpLimiter, w as withSession } from './session-DbtCnbiG.cjs';
5
+ import { I as IAuthConfig } from './session-BoJjRB7t.cjs';
6
+ export { A as AUTH_CONFIG_KEYS, a as AuthLimitedRoute, b as AuthMessageKey, c as IAuthRateLimitConfig, d as IAuthRuntimeConfig, e as IAuthSecrets, M as MESSAGE_KEYS, f as buildAuthAccountLimiter, g as buildAuthIpLimiter, w as withSession } from './session-BoJjRB7t.cjs';
7
7
  export { IUserDTO, toUserDTO } from './dtos/user.cjs';
8
8
  export { requireAuth, validate } from '@fonderie/core/middlewares';
9
9
  import { z } from 'zod';
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ export { IMfaChallenge, ISession, IUser } from './types.js';
2
2
  import { IFonderieModule, IFonderieApp } from '@fonderie/core';
3
3
  import { IStoreAdapter } from '@fonderie/store';
4
4
  import { EventBus } from '@fonderie/events';
5
- import { I as IAuthConfig } from './session-DbtCnbiG.js';
6
- export { A as AUTH_CONFIG_KEYS, a as AuthLimitedRoute, b as AuthMessageKey, c as IAuthRateLimitConfig, d as IAuthRuntimeConfig, e as IAuthSecrets, M as MESSAGE_KEYS, f as buildAuthAccountLimiter, g as buildAuthIpLimiter, w as withSession } from './session-DbtCnbiG.js';
5
+ import { I as IAuthConfig } from './session-BoJjRB7t.js';
6
+ export { A as AUTH_CONFIG_KEYS, a as AuthLimitedRoute, b as AuthMessageKey, c as IAuthRateLimitConfig, d as IAuthRuntimeConfig, e as IAuthSecrets, M as MESSAGE_KEYS, f as buildAuthAccountLimiter, g as buildAuthIpLimiter, w as withSession } from './session-BoJjRB7t.js';
7
7
  export { IUserDTO, toUserDTO } from './dtos/user.js';
8
8
  export { requireAuth, validate } from '@fonderie/core/middlewares';
9
9
  import { z } from 'zod';
package/dist/index.js CHANGED
@@ -718,6 +718,7 @@ function mfaController(store, config, issuer, bus) {
718
718
  await users.confirmMfaSecret(ctx.user.id);
719
719
  bus?.emit(NOTIFICATION_EVENT, {
720
720
  type: MESSAGE_KEYS.mfaEnabled,
721
+ locale: ctx.user.locale,
721
722
  data: {},
722
723
  recipient: { email: ctx.user.email, phone: null, deviceToken: null }
723
724
  }).catch(() => {
@@ -809,6 +810,7 @@ function mfaController(store, config, issuer, bus) {
809
810
  await backupCodes.replace(ctx.user.id, codeHashes);
810
811
  bus?.emit(NOTIFICATION_EVENT, {
811
812
  type: MESSAGE_KEYS.mfaBackupCodesRegenerated,
813
+ locale: ctx.user.locale,
812
814
  data: {},
813
815
  recipient: { email: ctx.user.email, phone: null, deviceToken: null }
814
816
  }).catch(() => {
@@ -835,6 +837,7 @@ function mfaController(store, config, issuer, bus) {
835
837
  await Promise.all([users.disableMfa(ctx.user.id), backupCodes.deleteByUser(ctx.user.id)]);
836
838
  bus?.emit(NOTIFICATION_EVENT, {
837
839
  type: MESSAGE_KEYS.mfaDisabled,
840
+ locale: user.locale,
838
841
  data: {},
839
842
  recipient: { email: user.email, phone: null, deviceToken: null }
840
843
  }).catch(() => {
@@ -1082,6 +1085,7 @@ function authController(store, config, bus) {
1082
1085
  NOTIFICATION_EVENT2,
1083
1086
  {
1084
1087
  type: MESSAGE_KEYS.emailRegistration,
1088
+ locale: user.locale,
1085
1089
  data: { pin, firstName: firstName ?? "" },
1086
1090
  recipient: { email: normalizedEmail, phone: null, deviceToken: null }
1087
1091
  },
@@ -1145,6 +1149,7 @@ function authController(store, config, bus) {
1145
1149
  NOTIFICATION_EVENT2,
1146
1150
  {
1147
1151
  type: MESSAGE_KEYS.phoneOtp,
1152
+ locale: user.locale,
1148
1153
  data: { otp },
1149
1154
  recipient: { email: null, phone: normalizePhone(phone2), deviceToken: null }
1150
1155
  },
@@ -1257,6 +1262,7 @@ function authController(store, config, bus) {
1257
1262
  await phoneVerif.upsert(user.id, normalizePhone(phone2), otp, expiresAt);
1258
1263
  bus?.emit(NOTIFICATION_EVENT2, {
1259
1264
  type: MESSAGE_KEYS.phoneOtp,
1265
+ locale: user.locale,
1260
1266
  data: { otp },
1261
1267
  recipient: { email: null, phone: normalizePhone(phone2), deviceToken: null }
1262
1268
  }).catch(() => {
@@ -1371,6 +1377,7 @@ function authController(store, config, bus) {
1371
1377
  await passwordReset.create(user.id, pin, expiresAt);
1372
1378
  bus?.emit(NOTIFICATION_EVENT2, {
1373
1379
  type: MESSAGE_KEYS.passwordReset,
1380
+ locale: user.locale,
1374
1381
  recipient: { email: email2, phone: null, deviceToken: null },
1375
1382
  data: { pin }
1376
1383
  }).catch(() => {
@@ -1537,6 +1544,7 @@ function authController(store, config, bus) {
1537
1544
  await phoneVerif.upsert(ctx.user.id, phone2, otp, expiresAt2);
1538
1545
  bus?.emit(NOTIFICATION_EVENT2, {
1539
1546
  type: MESSAGE_KEYS.phoneOtp,
1547
+ locale: ctx.user.locale,
1540
1548
  data: { otp },
1541
1549
  recipient: { email: null, phone: phone2, deviceToken: null }
1542
1550
  }).catch(() => {
@@ -1576,6 +1584,7 @@ function authController(store, config, bus) {
1576
1584
  await emailVerif.replace(ctx.user.id, pin, expiresAt);
1577
1585
  bus?.emit(NOTIFICATION_EVENT2, {
1578
1586
  type: MESSAGE_KEYS.emailVerification,
1587
+ locale: ctx.user.locale,
1579
1588
  recipient: { email: ctx.user.email, phone: null, deviceToken: null },
1580
1589
  data: { pin }
1581
1590
  }).catch(() => {
@@ -1687,6 +1696,7 @@ function userController(store, config, bus) {
1687
1696
  await users.updateEmail(ctx.user.id, normalised);
1688
1697
  bus?.emit(NOTIFICATION_EVENT3, {
1689
1698
  type: MESSAGE_KEYS.emailVerification,
1699
+ locale: ctx.user.locale,
1690
1700
  data: { pin },
1691
1701
  recipient: { email: normalised, phone: null, deviceToken: null }
1692
1702
  }).catch(() => {
@@ -1694,6 +1704,7 @@ function userController(store, config, bus) {
1694
1704
  if (oldEmail) {
1695
1705
  bus?.emit(NOTIFICATION_EVENT3, {
1696
1706
  type: MESSAGE_KEYS.emailChanged,
1707
+ locale: ctx.user.locale,
1697
1708
  data: { newEmail: normalised },
1698
1709
  recipient: { email: oldEmail, phone: null, deviceToken: null }
1699
1710
  }).catch(() => {
@@ -1729,6 +1740,7 @@ function userController(store, config, bus) {
1729
1740
  await users.updatePhone(ctx.user.id, normalised);
1730
1741
  bus?.emit(NOTIFICATION_EVENT3, {
1731
1742
  type: MESSAGE_KEYS.phoneOtp,
1743
+ locale: ctx.user.locale,
1732
1744
  data: { otp },
1733
1745
  recipient: { email: null, phone: normalised, deviceToken: null }
1734
1746
  }).catch(() => {
@@ -1736,6 +1748,7 @@ function userController(store, config, bus) {
1736
1748
  if (ctx.user.email) {
1737
1749
  bus?.emit(NOTIFICATION_EVENT3, {
1738
1750
  type: MESSAGE_KEYS.phoneChanged,
1751
+ locale: ctx.user.locale,
1739
1752
  data: {},
1740
1753
  recipient: { email: ctx.user.email, phone: null, deviceToken: null }
1741
1754
  }).catch(() => {
@@ -1904,44 +1917,42 @@ function buildAuthRoutes(store, config, bus) {
1904
1917
  const passthrough = (_ctx, next) => next();
1905
1918
  const ipLimit = (route) => buildAuthIpLimiter(route, store, config.rateLimit) ?? passthrough;
1906
1919
  const acctLimit = (route) => buildAuthAccountLimiter(route, store, config.rateLimit) ?? passthrough;
1920
+ const R = (id, method, path, ...handlers) => {
1921
+ const o = config.routes?.[id];
1922
+ if (!o) return [method, path, ...handlers];
1923
+ if (typeof o === "string") return [method, o, ...handlers];
1924
+ return [o.method ?? method, o.path ?? path, ...handlers];
1925
+ };
1907
1926
  const routes = [
1908
1927
  // Registration & Login (Public)
1909
- ["POST", "/auth/register", ipLimit("register"), validate(registerSchema), auth.register],
1910
- ["POST", "/auth/login", ipLimit("login"), validate(loginSchema), acctLimit("login"), auth.login],
1928
+ R("register", "POST", "/auth/register", ipLimit("register"), validate(registerSchema), auth.register),
1929
+ R("login", "POST", "/auth/login", ipLimit("login"), validate(loginSchema), acctLimit("login"), auth.login),
1911
1930
  // Token Management (Public)
1912
- ["POST", "/auth/refresh", validate(refreshSchema), auth.refresh],
1931
+ R("refresh", "POST", "/auth/refresh", validate(refreshSchema), auth.refresh),
1913
1932
  // Email — Password Recovery (Public)
1914
- ["POST", "/auth/email/forgot", ipLimit("forgot"), validate(forgotPasswordSchema), acctLimit("forgot"), auth.forgotPassword],
1915
- ["POST", "/auth/email/reset", validate(resetPasswordSchema), auth.resetPassword],
1933
+ R("forgotPassword", "POST", "/auth/email/forgot", ipLimit("forgot"), validate(forgotPasswordSchema), acctLimit("forgot"), auth.forgotPassword),
1934
+ R("resetPassword", "POST", "/auth/email/reset", validate(resetPasswordSchema), auth.resetPassword),
1916
1935
  // Verification (Protected — email or phone, determined by loginMethod)
1917
- ["POST", "/auth/verify", requireAuth, validate(verifySchema), auth.verify],
1918
- ["GET", "/auth/send-verification", requireAuth, auth.sendVerification],
1936
+ R("verifyEmail", "POST", "/auth/verify", requireAuth, validate(verifySchema), auth.verify),
1937
+ R("sendVerification", "GET", "/auth/send-verification", requireAuth, auth.sendVerification),
1919
1938
  // Account Management (Protected)
1920
- ["POST", "/auth/logout", requireAuth, validate(refreshSchema), auth.logout],
1939
+ R("logout", "POST", "/auth/logout", requireAuth, validate(refreshSchema), auth.logout),
1921
1940
  // User Profile (Protected; writes also gate on requireVerification)
1922
- ["GET", "/users", requireAuth, user.me],
1923
- ["PUT", "/users/profile", requireAuth, verifyGate, validate(updateProfileSchema), user.updateProfile],
1924
- ["PUT", "/users/preferences", requireAuth, verifyGate, validate(updatePreferencesSchema), user.updatePreferences],
1925
- ["PUT", "/users/email", requireAuth, verifyGate, validate(updateEmailSchema), user.updateEmail],
1926
- ["PUT", "/users/phone", requireAuth, verifyGate, validate(updatePhoneSchema), user.updatePhone],
1927
- ["PUT", "/users/password", requireAuth, validate(changePasswordSchema), user.changePassword],
1928
- ["DELETE", "/users", requireAuth, verifyGate, user.deleteMe],
1941
+ R("me", "GET", "/users", requireAuth, user.me),
1942
+ R("updateProfile", "PUT", "/users/profile", requireAuth, verifyGate, validate(updateProfileSchema), user.updateProfile),
1943
+ R("updatePreferences", "PUT", "/users/preferences", requireAuth, verifyGate, validate(updatePreferencesSchema), user.updatePreferences),
1944
+ R("updateEmail", "PUT", "/users/email", requireAuth, verifyGate, validate(updateEmailSchema), user.updateEmail),
1945
+ R("updatePhone", "PUT", "/users/phone", requireAuth, verifyGate, validate(updatePhoneSchema), user.updatePhone),
1946
+ R("changePassword", "PUT", "/users/password", requireAuth, validate(changePasswordSchema), user.changePassword),
1947
+ R("deleteMe", "DELETE", "/users", requireAuth, verifyGate, user.deleteMe),
1929
1948
  // MFA (email sessions only — requireVerified is always enforced here
1930
1949
  // because MFA is a security feature and email verification is meaningful)
1931
- ["POST", "/auth/mfa/setup", requireAuth, requireEmailLogin, requireVerified, mfa.setup],
1950
+ R("mfaSetup", "POST", "/auth/mfa/setup", requireAuth, requireEmailLogin, requireVerified, mfa.setup),
1932
1951
  // /auth/mfa/verify accepts both mfaPending tokens (TOTP/backup-code login)
1933
1952
  // and full tokens (setup confirmation), so requireAnyAuth is used here.
1934
- ["POST", "/auth/mfa/verify", ipLimit("mfaVerify"), requireAnyAuth, requireEmailLogin, requireVerified, validate(mfaTokenSchema), mfa.verify],
1935
- ["POST", "/auth/mfa/disable", requireAuth, requireEmailLogin, requireVerified, validate(mfaTokenSchema), mfa.disable],
1936
- [
1937
- "POST",
1938
- "/auth/mfa/backup-codes",
1939
- requireAuth,
1940
- requireEmailLogin,
1941
- requireVerified,
1942
- validate(mfaTokenSchema),
1943
- mfa.regenerateBackupCodes
1944
- ]
1953
+ R("mfaVerify", "POST", "/auth/mfa/verify", ipLimit("mfaVerify"), requireAnyAuth, requireEmailLogin, requireVerified, validate(mfaTokenSchema), mfa.verify),
1954
+ R("mfaDisable", "POST", "/auth/mfa/disable", requireAuth, requireEmailLogin, requireVerified, validate(mfaTokenSchema), mfa.disable),
1955
+ R("mfaBackupCodes", "POST", "/auth/mfa/backup-codes", requireAuth, requireEmailLogin, requireVerified, validate(mfaTokenSchema), mfa.regenerateBackupCodes)
1945
1956
  ];
1946
1957
  if (config.providers.includes("google")) {
1947
1958
  routes.push(