najm-auth 2.0.14 → 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.js CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/AuthPlugin.ts
9
- import { Err as Err13, plugin } from "najm-core";
9
+ import { Err as Err15, plugin } from "najm-core";
10
10
  import { cache } from "najm-cache";
11
11
 
12
12
  // src/auth.tokens.ts
@@ -102,6 +102,17 @@ var credentialSetupSessionsTable = pgTable("credential_setup_sessions", {
102
102
  userPurposeIdx: index("credential_setup_sessions_user_purpose_idx").on(table.userId, table.purpose),
103
103
  expiresAtIdx: index("credential_setup_sessions_expires_at_idx").on(table.expiresAt)
104
104
  }));
105
+ var credentialSetupRequirementsTable = pgTable("credential_setup_requirements", {
106
+ userId: text("user_id").references(() => usersTable.id, { onDelete: "cascade" }).notNull(),
107
+ purpose: text("purpose").notNull(),
108
+ temporaryCredentialKind: text("temporary_credential_kind"),
109
+ required: boolean("required").default(true).notNull(),
110
+ completedAt: timestamp("completed_at", { mode: "string" }),
111
+ createdAt: timestamp("created_at", { mode: "string" }).defaultNow(),
112
+ updatedAt: timestamp("updated_at", { mode: "string" }).defaultNow().$onUpdate(() => sql`CURRENT_TIMESTAMP`)
113
+ }, (table) => ({
114
+ pk: primaryKey({ columns: [table.userId, table.purpose] })
115
+ }));
105
116
  var rolePermissionsTable = pgTable("role_permissions", {
106
117
  roleId: text("role_id").notNull().references(() => rolesTable.id, { onDelete: "cascade" }),
107
118
  permissionId: text("permission_id").notNull().references(() => permissionsTable.id, { onDelete: "cascade" }),
@@ -114,13 +125,14 @@ var authSchema = {
114
125
  oauthAccounts: oauthAccountsTable,
115
126
  tokens: tokensTable,
116
127
  credentialSetupSessions: credentialSetupSessionsTable,
128
+ credentialSetupRequirements: credentialSetupRequirementsTable,
117
129
  roles: rolesTable,
118
130
  permissions: permissionsTable,
119
131
  rolePermissions: rolePermissionsTable
120
132
  };
121
133
 
122
134
  // src/schema/sqlite.ts
123
- import { sqliteTable, text as text2, integer as integer2, uniqueIndex as uniqueIndex2, index as index2 } from "drizzle-orm/sqlite-core";
135
+ import { sqliteTable, text as text2, integer as integer2, primaryKey as primaryKey2, uniqueIndex as uniqueIndex2, index as index2 } from "drizzle-orm/sqlite-core";
124
136
  import { sql as sql2 } from "drizzle-orm";
125
137
  import { nanoid as nanoid2 } from "nanoid";
126
138
  var baseFields2 = /* @__PURE__ */ __name((idLength = 5) => ({
@@ -194,6 +206,17 @@ var credentialSetupSessionsTable2 = sqliteTable("credential_setup_sessions", {
194
206
  userPurposeIdx: index2("credential_setup_sessions_user_purpose_idx").on(table.userId, table.purpose),
195
207
  expiresAtIdx: index2("credential_setup_sessions_expires_at_idx").on(table.expiresAt)
196
208
  }));
209
+ var credentialSetupRequirementsTable2 = sqliteTable("credential_setup_requirements", {
210
+ userId: text2("user_id").references(() => usersTable2.id, { onDelete: "cascade" }).notNull(),
211
+ purpose: text2("purpose").notNull(),
212
+ temporaryCredentialKind: text2("temporary_credential_kind"),
213
+ required: integer2("required", { mode: "boolean" }).default(true).notNull(),
214
+ completedAt: text2("completed_at"),
215
+ createdAt: text2("created_at").$defaultFn(() => (/* @__PURE__ */ new Date()).toISOString()),
216
+ updatedAt: text2("updated_at").$defaultFn(() => (/* @__PURE__ */ new Date()).toISOString()).$onUpdate(() => sql2`(datetime('now'))`)
217
+ }, (table) => ({
218
+ pk: primaryKey2({ columns: [table.userId, table.purpose] })
219
+ }));
197
220
  var rolePermissionsTable2 = sqliteTable("role_permissions", {
198
221
  ...baseFields2(10),
199
222
  roleId: text2("role_id").notNull().references(() => rolesTable2.id, { onDelete: "cascade" }),
@@ -206,6 +229,7 @@ var authSchema2 = {
206
229
  oauthAccounts: oauthAccountsTable2,
207
230
  tokens: tokensTable2,
208
231
  credentialSetupSessions: credentialSetupSessionsTable2,
232
+ credentialSetupRequirements: credentialSetupRequirementsTable2,
209
233
  roles: rolesTable2,
210
234
  permissions: permissionsTable2,
211
235
  rolePermissions: rolePermissionsTable2
@@ -457,14 +481,15 @@ CookieManager = __decorate2([
457
481
  ], CookieManager);
458
482
 
459
483
  // src/auth/AuthController.ts
460
- import { Controller, Err as Err9 } from "najm-core";
484
+ import { Controller, Err as Err13 } from "najm-core";
461
485
  import { Get, Post, ResMsg } from "najm-core";
462
486
  import { Body, User as User2, Headers, Ctx } from "najm-core";
463
487
 
464
488
  // src/auth/AuthService.ts
465
- import { Injectable as Injectable8, Inject as Inject8 } from "najm-core";
466
- import { Err as Err8, Log } from "najm-core";
467
- import { I18n as I18n6, I18nService as I18nService2 } from "najm-i18n";
489
+ import { Injectable as Injectable11, Inject as Inject11 } from "najm-core";
490
+ import { Err as Err12, Log } from "najm-core";
491
+ import { Transaction as Transaction4 } from "najm-database";
492
+ import { I18n as I18n8, I18nService as I18nService2 } from "najm-i18n";
468
493
  import { EmailService, passwordResetTemplate, accountInviteTemplate } from "najm-email";
469
494
  import { nanoid as nanoid5 } from "nanoid";
470
495
 
@@ -745,6 +770,17 @@ var UserValidator = class UserValidator2 {
745
770
  Err(this.t("errors.emailExists"), 409);
746
771
  }
747
772
  }
773
+ /**
774
+ * Check that a normalized phone number is not already taken.
775
+ */
776
+ async checkPhoneUnique(phone, excludeId) {
777
+ if (!phone)
778
+ return;
779
+ const existingUser = await this.userRepository.findByPhone(phone);
780
+ if (existingUser && existingUser.id !== excludeId) {
781
+ Err(this.t("errors.phoneExists"), 409);
782
+ }
783
+ }
748
784
  /**
749
785
  * Check if user exists by ID
750
786
  */
@@ -827,6 +863,7 @@ var UserValidator = class UserValidator2 {
827
863
  if (!password) {
828
864
  Err("Password is required", 400);
829
865
  }
866
+ this.validatePasswordLength(password);
830
867
  const minLength = 8;
831
868
  const hasUppercase = /[A-Z]/.test(password);
832
869
  const hasLowercase = /[a-z]/.test(password);
@@ -844,6 +881,12 @@ var UserValidator = class UserValidator2 {
844
881
  Err("Password must contain at least one number", 400);
845
882
  }
846
883
  }
884
+ /** Keep every byte passed to bcrypt significant. */
885
+ validatePasswordLength(password) {
886
+ if (new TextEncoder().encode(password).length > 72) {
887
+ Err("Password must be at most 72 bytes", 400);
888
+ }
889
+ }
847
890
  };
848
891
  __decorate4([
849
892
  I18n("users"),
@@ -1185,6 +1228,110 @@ var isEmpty = _isEmpty;
1185
1228
  var isPath = /* @__PURE__ */ __name((img) => typeof img === "string" && img.trim().length > 0 && (img.startsWith("/") || img.startsWith("http") || img.startsWith("storage/")), "isPath");
1186
1229
  var isFile = /* @__PURE__ */ __name((img) => !!img && typeof img !== "string" && img instanceof File, "isFile");
1187
1230
 
1231
+ // src/identity/presets.ts
1232
+ var compactPhone = /* @__PURE__ */ __name((value) => value.trim().replace(/[\s().-]+/g, ""), "compactPhone");
1233
+ var MOROCCO_LOCAL = /^0\d{9}$/;
1234
+ var MOROCCO_NATIONAL = /^212\d{9}$/;
1235
+ var MOROCCO_E164 = /^\+212\d{9}$/;
1236
+ var normalizeMoroccanPhone = /* @__PURE__ */ __name((value) => {
1237
+ const compact = compactPhone(value);
1238
+ if (MOROCCO_LOCAL.test(compact))
1239
+ return `+212${compact.slice(1)}`;
1240
+ if (MOROCCO_NATIONAL.test(compact))
1241
+ return `+${compact}`;
1242
+ if (MOROCCO_E164.test(compact))
1243
+ return compact;
1244
+ return null;
1245
+ }, "normalizeMoroccanPhone");
1246
+ var moroccoIdentityPreset = {
1247
+ name: "ma",
1248
+ normalize: normalizeMoroccanPhone
1249
+ };
1250
+ var TUNISIA_LOCAL = /^\d{8}$/;
1251
+ var TUNISIA_NATIONAL = /^216\d{8}$/;
1252
+ var TUNISIA_E164 = /^\+216\d{8}$/;
1253
+ var normalizeTunisianPhone = /* @__PURE__ */ __name((value) => {
1254
+ const compact = compactPhone(value);
1255
+ if (TUNISIA_LOCAL.test(compact))
1256
+ return `+216${compact}`;
1257
+ if (TUNISIA_NATIONAL.test(compact))
1258
+ return `+${compact}`;
1259
+ if (TUNISIA_E164.test(compact))
1260
+ return compact;
1261
+ return null;
1262
+ }, "normalizeTunisianPhone");
1263
+ var tunisiaIdentityPreset = {
1264
+ name: "tn",
1265
+ normalize: normalizeTunisianPhone
1266
+ };
1267
+ var IDENTITY_PRESETS = {
1268
+ ma: moroccoIdentityPreset,
1269
+ tn: tunisiaIdentityPreset
1270
+ };
1271
+ var DEFAULT_IDENTITY_PRESET = "ma";
1272
+
1273
+ // src/identity/resolver.ts
1274
+ var MAX_IDENTIFIER_LENGTH = 254;
1275
+ var E164 = /^\+[1-9]\d{7,14}$/;
1276
+ var normalizeE164 = /* @__PURE__ */ __name((value) => {
1277
+ const compact = compactPhone(value);
1278
+ const international = compact.startsWith("00") ? `+${compact.slice(2)}` : compact;
1279
+ return E164.test(international) ? international : null;
1280
+ }, "normalizeE164");
1281
+ var selectPreset = /* @__PURE__ */ __name((preset) => {
1282
+ if (preset === null)
1283
+ return null;
1284
+ if (preset === void 0)
1285
+ return IDENTITY_PRESETS[DEFAULT_IDENTITY_PRESET];
1286
+ if (typeof preset === "string") {
1287
+ const selected = IDENTITY_PRESETS[preset];
1288
+ if (!selected)
1289
+ throw new Error(`auth.identity.preset '${preset}' is not a built-in identity preset`);
1290
+ return selected;
1291
+ }
1292
+ if (typeof preset.normalize !== "function") {
1293
+ throw new Error("auth.identity.preset must expose a normalize(value) function");
1294
+ }
1295
+ return preset;
1296
+ }, "selectPreset");
1297
+ function createIdentityResolver(config) {
1298
+ const preset = selectPreset(config?.preset);
1299
+ const extend = config?.extend ?? [];
1300
+ if (extend.some((normalizer) => typeof normalizer !== "function")) {
1301
+ throw new Error("auth.identity.extend must contain only normalizer functions");
1302
+ }
1303
+ const pipeline = [
1304
+ ...extend,
1305
+ ...preset ? [preset.normalize] : [],
1306
+ normalizeE164
1307
+ ];
1308
+ return (value) => {
1309
+ if (typeof value !== "string")
1310
+ return null;
1311
+ const trimmed = value.trim();
1312
+ if (!trimmed || trimmed.length > MAX_IDENTIFIER_LENGTH)
1313
+ return null;
1314
+ if (trimmed.includes("@"))
1315
+ return trimmed.toLowerCase();
1316
+ for (const normalize of pipeline) {
1317
+ const normalized = normalize(trimmed);
1318
+ if (normalized)
1319
+ return normalized;
1320
+ }
1321
+ return null;
1322
+ };
1323
+ }
1324
+ __name(createIdentityResolver, "createIdentityResolver");
1325
+ var defaultResolver = createIdentityResolver();
1326
+ function normalizeAuthIdentifier(value) {
1327
+ return defaultResolver(value);
1328
+ }
1329
+ __name(normalizeAuthIdentifier, "normalizeAuthIdentifier");
1330
+ function isEmailIdentifier(value) {
1331
+ return value.includes("@");
1332
+ }
1333
+ __name(isEmailIdentifier, "isEmailIdentifier");
1334
+
1188
1335
  // src/users/UserService.ts
1189
1336
  import { Err as Err5 } from "najm-core";
1190
1337
  var __decorate8 = function(decorators, target, key, desc) {
@@ -1209,6 +1356,7 @@ var _e;
1209
1356
  var _f;
1210
1357
  var _g;
1211
1358
  var _h;
1359
+ var E164_PHONE = /^\+[1-9]\d{7,14}$/;
1212
1360
  var UserService = class UserService2 {
1213
1361
  static {
1214
1362
  __name(this, "UserService");
@@ -1296,15 +1444,25 @@ var UserService = class UserService2 {
1296
1444
  async getAuthRecordById(id) {
1297
1445
  return await this.userRepository.getRawById(id);
1298
1446
  }
1299
- async create(data) {
1300
- const { id, email: email2, name, image, emailVerified, password, roleId, role } = data;
1447
+ async create(data, options = {}) {
1448
+ const { id, email: email2, name, image, emailVerified, password, roleId, role, phone } = data;
1301
1449
  if (!password || typeof password !== "string" || password.trim().length === 0) {
1302
1450
  Err5("Password is required");
1303
1451
  }
1304
- this.userValidator.validatePasswordStrength(password);
1452
+ this.userValidator.validatePasswordLength(password);
1453
+ if (options.validatePasswordStrength !== false) {
1454
+ this.userValidator.validatePasswordStrength(password);
1455
+ }
1305
1456
  let userId = id || nanoid3(10);
1306
1457
  await this.userValidator.checkEmailUnique(data.email);
1307
1458
  await this.userValidator.checkUserIdIsUnique(userId);
1459
+ const normalizedPhone = phone == null ? null : this.authConfig.identity?.resolve(phone) ?? normalizeAuthIdentifier(phone);
1460
+ if (phone != null && (!normalizedPhone || !E164_PHONE.test(normalizedPhone))) {
1461
+ Err5("A valid phone number is required", 400);
1462
+ }
1463
+ if (normalizedPhone) {
1464
+ await this.userValidator.checkPhoneUnique(normalizedPhone, userId);
1465
+ }
1308
1466
  const hashedPassword = await this.encryptionService.hashPassword(password);
1309
1467
  const resolvedRoleId = await this.resolveUserRole(roleId, role);
1310
1468
  const userDetails = {
@@ -1315,6 +1473,7 @@ var UserService = class UserService2 {
1315
1473
  password: hashedPassword,
1316
1474
  roleId: resolvedRoleId,
1317
1475
  emailVerified,
1476
+ ...normalizedPhone ? { phone: normalizedPhone } : {},
1318
1477
  status: data.status ?? this.authConfig.registrationMode ?? "active"
1319
1478
  };
1320
1479
  const newUser = await this.userRepository.create(userDetails);
@@ -1411,7 +1570,7 @@ __decorate8([
1411
1570
  __decorate8([
1412
1571
  Transaction(),
1413
1572
  __metadata8("design:type", Function),
1414
- __metadata8("design:paramtypes", [typeof (_g = typeof Record !== "undefined" && Record) === "function" ? _g : Object]),
1573
+ __metadata8("design:paramtypes", [typeof (_g = typeof Record !== "undefined" && Record) === "function" ? _g : Object, Object]),
1415
1574
  __metadata8("design:returntype", typeof (_h = typeof Promise !== "undefined" && Promise) === "function" ? _h : Object)
1416
1575
  ], UserService.prototype, "create", null);
1417
1576
  UserService = __decorate8([
@@ -1421,7 +1580,7 @@ UserService = __decorate8([
1421
1580
  ], UserService);
1422
1581
 
1423
1582
  // src/tokens/TokenService.ts
1424
- import { Injectable as Injectable6, Inject as Inject7 } from "najm-core";
1583
+ import { Injectable as Injectable6, Inject as Inject8 } from "najm-core";
1425
1584
  import { I18n as I18n5 } from "najm-i18n";
1426
1585
  import { CacheService } from "najm-cache";
1427
1586
  import { createHash } from "crypto";
@@ -1543,7 +1702,11 @@ TokenRepository = __decorate9([
1543
1702
 
1544
1703
  // src/tokens/TokenService.ts
1545
1704
  import timestring2 from "timestring";
1546
- import { Err as Err6 } from "najm-core";
1705
+
1706
+ // src/credentialSetup/CredentialSetupRequirementRepository.ts
1707
+ import { and as and2, eq as eq5 } from "drizzle-orm";
1708
+ import { Err as Err6, Inject as Inject7, Repository as Repository4 } from "najm-core";
1709
+ import { DB as DB4 } from "najm-database";
1547
1710
  var __decorate10 = function(decorators, target, key, desc) {
1548
1711
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1549
1712
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1553,10 +1716,82 @@ var __decorate10 = function(decorators, target, key, desc) {
1553
1716
  var __metadata10 = function(k, v) {
1554
1717
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1555
1718
  };
1719
+ var CredentialSetupRequirementRepository = class CredentialSetupRequirementRepository2 {
1720
+ static {
1721
+ __name(this, "CredentialSetupRequirementRepository");
1722
+ }
1723
+ db;
1724
+ schema;
1725
+ get requirements() {
1726
+ const requirements = this.schema.credentialSetupRequirements;
1727
+ if (!requirements) {
1728
+ Err6.invalidOperation("auth.schema.credentialSetupRequirements is required for credential-setup requirements");
1729
+ }
1730
+ return requirements;
1731
+ }
1732
+ get columns() {
1733
+ const requirements = this.requirements;
1734
+ return {
1735
+ userId: requirements.userId,
1736
+ purpose: requirements.purpose,
1737
+ temporaryCredentialKind: requirements.temporaryCredentialKind,
1738
+ required: requirements.required,
1739
+ completedAt: requirements.completedAt
1740
+ };
1741
+ }
1742
+ async markRequired(userId, purpose, temporaryCredentialKind) {
1743
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1744
+ const [requirement] = await this.db.insert(this.requirements).values({ userId, purpose, temporaryCredentialKind, required: true }).onConflictDoUpdate({
1745
+ target: [this.requirements.userId, this.requirements.purpose],
1746
+ set: { temporaryCredentialKind, required: true, completedAt: null, updatedAt: now }
1747
+ }).returning(this.columns);
1748
+ return requirement;
1749
+ }
1750
+ async find(userId, purpose) {
1751
+ const [requirement] = await this.db.select(this.columns).from(this.requirements).where(and2(eq5(this.requirements.userId, userId), eq5(this.requirements.purpose, purpose))).limit(1);
1752
+ return requirement;
1753
+ }
1754
+ async listRequired(userId) {
1755
+ return this.db.select(this.columns).from(this.requirements).where(and2(eq5(this.requirements.userId, userId), eq5(this.requirements.required, true)));
1756
+ }
1757
+ /** Only a still-required row completes, so a replayed completion is a no-op. */
1758
+ async complete(userId, purpose) {
1759
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1760
+ const [requirement] = await this.db.update(this.requirements).set({ required: false, completedAt: now, updatedAt: now }).where(and2(eq5(this.requirements.userId, userId), eq5(this.requirements.purpose, purpose), eq5(this.requirements.required, true))).returning(this.columns);
1761
+ return requirement;
1762
+ }
1763
+ };
1764
+ __decorate10([
1765
+ DB4(),
1766
+ __metadata10("design:type", Object)
1767
+ ], CredentialSetupRequirementRepository.prototype, "db", void 0);
1768
+ __decorate10([
1769
+ Inject7(AUTH_SCHEMA),
1770
+ __metadata10("design:type", Object)
1771
+ ], CredentialSetupRequirementRepository.prototype, "schema", void 0);
1772
+ CredentialSetupRequirementRepository = __decorate10([
1773
+ Repository4()
1774
+ ], CredentialSetupRequirementRepository);
1775
+
1776
+ // src/credentialSetup/types.ts
1777
+ var PASSWORD_SETUP_PURPOSE = "password";
1778
+
1779
+ // src/tokens/TokenService.ts
1780
+ import { Err as Err7 } from "najm-core";
1781
+ var __decorate11 = function(decorators, target, key, desc) {
1782
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1783
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1784
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1785
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1786
+ };
1787
+ var __metadata11 = function(k, v) {
1788
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1789
+ };
1556
1790
  var TokenService_1;
1557
1791
  var _a6;
1558
1792
  var _b4;
1559
1793
  var _c2;
1794
+ var _d2;
1560
1795
  var TokenService = class TokenService2 {
1561
1796
  static {
1562
1797
  __name(this, "TokenService");
@@ -1567,12 +1802,14 @@ var TokenService = class TokenService2 {
1567
1802
  tokenRepository;
1568
1803
  cookieManager;
1569
1804
  cache;
1805
+ credentialSetupRequirements;
1570
1806
  config;
1571
1807
  t;
1572
- constructor(tokenRepository, cookieManager, cache2) {
1808
+ constructor(tokenRepository, cookieManager, cache2, credentialSetupRequirements) {
1573
1809
  this.tokenRepository = tokenRepository;
1574
1810
  this.cookieManager = cookieManager;
1575
1811
  this.cache = cache2;
1812
+ this.credentialSetupRequirements = credentialSetupRequirements;
1576
1813
  }
1577
1814
  /**
1578
1815
  * Get blacklist key prefix
@@ -1612,7 +1849,7 @@ var TokenService = class TokenService2 {
1612
1849
  if (authorization?.startsWith("Bearer ")) {
1613
1850
  return authorization.split(" ")[1];
1614
1851
  }
1615
- Err6(this.t("errors.tokenMissing"), 401);
1852
+ Err7(this.t("errors.tokenMissing"), 401);
1616
1853
  }
1617
1854
  /**
1618
1855
  * Verify access token and check blacklist
@@ -1623,7 +1860,7 @@ var TokenService = class TokenService2 {
1623
1860
  try {
1624
1861
  payload = jwt.verify(token, this.config.jwt.accessSecret);
1625
1862
  } catch {
1626
- Err6(this.t("errors.tokenVerificationFailed"), 401);
1863
+ Err7(this.t("errors.tokenVerificationFailed"), 401);
1627
1864
  }
1628
1865
  const sessionKey = this.sessionVersionKey(payload.userId);
1629
1866
  const blacklistKey = payload.jti ? `${this.blacklistPrefix}${payload.jti}` : null;
@@ -1636,15 +1873,15 @@ var TokenService = class TokenService2 {
1636
1873
  const values = await this.getCacheValues(keys);
1637
1874
  const valueByKey = new Map(keys.map((key, i) => [key, values[i]]));
1638
1875
  if (blacklistKey && valueByKey.get(blacklistKey) != null) {
1639
- Err6(this.t("errors.tokenRevoked"), 401);
1876
+ Err7(this.t("errors.tokenRevoked"), 401);
1640
1877
  }
1641
1878
  if (familyKey && valueByKey.get(familyKey) != null) {
1642
- Err6(this.t("errors.tokenRevoked"), 401);
1879
+ Err7(this.t("errors.tokenRevoked"), 401);
1643
1880
  }
1644
1881
  const activeSessionVersion = this.parseSessionVersion(valueByKey.get(sessionKey) ?? null);
1645
1882
  const tokenSessionVersion = payload.sessionVersion ?? 0;
1646
1883
  if (tokenSessionVersion !== activeSessionVersion) {
1647
- Err6(this.t("errors.tokenRevoked"), 401);
1884
+ Err7(this.t("errors.tokenRevoked"), 401);
1648
1885
  }
1649
1886
  return payload;
1650
1887
  }
@@ -1653,13 +1890,13 @@ var TokenService = class TokenService2 {
1653
1890
  try {
1654
1891
  decoded = jwt.verify(token, this.config.jwt.refreshSecret);
1655
1892
  } catch {
1656
- Err6(this.t("errors.tokenVerificationFailed"), 401);
1893
+ Err7(this.t("errors.tokenVerificationFailed"), 401);
1657
1894
  }
1658
1895
  if (decoded.type && decoded.type !== "refresh") {
1659
- Err6(this.t("errors.tokenVerificationFailed"), 401);
1896
+ Err7(this.t("errors.tokenVerificationFailed"), 401);
1660
1897
  }
1661
1898
  if (!decoded.tokenFamily) {
1662
- Err6(this.t("errors.tokenVerificationFailed"), 401);
1899
+ Err7(this.t("errors.tokenVerificationFailed"), 401);
1663
1900
  }
1664
1901
  return { userId: decoded.userId, tokenFamily: decoded.tokenFamily };
1665
1902
  }
@@ -1678,12 +1915,12 @@ var TokenService = class TokenService2 {
1678
1915
  async resolveRefreshSessionFromCookie() {
1679
1916
  const refreshToken = this.cookieManager.getRefreshToken();
1680
1917
  if (!refreshToken) {
1681
- Err6(this.t("errors.refreshTokenMissing"), 401);
1918
+ Err7(this.t("errors.refreshTokenMissing"), 401);
1682
1919
  }
1683
1920
  const { userId, tokenFamily } = this.verifyRefreshToken(refreshToken);
1684
1921
  const stored = await this.tokenRepository.getByFamily(tokenFamily);
1685
1922
  if (!stored || stored.userId !== userId) {
1686
- Err6(this.t("errors.refreshTokenInvalid"), 401);
1923
+ Err7(this.t("errors.refreshTokenInvalid"), 401);
1687
1924
  }
1688
1925
  const presentedHash = this.hashToken(refreshToken);
1689
1926
  if (presentedHash === stored.token) {
@@ -1693,7 +1930,7 @@ var TokenService = class TokenService2 {
1693
1930
  if (canRecover) {
1694
1931
  return { userId, tokenFamily };
1695
1932
  }
1696
- Err6(this.t("errors.refreshTokenInvalid"), 401);
1933
+ Err7(this.t("errors.refreshTokenInvalid"), 401);
1697
1934
  }
1698
1935
  async resolveUserFromCookie() {
1699
1936
  return (await this.resolveRefreshSessionFromCookie()).userId;
@@ -1870,12 +2107,12 @@ var TokenService = class TokenService2 {
1870
2107
  async refreshTokens() {
1871
2108
  const refreshToken = this.cookieManager.getRefreshToken();
1872
2109
  if (!refreshToken) {
1873
- Err6(this.t("errors.refreshTokenMissing"), 401);
2110
+ Err7(this.t("errors.refreshTokenMissing"), 401);
1874
2111
  }
1875
2112
  const { userId, tokenFamily } = this.verifyRefreshToken(refreshToken);
1876
2113
  const stored = await this.tokenRepository.getByFamily(tokenFamily);
1877
2114
  if (!stored || stored.userId !== userId) {
1878
- Err6(this.t("errors.refreshTokenInvalid"), 401);
2115
+ Err7(this.t("errors.refreshTokenInvalid"), 401);
1879
2116
  }
1880
2117
  const presentedHash = this.hashToken(refreshToken);
1881
2118
  await this.requireActiveRefreshUser(userId, tokenFamily);
@@ -1886,18 +2123,25 @@ var TokenService = class TokenService2 {
1886
2123
  if (canRecover) {
1887
2124
  const claimed = await this.tokenRepository.markPreviousUsed(tokenFamily, presentedHash);
1888
2125
  if (!claimed?.length) {
1889
- Err6(this.t("errors.refreshTokenInvalid"), 401);
2126
+ Err7(this.t("errors.refreshTokenInvalid"), 401);
1890
2127
  }
1891
2128
  return this.generateTokens(userId, tokenFamily);
1892
2129
  }
1893
2130
  await this.revokeSuspectRefreshFamily(userId, tokenFamily);
1894
- Err6(this.t("errors.refreshTokenInvalid"), 401);
2131
+ Err7(this.t("errors.refreshTokenInvalid"), 401);
1895
2132
  }
1896
2133
  async requireActiveRefreshUser(userId, tokenFamily) {
1897
2134
  const user = await this.tokenRepository.getUser(userId);
1898
2135
  if (!user || user.status !== "active") {
1899
2136
  await this.revokeFamily(tokenFamily);
1900
- Err6(this.t("errors.refreshTokenInvalid"), 401);
2137
+ Err7(this.t("errors.refreshTokenInvalid"), 401);
2138
+ }
2139
+ const requirement = await this.credentialSetupRequirements?.find(userId, PASSWORD_SETUP_PURPOSE);
2140
+ if (requirement?.required) {
2141
+ await this.revokeFamily(tokenFamily);
2142
+ this.cookieManager.clearRefreshToken();
2143
+ this.cookieManager.clearSessionCookie();
2144
+ Err7(this.t("errors.credentialSetupRequired"), 403);
1901
2145
  }
1902
2146
  return user;
1903
2147
  }
@@ -1931,7 +2175,7 @@ var TokenService = class TokenService2 {
1931
2175
  const userId = await this.resolveUserFromCookie();
1932
2176
  const user = await this.getUserById(userId);
1933
2177
  if (!user) {
1934
- Err6(this.t("errors.refreshTokenInvalid"), 401);
2178
+ Err7(this.t("errors.refreshTokenInvalid"), 401);
1935
2179
  }
1936
2180
  return user;
1937
2181
  }
@@ -2073,15 +2317,15 @@ var TokenService = class TokenService2 {
2073
2317
  try {
2074
2318
  decoded = jwt.verify(token, this.config.jwt.refreshSecret);
2075
2319
  } catch {
2076
- Err6(this.t("errors.resetTokenExpired"));
2320
+ Err7(this.t("errors.resetTokenExpired"));
2077
2321
  }
2078
2322
  if (decoded.type !== "reset" && decoded.type !== "invite" || !decoded.jti) {
2079
- Err6(this.t("errors.invalidResetToken"));
2323
+ Err7(this.t("errors.invalidResetToken"));
2080
2324
  }
2081
2325
  const key = `${this.resetTokenPrefix}${decoded.userId}`;
2082
2326
  const storedJti = await this.cache.get(key);
2083
2327
  if (!storedJti || storedJti !== decoded.jti) {
2084
- Err6(this.t("errors.invalidResetToken"));
2328
+ Err7(this.t("errors.invalidResetToken"));
2085
2329
  }
2086
2330
  await this.cache.del(key);
2087
2331
  return decoded.userId;
@@ -2090,37 +2334,196 @@ var TokenService = class TokenService2 {
2090
2334
  return this.parseSessionVersion(await this.cache.get(this.sessionVersionKey(userId)));
2091
2335
  }
2092
2336
  };
2093
- __decorate10([
2094
- Inject7(AUTH_CONFIG),
2095
- __metadata10("design:type", Object)
2337
+ __decorate11([
2338
+ Inject8(AUTH_CONFIG),
2339
+ __metadata11("design:type", Object)
2096
2340
  ], TokenService.prototype, "config", void 0);
2097
- __decorate10([
2341
+ __decorate11([
2098
2342
  I18n5("auth"),
2099
- __metadata10("design:type", Object)
2343
+ __metadata11("design:type", Object)
2100
2344
  ], TokenService.prototype, "t", void 0);
2101
- TokenService = TokenService_1 = __decorate10([
2345
+ TokenService = TokenService_1 = __decorate11([
2102
2346
  Injectable6(),
2103
- __metadata10("design:paramtypes", [typeof (_a6 = typeof TokenRepository !== "undefined" && TokenRepository) === "function" ? _a6 : Object, typeof (_b4 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _b4 : Object, typeof (_c2 = typeof CacheService !== "undefined" && CacheService) === "function" ? _c2 : Object])
2347
+ __metadata11("design:paramtypes", [typeof (_a6 = typeof TokenRepository !== "undefined" && TokenRepository) === "function" ? _a6 : Object, typeof (_b4 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _b4 : Object, typeof (_c2 = typeof CacheService !== "undefined" && CacheService) === "function" ? _c2 : Object, typeof (_d2 = typeof CredentialSetupRequirementRepository !== "undefined" && CredentialSetupRequirementRepository) === "function" ? _d2 : Object])
2104
2348
  ], TokenService);
2105
2349
 
2106
2350
  // src/auth/AuthService.ts
2107
2351
  import timestring3 from "timestring";
2108
2352
 
2109
2353
  // src/auth/AuthSessionService.ts
2354
+ import { Injectable as Injectable8 } from "najm-core";
2355
+ import { Err as Err9 } from "najm-core";
2356
+
2357
+ // src/credentialSetup/CredentialSetupRequirementService.ts
2110
2358
  import { Injectable as Injectable7 } from "najm-core";
2111
- import { Err as Err7 } from "najm-core";
2112
- var __decorate11 = function(decorators, target, key, desc) {
2359
+ import { Transaction as Transaction2 } from "najm-database";
2360
+
2361
+ // src/identity/temporaryCredential.ts
2362
+ var EXACT_TEMPORARY_CREDENTIAL_KIND = "exact";
2363
+ var exactKind = {
2364
+ name: EXACT_TEMPORARY_CREDENTIAL_KIND,
2365
+ normalize: /* @__PURE__ */ __name((value) => value, "normalize")
2366
+ };
2367
+ var MOROCCAN_CIN_TEMPORARY_CREDENTIAL_KIND = "ma-cin";
2368
+ var MOROCCAN_CIN = /^[a-z]{1,3}\d{5,17}$/i;
2369
+ function isMoroccanCin(value) {
2370
+ const trimmed = value.trim();
2371
+ return trimmed.length >= 8 && trimmed.length <= 20 && MOROCCAN_CIN.test(trimmed);
2372
+ }
2373
+ __name(isMoroccanCin, "isMoroccanCin");
2374
+ function normalizeMoroccanCin(value) {
2375
+ return isMoroccanCin(value) ? value.trim().toLowerCase() : value;
2376
+ }
2377
+ __name(normalizeMoroccanCin, "normalizeMoroccanCin");
2378
+ var moroccanCinKind = {
2379
+ name: MOROCCAN_CIN_TEMPORARY_CREDENTIAL_KIND,
2380
+ normalize: normalizeMoroccanCin,
2381
+ isTemporaryShape: isMoroccanCin
2382
+ };
2383
+ var KINDS = /* @__PURE__ */ new Map([
2384
+ [exactKind.name, exactKind],
2385
+ [moroccanCinKind.name, moroccanCinKind]
2386
+ ]);
2387
+ function resolveTemporaryCredentialKind(name) {
2388
+ const kind = KINDS.get(name?.trim() || EXACT_TEMPORARY_CREDENTIAL_KIND);
2389
+ if (!kind) {
2390
+ throw new Error(`Unknown temporary credential kind '${name}'`);
2391
+ }
2392
+ return kind;
2393
+ }
2394
+ __name(resolveTemporaryCredentialKind, "resolveTemporaryCredentialKind");
2395
+ function isTemporaryCredentialKind(name) {
2396
+ return KINDS.has(name);
2397
+ }
2398
+ __name(isTemporaryCredentialKind, "isTemporaryCredentialKind");
2399
+ function toTemporaryCredential(input) {
2400
+ if (typeof input === "string") {
2401
+ return { kind: EXACT_TEMPORARY_CREDENTIAL_KIND, value: input };
2402
+ }
2403
+ if (!input || typeof input.value !== "string") {
2404
+ throw new Error("temporaryCredential must be a string or { kind, value }");
2405
+ }
2406
+ return { kind: input.kind || EXACT_TEMPORARY_CREDENTIAL_KIND, value: input.value };
2407
+ }
2408
+ __name(toTemporaryCredential, "toTemporaryCredential");
2409
+ function moroccanCinTemporaryCredential(value) {
2410
+ if (!isMoroccanCin(value)) {
2411
+ throw new Error("moroccanCinTemporaryCredential requires a valid Moroccan CIN");
2412
+ }
2413
+ return { kind: MOROCCAN_CIN_TEMPORARY_CREDENTIAL_KIND, value };
2414
+ }
2415
+ __name(moroccanCinTemporaryCredential, "moroccanCinTemporaryCredential");
2416
+
2417
+ // src/credentialSetup/purpose.ts
2418
+ import { Err as Err8 } from "najm-core";
2419
+ var PURPOSE_PATTERN = /^[a-z0-9](?:[a-z0-9:_-]{0,62}[a-z0-9])?$/;
2420
+ function normalizeSetupPurpose(purpose) {
2421
+ const normalized = purpose?.trim().toLowerCase();
2422
+ if (!normalized || !PURPOSE_PATTERN.test(normalized)) {
2423
+ Err8("Credential setup purpose must be 1-64 lowercase letters, numbers, colon, underscore, or hyphen", 500);
2424
+ }
2425
+ return normalized;
2426
+ }
2427
+ __name(normalizeSetupPurpose, "normalizeSetupPurpose");
2428
+
2429
+ // src/credentialSetup/CredentialSetupRequirementService.ts
2430
+ var __decorate12 = function(decorators, target, key, desc) {
2113
2431
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2114
2432
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2115
2433
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2116
2434
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2117
2435
  };
2118
- var __metadata11 = function(k, v) {
2436
+ var __metadata12 = function(k, v) {
2119
2437
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2120
2438
  };
2121
2439
  var _a7;
2122
2440
  var _b5;
2123
2441
  var _c3;
2442
+ var CredentialSetupRequirementService = class CredentialSetupRequirementService2 {
2443
+ static {
2444
+ __name(this, "CredentialSetupRequirementService");
2445
+ }
2446
+ repository;
2447
+ tokens;
2448
+ constructor(repository, tokens) {
2449
+ this.repository = repository;
2450
+ this.tokens = tokens;
2451
+ }
2452
+ /**
2453
+ * Idempotent. Re-marking clears a previous completion, and revokes the
2454
+ * user's current sessions so an already signed-in browser cannot skip it.
2455
+ */
2456
+ async markRequired(userId, purpose, options = {}) {
2457
+ const kind = options.temporaryCredentialKind ?? null;
2458
+ if (kind)
2459
+ resolveTemporaryCredentialKind(kind);
2460
+ const requirement = await this.repository.markRequired(userId, normalizeSetupPurpose(purpose), kind);
2461
+ await this.tokens.invalidateUserAccessTokens(userId);
2462
+ await this.tokens.revokeAllForUser(userId);
2463
+ return requirement;
2464
+ }
2465
+ async find(userId, purpose) {
2466
+ const requirement = await this.repository.find(userId, normalizeSetupPurpose(purpose));
2467
+ return requirement?.required ? requirement : void 0;
2468
+ }
2469
+ async isRequired(userId, purpose) {
2470
+ return Boolean(await this.find(userId, purpose));
2471
+ }
2472
+ async listRequired(userId) {
2473
+ return this.repository.listRequired(userId);
2474
+ }
2475
+ /** Returns the completed row, or `undefined` when nothing was still required. */
2476
+ async completeRequirement(userId, purpose) {
2477
+ return this.repository.complete(userId, normalizeSetupPurpose(purpose));
2478
+ }
2479
+ };
2480
+ __decorate12([
2481
+ Transaction2({ retries: 2 }),
2482
+ __metadata12("design:type", Function),
2483
+ __metadata12("design:paramtypes", [String, String, Object]),
2484
+ __metadata12("design:returntype", typeof (_c3 = typeof Promise !== "undefined" && Promise) === "function" ? _c3 : Object)
2485
+ ], CredentialSetupRequirementService.prototype, "markRequired", null);
2486
+ CredentialSetupRequirementService = __decorate12([
2487
+ Injectable7(),
2488
+ __metadata12("design:paramtypes", [typeof (_a7 = typeof CredentialSetupRequirementRepository !== "undefined" && CredentialSetupRequirementRepository) === "function" ? _a7 : Object, typeof (_b5 = typeof TokenService !== "undefined" && TokenService) === "function" ? _b5 : Object])
2489
+ ], CredentialSetupRequirementService);
2490
+
2491
+ // src/credentialSetup/errors.ts
2492
+ import { BaseError } from "najm-core";
2493
+ var CREDENTIAL_SETUP_CODES = {
2494
+ /** Login succeeded but the account must replace its credential first. */
2495
+ REQUIRED: "AUTH_CREDENTIAL_SETUP_REQUIRED",
2496
+ /** No setup cookie was presented. */
2497
+ SESSION_REQUIRED: "AUTH_CREDENTIAL_SETUP_SESSION_REQUIRED",
2498
+ /** The setup cookie is unknown, already used, or expired. */
2499
+ SESSION_INVALID: "AUTH_CREDENTIAL_SETUP_SESSION_INVALID",
2500
+ /** Nothing was still required for this user and purpose. */
2501
+ ALREADY_COMPLETED: "AUTH_CREDENTIAL_SETUP_ALREADY_COMPLETED",
2502
+ /** The replacement failed the configured policy. */
2503
+ PASSWORD_REJECTED: "AUTH_CREDENTIAL_SETUP_PASSWORD_REJECTED",
2504
+ /** The replacement is the credential being replaced. */
2505
+ SAME_PASSWORD: "AUTH_CREDENTIAL_SETUP_SAME_PASSWORD",
2506
+ /** OAuth cannot mint a session while a requirement is outstanding. */
2507
+ OAUTH_BLOCKED: "oauth_credential_setup_required"
2508
+ };
2509
+ var credentialSetupError = /* @__PURE__ */ __name((code, message, status = 400) => {
2510
+ throw new BaseError(code, message, status);
2511
+ }, "credentialSetupError");
2512
+
2513
+ // src/auth/AuthSessionService.ts
2514
+ var __decorate13 = function(decorators, target, key, desc) {
2515
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2516
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2517
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2518
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2519
+ };
2520
+ var __metadata13 = function(k, v) {
2521
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2522
+ };
2523
+ var _a8;
2524
+ var _b6;
2525
+ var _c4;
2526
+ var _d3;
2124
2527
  var AuthSessionService = class AuthSessionService2 {
2125
2528
  static {
2126
2529
  __name(this, "AuthSessionService");
@@ -2128,14 +2531,19 @@ var AuthSessionService = class AuthSessionService2 {
2128
2531
  tokenService;
2129
2532
  userService;
2130
2533
  cookieManager;
2131
- constructor(tokenService, userService, cookieManager) {
2534
+ credentialSetupRequirements;
2535
+ constructor(tokenService, userService, cookieManager, credentialSetupRequirements) {
2132
2536
  this.tokenService = tokenService;
2133
2537
  this.userService = userService;
2134
2538
  this.cookieManager = cookieManager;
2539
+ this.credentialSetupRequirements = credentialSetupRequirements;
2135
2540
  }
2136
2541
  async establish(user) {
2137
2542
  if (user.status !== "active") {
2138
- Err7("oauth_account_inactive", 403);
2543
+ Err9("oauth_account_inactive", 403);
2544
+ }
2545
+ if (await this.credentialSetupRequirements?.isRequired(user.id, PASSWORD_SETUP_PURPOSE)) {
2546
+ credentialSetupError(CREDENTIAL_SETUP_CODES.REQUIRED, "Credential setup is required before a session can be established", 403);
2139
2547
  }
2140
2548
  await this.tokenService.deleteExpiredSessions();
2141
2549
  const generated = await this.tokenService.generateTokens(user.id);
@@ -2158,93 +2566,485 @@ var AuthSessionService = class AuthSessionService2 {
2158
2566
  return { ...tokens, user };
2159
2567
  }
2160
2568
  };
2161
- AuthSessionService = __decorate11([
2162
- Injectable7(),
2163
- __metadata11("design:paramtypes", [typeof (_a7 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a7 : Object, typeof (_b5 = typeof UserService !== "undefined" && UserService) === "function" ? _b5 : Object, typeof (_c3 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _c3 : Object])
2569
+ AuthSessionService = __decorate13([
2570
+ Injectable8(),
2571
+ __metadata13("design:paramtypes", [typeof (_a8 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a8 : Object, typeof (_b6 = typeof UserService !== "undefined" && UserService) === "function" ? _b6 : Object, typeof (_c4 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _c4 : Object, typeof (_d3 = typeof CredentialSetupRequirementService !== "undefined" && CredentialSetupRequirementService) === "function" ? _d3 : Object])
2164
2572
  ], AuthSessionService);
2165
2573
 
2166
- // src/auth/authIdentity.ts
2167
- var PHONE_PATTERN = /^\+[1-9]\d{7,14}$/;
2168
- function normalizeAuthIdentifier(value) {
2169
- if (typeof value !== "string")
2170
- return null;
2171
- const trimmed = value.trim();
2172
- if (!trimmed || trimmed.length > 254)
2173
- return null;
2174
- if (trimmed.includes("@")) {
2175
- return trimmed.toLowerCase();
2176
- }
2177
- const compact = trimmed.replace(/[\s().-]+/g, "");
2178
- const international = compact.startsWith("00") ? `+${compact.slice(2)}` : compact;
2179
- return PHONE_PATTERN.test(international) ? international : null;
2180
- }
2181
- __name(normalizeAuthIdentifier, "normalizeAuthIdentifier");
2182
- function isEmailIdentifier(value) {
2183
- return value.includes("@");
2184
- }
2185
- __name(isEmailIdentifier, "isEmailIdentifier");
2574
+ // src/credentialSetup/PasswordSetupService.ts
2575
+ import { Inject as Inject10, Injectable as Injectable10 } from "najm-core";
2576
+ import { I18n as I18n7 } from "najm-i18n";
2186
2577
 
2187
- // src/auth/AuthService.ts
2188
- var __decorate12 = function(decorators, target, key, desc) {
2578
+ // src/credentialSetup/CredentialSetupService.ts
2579
+ import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
2580
+ import { CookieService as CookieService2 } from "najm-cookies";
2581
+ import { Err as Err11, Injectable as Injectable9 } from "najm-core";
2582
+ import { Transaction as Transaction3 } from "najm-database";
2583
+ import { I18n as I18n6 } from "najm-i18n";
2584
+
2585
+ // src/credentialSetup/CredentialSetupRepository.ts
2586
+ import { and as and3, eq as eq6, gt, isNull as isNull2, lt as lt2 } from "drizzle-orm";
2587
+ import { Err as Err10, Inject as Inject9, Repository as Repository5 } from "najm-core";
2588
+ import { DB as DB5 } from "najm-database";
2589
+ var __decorate14 = function(decorators, target, key, desc) {
2189
2590
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2190
2591
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2191
2592
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2192
2593
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2193
2594
  };
2194
- var __metadata12 = function(k, v) {
2595
+ var __metadata14 = function(k, v) {
2195
2596
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2196
2597
  };
2197
- var _a8;
2198
- var _b6;
2199
- var _c4;
2200
- var _d2;
2201
- var _e2;
2202
- var _f2;
2203
- var _g2;
2204
- var _h2;
2205
- var AuthService = class AuthService2 {
2598
+ var CredentialSetupRepository = class CredentialSetupRepository2 {
2206
2599
  static {
2207
- __name(this, "AuthService");
2600
+ __name(this, "CredentialSetupRepository");
2208
2601
  }
2209
- tokenService;
2210
- userService;
2211
- userValidator;
2212
- encryptionService;
2213
- cookieManager;
2214
- i18nService;
2215
- emailService;
2216
- authSessionService;
2217
- config;
2218
- t;
2219
- logger;
2220
- dummyHash;
2221
- constructor(tokenService, userService, userValidator, encryptionService, cookieManager, i18nService, emailService, authSessionService) {
2222
- this.tokenService = tokenService;
2223
- this.userService = userService;
2224
- this.userValidator = userValidator;
2225
- this.encryptionService = encryptionService;
2226
- this.cookieManager = cookieManager;
2227
- this.i18nService = i18nService;
2228
- this.emailService = emailService;
2229
- this.authSessionService = authSessionService;
2602
+ db;
2603
+ schema;
2604
+ get sessions() {
2605
+ const sessions = this.schema.credentialSetupSessions;
2606
+ if (!sessions) {
2607
+ Err10.invalidOperation("auth.schema.credentialSetupSessions is required to use CredentialSetupService");
2608
+ }
2609
+ return sessions;
2230
2610
  }
2231
- isLockoutActive(lockoutUntil) {
2232
- if (!lockoutUntil)
2233
- return false;
2234
- return new Date(lockoutUntil).getTime() > Date.now();
2611
+ async replaceActive(data) {
2612
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2613
+ await this.db.update(this.sessions).set({ revokedAt: now, updatedAt: now }).where(and3(eq6(this.sessions.userId, data.userId), eq6(this.sessions.purpose, data.purpose), isNull2(this.sessions.consumedAt), isNull2(this.sessions.revokedAt)));
2614
+ const [session] = await this.db.insert(this.sessions).values(data).returning({
2615
+ userId: this.sessions.userId,
2616
+ purpose: this.sessions.purpose,
2617
+ expiresAt: this.sessions.expiresAt
2618
+ });
2619
+ return session;
2235
2620
  }
2236
- nextLockoutUntil() {
2237
- const durationMs = timestring3(this.config.lockout.duration, "ms");
2238
- return new Date(Date.now() + durationMs).toISOString();
2621
+ async findActive(tokenHash, purpose) {
2622
+ const [session] = await this.db.select({
2623
+ userId: this.sessions.userId,
2624
+ purpose: this.sessions.purpose,
2625
+ expiresAt: this.sessions.expiresAt
2626
+ }).from(this.sessions).where(and3(eq6(this.sessions.tokenHash, tokenHash), eq6(this.sessions.purpose, purpose), isNull2(this.sessions.consumedAt), isNull2(this.sessions.revokedAt), gt(this.sessions.expiresAt, (/* @__PURE__ */ new Date()).toISOString()))).limit(1);
2627
+ return session;
2239
2628
  }
2240
- getDummyHash() {
2241
- this.dummyHash ??= this.encryptionService.hashPassword("najm-auth-dummy-password");
2242
- return this.dummyHash;
2629
+ async consume(tokenHash, purpose) {
2630
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2631
+ const [session] = await this.db.update(this.sessions).set({ consumedAt: now, updatedAt: now }).where(and3(eq6(this.sessions.tokenHash, tokenHash), eq6(this.sessions.purpose, purpose), isNull2(this.sessions.consumedAt), isNull2(this.sessions.revokedAt), gt(this.sessions.expiresAt, now))).returning({
2632
+ userId: this.sessions.userId,
2633
+ purpose: this.sessions.purpose,
2634
+ expiresAt: this.sessions.expiresAt
2635
+ });
2636
+ return session;
2243
2637
  }
2244
- async warmupPasswordHash() {
2245
- await this.getDummyHash();
2638
+ async revoke(tokenHash, purpose) {
2639
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2640
+ const [session] = await this.db.update(this.sessions).set({ revokedAt: now, updatedAt: now }).where(and3(eq6(this.sessions.tokenHash, tokenHash), eq6(this.sessions.purpose, purpose), isNull2(this.sessions.consumedAt), isNull2(this.sessions.revokedAt))).returning({ userId: this.sessions.userId });
2641
+ return session;
2246
2642
  }
2247
- async registerUser(body) {
2643
+ async deleteExpired() {
2644
+ return this.db.delete(this.sessions).where(lt2(this.sessions.expiresAt, (/* @__PURE__ */ new Date()).toISOString())).returning({ userId: this.sessions.userId });
2645
+ }
2646
+ };
2647
+ __decorate14([
2648
+ DB5(),
2649
+ __metadata14("design:type", Object)
2650
+ ], CredentialSetupRepository.prototype, "db", void 0);
2651
+ __decorate14([
2652
+ Inject9(AUTH_SCHEMA),
2653
+ __metadata14("design:type", Object)
2654
+ ], CredentialSetupRepository.prototype, "schema", void 0);
2655
+ CredentialSetupRepository = __decorate14([
2656
+ Repository5()
2657
+ ], CredentialSetupRepository);
2658
+
2659
+ // src/credentialSetup/CredentialSetupService.ts
2660
+ var __decorate15 = function(decorators, target, key, desc) {
2661
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2662
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2663
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2664
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2665
+ };
2666
+ var __metadata15 = function(k, v) {
2667
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2668
+ };
2669
+ var _a9;
2670
+ var _b7;
2671
+ var _c5;
2672
+ var _d4;
2673
+ var _e2;
2674
+ var _f2;
2675
+ var _g2;
2676
+ var DEFAULT_CREDENTIAL_SETUP_COOKIE_NAME = "najm.credential-setup";
2677
+ var DEFAULT_CREDENTIAL_SETUP_TTL_MS = 10 * 60 * 1e3;
2678
+ var MAX_TTL_MS = 24 * 60 * 60 * 1e3;
2679
+ var COOKIE_NAME_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
2680
+ var CredentialSetupService = class CredentialSetupService2 {
2681
+ static {
2682
+ __name(this, "CredentialSetupService");
2683
+ }
2684
+ repository;
2685
+ tokens;
2686
+ authCookies;
2687
+ cookies;
2688
+ t;
2689
+ constructor(repository, tokens, authCookies, cookies2) {
2690
+ this.repository = repository;
2691
+ this.tokens = tokens;
2692
+ this.authCookies = authCookies;
2693
+ this.cookies = cookies2;
2694
+ }
2695
+ /**
2696
+ * Revoke normal auth sessions and issue a single-purpose, short-lived,
2697
+ * browser-session cookie. No access or refresh token is minted.
2698
+ */
2699
+ async begin(userId, options) {
2700
+ const resolved = this.resolveOptions(options);
2701
+ const token = randomBytes2(32).toString("base64url");
2702
+ const expiresAt = new Date(Date.now() + resolved.ttlMs).toISOString();
2703
+ await this.repository.deleteExpired();
2704
+ await this.repository.replaceActive({
2705
+ userId,
2706
+ purpose: resolved.purpose,
2707
+ tokenHash: this.hashToken(token),
2708
+ expiresAt
2709
+ });
2710
+ await this.tokens.invalidateUserAccessTokens(userId);
2711
+ await this.tokens.revokeAllForUser(userId);
2712
+ this.authCookies.clearRefreshToken();
2713
+ this.authCookies.clearSessionCookie();
2714
+ this.setCookie(token, resolved);
2715
+ return { purpose: resolved.purpose, expiresAt };
2716
+ }
2717
+ /** Validate and return the current active setup session without consuming it. */
2718
+ async require(options) {
2719
+ const resolved = this.resolveOptions(options);
2720
+ const token = this.cookies.get(resolved.cookieName);
2721
+ if (!token)
2722
+ this.sessionRequired();
2723
+ const session = await this.repository.findActive(this.hashToken(token), resolved.purpose);
2724
+ if (!session) {
2725
+ this.clearCookie(resolved);
2726
+ this.sessionInvalid();
2727
+ }
2728
+ return session;
2729
+ }
2730
+ /**
2731
+ * Atomically consume the setup session and execute the application-owned
2732
+ * credential mutation in the same database transaction. If the callback
2733
+ * fails, consumption rolls back and the browser may safely retry.
2734
+ */
2735
+ async consume(options, complete) {
2736
+ const resolved = this.resolveOptions(options);
2737
+ const token = this.cookies.get(resolved.cookieName);
2738
+ if (!token)
2739
+ this.sessionRequired();
2740
+ const session = await this.repository.consume(this.hashToken(token), resolved.purpose);
2741
+ if (!session) {
2742
+ this.clearCookie(resolved);
2743
+ this.sessionInvalid();
2744
+ }
2745
+ const result = await complete(session);
2746
+ this.clearCookie(resolved);
2747
+ return result;
2748
+ }
2749
+ async cancel(options) {
2750
+ const resolved = this.resolveOptions(options);
2751
+ const token = this.cookies.get(resolved.cookieName);
2752
+ if (token) {
2753
+ await this.repository.revoke(this.hashToken(token), resolved.purpose);
2754
+ }
2755
+ this.clearCookie(resolved);
2756
+ return { cancelled: true };
2757
+ }
2758
+ async pruneExpired() {
2759
+ await this.repository.deleteExpired();
2760
+ }
2761
+ /** Tolerates direct construction outside DI, where `t` is not injected. */
2762
+ message(key, fallback) {
2763
+ try {
2764
+ return this.t?.(key) || fallback;
2765
+ } catch {
2766
+ return fallback;
2767
+ }
2768
+ }
2769
+ sessionRequired() {
2770
+ return credentialSetupError(CREDENTIAL_SETUP_CODES.SESSION_REQUIRED, this.message("errors.credentialSetupSessionRequired", "Credential setup session is required"), 401);
2771
+ }
2772
+ sessionInvalid() {
2773
+ return credentialSetupError(CREDENTIAL_SETUP_CODES.SESSION_INVALID, this.message("errors.credentialSetupSessionInvalid", "Credential setup session is invalid or expired"), 401);
2774
+ }
2775
+ resolveOptions(options) {
2776
+ const purpose = normalizeSetupPurpose(options.purpose);
2777
+ const cookieName = options.cookieName?.trim() || DEFAULT_CREDENTIAL_SETUP_COOKIE_NAME;
2778
+ const ttlMs = options.ttlMs ?? DEFAULT_CREDENTIAL_SETUP_TTL_MS;
2779
+ const cookiePath = options.cookiePath ?? "/";
2780
+ if (!COOKIE_NAME_PATTERN.test(cookieName) || cookieName.length > 128) {
2781
+ Err11("Credential setup cookie name is invalid", 500);
2782
+ }
2783
+ if (!Number.isInteger(ttlMs) || ttlMs < 1e3 || ttlMs > MAX_TTL_MS) {
2784
+ Err11("Credential setup ttlMs must be an integer between 1000 and 86400000", 500);
2785
+ }
2786
+ if (!cookiePath.startsWith("/") || cookiePath.includes(";") || cookiePath.includes("\\")) {
2787
+ Err11("Credential setup cookiePath must be a same-origin path", 500);
2788
+ }
2789
+ return { purpose, cookieName, ttlMs, cookiePath };
2790
+ }
2791
+ hashToken(token) {
2792
+ return createHash2("sha256").update(token).digest("hex");
2793
+ }
2794
+ setCookie(token, options) {
2795
+ this.cookies.setSession(options.cookieName, token, {
2796
+ httpOnly: true,
2797
+ path: options.cookiePath,
2798
+ sameSite: "Strict",
2799
+ secure: process.env.NODE_ENV === "production"
2800
+ });
2801
+ }
2802
+ clearCookie(options) {
2803
+ this.cookies.delete(options.cookieName, {
2804
+ path: options.cookiePath,
2805
+ secure: process.env.NODE_ENV === "production"
2806
+ });
2807
+ }
2808
+ };
2809
+ __decorate15([
2810
+ I18n6("auth"),
2811
+ __metadata15("design:type", Object)
2812
+ ], CredentialSetupService.prototype, "t", void 0);
2813
+ __decorate15([
2814
+ Transaction3({ retries: 2 }),
2815
+ __metadata15("design:type", Function),
2816
+ __metadata15("design:paramtypes", [String, Object]),
2817
+ __metadata15("design:returntype", typeof (_e2 = typeof Promise !== "undefined" && Promise) === "function" ? _e2 : Object)
2818
+ ], CredentialSetupService.prototype, "begin", null);
2819
+ __decorate15([
2820
+ Transaction3({ retries: 2 }),
2821
+ __metadata15("design:type", Function),
2822
+ __metadata15("design:paramtypes", [Object, Function]),
2823
+ __metadata15("design:returntype", typeof (_f2 = typeof Promise !== "undefined" && Promise) === "function" ? _f2 : Object)
2824
+ ], CredentialSetupService.prototype, "consume", null);
2825
+ __decorate15([
2826
+ Transaction3({ retries: 2 }),
2827
+ __metadata15("design:type", Function),
2828
+ __metadata15("design:paramtypes", [Object]),
2829
+ __metadata15("design:returntype", typeof (_g2 = typeof Promise !== "undefined" && Promise) === "function" ? _g2 : Object)
2830
+ ], CredentialSetupService.prototype, "cancel", null);
2831
+ CredentialSetupService = __decorate15([
2832
+ Injectable9(),
2833
+ __metadata15("design:paramtypes", [typeof (_a9 = typeof CredentialSetupRepository !== "undefined" && CredentialSetupRepository) === "function" ? _a9 : Object, typeof (_b7 = typeof TokenService !== "undefined" && TokenService) === "function" ? _b7 : Object, typeof (_c5 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _c5 : Object, typeof (_d4 = typeof CookieService2 !== "undefined" && CookieService2) === "function" ? _d4 : Object])
2834
+ ], CredentialSetupService);
2835
+
2836
+ // src/credentialSetup/PasswordSetupService.ts
2837
+ var __decorate16 = function(decorators, target, key, desc) {
2838
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2839
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2840
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2841
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2842
+ };
2843
+ var __metadata16 = function(k, v) {
2844
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2845
+ };
2846
+ var _a10;
2847
+ var _b8;
2848
+ var _c6;
2849
+ var _d5;
2850
+ var _e3;
2851
+ var _f3;
2852
+ var PasswordSetupService = class PasswordSetupService2 {
2853
+ static {
2854
+ __name(this, "PasswordSetupService");
2855
+ }
2856
+ setup;
2857
+ requirements;
2858
+ users;
2859
+ userRecords;
2860
+ validator;
2861
+ encryption;
2862
+ config;
2863
+ t;
2864
+ constructor(setup, requirements, users, userRecords, validator, encryption) {
2865
+ this.setup = setup;
2866
+ this.requirements = requirements;
2867
+ this.users = users;
2868
+ this.userRecords = userRecords;
2869
+ this.validator = validator;
2870
+ this.encryption = encryption;
2871
+ }
2872
+ /** Tolerates direct construction outside DI, where `t` is not injected. */
2873
+ message(key, fallback) {
2874
+ try {
2875
+ return this.t?.(key) || fallback;
2876
+ } catch {
2877
+ return fallback;
2878
+ }
2879
+ }
2880
+ get options() {
2881
+ const { cookieName, ttlMs } = this.config.credentialSetup.password;
2882
+ return { purpose: PASSWORD_SETUP_PURPOSE, cookieName, ttlMs };
2883
+ }
2884
+ pending(session) {
2885
+ return {
2886
+ nextStep: "credential_setup",
2887
+ setupRequired: true,
2888
+ purpose: session.purpose,
2889
+ expiresAt: session.expiresAt
2890
+ };
2891
+ }
2892
+ /** Revoke normal sessions and hand the browser a short-lived setup cookie. */
2893
+ async begin(userId) {
2894
+ return this.pending(await this.setup.begin(userId, this.options));
2895
+ }
2896
+ /** Read the active setup session without consuming it. */
2897
+ async status() {
2898
+ return this.pending(await this.setup.require(this.options));
2899
+ }
2900
+ /**
2901
+ * Everything that can fail on the user's input is checked against the
2902
+ * *unconsumed* session, so a mistyped replacement leaves the browser able to
2903
+ * retry. Only the two writes that must agree — the password and the
2904
+ * requirement — happen inside the one-time consumption.
2905
+ */
2906
+ async change(newPassword) {
2907
+ const { userId } = await this.setup.require(this.options);
2908
+ const password = await this.validateReplacement(userId, newPassword);
2909
+ const hashed = await this.encryption.hashPassword(password);
2910
+ await this.setup.consume(this.options, (session) => this.persist(session.userId, hashed));
2911
+ return { changed: true, signInAgain: true };
2912
+ }
2913
+ async cancel() {
2914
+ return this.setup.cancel(this.options);
2915
+ }
2916
+ async validateReplacement(userId, submitted) {
2917
+ const requirement = await this.requirements.find(userId, PASSWORD_SETUP_PURPOSE);
2918
+ if (!requirement) {
2919
+ credentialSetupError(CREDENTIAL_SETUP_CODES.ALREADY_COMPLETED, this.message("errors.credentialSetupAlreadyCompleted", "The password was already replaced. Please sign in again."), 409);
2920
+ }
2921
+ const kind = resolveTemporaryCredentialKind(requirement.temporaryCredentialKind);
2922
+ const newPassword = this.validatePolicy(submitted);
2923
+ if (kind.isTemporaryShape?.(newPassword)) {
2924
+ credentialSetupError(CREDENTIAL_SETUP_CODES.PASSWORD_REJECTED, this.message("errors.credentialSetupTemporaryShape", "Choose a password that is not your temporary credential."), 400);
2925
+ }
2926
+ const user = await this.users.getAuthRecordById(userId);
2927
+ if (!user?.password) {
2928
+ credentialSetupError(CREDENTIAL_SETUP_CODES.SESSION_INVALID, this.message("errors.invalidCredentials", "Invalid email or password"), 401);
2929
+ }
2930
+ if (await this.isCurrentPassword(newPassword, kind.normalize(newPassword), user.password)) {
2931
+ credentialSetupError(CREDENTIAL_SETUP_CODES.SAME_PASSWORD, this.message("errors.credentialSetupSamePassword", "Choose a password different from your current one."), 400);
2932
+ }
2933
+ return newPassword;
2934
+ }
2935
+ /**
2936
+ * Runs inside the setup-session consumption transaction, so the password
2937
+ * update, the requirement completion, and the one-time session all commit or
2938
+ * roll back together.
2939
+ */
2940
+ async persist(userId, password) {
2941
+ await this.userRecords.update(userId, { password });
2942
+ const completed = await this.requirements.completeRequirement(userId, PASSWORD_SETUP_PURPOSE);
2943
+ if (!completed) {
2944
+ credentialSetupError(CREDENTIAL_SETUP_CODES.ALREADY_COMPLETED, this.message("errors.credentialSetupAlreadyCompleted", "The password was already replaced. Please sign in again."), 409);
2945
+ }
2946
+ return userId;
2947
+ }
2948
+ validatePolicy(submitted) {
2949
+ const parsed = this.config.credentialSetup.password.passwordSchema.safeParse(submitted);
2950
+ if (!parsed.success) {
2951
+ credentialSetupError(CREDENTIAL_SETUP_CODES.PASSWORD_REJECTED, parsed.error.issues[0]?.message ?? this.message("errors.credentialSetupPasswordRejected", "Choose a different password."), 422);
2952
+ }
2953
+ return parsed.data;
2954
+ }
2955
+ /**
2956
+ * The stored hash is of the *normalized* temporary credential, so a
2957
+ * differently-cased retype has to be compared in both forms.
2958
+ */
2959
+ async isCurrentPassword(submitted, normalized, storedHash) {
2960
+ if (await this.validator.comparePassword(submitted, storedHash))
2961
+ return true;
2962
+ if (normalized === submitted)
2963
+ return false;
2964
+ return this.validator.comparePassword(normalized, storedHash);
2965
+ }
2966
+ };
2967
+ __decorate16([
2968
+ Inject10(AUTH_CONFIG),
2969
+ __metadata16("design:type", Object)
2970
+ ], PasswordSetupService.prototype, "config", void 0);
2971
+ __decorate16([
2972
+ I18n7("auth"),
2973
+ __metadata16("design:type", Object)
2974
+ ], PasswordSetupService.prototype, "t", void 0);
2975
+ PasswordSetupService = __decorate16([
2976
+ Injectable10(),
2977
+ __metadata16("design:paramtypes", [typeof (_a10 = typeof CredentialSetupService !== "undefined" && CredentialSetupService) === "function" ? _a10 : Object, typeof (_b8 = typeof CredentialSetupRequirementService !== "undefined" && CredentialSetupRequirementService) === "function" ? _b8 : Object, typeof (_c6 = typeof UserService !== "undefined" && UserService) === "function" ? _c6 : Object, typeof (_d5 = typeof UserRepository !== "undefined" && UserRepository) === "function" ? _d5 : Object, typeof (_e3 = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _e3 : Object, typeof (_f3 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _f3 : Object])
2978
+ ], PasswordSetupService);
2979
+
2980
+ // src/auth/AuthService.ts
2981
+ var __decorate17 = function(decorators, target, key, desc) {
2982
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2983
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2984
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2985
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2986
+ };
2987
+ var __metadata17 = function(k, v) {
2988
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2989
+ };
2990
+ var _a11;
2991
+ var _b9;
2992
+ var _c7;
2993
+ var _d6;
2994
+ var _e4;
2995
+ var _f4;
2996
+ var _g3;
2997
+ var _h2;
2998
+ var _j;
2999
+ var _k;
3000
+ var _l;
3001
+ var AuthService = class AuthService2 {
3002
+ static {
3003
+ __name(this, "AuthService");
3004
+ }
3005
+ tokenService;
3006
+ userService;
3007
+ userValidator;
3008
+ encryptionService;
3009
+ cookieManager;
3010
+ i18nService;
3011
+ emailService;
3012
+ authSessionService;
3013
+ credentialSetupRequirements;
3014
+ passwordSetup;
3015
+ config;
3016
+ t;
3017
+ logger;
3018
+ dummyHash;
3019
+ constructor(tokenService, userService, userValidator, encryptionService, cookieManager, i18nService, emailService, authSessionService, credentialSetupRequirements, passwordSetup) {
3020
+ this.tokenService = tokenService;
3021
+ this.userService = userService;
3022
+ this.userValidator = userValidator;
3023
+ this.encryptionService = encryptionService;
3024
+ this.cookieManager = cookieManager;
3025
+ this.i18nService = i18nService;
3026
+ this.emailService = emailService;
3027
+ this.authSessionService = authSessionService;
3028
+ this.credentialSetupRequirements = credentialSetupRequirements;
3029
+ this.passwordSetup = passwordSetup;
3030
+ }
3031
+ isLockoutActive(lockoutUntil) {
3032
+ if (!lockoutUntil)
3033
+ return false;
3034
+ return new Date(lockoutUntil).getTime() > Date.now();
3035
+ }
3036
+ nextLockoutUntil() {
3037
+ const durationMs = timestring3(this.config.lockout.duration, "ms");
3038
+ return new Date(Date.now() + durationMs).toISOString();
3039
+ }
3040
+ getDummyHash() {
3041
+ this.dummyHash ??= this.encryptionService.hashPassword("najm-auth-dummy-password");
3042
+ return this.dummyHash;
3043
+ }
3044
+ async warmupPasswordHash() {
3045
+ await this.getDummyHash();
3046
+ }
3047
+ async registerUser(body) {
2248
3048
  return await this.userService.create({
2249
3049
  name: body.name,
2250
3050
  email: body.email,
@@ -2268,6 +3068,7 @@ var AuthService = class AuthService2 {
2268
3068
  id: body.id,
2269
3069
  name: body.name,
2270
3070
  email: body.email,
3071
+ phone: body.phone,
2271
3072
  role: body.role,
2272
3073
  roleId: body.roleId,
2273
3074
  image: body.image,
@@ -2298,24 +3099,79 @@ var AuthService = class AuthService2 {
2298
3099
  * Returns the created (sanitized) user so the caller can link `userId`.
2299
3100
  */
2300
3101
  async provisionUser(body) {
2301
- const password = typeof body.password === "string" ? body.password.trim() : "";
3102
+ const input = body;
3103
+ if (input.requireCredentialSetup) {
3104
+ return this.provisionWithCredentialSetup(input);
3105
+ }
3106
+ if (input.temporaryCredential) {
3107
+ Err12("provisionUser requires requireCredentialSetup when a temporaryCredential is supplied", 400);
3108
+ }
3109
+ const password = typeof input.password === "string" ? input.password.trim() : "";
2302
3110
  if (password) {
2303
3111
  return this.userService.create({
2304
- id: body.id,
2305
- name: body.name,
2306
- email: body.email,
2307
- role: body.role,
2308
- roleId: body.roleId,
2309
- image: body.image,
3112
+ id: input.id,
3113
+ name: input.name,
3114
+ email: input.email,
3115
+ phone: input.phone,
3116
+ role: input.role,
3117
+ roleId: input.roleId,
3118
+ image: input.image,
2310
3119
  password,
2311
- status: body.status ?? "active"
3120
+ status: input.status ?? "active"
2312
3121
  });
2313
3122
  }
2314
- return this.inviteUser(body);
3123
+ return this.inviteUser(input);
3124
+ }
3125
+ /**
3126
+ * Create the account and mark the durable requirement in one transaction, so
3127
+ * a user never exists holding a temporary credential that nothing forces
3128
+ * them to replace. No session is issued here.
3129
+ */
3130
+ async provisionWithCredentialSetup(body) {
3131
+ if (body.password != null) {
3132
+ Err12("provisionUser cannot set a password and a temporaryCredential at the same time", 400);
3133
+ }
3134
+ if (!body.temporaryCredential) {
3135
+ Err12("provisionUser requires a temporaryCredential when credential setup is required", 400);
3136
+ }
3137
+ if (!this.credentialSetupRequirements) {
3138
+ Err12.invalidOperation("Credential setup is unavailable: CredentialSetupRequirementService is not registered");
3139
+ }
3140
+ const temporary = toTemporaryCredential(body.temporaryCredential);
3141
+ const kind = resolveTemporaryCredentialKind(temporary.kind);
3142
+ if (kind.isTemporaryShape && !kind.isTemporaryShape(temporary.value)) {
3143
+ Err12(`Invalid temporary credential for kind '${kind.name}'`, 400);
3144
+ }
3145
+ const password = kind.normalize(temporary.value);
3146
+ if (!password?.trim()) {
3147
+ Err12("provisionUser requires a non-empty temporaryCredential", 400);
3148
+ }
3149
+ const user = await this.userService.create({
3150
+ id: body.id,
3151
+ name: body.name,
3152
+ email: body.email,
3153
+ phone: body.phone,
3154
+ role: body.role,
3155
+ roleId: body.roleId,
3156
+ image: body.image,
3157
+ password,
3158
+ status: body.status ?? "active"
3159
+ }, { validatePasswordStrength: false });
3160
+ await this.credentialSetupRequirements.markRequired(user.id, body.requireCredentialSetup, {
3161
+ temporaryCredentialKind: kind.name
3162
+ });
3163
+ return user;
2315
3164
  }
2316
3165
  async loginUser(body) {
2317
- const user = await this.verifyCredentials(body);
2318
- return this.establishSession(user);
3166
+ const { user, requirement } = await this.authenticate(body, { kind: "active" });
3167
+ if (requirement) {
3168
+ if (!this.passwordSetup) {
3169
+ Err12.invalidOperation("Credential setup is required but PasswordSetupService is not registered");
3170
+ }
3171
+ return this.passwordSetup.begin(user.id);
3172
+ }
3173
+ const session = await this.establishSession(user);
3174
+ return { ...session, nextStep: "authenticated" };
2319
3175
  }
2320
3176
  /**
2321
3177
  * Verify credentials and account policy without minting access/refresh
@@ -2323,7 +3179,7 @@ var AuthService = class AuthService2 {
2323
3179
  * this before issuing a purpose-bound CredentialSetupService session.
2324
3180
  */
2325
3181
  async verifyCredentials(body) {
2326
- return this.verifyCredentialsForPolicy(body, { kind: "active" });
3182
+ return (await this.authenticate(body, { kind: "active" })).user;
2327
3183
  }
2328
3184
  /**
2329
3185
  * Verify a pending, unverified account for one exact application role.
@@ -2332,17 +3188,22 @@ var AuthService = class AuthService2 {
2332
3188
  */
2333
3189
  async verifyPendingCredentials(body, expectedRole) {
2334
3190
  if (!expectedRole.trim()) {
2335
- Err8(this.t("errors.invalidCredentials"), 401);
3191
+ Err12(this.t("errors.invalidCredentials"), 401);
2336
3192
  }
2337
- return this.verifyCredentialsForPolicy(body, {
3193
+ return (await this.authenticate(body, {
2338
3194
  kind: "pending",
2339
3195
  expectedRole: expectedRole.trim().toLowerCase()
2340
- });
3196
+ })).user;
2341
3197
  }
2342
- async verifyCredentialsForPolicy(body, policy) {
2343
- const password = body.password;
3198
+ /**
3199
+ * The one credential path. Resolves identity, the durable setup requirement,
3200
+ * and the credential normalization that requirement implies — in that order —
3201
+ * before a single hash comparison decides the outcome. Nothing about the
3202
+ * requirement is revealed until credentials and account policy have passed.
3203
+ */
3204
+ async authenticate(body, policy) {
2344
3205
  const rawIdentifier = "identifier" in body ? body.identifier : body.email;
2345
- const identifier = normalizeAuthIdentifier(rawIdentifier);
3206
+ const identifier = this.config.identity?.resolve(rawIdentifier) ?? normalizeAuthIdentifier(rawIdentifier);
2346
3207
  let user;
2347
3208
  if (identifier && isEmailIdentifier(identifier)) {
2348
3209
  user = await this.userService.findByEmailInsensitive(identifier);
@@ -2356,42 +3217,65 @@ var AuthService = class AuthService2 {
2356
3217
  user.lockoutUntil = null;
2357
3218
  }
2358
3219
  if (user && this.isLockoutActive(user.lockoutUntil)) {
2359
- Err8(this.t("errors.accountLocked"), 423);
3220
+ Err12(this.t("errors.accountLocked"), 423);
2360
3221
  }
2361
- const storedHash = user?.password ?? await this.getDummyHash();
2362
- const isValid = await this.userValidator.comparePassword(password, storedHash);
3222
+ const requirement = await this.credentialSetupRequirements?.find(user?.id ?? "", PASSWORD_SETUP_PURPOSE);
3223
+ const { credential, kindUnavailable } = this.resolveLoginCredential(body.password, requirement);
3224
+ const storedHash = kindUnavailable || !user?.password ? await this.getDummyHash() : user.password;
3225
+ const isValid = await this.userValidator.comparePassword(credential, storedHash);
2363
3226
  if (!user || !isValid) {
2364
3227
  if (user) {
2365
3228
  const attempts = await this.userService.incrementFailedAttempts(user.id);
2366
3229
  if (attempts >= this.config.lockout.maxAttempts) {
2367
3230
  await this.userService.setLockout(user.id, this.nextLockoutUntil());
2368
- Err8(this.t("errors.accountLocked"), 423);
3231
+ Err12(this.t("errors.accountLocked"), 423);
2369
3232
  }
2370
3233
  }
2371
- Err8(this.t("errors.invalidCredentials"), 401);
3234
+ Err12(this.t("errors.invalidCredentials"), 401);
2372
3235
  }
2373
3236
  if (policy.kind === "pending") {
2374
3237
  const role = typeof user.role === "string" ? user.role.toLowerCase() : "";
2375
3238
  if (user.status !== "pending" || user.emailVerified || role !== policy.expectedRole) {
2376
- Err8(this.t("errors.invalidCredentials"), 401);
3239
+ Err12(this.t("errors.invalidCredentials"), 401);
2377
3240
  }
2378
3241
  } else {
2379
3242
  if (user.status !== "active") {
2380
- Err8(this.t("errors.accountInactive"), 403);
3243
+ Err12(this.t("errors.accountInactive"), 403);
2381
3244
  }
2382
3245
  if (this.config.requireVerifiedEmail && !user.emailVerified) {
2383
- Err8(this.t("errors.emailNotVerified"), 403);
3246
+ Err12(this.t("errors.emailNotVerified"), 403);
2384
3247
  }
2385
3248
  }
2386
3249
  if ((user.failedLoginAttempts ?? 0) > 0 || user.lockoutUntil) {
2387
3250
  await this.userService.resetFailedAttempts(user.id);
2388
3251
  }
2389
3252
  const { password: _, failedLoginAttempts: __, lockoutUntil: ___, ...sanitized } = user;
2390
- return sanitized;
3253
+ return { user: sanitized, requirement };
3254
+ }
3255
+ /**
3256
+ * A user-chosen password is compared byte-for-byte. Only an active
3257
+ * requirement, and only its own stored kind, can transform the submitted
3258
+ * value — so lowercasing a CIN never leaks into normal logins.
3259
+ */
3260
+ resolveLoginCredential(password, requirement) {
3261
+ if (!requirement)
3262
+ return { credential: password, kindUnavailable: false };
3263
+ try {
3264
+ const kind = resolveTemporaryCredentialKind(requirement.temporaryCredentialKind);
3265
+ return { credential: kind.normalize(password), kindUnavailable: false };
3266
+ } catch (error) {
3267
+ this.logger.error("Unresolvable temporary credential kind on an active requirement", {
3268
+ userId: requirement.userId,
3269
+ purpose: requirement.purpose,
3270
+ kind: requirement.temporaryCredentialKind,
3271
+ error
3272
+ });
3273
+ return { credential: password, kindUnavailable: true };
3274
+ }
2391
3275
  }
2392
3276
  /** Establish a complete normal auth session for an already verified user. */
2393
3277
  async establishSession(user) {
2394
- this.authSessionService ??= new AuthSessionService(this.tokenService, this.userService, this.cookieManager);
3278
+ this.authSessionService ??= new AuthSessionService(this.tokenService, this.userService, this.cookieManager, this.credentialSetupRequirements);
2395
3279
  return this.authSessionService.establish(user);
2396
3280
  }
2397
3281
  async refreshTokens() {
@@ -2509,11 +3393,11 @@ var AuthService = class AuthService2 {
2509
3393
  async changePassword(userId, currentPassword, newPassword) {
2510
3394
  const user = await this.userService.getAuthRecordById(userId);
2511
3395
  if (!user?.password) {
2512
- Err8(this.t("errors.invalidCredentials"), 401);
3396
+ Err12(this.t("errors.invalidCredentials"), 401);
2513
3397
  }
2514
3398
  const isValid = await this.userValidator.comparePassword(currentPassword, user.password);
2515
3399
  if (!isValid) {
2516
- Err8(this.t("errors.invalidCredentials"), 401);
3400
+ Err12(this.t("errors.invalidCredentials"), 401);
2517
3401
  }
2518
3402
  this.userValidator.validatePasswordStrength(newPassword);
2519
3403
  await this.userService.update(userId, { password: newPassword });
@@ -2534,33 +3418,39 @@ var AuthService = class AuthService2 {
2534
3418
  return { message: this.t("success.passwordReset") };
2535
3419
  }
2536
3420
  };
2537
- __decorate12([
2538
- Inject8(AUTH_CONFIG),
2539
- __metadata12("design:type", Object)
3421
+ __decorate17([
3422
+ Inject11(AUTH_CONFIG),
3423
+ __metadata17("design:type", Object)
2540
3424
  ], AuthService.prototype, "config", void 0);
2541
- __decorate12([
2542
- I18n6("auth"),
2543
- __metadata12("design:type", Object)
3425
+ __decorate17([
3426
+ I18n8("auth"),
3427
+ __metadata17("design:type", Object)
2544
3428
  ], AuthService.prototype, "t", void 0);
2545
- __decorate12([
3429
+ __decorate17([
2546
3430
  Log(),
2547
- __metadata12("design:type", Object)
3431
+ __metadata17("design:type", Object)
2548
3432
  ], AuthService.prototype, "logger", void 0);
2549
- AuthService = __decorate12([
2550
- Injectable8(),
2551
- __metadata12("design:paramtypes", [typeof (_a8 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a8 : Object, typeof (_b6 = typeof UserService !== "undefined" && UserService) === "function" ? _b6 : Object, typeof (_c4 = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _c4 : Object, typeof (_d2 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _d2 : Object, typeof (_e2 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _e2 : Object, typeof (_f2 = typeof I18nService2 !== "undefined" && I18nService2) === "function" ? _f2 : Object, typeof (_g2 = typeof EmailService !== "undefined" && EmailService) === "function" ? _g2 : Object, typeof (_h2 = typeof AuthSessionService !== "undefined" && AuthSessionService) === "function" ? _h2 : Object])
3433
+ __decorate17([
3434
+ Transaction4(),
3435
+ __metadata17("design:type", Function),
3436
+ __metadata17("design:paramtypes", [Object]),
3437
+ __metadata17("design:returntype", typeof (_l = typeof Promise !== "undefined" && Promise) === "function" ? _l : Object)
3438
+ ], AuthService.prototype, "provisionWithCredentialSetup", null);
3439
+ AuthService = __decorate17([
3440
+ Injectable11(),
3441
+ __metadata17("design:paramtypes", [typeof (_a11 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a11 : Object, typeof (_b9 = typeof UserService !== "undefined" && UserService) === "function" ? _b9 : Object, typeof (_c7 = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _c7 : Object, typeof (_d6 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _d6 : Object, typeof (_e4 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _e4 : Object, typeof (_f4 = typeof I18nService2 !== "undefined" && I18nService2) === "function" ? _f4 : Object, typeof (_g3 = typeof EmailService !== "undefined" && EmailService) === "function" ? _g3 : Object, typeof (_h2 = typeof AuthSessionService !== "undefined" && AuthSessionService) === "function" ? _h2 : Object, typeof (_j = typeof CredentialSetupRequirementService !== "undefined" && CredentialSetupRequirementService) === "function" ? _j : Object, typeof (_k = typeof PasswordSetupService !== "undefined" && PasswordSetupService) === "function" ? _k : Object])
2552
3442
  ], AuthService);
2553
3443
 
2554
3444
  // src/auth/AuthGuard.ts
2555
3445
  import { Service as Service2, User } from "najm-core";
2556
3446
  import { createGuard } from "najm-guard";
2557
- var __decorate13 = function(decorators, target, key, desc) {
3447
+ var __decorate18 = function(decorators, target, key, desc) {
2558
3448
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2559
3449
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2560
3450
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2561
3451
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2562
3452
  };
2563
- var __metadata13 = function(k, v) {
3453
+ var __metadata18 = function(k, v) {
2564
3454
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2565
3455
  };
2566
3456
  var __param3 = function(paramIndex, decorator) {
@@ -2576,13 +3466,13 @@ var AuthGuard = class AuthGuard2 {
2576
3466
  return !!user;
2577
3467
  }
2578
3468
  };
2579
- __decorate13([
3469
+ __decorate18([
2580
3470
  __param3(0, User()),
2581
- __metadata13("design:type", Function),
2582
- __metadata13("design:paramtypes", [Object]),
2583
- __metadata13("design:returntype", Boolean)
3471
+ __metadata18("design:type", Function),
3472
+ __metadata18("design:paramtypes", [Object]),
3473
+ __metadata18("design:returntype", Boolean)
2584
3474
  ], AuthGuard.prototype, "canActivate", null);
2585
- AuthGuard = __decorate13([
3475
+ AuthGuard = __decorate18([
2586
3476
  Service2()
2587
3477
  ], AuthGuard);
2588
3478
  var isAuth = createGuard(AuthGuard);
@@ -2591,13 +3481,13 @@ var isAuth = createGuard(AuthGuard);
2591
3481
  import { Service as Service3 } from "najm-core";
2592
3482
  import { GuardParams, Role as RequestRole } from "najm-core";
2593
3483
  import { composeGuards, createGuard as createGuard2 } from "najm-guard";
2594
- var __decorate14 = function(decorators, target, key, desc) {
3484
+ var __decorate19 = function(decorators, target, key, desc) {
2595
3485
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2596
3486
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2597
3487
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2598
3488
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2599
3489
  };
2600
- var __metadata14 = function(k, v) {
3490
+ var __metadata19 = function(k, v) {
2601
3491
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2602
3492
  };
2603
3493
  var __param4 = function(paramIndex, decorator) {
@@ -2620,14 +3510,14 @@ var RoleGuard = class RoleGuard2 {
2620
3510
  return false;
2621
3511
  }
2622
3512
  };
2623
- __decorate14([
3513
+ __decorate19([
2624
3514
  __param4(0, GuardParams()),
2625
3515
  __param4(1, RequestRole()),
2626
- __metadata14("design:type", Function),
2627
- __metadata14("design:paramtypes", [Object, String]),
2628
- __metadata14("design:returntype", void 0)
3516
+ __metadata19("design:type", Function),
3517
+ __metadata19("design:paramtypes", [Object, String]),
3518
+ __metadata19("design:returntype", void 0)
2629
3519
  ], RoleGuard.prototype, "canActivate", null);
2630
- RoleGuard = __decorate14([
3520
+ RoleGuard = __decorate19([
2631
3521
  Service3()
2632
3522
  ], RoleGuard);
2633
3523
  var Role = createGuard2(RoleGuard);
@@ -2637,7 +3527,23 @@ var isAdministrator = composeGuards(isAuth(), Role(ROLE_GROUPS.ADMINISTRATORS));
2637
3527
  // src/auth/AuthController.ts
2638
3528
  import { Validate } from "najm-validation";
2639
3529
  import { RateLimit } from "najm-rate";
2640
- import { createHash as createHash2 } from "crypto";
3530
+ import { createHash as createHash3 } from "crypto";
3531
+
3532
+ // src/identity/requestResolver.ts
3533
+ var CONTEXT_RESOLVER_KEY = "najm.auth.identityResolver";
3534
+ var defaultResolver2 = createIdentityResolver();
3535
+ function setRequestIdentityResolver(context, resolver) {
3536
+ context.set(CONTEXT_RESOLVER_KEY, resolver);
3537
+ }
3538
+ __name(setRequestIdentityResolver, "setRequestIdentityResolver");
3539
+ function getRequestIdentityResolver(context) {
3540
+ try {
3541
+ return context.get(CONTEXT_RESOLVER_KEY) ?? defaultResolver2;
3542
+ } catch {
3543
+ return defaultResolver2;
3544
+ }
3545
+ }
3546
+ __name(getRequestIdentityResolver, "getRequestIdentityResolver");
2641
3547
 
2642
3548
  // src/users/UserDto.ts
2643
3549
  import { z } from "zod";
@@ -2670,14 +3576,17 @@ var userIdParam = z.object({
2670
3576
  id: z.string().min(1, "User ID is required")
2671
3577
  });
2672
3578
  var identifierField = z.string().trim().min(1).max(254);
3579
+ var loginCredentialField = z.string().min(1, "Password is required").refine((v) => new TextEncoder().encode(v).length <= 72, "Password must be at most 72 bytes");
2673
3580
  var loginDto = z.union([
2674
3581
  z.object({
2675
3582
  identifier: identifierField,
2676
- password: passwordField
3583
+ password: loginCredentialField,
3584
+ rememberMe: z.boolean().optional()
2677
3585
  }),
2678
3586
  z.object({
2679
3587
  email: emailField,
2680
- password: passwordField
3588
+ password: loginCredentialField,
3589
+ rememberMe: z.boolean().optional()
2681
3590
  })
2682
3591
  ]);
2683
3592
  var changePasswordDto = z.object({
@@ -2710,13 +3619,13 @@ var userListQuery = z.object({
2710
3619
  });
2711
3620
 
2712
3621
  // src/auth/AuthController.ts
2713
- var __decorate15 = function(decorators, target, key, desc) {
3622
+ var __decorate20 = function(decorators, target, key, desc) {
2714
3623
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2715
3624
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2716
3625
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2717
3626
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2718
3627
  };
2719
- var __metadata15 = function(k, v) {
3628
+ var __metadata20 = function(k, v) {
2720
3629
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2721
3630
  };
2722
3631
  var __param5 = function(paramIndex, decorator) {
@@ -2724,8 +3633,8 @@ var __param5 = function(paramIndex, decorator) {
2724
3633
  decorator(target, key, paramIndex);
2725
3634
  };
2726
3635
  };
2727
- var _a9;
2728
- var hashKeyPart = /* @__PURE__ */ __name((value) => createHash2("sha256").update(value).digest("base64url").slice(0, 32), "hashKeyPart");
3636
+ var _a12;
3637
+ var hashKeyPart = /* @__PURE__ */ __name((value) => createHash3("sha256").update(value).digest("base64url").slice(0, 32), "hashKeyPart");
2729
3638
  var cookieFingerprint = /* @__PURE__ */ __name(() => (ctx) => {
2730
3639
  const ip = ctx.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? ctx.req.header("x-real-ip") ?? "unknown";
2731
3640
  const cookie = ctx.req.raw.headers.get("cookie") ?? "";
@@ -2737,7 +3646,7 @@ var authIdentityRateLimitKey = /* @__PURE__ */ __name(async (ctx) => {
2737
3646
  try {
2738
3647
  const body = await ctx.req.json();
2739
3648
  const identity = body?.identifier ?? body?.email;
2740
- const normalizedIdentity = normalizeAuthIdentifier(identity);
3649
+ const normalizedIdentity = getRequestIdentityResolver(ctx)(identity);
2741
3650
  if (normalizedIdentity) {
2742
3651
  return `${ip}:${hashKeyPart(normalizedIdentity)}`;
2743
3652
  }
@@ -2767,7 +3676,7 @@ var AuthController = class AuthController2 {
2767
3676
  }
2768
3677
  async recoverSession(recoveryRequest, ctx) {
2769
3678
  if (recoveryRequest !== "1") {
2770
- Err9("Invalid session recovery request", 400);
3679
+ Err13("Invalid session recovery request", 400);
2771
3680
  }
2772
3681
  ctx.header("Cache-Control", "private, no-store");
2773
3682
  ctx.header("Vary", "Cookie");
@@ -2789,123 +3698,123 @@ var AuthController = class AuthController2 {
2789
3698
  return this.authService.resetPassword(body.token, body.newPassword);
2790
3699
  }
2791
3700
  };
2792
- __decorate15([
3701
+ __decorate20([
2793
3702
  Post("/register"),
2794
3703
  RateLimit({ limit: 5, window: "15m", key: authIdentityRateLimitKey }),
2795
3704
  Validate(registerDto),
2796
3705
  ResMsg("auth.success.register"),
2797
3706
  __param5(0, Body()),
2798
- __metadata15("design:type", Function),
2799
- __metadata15("design:paramtypes", [Object]),
2800
- __metadata15("design:returntype", Promise)
3707
+ __metadata20("design:type", Function),
3708
+ __metadata20("design:paramtypes", [Object]),
3709
+ __metadata20("design:returntype", Promise)
2801
3710
  ], AuthController.prototype, "registerUser", null);
2802
- __decorate15([
3711
+ __decorate20([
2803
3712
  Post("/login"),
2804
3713
  RateLimit({ limit: 5, window: "15m", key: authIdentityRateLimitKey, message: "Too many login attempts. Please try again later." }),
2805
3714
  Validate(loginDto),
2806
3715
  ResMsg("auth.success.login"),
2807
3716
  __param5(0, Body()),
2808
- __metadata15("design:type", Function),
2809
- __metadata15("design:paramtypes", [Object]),
2810
- __metadata15("design:returntype", Promise)
3717
+ __metadata20("design:type", Function),
3718
+ __metadata20("design:paramtypes", [Object]),
3719
+ __metadata20("design:returntype", Promise)
2811
3720
  ], AuthController.prototype, "loginUser", null);
2812
- __decorate15([
3721
+ __decorate20([
2813
3722
  Post("/invite"),
2814
3723
  isAdmin(),
2815
3724
  RateLimit({ limit: 20, window: "15m", key: "user" }),
2816
3725
  Validate(inviteUserDto),
2817
3726
  ResMsg("auth.success.accountInviteSent"),
2818
3727
  __param5(0, Body()),
2819
- __metadata15("design:type", Function),
2820
- __metadata15("design:paramtypes", [Object]),
2821
- __metadata15("design:returntype", Promise)
3728
+ __metadata20("design:type", Function),
3729
+ __metadata20("design:paramtypes", [Object]),
3730
+ __metadata20("design:returntype", Promise)
2822
3731
  ], AuthController.prototype, "inviteUser", null);
2823
- __decorate15([
3732
+ __decorate20([
2824
3733
  Post("/refresh"),
2825
3734
  RateLimit({ limit: 15, window: "15m", key: cookieFingerprint() }),
2826
3735
  ResMsg("auth.success.tokenRefreshed"),
2827
- __metadata15("design:type", Function),
2828
- __metadata15("design:paramtypes", []),
2829
- __metadata15("design:returntype", Promise)
3736
+ __metadata20("design:type", Function),
3737
+ __metadata20("design:paramtypes", []),
3738
+ __metadata20("design:returntype", Promise)
2830
3739
  ], AuthController.prototype, "refreshTokens", null);
2831
- __decorate15([
3740
+ __decorate20([
2832
3741
  Post("/session/recover"),
2833
3742
  RateLimit({ limit: 120, window: "1m", key: cookieFingerprint() }),
2834
3743
  ResMsg("auth.success.sessionRecovered"),
2835
3744
  __param5(0, Headers("x-najm-session-recovery")),
2836
3745
  __param5(1, Ctx()),
2837
- __metadata15("design:type", Function),
2838
- __metadata15("design:paramtypes", [String, Object]),
2839
- __metadata15("design:returntype", Promise)
3746
+ __metadata20("design:type", Function),
3747
+ __metadata20("design:paramtypes", [String, Object]),
3748
+ __metadata20("design:returntype", Promise)
2840
3749
  ], AuthController.prototype, "recoverSession", null);
2841
- __decorate15([
3750
+ __decorate20([
2842
3751
  Post("/logout"),
2843
3752
  isAuth(),
2844
3753
  RateLimit({ limit: 10, window: "15m", key: "user" }),
2845
3754
  __param5(0, User2("id")),
2846
3755
  __param5(1, Headers("authorization")),
2847
- __metadata15("design:type", Function),
2848
- __metadata15("design:paramtypes", [String, String]),
2849
- __metadata15("design:returntype", Promise)
3756
+ __metadata20("design:type", Function),
3757
+ __metadata20("design:paramtypes", [String, String]),
3758
+ __metadata20("design:returntype", Promise)
2850
3759
  ], AuthController.prototype, "logoutUser", null);
2851
- __decorate15([
3760
+ __decorate20([
2852
3761
  Post("/change-password"),
2853
3762
  isAuth(),
2854
3763
  Validate(changePasswordDto),
2855
3764
  ResMsg("auth.success.passwordChanged"),
2856
3765
  __param5(0, User2("id")),
2857
3766
  __param5(1, Body()),
2858
- __metadata15("design:type", Function),
2859
- __metadata15("design:paramtypes", [String, Object]),
2860
- __metadata15("design:returntype", Promise)
3767
+ __metadata20("design:type", Function),
3768
+ __metadata20("design:paramtypes", [String, Object]),
3769
+ __metadata20("design:returntype", Promise)
2861
3770
  ], AuthController.prototype, "changePassword", null);
2862
- __decorate15([
3771
+ __decorate20([
2863
3772
  Get("/me"),
2864
3773
  RateLimit({ limit: 30, window: "1m", key: cookieFingerprint() }),
2865
3774
  ResMsg("auth.users.success.retrieved"),
2866
3775
  __param5(0, Headers("authorization")),
2867
- __metadata15("design:type", Function),
2868
- __metadata15("design:paramtypes", [String]),
2869
- __metadata15("design:returntype", Promise)
3776
+ __metadata20("design:type", Function),
3777
+ __metadata20("design:paramtypes", [String]),
3778
+ __metadata20("design:returntype", Promise)
2870
3779
  ], AuthController.prototype, "userProfile", null);
2871
- __decorate15([
3780
+ __decorate20([
2872
3781
  Post("/forgot-password"),
2873
3782
  RateLimit({ limit: 3, window: "15m", key: authIdentityRateLimitKey, message: "Too many password reset requests. Please try again later." }),
2874
3783
  Validate(resetPasswordDto),
2875
3784
  ResMsg("auth.success.passwordResetSent"),
2876
3785
  __param5(0, Body()),
2877
- __metadata15("design:type", Function),
2878
- __metadata15("design:paramtypes", [Object]),
2879
- __metadata15("design:returntype", Promise)
3786
+ __metadata20("design:type", Function),
3787
+ __metadata20("design:paramtypes", [Object]),
3788
+ __metadata20("design:returntype", Promise)
2880
3789
  ], AuthController.prototype, "forgotPassword", null);
2881
- __decorate15([
3790
+ __decorate20([
2882
3791
  Post("/reset-password"),
2883
3792
  RateLimit({ limit: 5, window: "15m", key: "ip", message: "Too many password reset attempts. Please try again later." }),
2884
3793
  Validate(confirmResetPasswordDto),
2885
3794
  ResMsg("auth.success.passwordReset"),
2886
3795
  __param5(0, Body()),
2887
- __metadata15("design:type", Function),
2888
- __metadata15("design:paramtypes", [Object]),
2889
- __metadata15("design:returntype", Promise)
3796
+ __metadata20("design:type", Function),
3797
+ __metadata20("design:paramtypes", [Object]),
3798
+ __metadata20("design:returntype", Promise)
2890
3799
  ], AuthController.prototype, "resetPassword", null);
2891
- AuthController = __decorate15([
3800
+ AuthController = __decorate20([
2892
3801
  Controller("/auth"),
2893
- __metadata15("design:paramtypes", [typeof (_a9 = typeof AuthService !== "undefined" && AuthService) === "function" ? _a9 : Object])
3802
+ __metadata20("design:paramtypes", [typeof (_a12 = typeof AuthService !== "undefined" && AuthService) === "function" ? _a12 : Object])
2894
3803
  ], AuthController);
2895
3804
 
2896
3805
  // src/auth/AuthResolver.ts
2897
- import { APP, Container, DI, Inject as Inject9, LOGGER, Meta, Service as Service4 } from "najm-core";
3806
+ import { APP, Container, DI, Inject as Inject12, LOGGER, Meta, Service as Service4 } from "najm-core";
2898
3807
  import { USER, ROLE, PERMISSIONS } from "najm-guard";
2899
- var __decorate16 = function(decorators, target, key, desc) {
3808
+ var __decorate21 = function(decorators, target, key, desc) {
2900
3809
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2901
3810
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2902
3811
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2903
3812
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2904
3813
  };
2905
- var __metadata16 = function(k, v) {
3814
+ var __metadata21 = function(k, v) {
2906
3815
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2907
3816
  };
2908
- var _a10;
3817
+ var _a13;
2909
3818
  var AuthResolver = class AuthResolver2 {
2910
3819
  static {
2911
3820
  __name(this, "AuthResolver");
@@ -3016,27 +3925,76 @@ var AuthResolver = class AuthResolver2 {
3016
3925
  await next();
3017
3926
  });
3018
3927
  }
3019
- async onReady() {
3020
- const authService = await this.container.resolve(AuthService);
3021
- await authService.warmupPasswordHash();
3928
+ async onReady() {
3929
+ const authService = await this.container.resolve(AuthService);
3930
+ await authService.warmupPasswordHash();
3931
+ }
3932
+ };
3933
+ __decorate21([
3934
+ DI(),
3935
+ __metadata21("design:type", typeof (_a13 = typeof Container !== "undefined" && Container) === "function" ? _a13 : Object)
3936
+ ], AuthResolver.prototype, "container", void 0);
3937
+ __decorate21([
3938
+ Inject12(APP),
3939
+ __metadata21("design:type", Object)
3940
+ ], AuthResolver.prototype, "app", void 0);
3941
+ __decorate21([
3942
+ Inject12(LOGGER),
3943
+ __metadata21("design:type", Object)
3944
+ ], AuthResolver.prototype, "log", void 0);
3945
+ AuthResolver = __decorate21([
3946
+ Service4(),
3947
+ Meta({ layer: "plugin", order: 30 })
3948
+ ], AuthResolver);
3949
+
3950
+ // src/auth/AuthIdentityContextService.ts
3951
+ import { DI as DI2, Inject as Inject13, INJECTION_TYPES, Meta as Meta2, Service as Service5 } from "najm-core";
3952
+ var __decorate22 = function(decorators, target, key, desc) {
3953
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3954
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3955
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3956
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
3957
+ };
3958
+ var __metadata22 = function(k, v) {
3959
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3960
+ };
3961
+ var __param6 = function(paramIndex, decorator) {
3962
+ return function(target, key) {
3963
+ decorator(target, key, paramIndex);
3964
+ };
3965
+ };
3966
+ var AuthIdentityContextService = class AuthIdentityContextService2 {
3967
+ static {
3968
+ __name(this, "AuthIdentityContextService");
3969
+ }
3970
+ config;
3971
+ container;
3972
+ constructor(config) {
3973
+ this.config = config;
3974
+ }
3975
+ async configure() {
3976
+ this.container.setInjection({
3977
+ type: INJECTION_TYPES.MIDDLEWARE,
3978
+ scope: "global",
3979
+ name: "auth-identity-context",
3980
+ order: 14,
3981
+ handler: /* @__PURE__ */ __name(async (context, next) => {
3982
+ setRequestIdentityResolver(context, this.config.identity.resolve);
3983
+ return next();
3984
+ }, "handler")
3985
+ });
3022
3986
  }
3023
3987
  };
3024
- __decorate16([
3025
- DI(),
3026
- __metadata16("design:type", typeof (_a10 = typeof Container !== "undefined" && Container) === "function" ? _a10 : Object)
3027
- ], AuthResolver.prototype, "container", void 0);
3028
- __decorate16([
3029
- Inject9(APP),
3030
- __metadata16("design:type", Object)
3031
- ], AuthResolver.prototype, "app", void 0);
3032
- __decorate16([
3033
- Inject9(LOGGER),
3034
- __metadata16("design:type", Object)
3035
- ], AuthResolver.prototype, "log", void 0);
3036
- AuthResolver = __decorate16([
3037
- Service4(),
3038
- Meta({ layer: "plugin", order: 30 })
3039
- ], AuthResolver);
3988
+ __decorate22([
3989
+ DI2(),
3990
+ __metadata22("design:type", Object)
3991
+ ], AuthIdentityContextService.prototype, "container", void 0);
3992
+ AuthIdentityContextService = __decorate22([
3993
+ Service5(),
3994
+ Meta2({ layer: "plugin", order: 14 }),
3995
+ __param6(0, Inject13(AUTH_CONFIG)),
3996
+ __metadata22("design:paramtypes", [Object])
3997
+ ], AuthIdentityContextService);
3040
3998
 
3041
3999
  // src/auth/runAsUser.ts
3042
4000
  import { randomUUID } from "crypto";
@@ -3069,7 +4027,8 @@ var AUTH_MODULE = [
3069
4027
  EncryptionService,
3070
4028
  AuthGuard,
3071
4029
  AuthController,
3072
- AuthResolver
4030
+ AuthResolver,
4031
+ AuthIdentityContextService
3073
4032
  ];
3074
4033
 
3075
4034
  // src/users/index.ts
@@ -3180,21 +4139,21 @@ var assignRoleDto = z2.object({
3180
4139
  });
3181
4140
 
3182
4141
  // src/roles/RoleController.ts
3183
- var __decorate17 = function(decorators, target, key, desc) {
4142
+ var __decorate23 = function(decorators, target, key, desc) {
3184
4143
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3185
4144
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3186
4145
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3187
4146
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3188
4147
  };
3189
- var __metadata17 = function(k, v) {
4148
+ var __metadata23 = function(k, v) {
3190
4149
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3191
4150
  };
3192
- var __param6 = function(paramIndex, decorator) {
4151
+ var __param7 = function(paramIndex, decorator) {
3193
4152
  return function(target, key) {
3194
4153
  decorator(target, key, paramIndex);
3195
4154
  };
3196
4155
  };
3197
- var _a11;
4156
+ var _a14;
3198
4157
  var RoleController = class RoleController2 {
3199
4158
  static {
3200
4159
  __name(this, "RoleController");
@@ -3219,35 +4178,35 @@ var RoleController = class RoleController2 {
3219
4178
  return this.roleService.delete(params.id);
3220
4179
  }
3221
4180
  };
3222
- __decorate17([
4181
+ __decorate23([
3223
4182
  Get2(),
3224
4183
  isAdmin(),
3225
4184
  ResMsg2("roles.success.retrieved"),
3226
- __metadata17("design:type", Function),
3227
- __metadata17("design:paramtypes", []),
3228
- __metadata17("design:returntype", Promise)
4185
+ __metadata23("design:type", Function),
4186
+ __metadata23("design:paramtypes", []),
4187
+ __metadata23("design:returntype", Promise)
3229
4188
  ], RoleController.prototype, "getRoles", null);
3230
- __decorate17([
4189
+ __decorate23([
3231
4190
  Get2("/:id"),
3232
4191
  isAdmin(),
3233
4192
  Validate2({ params: roleIdParam }),
3234
4193
  ResMsg2("roles.success.retrieved"),
3235
- __param6(0, Params()),
3236
- __metadata17("design:type", Function),
3237
- __metadata17("design:paramtypes", [Object]),
3238
- __metadata17("design:returntype", Promise)
4194
+ __param7(0, Params()),
4195
+ __metadata23("design:type", Function),
4196
+ __metadata23("design:paramtypes", [Object]),
4197
+ __metadata23("design:returntype", Promise)
3239
4198
  ], RoleController.prototype, "getRole", null);
3240
- __decorate17([
4199
+ __decorate23([
3241
4200
  Post2(),
3242
4201
  isAdmin(),
3243
4202
  Validate2(createRoleDto),
3244
4203
  ResMsg2("roles.success.created"),
3245
- __param6(0, Body2()),
3246
- __metadata17("design:type", Function),
3247
- __metadata17("design:paramtypes", [Object]),
3248
- __metadata17("design:returntype", Promise)
4204
+ __param7(0, Body2()),
4205
+ __metadata23("design:type", Function),
4206
+ __metadata23("design:paramtypes", [Object]),
4207
+ __metadata23("design:returntype", Promise)
3249
4208
  ], RoleController.prototype, "createRole", null);
3250
- __decorate17([
4209
+ __decorate23([
3251
4210
  Put("/:id"),
3252
4211
  isAdmin(),
3253
4212
  Validate2({
@@ -3255,44 +4214,44 @@ __decorate17([
3255
4214
  body: updateRoleDto
3256
4215
  }),
3257
4216
  ResMsg2("roles.success.updated"),
3258
- __param6(0, Params()),
3259
- __param6(1, Body2()),
3260
- __metadata17("design:type", Function),
3261
- __metadata17("design:paramtypes", [Object, Object]),
3262
- __metadata17("design:returntype", Promise)
4217
+ __param7(0, Params()),
4218
+ __param7(1, Body2()),
4219
+ __metadata23("design:type", Function),
4220
+ __metadata23("design:paramtypes", [Object, Object]),
4221
+ __metadata23("design:returntype", Promise)
3263
4222
  ], RoleController.prototype, "updateRole", null);
3264
- __decorate17([
4223
+ __decorate23([
3265
4224
  Delete("/:id"),
3266
4225
  isAdmin(),
3267
4226
  Validate2({ params: roleIdParam }),
3268
4227
  ResMsg2("roles.success.deleted"),
3269
- __param6(0, Params()),
3270
- __metadata17("design:type", Function),
3271
- __metadata17("design:paramtypes", [Object]),
3272
- __metadata17("design:returntype", Promise)
4228
+ __param7(0, Params()),
4229
+ __metadata23("design:type", Function),
4230
+ __metadata23("design:paramtypes", [Object]),
4231
+ __metadata23("design:returntype", Promise)
3273
4232
  ], RoleController.prototype, "deleteRole", null);
3274
- RoleController = __decorate17([
4233
+ RoleController = __decorate23([
3275
4234
  Controller2("/roles"),
3276
- __metadata17("design:paramtypes", [typeof (_a11 = typeof RoleService !== "undefined" && RoleService) === "function" ? _a11 : Object])
4235
+ __metadata23("design:paramtypes", [typeof (_a14 = typeof RoleService !== "undefined" && RoleService) === "function" ? _a14 : Object])
3277
4236
  ], RoleController);
3278
4237
 
3279
4238
  // src/users/UserController.ts
3280
4239
  import { Validate as Validate3 } from "najm-validation";
3281
- var __decorate18 = function(decorators, target, key, desc) {
4240
+ var __decorate24 = function(decorators, target, key, desc) {
3282
4241
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3283
4242
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3284
4243
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3285
4244
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3286
4245
  };
3287
- var __metadata18 = function(k, v) {
4246
+ var __metadata24 = function(k, v) {
3288
4247
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3289
4248
  };
3290
- var __param7 = function(paramIndex, decorator) {
4249
+ var __param8 = function(paramIndex, decorator) {
3291
4250
  return function(target, key) {
3292
4251
  decorator(target, key, paramIndex);
3293
4252
  };
3294
4253
  };
3295
- var _a12;
4254
+ var _a15;
3296
4255
  var UserController = class UserController2 {
3297
4256
  static {
3298
4257
  __name(this, "UserController");
@@ -3339,75 +4298,75 @@ var UserController = class UserController2 {
3339
4298
  return this.userService.removeRole(params.userId);
3340
4299
  }
3341
4300
  };
3342
- __decorate18([
4301
+ __decorate24([
3343
4302
  Get3(),
3344
4303
  isAdmin(),
3345
4304
  Validate3({ query: userListQuery }),
3346
4305
  ResMsg3("users.success.retrieved"),
3347
- __param7(0, Query()),
3348
- __metadata18("design:type", Function),
3349
- __metadata18("design:paramtypes", [Object]),
3350
- __metadata18("design:returntype", Promise)
4306
+ __param8(0, Query()),
4307
+ __metadata24("design:type", Function),
4308
+ __metadata24("design:paramtypes", [Object]),
4309
+ __metadata24("design:returntype", Promise)
3351
4310
  ], UserController.prototype, "getUsers", null);
3352
- __decorate18([
4311
+ __decorate24([
3353
4312
  Get3("/lang"),
3354
4313
  isAuth(),
3355
4314
  ResMsg3("users.success.retrieved"),
3356
- __metadata18("design:type", Function),
3357
- __metadata18("design:paramtypes", []),
3358
- __metadata18("design:returntype", Promise)
4315
+ __metadata24("design:type", Function),
4316
+ __metadata24("design:paramtypes", []),
4317
+ __metadata24("design:returntype", Promise)
3359
4318
  ], UserController.prototype, "getLang", null);
3360
- __decorate18([
4319
+ __decorate24([
3361
4320
  Post3("/lang/:language"),
3362
4321
  isAuth(),
3363
4322
  Validate3({ params: languageParam }),
3364
4323
  ResMsg3("users.success.updated"),
3365
- __param7(0, Params2()),
3366
- __metadata18("design:type", Function),
3367
- __metadata18("design:paramtypes", [Object]),
3368
- __metadata18("design:returntype", Promise)
4324
+ __param8(0, Params2()),
4325
+ __metadata24("design:type", Function),
4326
+ __metadata24("design:paramtypes", [Object]),
4327
+ __metadata24("design:returntype", Promise)
3369
4328
  ], UserController.prototype, "updateLang", null);
3370
- __decorate18([
4329
+ __decorate24([
3371
4330
  Get3("/:id"),
3372
4331
  isAdmin(),
3373
4332
  Validate3({ params: userIdParam }),
3374
4333
  ResMsg3("users.success.retrieved"),
3375
- __param7(0, Params2()),
3376
- __metadata18("design:type", Function),
3377
- __metadata18("design:paramtypes", [Object]),
3378
- __metadata18("design:returntype", Promise)
4334
+ __param8(0, Params2()),
4335
+ __metadata24("design:type", Function),
4336
+ __metadata24("design:paramtypes", [Object]),
4337
+ __metadata24("design:returntype", Promise)
3379
4338
  ], UserController.prototype, "getUser", null);
3380
- __decorate18([
4339
+ __decorate24([
3381
4340
  Get3("/email/:email"),
3382
4341
  isAdmin(),
3383
4342
  Validate3({ params: emailParam }),
3384
4343
  ResMsg3("users.success.retrieved"),
3385
- __param7(0, Params2()),
3386
- __metadata18("design:type", Function),
3387
- __metadata18("design:paramtypes", [Object]),
3388
- __metadata18("design:returntype", Promise)
4344
+ __param8(0, Params2()),
4345
+ __metadata24("design:type", Function),
4346
+ __metadata24("design:paramtypes", [Object]),
4347
+ __metadata24("design:returntype", Promise)
3389
4348
  ], UserController.prototype, "getByEmail", null);
3390
- __decorate18([
4349
+ __decorate24([
3391
4350
  Get3("/role/:userId"),
3392
4351
  isAdmin(),
3393
4352
  Validate3({ params: userIdInParam }),
3394
4353
  ResMsg3("users.success.retrieved"),
3395
- __param7(0, Params2()),
3396
- __metadata18("design:type", Function),
3397
- __metadata18("design:paramtypes", [Object]),
3398
- __metadata18("design:returntype", Promise)
4354
+ __param8(0, Params2()),
4355
+ __metadata24("design:type", Function),
4356
+ __metadata24("design:paramtypes", [Object]),
4357
+ __metadata24("design:returntype", Promise)
3399
4358
  ], UserController.prototype, "getRole", null);
3400
- __decorate18([
4359
+ __decorate24([
3401
4360
  Post3(),
3402
4361
  isAdmin(),
3403
4362
  Validate3(createUserDto),
3404
4363
  ResMsg3("users.success.created"),
3405
- __param7(0, Body3()),
3406
- __metadata18("design:type", Function),
3407
- __metadata18("design:paramtypes", [Object]),
3408
- __metadata18("design:returntype", Promise)
4364
+ __param8(0, Body3()),
4365
+ __metadata24("design:type", Function),
4366
+ __metadata24("design:paramtypes", [Object]),
4367
+ __metadata24("design:returntype", Promise)
3409
4368
  ], UserController.prototype, "create", null);
3410
- __decorate18([
4369
+ __decorate24([
3411
4370
  Put2("/:id"),
3412
4371
  isAdmin(),
3413
4372
  Validate3({
@@ -3415,53 +4374,53 @@ __decorate18([
3415
4374
  body: updateUserDto
3416
4375
  }),
3417
4376
  ResMsg3("users.success.updated"),
3418
- __param7(0, Params2()),
3419
- __param7(1, Body3()),
3420
- __metadata18("design:type", Function),
3421
- __metadata18("design:paramtypes", [Object, Object]),
3422
- __metadata18("design:returntype", Promise)
4377
+ __param8(0, Params2()),
4378
+ __param8(1, Body3()),
4379
+ __metadata24("design:type", Function),
4380
+ __metadata24("design:paramtypes", [Object, Object]),
4381
+ __metadata24("design:returntype", Promise)
3423
4382
  ], UserController.prototype, "update", null);
3424
- __decorate18([
4383
+ __decorate24([
3425
4384
  Delete2("/:id"),
3426
4385
  isAdmin(),
3427
4386
  Validate3({ params: userIdParam }),
3428
4387
  ResMsg3("users.success.deleted"),
3429
- __param7(0, Params2()),
3430
- __metadata18("design:type", Function),
3431
- __metadata18("design:paramtypes", [Object]),
3432
- __metadata18("design:returntype", Promise)
4388
+ __param8(0, Params2()),
4389
+ __metadata24("design:type", Function),
4390
+ __metadata24("design:paramtypes", [Object]),
4391
+ __metadata24("design:returntype", Promise)
3433
4392
  ], UserController.prototype, "delete", null);
3434
- __decorate18([
4393
+ __decorate24([
3435
4394
  Delete2(),
3436
4395
  isAdmin(),
3437
4396
  ResMsg3("users.success.allDeleted"),
3438
- __metadata18("design:type", Function),
3439
- __metadata18("design:paramtypes", []),
3440
- __metadata18("design:returntype", Promise)
4397
+ __metadata24("design:type", Function),
4398
+ __metadata24("design:paramtypes", []),
4399
+ __metadata24("design:returntype", Promise)
3441
4400
  ], UserController.prototype, "deleteAll", null);
3442
- __decorate18([
4401
+ __decorate24([
3443
4402
  Post3("/assign/:userId/:roleId"),
3444
4403
  isAdmin(),
3445
4404
  Validate3({ params: assignRoleParams }),
3446
4405
  ResMsg3("users.success.updated"),
3447
- __param7(0, Params2()),
3448
- __metadata18("design:type", Function),
3449
- __metadata18("design:paramtypes", [Object]),
3450
- __metadata18("design:returntype", Promise)
4406
+ __param8(0, Params2()),
4407
+ __metadata24("design:type", Function),
4408
+ __metadata24("design:paramtypes", [Object]),
4409
+ __metadata24("design:returntype", Promise)
3451
4410
  ], UserController.prototype, "assignRole", null);
3452
- __decorate18([
4411
+ __decorate24([
3453
4412
  Delete2("/remove/:userId"),
3454
4413
  isAdmin(),
3455
4414
  Validate3({ params: userIdInParam }),
3456
4415
  ResMsg3("users.success.updated"),
3457
- __param7(0, Params2()),
3458
- __metadata18("design:type", Function),
3459
- __metadata18("design:paramtypes", [Object]),
3460
- __metadata18("design:returntype", Promise)
4416
+ __param8(0, Params2()),
4417
+ __metadata24("design:type", Function),
4418
+ __metadata24("design:paramtypes", [Object]),
4419
+ __metadata24("design:returntype", Promise)
3461
4420
  ], UserController.prototype, "removeRole", null);
3462
- UserController = __decorate18([
4421
+ UserController = __decorate24([
3463
4422
  Controller3("/users"),
3464
- __metadata18("design:paramtypes", [typeof (_a12 = typeof UserService !== "undefined" && UserService) === "function" ? _a12 : Object])
4423
+ __metadata24("design:paramtypes", [typeof (_a15 = typeof UserService !== "undefined" && UserService) === "function" ? _a15 : Object])
3465
4424
  ], UserController);
3466
4425
 
3467
4426
  // src/permissions/index.ts
@@ -3481,16 +4440,16 @@ __export(permissions_exports, {
3481
4440
  });
3482
4441
 
3483
4442
  // src/permissions/PermissionRepository.ts
3484
- import { eq as eq5, and as and2 } from "drizzle-orm";
3485
- import { Repository as Repository4, Inject as Inject10 } from "najm-core";
3486
- import { DB as DB4 } from "najm-database";
3487
- var __decorate19 = function(decorators, target, key, desc) {
4443
+ import { eq as eq7, and as and4 } from "drizzle-orm";
4444
+ import { Repository as Repository6, Inject as Inject14 } from "najm-core";
4445
+ import { DB as DB6 } from "najm-database";
4446
+ var __decorate25 = function(decorators, target, key, desc) {
3488
4447
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3489
4448
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3490
4449
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3491
4450
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3492
4451
  };
3493
- var __metadata19 = function(k, v) {
4452
+ var __metadata25 = function(k, v) {
3494
4453
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3495
4454
  };
3496
4455
  var PermissionRepository = class PermissionRepository2 {
@@ -3512,26 +4471,26 @@ var PermissionRepository = class PermissionRepository2 {
3512
4471
  return await this.db.select().from(this.permissions);
3513
4472
  }
3514
4473
  async getById(id) {
3515
- const [existingPermission] = await this.db.select().from(this.permissions).where(eq5(this.permissions.id, id));
4474
+ const [existingPermission] = await this.db.select().from(this.permissions).where(eq7(this.permissions.id, id));
3516
4475
  return existingPermission;
3517
4476
  }
3518
4477
  async getByName(name) {
3519
- const [existingPermission] = await this.db.select().from(this.permissions).where(eq5(this.permissions.name, name));
4478
+ const [existingPermission] = await this.db.select().from(this.permissions).where(eq7(this.permissions.name, name));
3520
4479
  return existingPermission;
3521
4480
  }
3522
4481
  async getByResource(resource) {
3523
- return await this.db.select().from(this.permissions).where(eq5(this.permissions.resource, resource));
4482
+ return await this.db.select().from(this.permissions).where(eq7(this.permissions.resource, resource));
3524
4483
  }
3525
4484
  async create(data) {
3526
4485
  const [newPermission] = await this.db.insert(this.permissions).values(data).returning();
3527
4486
  return newPermission;
3528
4487
  }
3529
4488
  async update(id, data) {
3530
- const [updatedPermission] = await this.db.update(this.permissions).set(data).where(eq5(this.permissions.id, id)).returning();
4489
+ const [updatedPermission] = await this.db.update(this.permissions).set(data).where(eq7(this.permissions.id, id)).returning();
3531
4490
  return updatedPermission;
3532
4491
  }
3533
4492
  async delete(id) {
3534
- const [deletedPermission] = await this.db.delete(this.permissions).where(eq5(this.permissions.id, id)).returning();
4493
+ const [deletedPermission] = await this.db.delete(this.permissions).where(eq7(this.permissions.id, id)).returning();
3535
4494
  return deletedPermission;
3536
4495
  }
3537
4496
  async getPermissionsByRole(roleId) {
@@ -3541,25 +4500,25 @@ var PermissionRepository = class PermissionRepository2 {
3541
4500
  description: this.permissions.description,
3542
4501
  resource: this.permissions.resource,
3543
4502
  action: this.permissions.action
3544
- }).from(this.rolePermissions).leftJoin(this.permissions, eq5(this.rolePermissions.permissionId, this.permissions.id)).where(eq5(this.rolePermissions.roleId, roleId));
4503
+ }).from(this.rolePermissions).leftJoin(this.permissions, eq7(this.rolePermissions.permissionId, this.permissions.id)).where(eq7(this.rolePermissions.roleId, roleId));
3545
4504
  }
3546
4505
  async getRolesByPermission(permissionId) {
3547
4506
  return await this.db.select({
3548
4507
  id: this.roles.id,
3549
4508
  name: this.roles.name,
3550
4509
  description: this.roles.description
3551
- }).from(this.rolePermissions).leftJoin(this.roles, eq5(this.rolePermissions.roleId, this.roles.id)).where(eq5(this.rolePermissions.permissionId, permissionId));
4510
+ }).from(this.rolePermissions).leftJoin(this.roles, eq7(this.rolePermissions.roleId, this.roles.id)).where(eq7(this.rolePermissions.permissionId, permissionId));
3552
4511
  }
3553
4512
  async assignPermissionToRole(roleId, permissionId) {
3554
4513
  const [newRolePermission] = await this.db.insert(this.rolePermissions).values({ roleId, permissionId }).returning();
3555
4514
  return newRolePermission;
3556
4515
  }
3557
4516
  async removePermissionFromRole(roleId, permissionId) {
3558
- const [deletedRolePermission] = await this.db.delete(this.rolePermissions).where(and2(eq5(this.rolePermissions.roleId, roleId), eq5(this.rolePermissions.permissionId, permissionId))).returning();
4517
+ const [deletedRolePermission] = await this.db.delete(this.rolePermissions).where(and4(eq7(this.rolePermissions.roleId, roleId), eq7(this.rolePermissions.permissionId, permissionId))).returning();
3559
4518
  return deletedRolePermission;
3560
4519
  }
3561
4520
  async checkRoleHasPermission(roleId, permissionId) {
3562
- const [rolePermission] = await this.db.select().from(this.rolePermissions).where(and2(eq5(this.rolePermissions.roleId, roleId), eq5(this.rolePermissions.permissionId, permissionId)));
4521
+ const [rolePermission] = await this.db.select().from(this.rolePermissions).where(and4(eq7(this.rolePermissions.roleId, roleId), eq7(this.rolePermissions.permissionId, permissionId)));
3563
4522
  return !!rolePermission;
3564
4523
  }
3565
4524
  async deleteAll() {
@@ -3568,32 +4527,32 @@ var PermissionRepository = class PermissionRepository2 {
3568
4527
  return deletedPermissions;
3569
4528
  }
3570
4529
  };
3571
- __decorate19([
3572
- DB4(),
3573
- __metadata19("design:type", Object)
4530
+ __decorate25([
4531
+ DB6(),
4532
+ __metadata25("design:type", Object)
3574
4533
  ], PermissionRepository.prototype, "db", void 0);
3575
- __decorate19([
3576
- Inject10(AUTH_SCHEMA),
3577
- __metadata19("design:type", Object)
4534
+ __decorate25([
4535
+ Inject14(AUTH_SCHEMA),
4536
+ __metadata25("design:type", Object)
3578
4537
  ], PermissionRepository.prototype, "schema", void 0);
3579
- PermissionRepository = __decorate19([
3580
- Repository4()
4538
+ PermissionRepository = __decorate25([
4539
+ Repository6()
3581
4540
  ], PermissionRepository);
3582
4541
 
3583
4542
  // src/permissions/PermissionGuards.ts
3584
- import { Injectable as Injectable9 } from "najm-core";
4543
+ import { Injectable as Injectable12 } from "najm-core";
3585
4544
  import { GuardParams as GuardParams2, User as User3 } from "najm-core";
3586
4545
  import { createGuard as createGuard4, composeGuards as composeGuards3 } from "najm-guard";
3587
- var __decorate20 = function(decorators, target, key, desc) {
4546
+ var __decorate26 = function(decorators, target, key, desc) {
3588
4547
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3589
4548
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3590
4549
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3591
4550
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3592
4551
  };
3593
- var __metadata20 = function(k, v) {
4552
+ var __metadata26 = function(k, v) {
3594
4553
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3595
4554
  };
3596
- var __param8 = function(paramIndex, decorator) {
4555
+ var __param9 = function(paramIndex, decorator) {
3597
4556
  return function(target, key) {
3598
4557
  decorator(target, key, paramIndex);
3599
4558
  };
@@ -3626,15 +4585,15 @@ var PermissionGuard = class PermissionGuard2 {
3626
4585
  return false;
3627
4586
  }
3628
4587
  };
3629
- __decorate20([
3630
- __param8(0, GuardParams2()),
3631
- __param8(1, User3("permissions")),
3632
- __metadata20("design:type", Function),
3633
- __metadata20("design:paramtypes", [String, Array]),
3634
- __metadata20("design:returntype", Object)
4588
+ __decorate26([
4589
+ __param9(0, GuardParams2()),
4590
+ __param9(1, User3("permissions")),
4591
+ __metadata26("design:type", Function),
4592
+ __metadata26("design:paramtypes", [String, Array]),
4593
+ __metadata26("design:returntype", Object)
3635
4594
  ], PermissionGuard.prototype, "canActivate", null);
3636
- PermissionGuard = __decorate20([
3637
- Injectable9()
4595
+ PermissionGuard = __decorate26([
4596
+ Injectable12()
3638
4597
  ], PermissionGuard);
3639
4598
  var Permission = createGuard4(PermissionGuard);
3640
4599
  var Can = /* @__PURE__ */ __name((permission) => composeGuards3(isAuth(), Permission(permission))(), "Can");
@@ -3645,23 +4604,23 @@ import { Get as Get4, Post as Post4, Put as Put3, Delete as Delete3, ResMsg as R
3645
4604
  import { Params as Params3, Body as Body4 } from "najm-core";
3646
4605
 
3647
4606
  // src/permissions/PermissionService.ts
3648
- import { Injectable as Injectable11 } from "najm-core";
4607
+ import { Injectable as Injectable14 } from "najm-core";
3649
4608
 
3650
4609
  // src/permissions/PermissionValidator.ts
3651
- import { Injectable as Injectable10 } from "najm-core";
3652
- import { I18n as I18n7 } from "najm-i18n";
3653
- import { Err as Err10 } from "najm-core";
3654
- var __decorate21 = function(decorators, target, key, desc) {
4610
+ import { Injectable as Injectable13 } from "najm-core";
4611
+ import { I18n as I18n9 } from "najm-i18n";
4612
+ import { Err as Err14 } from "najm-core";
4613
+ var __decorate27 = function(decorators, target, key, desc) {
3655
4614
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3656
4615
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3657
4616
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3658
4617
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3659
4618
  };
3660
- var __metadata21 = function(k, v) {
4619
+ var __metadata27 = function(k, v) {
3661
4620
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3662
4621
  };
3663
- var _a13;
3664
- var _b7;
4622
+ var _a16;
4623
+ var _b10;
3665
4624
  var PermissionValidator = class PermissionValidator2 {
3666
4625
  static {
3667
4626
  __name(this, "PermissionValidator");
@@ -3679,7 +4638,7 @@ var PermissionValidator = class PermissionValidator2 {
3679
4638
  async checkPermissionExists(id) {
3680
4639
  const permission = await this.permissionRepository.getById(id);
3681
4640
  if (!permission) {
3682
- Err10(this.t("errors.notFound"), 404);
4641
+ Err14(this.t("errors.notFound"), 404);
3683
4642
  }
3684
4643
  return permission;
3685
4644
  }
@@ -3689,7 +4648,7 @@ var PermissionValidator = class PermissionValidator2 {
3689
4648
  async checkPermissionExistsByName(name) {
3690
4649
  const permission = await this.permissionRepository.getByName(name);
3691
4650
  if (!permission) {
3692
- Err10(this.t("errors.notFound"), 404);
4651
+ Err14(this.t("errors.notFound"), 404);
3693
4652
  }
3694
4653
  return permission;
3695
4654
  }
@@ -3701,7 +4660,7 @@ var PermissionValidator = class PermissionValidator2 {
3701
4660
  return;
3702
4661
  const existingPermission = await this.permissionRepository.getByName(name);
3703
4662
  if (existingPermission && existingPermission.id !== excludeId) {
3704
- Err10(this.t("errors.nameExists"), 409);
4663
+ Err14(this.t("errors.nameExists"), 409);
3705
4664
  }
3706
4665
  }
3707
4666
  /**
@@ -3724,32 +4683,32 @@ var PermissionValidator = class PermissionValidator2 {
3724
4683
  await this.checkPermissionExists(permissionId);
3725
4684
  const hasPermission = await this.permissionRepository.checkRoleHasPermission(roleId, permissionId);
3726
4685
  if (hasPermission) {
3727
- Err10(this.t("errors.roleAlreadyHasPermission"), 409);
4686
+ Err14(this.t("errors.roleAlreadyHasPermission"), 409);
3728
4687
  }
3729
4688
  }
3730
4689
  };
3731
- __decorate21([
3732
- I18n7("permissions"),
3733
- __metadata21("design:type", Object)
4690
+ __decorate27([
4691
+ I18n9("permissions"),
4692
+ __metadata27("design:type", Object)
3734
4693
  ], PermissionValidator.prototype, "t", void 0);
3735
- PermissionValidator = __decorate21([
3736
- Injectable10(),
3737
- __metadata21("design:paramtypes", [typeof (_a13 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a13 : Object, typeof (_b7 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _b7 : Object])
4694
+ PermissionValidator = __decorate27([
4695
+ Injectable13(),
4696
+ __metadata27("design:paramtypes", [typeof (_a16 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a16 : Object, typeof (_b10 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _b10 : Object])
3738
4697
  ], PermissionValidator);
3739
4698
 
3740
4699
  // src/permissions/PermissionService.ts
3741
- var __decorate22 = function(decorators, target, key, desc) {
4700
+ var __decorate28 = function(decorators, target, key, desc) {
3742
4701
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3743
4702
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3744
4703
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3745
4704
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3746
4705
  };
3747
- var __metadata22 = function(k, v) {
4706
+ var __metadata28 = function(k, v) {
3748
4707
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3749
4708
  };
3750
- var _a14;
3751
- var _b8;
3752
- var _c5;
4709
+ var _a17;
4710
+ var _b11;
4711
+ var _c8;
3753
4712
  var PermissionService = class PermissionService2 {
3754
4713
  static {
3755
4714
  __name(this, "PermissionService");
@@ -3854,9 +4813,9 @@ var PermissionService = class PermissionService2 {
3854
4813
  return await this.permissionRepository.deleteAll();
3855
4814
  }
3856
4815
  };
3857
- PermissionService = __decorate22([
3858
- Injectable11(),
3859
- __metadata22("design:paramtypes", [typeof (_a14 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a14 : Object, typeof (_b8 = typeof PermissionValidator !== "undefined" && PermissionValidator) === "function" ? _b8 : Object, typeof (_c5 = typeof RoleService !== "undefined" && RoleService) === "function" ? _c5 : Object])
4816
+ PermissionService = __decorate28([
4817
+ Injectable14(),
4818
+ __metadata28("design:paramtypes", [typeof (_a17 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a17 : Object, typeof (_b11 = typeof PermissionValidator !== "undefined" && PermissionValidator) === "function" ? _b11 : Object, typeof (_c8 = typeof RoleService !== "undefined" && RoleService) === "function" ? _c8 : Object])
3860
4819
  ], PermissionService);
3861
4820
 
3862
4821
  // src/permissions/PermissionController.ts
@@ -3889,21 +4848,21 @@ var checkPermissionDto = z3.object({
3889
4848
  });
3890
4849
 
3891
4850
  // src/permissions/PermissionController.ts
3892
- var __decorate23 = function(decorators, target, key, desc) {
4851
+ var __decorate29 = function(decorators, target, key, desc) {
3893
4852
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3894
4853
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3895
4854
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3896
4855
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3897
4856
  };
3898
- var __metadata23 = function(k, v) {
4857
+ var __metadata29 = function(k, v) {
3899
4858
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3900
4859
  };
3901
- var __param9 = function(paramIndex, decorator) {
4860
+ var __param10 = function(paramIndex, decorator) {
3902
4861
  return function(target, key) {
3903
4862
  decorator(target, key, paramIndex);
3904
4863
  };
3905
4864
  };
3906
- var _a15;
4865
+ var _a18;
3907
4866
  var PermissionController = class PermissionController2 {
3908
4867
  static {
3909
4868
  __name(this, "PermissionController");
@@ -3949,101 +4908,101 @@ var PermissionController = class PermissionController2 {
3949
4908
  return this.permissionService.deleteAll();
3950
4909
  }
3951
4910
  };
3952
- __decorate23([
4911
+ __decorate29([
3953
4912
  Get4(),
3954
4913
  ResMsg4("permissions.success.retrieved"),
3955
- __metadata23("design:type", Function),
3956
- __metadata23("design:paramtypes", []),
3957
- __metadata23("design:returntype", Promise)
4914
+ __metadata29("design:type", Function),
4915
+ __metadata29("design:paramtypes", []),
4916
+ __metadata29("design:returntype", Promise)
3958
4917
  ], PermissionController.prototype, "getPermissions", null);
3959
- __decorate23([
4918
+ __decorate29([
3960
4919
  Get4("/:id"),
3961
4920
  Validate4({ params: permissionIdParam }),
3962
4921
  ResMsg4("permissions.success.retrieved"),
3963
- __param9(0, Params3()),
3964
- __metadata23("design:type", Function),
3965
- __metadata23("design:paramtypes", [Object]),
3966
- __metadata23("design:returntype", Promise)
4922
+ __param10(0, Params3()),
4923
+ __metadata29("design:type", Function),
4924
+ __metadata29("design:paramtypes", [Object]),
4925
+ __metadata29("design:returntype", Promise)
3967
4926
  ], PermissionController.prototype, "getPermission", null);
3968
- __decorate23([
4927
+ __decorate29([
3969
4928
  Post4(),
3970
4929
  Validate4(createPermissionDto),
3971
4930
  ResMsg4({ message: "Permission created successfully", status: 201 }),
3972
- __param9(0, Body4()),
3973
- __metadata23("design:type", Function),
3974
- __metadata23("design:paramtypes", [Object]),
3975
- __metadata23("design:returntype", Promise)
4931
+ __param10(0, Body4()),
4932
+ __metadata29("design:type", Function),
4933
+ __metadata29("design:paramtypes", [Object]),
4934
+ __metadata29("design:returntype", Promise)
3976
4935
  ], PermissionController.prototype, "create", null);
3977
- __decorate23([
4936
+ __decorate29([
3978
4937
  Put3("/:id"),
3979
4938
  Validate4({
3980
4939
  params: permissionIdParam,
3981
4940
  body: updatePermissionDto
3982
4941
  }),
3983
4942
  ResMsg4("permissions.success.updated"),
3984
- __param9(0, Params3()),
3985
- __param9(1, Body4()),
3986
- __metadata23("design:type", Function),
3987
- __metadata23("design:paramtypes", [Object, Object]),
3988
- __metadata23("design:returntype", Promise)
4943
+ __param10(0, Params3()),
4944
+ __param10(1, Body4()),
4945
+ __metadata29("design:type", Function),
4946
+ __metadata29("design:paramtypes", [Object, Object]),
4947
+ __metadata29("design:returntype", Promise)
3989
4948
  ], PermissionController.prototype, "update", null);
3990
- __decorate23([
4949
+ __decorate29([
3991
4950
  Delete3("/:id"),
3992
4951
  Validate4({ params: permissionIdParam }),
3993
4952
  ResMsg4("permissions.success.deleted"),
3994
- __param9(0, Params3()),
3995
- __metadata23("design:type", Function),
3996
- __metadata23("design:paramtypes", [Object]),
3997
- __metadata23("design:returntype", Promise)
4953
+ __param10(0, Params3()),
4954
+ __metadata29("design:type", Function),
4955
+ __metadata29("design:paramtypes", [Object]),
4956
+ __metadata29("design:returntype", Promise)
3998
4957
  ], PermissionController.prototype, "delete", null);
3999
- __decorate23([
4958
+ __decorate29([
4000
4959
  Get4("/role/:id"),
4001
4960
  Validate4({ params: roleIdParam }),
4002
4961
  ResMsg4("permissions.success.retrieved"),
4003
- __param9(0, Params3()),
4004
- __metadata23("design:type", Function),
4005
- __metadata23("design:paramtypes", [Object]),
4006
- __metadata23("design:returntype", Promise)
4962
+ __param10(0, Params3()),
4963
+ __metadata29("design:type", Function),
4964
+ __metadata29("design:paramtypes", [Object]),
4965
+ __metadata29("design:returntype", Promise)
4007
4966
  ], PermissionController.prototype, "getByRole", null);
4008
- __decorate23([
4967
+ __decorate29([
4009
4968
  Get4("/roles/:id"),
4010
4969
  Validate4({ params: permissionIdParam }),
4011
4970
  ResMsg4("permissions.success.retrieved"),
4012
- __param9(0, Params3()),
4013
- __metadata23("design:type", Function),
4014
- __metadata23("design:paramtypes", [Object]),
4015
- __metadata23("design:returntype", Promise)
4971
+ __param10(0, Params3()),
4972
+ __metadata29("design:type", Function),
4973
+ __metadata29("design:paramtypes", [Object]),
4974
+ __metadata29("design:returntype", Promise)
4016
4975
  ], PermissionController.prototype, "getRolesByPermission", null);
4017
- __decorate23([
4976
+ __decorate29([
4018
4977
  Post4("/assign/:roleId/:permissionId"),
4019
4978
  Validate4({ params: assignPermissionDto }),
4020
4979
  ResMsg4("permissions.success.assigned"),
4021
- __param9(0, Params3()),
4022
- __metadata23("design:type", Function),
4023
- __metadata23("design:paramtypes", [Object]),
4024
- __metadata23("design:returntype", Promise)
4980
+ __param10(0, Params3()),
4981
+ __metadata29("design:type", Function),
4982
+ __metadata29("design:paramtypes", [Object]),
4983
+ __metadata29("design:returntype", Promise)
4025
4984
  ], PermissionController.prototype, "assignToRole", null);
4026
- __decorate23([
4985
+ __decorate29([
4027
4986
  Delete3("/remove/:roleId/:permissionId"),
4028
4987
  Validate4({ params: assignPermissionDto }),
4029
4988
  ResMsg4("permissions.success.removed"),
4030
- __param9(0, Params3()),
4031
- __metadata23("design:type", Function),
4032
- __metadata23("design:paramtypes", [Object]),
4033
- __metadata23("design:returntype", Promise)
4989
+ __param10(0, Params3()),
4990
+ __metadata29("design:type", Function),
4991
+ __metadata29("design:paramtypes", [Object]),
4992
+ __metadata29("design:returntype", Promise)
4034
4993
  ], PermissionController.prototype, "removeFromRole", null);
4035
- __decorate23([
4994
+ __decorate29([
4036
4995
  Delete3(),
4037
4996
  isAdmin(),
4038
4997
  ResMsg4("permissions.success.allDeleted"),
4039
- __metadata23("design:type", Function),
4040
- __metadata23("design:paramtypes", []),
4041
- __metadata23("design:returntype", Promise)
4998
+ __metadata29("design:type", Function),
4999
+ __metadata29("design:paramtypes", []),
5000
+ __metadata29("design:returntype", Promise)
4042
5001
  ], PermissionController.prototype, "deleteAll", null);
4043
- PermissionController = __decorate23([
5002
+ PermissionController = __decorate29([
4044
5003
  Controller4("/permissions"),
4045
5004
  isAdmin(),
4046
- __metadata23("design:paramtypes", [typeof (_a15 = typeof PermissionService !== "undefined" && PermissionService) === "function" ? _a15 : Object])
5005
+ __metadata29("design:paramtypes", [typeof (_a18 = typeof PermissionService !== "undefined" && PermissionService) === "function" ? _a18 : Object])
4047
5006
  ], PermissionController);
4048
5007
 
4049
5008
  // src/tokens/index.ts
@@ -4088,7 +5047,7 @@ var revokeTokenDto = z4.object({
4088
5047
  });
4089
5048
 
4090
5049
  // src/ownership/scopedOwnership.ts
4091
- import { aliasedTable, eq as eq6, getTableColumns, sql as sql4 } from "drizzle-orm";
5050
+ import { aliasedTable, eq as eq8, getTableColumns, sql as sql4 } from "drizzle-orm";
4092
5051
  var DEFAULT_ADMIN_ROLES = ["admin"];
4093
5052
  var DRIZZLE_NAME = Symbol.for("drizzle:Name");
4094
5053
  var DRIZZLE_BASE_NAME = Symbol.for("drizzle:BaseName");
@@ -4175,8 +5134,8 @@ function compile(steps) {
4175
5134
  return (uid, query) => {
4176
5135
  let q = query;
4177
5136
  for (const j of joins)
4178
- q = q.innerJoin(j.table, eq6(j.left, j.right));
4179
- return { query: q, condition: eq6(owner.col, uid) };
5137
+ q = q.innerJoin(j.table, eq8(j.left, j.right));
5138
+ return { query: q, condition: eq8(owner.col, uid) };
4180
5139
  };
4181
5140
  }
4182
5141
  __name(compile, "compile");
@@ -4250,18 +5209,18 @@ function own(table, opts) {
4250
5209
  __name(own, "own");
4251
5210
 
4252
5211
  // src/ownership/configureOwnership.ts
4253
- import { Injectable as Injectable12, Inject as Inject11, User as User4, Body as Body5, Params as Params4 } from "najm-core";
5212
+ import { Injectable as Injectable15, Inject as Inject15, User as User4, Body as Body5, Params as Params4 } from "najm-core";
4254
5213
  import { createGuard as createGuard5, composeGuards as composeGuards4 } from "najm-guard";
4255
- var __decorate24 = function(decorators, target, key, desc) {
5214
+ var __decorate30 = function(decorators, target, key, desc) {
4256
5215
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4257
5216
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4258
5217
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4259
5218
  return c > 3 && r && Object.defineProperty(target, key, r), r;
4260
5219
  };
4261
- var __metadata24 = function(k, v) {
5220
+ var __metadata30 = function(k, v) {
4262
5221
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4263
5222
  };
4264
- var __param10 = function(paramIndex, decorator) {
5223
+ var __param11 = function(paramIndex, decorator) {
4265
5224
  return function(target, key) {
4266
5225
  decorator(target, key, paramIndex);
4267
5226
  };
@@ -4278,7 +5237,7 @@ function toSingular(plural) {
4278
5237
  }
4279
5238
  __name(toSingular, "toSingular");
4280
5239
  function createResourceGuards(ownershipClass, resourceType, resource, options) {
4281
- var _a23, _b13;
5240
+ var _a26, _b15;
4282
5241
  const writeGuard = options?.adminGuard ?? isAdmin;
4283
5242
  let AccessGuard = class AccessGuard {
4284
5243
  static {
@@ -4290,19 +5249,19 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
4290
5249
  return allowed ? { owner: user } : false;
4291
5250
  }
4292
5251
  };
4293
- __decorate24([
4294
- Inject11(ownershipClass),
4295
- __metadata24("design:type", Object)
5252
+ __decorate30([
5253
+ Inject15(ownershipClass),
5254
+ __metadata30("design:type", Object)
4296
5255
  ], AccessGuard.prototype, "ownership", void 0);
4297
- __decorate24([
4298
- __param10(0, User4()),
4299
- __param10(1, Params4("id")),
4300
- __metadata24("design:type", Function),
4301
- __metadata24("design:paramtypes", [Object, String]),
4302
- __metadata24("design:returntype", typeof (_a23 = typeof Promise !== "undefined" && Promise) === "function" ? _a23 : Object)
5256
+ __decorate30([
5257
+ __param11(0, User4()),
5258
+ __param11(1, Params4("id")),
5259
+ __metadata30("design:type", Function),
5260
+ __metadata30("design:paramtypes", [Object, String]),
5261
+ __metadata30("design:returntype", typeof (_a26 = typeof Promise !== "undefined" && Promise) === "function" ? _a26 : Object)
4303
5262
  ], AccessGuard.prototype, "canActivate", null);
4304
- AccessGuard = __decorate24([
4305
- Injectable12()
5263
+ AccessGuard = __decorate30([
5264
+ Injectable15()
4306
5265
  ], AccessGuard);
4307
5266
  let ListGuard = class ListGuard {
4308
5267
  static {
@@ -4314,18 +5273,18 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
4314
5273
  return { filter: ids };
4315
5274
  }
4316
5275
  };
4317
- __decorate24([
4318
- Inject11(ownershipClass),
4319
- __metadata24("design:type", Object)
5276
+ __decorate30([
5277
+ Inject15(ownershipClass),
5278
+ __metadata30("design:type", Object)
4320
5279
  ], ListGuard.prototype, "ownership", void 0);
4321
- __decorate24([
4322
- __param10(0, User4()),
4323
- __metadata24("design:type", Function),
4324
- __metadata24("design:paramtypes", [Object]),
4325
- __metadata24("design:returntype", typeof (_b13 = typeof Promise !== "undefined" && Promise) === "function" ? _b13 : Object)
5280
+ __decorate30([
5281
+ __param11(0, User4()),
5282
+ __metadata30("design:type", Function),
5283
+ __metadata30("design:paramtypes", [Object]),
5284
+ __metadata30("design:returntype", typeof (_b15 = typeof Promise !== "undefined" && Promise) === "function" ? _b15 : Object)
4326
5285
  ], ListGuard.prototype, "canActivate", null);
4327
- ListGuard = __decorate24([
4328
- Injectable12()
5286
+ ListGuard = __decorate30([
5287
+ Injectable15()
4329
5288
  ], ListGuard);
4330
5289
  const access = createGuard5(AccessGuard);
4331
5290
  const list = createGuard5(ListGuard);
@@ -4456,11 +5415,11 @@ function configureOwnership(config) {
4456
5415
  }
4457
5416
  }
4458
5417
  };
4459
- GeneratedOwnershipService = __decorate24([
4460
- Injectable12()
5418
+ GeneratedOwnershipService = __decorate30([
5419
+ Injectable15()
4461
5420
  ], GeneratedOwnershipService);
4462
5421
  function bodyGuard(resourceType, bodyField, optional = false) {
4463
- var _a23;
5422
+ var _a26;
4464
5423
  let BodyAccessGuard = class BodyAccessGuard {
4465
5424
  static {
4466
5425
  __name(this, "BodyAccessGuard");
@@ -4473,19 +5432,19 @@ function configureOwnership(config) {
4473
5432
  return this.ownership.canAccess(user, resourceType, id);
4474
5433
  }
4475
5434
  };
4476
- __decorate24([
4477
- Inject11(GeneratedOwnershipService),
4478
- __metadata24("design:type", GeneratedOwnershipService)
5435
+ __decorate30([
5436
+ Inject15(GeneratedOwnershipService),
5437
+ __metadata30("design:type", GeneratedOwnershipService)
4479
5438
  ], BodyAccessGuard.prototype, "ownership", void 0);
4480
- __decorate24([
4481
- __param10(0, User4()),
4482
- __param10(1, Body5()),
4483
- __metadata24("design:type", Function),
4484
- __metadata24("design:paramtypes", [Object, Object]),
4485
- __metadata24("design:returntype", typeof (_a23 = typeof Promise !== "undefined" && Promise) === "function" ? _a23 : Object)
5439
+ __decorate30([
5440
+ __param11(0, User4()),
5441
+ __param11(1, Body5()),
5442
+ __metadata30("design:type", Function),
5443
+ __metadata30("design:paramtypes", [Object, Object]),
5444
+ __metadata30("design:returntype", typeof (_a26 = typeof Promise !== "undefined" && Promise) === "function" ? _a26 : Object)
4486
5445
  ], BodyAccessGuard.prototype, "canActivate", null);
4487
- BodyAccessGuard = __decorate24([
4488
- Injectable12()
5446
+ BodyAccessGuard = __decorate30([
5447
+ Injectable15()
4489
5448
  ], BodyAccessGuard);
4490
5449
  return createGuard5(BodyAccessGuard);
4491
5450
  }
@@ -4599,19 +5558,19 @@ __name(Policy, "Policy");
4599
5558
 
4600
5559
  // src/ownership/OwnedDecorator.ts
4601
5560
  import "reflect-metadata";
4602
- import { sql as sql5, and as and3 } from "drizzle-orm";
4603
- import { Injectable as Injectable13, Inject as Inject12, DI as DI2, Container as Container2, REQUEST_ID } from "najm-core";
5561
+ import { sql as sql5, and as and5 } from "drizzle-orm";
5562
+ import { Injectable as Injectable16, Inject as Inject16, DI as DI3, Container as Container2, REQUEST_ID } from "najm-core";
4604
5563
  import { USER as USER2 } from "najm-guard";
4605
- var __decorate25 = function(decorators, target, key, desc) {
5564
+ var __decorate31 = function(decorators, target, key, desc) {
4606
5565
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4607
5566
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4608
5567
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4609
5568
  return c > 3 && r && Object.defineProperty(target, key, r), r;
4610
5569
  };
4611
- var __metadata25 = function(k, v) {
5570
+ var __metadata31 = function(k, v) {
4612
5571
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4613
5572
  };
4614
- var _a16;
5573
+ var _a19;
4615
5574
  var OWNED_META = Symbol.for("najm:owned");
4616
5575
  var ScopeContext = class ScopeContext2 {
4617
5576
  static {
@@ -4643,18 +5602,18 @@ var ScopeContext = class ScopeContext2 {
4643
5602
  }
4644
5603
  }
4645
5604
  };
4646
- __decorate25([
4647
- DI2(),
4648
- __metadata25("design:type", typeof (_a16 = typeof Container2 !== "undefined" && Container2) === "function" ? _a16 : Object)
5605
+ __decorate31([
5606
+ DI3(),
5607
+ __metadata31("design:type", typeof (_a19 = typeof Container2 !== "undefined" && Container2) === "function" ? _a19 : Object)
4649
5608
  ], ScopeContext.prototype, "container", void 0);
4650
- ScopeContext = __decorate25([
4651
- Injectable13()
5609
+ ScopeContext = __decorate31([
5610
+ Injectable16()
4652
5611
  ], ScopeContext);
4653
5612
  function Owned(token) {
4654
5613
  return function(target) {
4655
5614
  Reflect.defineMetadata(OWNED_META, token, target);
4656
5615
  const proto = target.prototype;
4657
- Inject12(ScopeContext)(proto, "_scopeCtx");
5616
+ Inject16(ScopeContext)(proto, "_scopeCtx");
4658
5617
  function getUser(self) {
4659
5618
  return self._scopeCtx?.getUser() ?? null;
4660
5619
  }
@@ -4669,7 +5628,7 @@ function Owned(token) {
4669
5628
  return null;
4670
5629
  if (filtered.length === 1)
4671
5630
  return filtered[0];
4672
- return and3(...filtered);
5631
+ return and5(...filtered);
4673
5632
  }
4674
5633
  __name(combineConditions, "combineConditions");
4675
5634
  function applyQueryOptions(query, opts = {}, whereCondition) {
@@ -4762,7 +5721,15 @@ var en_default = {
4762
5721
  oauthProviderAccountLinked: "This Google account is already linked.",
4763
5722
  oauthSignupDisabled: "Registration with Google is disabled.",
4764
5723
  oauthHostedDomainDenied: "This Google Workspace domain is not allowed.",
4765
- oauthLinkSessionExpired: "Your session changed before Google could be linked. Please try again."
5724
+ oauthLinkSessionExpired: "Your session changed before Google could be linked. Please try again.",
5725
+ oauthCredentialSetupRequired: "Set a new password before signing in with Google.",
5726
+ credentialSetupRequired: "Set a new password before continuing.",
5727
+ credentialSetupSessionRequired: "Credential setup session is required.",
5728
+ credentialSetupSessionInvalid: "Credential setup session is invalid or expired.",
5729
+ credentialSetupAlreadyCompleted: "The password was already replaced. Please sign in again.",
5730
+ credentialSetupPasswordRejected: "Choose a different password.",
5731
+ credentialSetupTemporaryShape: "Choose a password that is not your temporary credential.",
5732
+ credentialSetupSamePassword: "Choose a password different from your current one."
4766
5733
  },
4767
5734
  success: {
4768
5735
  login: "Login successful",
@@ -4775,7 +5742,10 @@ var en_default = {
4775
5742
  tokenRefreshed: "Token refreshed successfully",
4776
5743
  sessionRecovered: "Session recovered successfully",
4777
5744
  oauthLogin: "Google sign-in successful",
4778
- oauthLinked: "Google account linked successfully"
5745
+ oauthLinked: "Google account linked successfully",
5746
+ credentialSetupPending: "Password setup is required",
5747
+ credentialSetupPasswordReplaced: "Password set successfully",
5748
+ credentialSetupCancelled: "Password setup cancelled"
4779
5749
  },
4780
5750
  emails: {
4781
5751
  passwordReset: {
@@ -4791,6 +5761,7 @@ var en_default = {
4791
5761
  notFound: "User not found",
4792
5762
  idExists: "User ID already exists",
4793
5763
  emailRequired: "Email is required",
5764
+ phoneExists: "Phone number already registered",
4794
5765
  passwordRequired: "Password is required",
4795
5766
  invalidEmail: "Invalid email format",
4796
5767
  weakPassword: "Password is too weak",
@@ -4852,7 +5823,7 @@ __name(getAuthLocale, "getAuthLocale");
4852
5823
  var AUTH_SUPPORTED_LANGUAGES = Object.keys(AUTH_LOCALES);
4853
5824
 
4854
5825
  // src/oauth/google/GoogleOAuthProvider.ts
4855
- import { Inject as Inject14, Injectable as Injectable15 } from "najm-core";
5826
+ import { Inject as Inject18, Injectable as Injectable18 } from "najm-core";
4856
5827
 
4857
5828
  // src/oauth/types.ts
4858
5829
  var OAuthFlowError = class extends Error {
@@ -4870,15 +5841,15 @@ var OAuthFlowError = class extends Error {
4870
5841
  };
4871
5842
 
4872
5843
  // src/oauth/google/GoogleTokenVerifier.ts
4873
- import { Inject as Inject13, Injectable as Injectable14 } from "najm-core";
5844
+ import { Inject as Inject17, Injectable as Injectable17 } from "najm-core";
4874
5845
  import { createRemoteJWKSet, jwtVerify } from "jose";
4875
- var __decorate26 = function(decorators, target, key, desc) {
5846
+ var __decorate32 = function(decorators, target, key, desc) {
4876
5847
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4877
5848
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4878
5849
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4879
5850
  return c > 3 && r && Object.defineProperty(target, key, r), r;
4880
5851
  };
4881
- var __metadata26 = function(k, v) {
5852
+ var __metadata32 = function(k, v) {
4882
5853
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4883
5854
  };
4884
5855
  var GOOGLE_JWKS = createRemoteJWKSet(new URL("https://www.googleapis.com/oauth2/v3/certs"));
@@ -4930,25 +5901,25 @@ var GoogleTokenVerifier = class GoogleTokenVerifier2 {
4930
5901
  return google;
4931
5902
  }
4932
5903
  };
4933
- __decorate26([
4934
- Inject13(AUTH_CONFIG),
4935
- __metadata26("design:type", Object)
5904
+ __decorate32([
5905
+ Inject17(AUTH_CONFIG),
5906
+ __metadata32("design:type", Object)
4936
5907
  ], GoogleTokenVerifier.prototype, "config", void 0);
4937
- GoogleTokenVerifier = __decorate26([
4938
- Injectable14()
5908
+ GoogleTokenVerifier = __decorate32([
5909
+ Injectable17()
4939
5910
  ], GoogleTokenVerifier);
4940
5911
 
4941
5912
  // src/oauth/google/GoogleOAuthProvider.ts
4942
- var __decorate27 = function(decorators, target, key, desc) {
5913
+ var __decorate33 = function(decorators, target, key, desc) {
4943
5914
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4944
5915
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4945
5916
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4946
5917
  return c > 3 && r && Object.defineProperty(target, key, r), r;
4947
5918
  };
4948
- var __metadata27 = function(k, v) {
5919
+ var __metadata33 = function(k, v) {
4949
5920
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4950
5921
  };
4951
- var _a17;
5922
+ var _a20;
4952
5923
  var AUTHORIZATION_ENDPOINT = "https://accounts.google.com/o/oauth2/v2/auth";
4953
5924
  var TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
4954
5925
  var GoogleOAuthProvider = class GoogleOAuthProvider2 {
@@ -5015,27 +5986,27 @@ var GoogleOAuthProvider = class GoogleOAuthProvider2 {
5015
5986
  throw new OAuthFlowError("oauth_provider_disabled", 404);
5016
5987
  return google;
5017
5988
  }
5018
- };
5019
- __decorate27([
5020
- Inject14(AUTH_CONFIG),
5021
- __metadata27("design:type", Object)
5989
+ };
5990
+ __decorate33([
5991
+ Inject18(AUTH_CONFIG),
5992
+ __metadata33("design:type", Object)
5022
5993
  ], GoogleOAuthProvider.prototype, "config", void 0);
5023
- GoogleOAuthProvider = __decorate27([
5024
- Injectable15(),
5025
- __metadata27("design:paramtypes", [typeof (_a17 = typeof GoogleTokenVerifier !== "undefined" && GoogleTokenVerifier) === "function" ? _a17 : Object])
5994
+ GoogleOAuthProvider = __decorate33([
5995
+ Injectable18(),
5996
+ __metadata33("design:paramtypes", [typeof (_a20 = typeof GoogleTokenVerifier !== "undefined" && GoogleTokenVerifier) === "function" ? _a20 : Object])
5026
5997
  ], GoogleOAuthProvider);
5027
5998
 
5028
5999
  // src/oauth/OAuthAccountRepository.ts
5029
- import { and as and4, eq as eq7 } from "drizzle-orm";
5030
- import { Inject as Inject15, Repository as Repository5 } from "najm-core";
5031
- import { DB as DB5 } from "najm-database";
5032
- var __decorate28 = function(decorators, target, key, desc) {
6000
+ import { and as and6, eq as eq9 } from "drizzle-orm";
6001
+ import { Inject as Inject19, Repository as Repository7 } from "najm-core";
6002
+ import { DB as DB7 } from "najm-database";
6003
+ var __decorate34 = function(decorators, target, key, desc) {
5033
6004
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5034
6005
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5035
6006
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5036
6007
  return c > 3 && r && Object.defineProperty(target, key, r), r;
5037
6008
  };
5038
- var __metadata28 = function(k, v) {
6009
+ var __metadata34 = function(k, v) {
5039
6010
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
5040
6011
  };
5041
6012
  var OAuthAccountRepository = class OAuthAccountRepository2 {
@@ -5051,11 +6022,11 @@ var OAuthAccountRepository = class OAuthAccountRepository2 {
5051
6022
  return this.schema.oauthAccounts;
5052
6023
  }
5053
6024
  async getByProviderAccount(provider, providerAccountId) {
5054
- const [account] = await this.db.select().from(this.accounts).where(and4(eq7(this.accounts.provider, provider), eq7(this.accounts.providerAccountId, providerAccountId))).limit(1);
6025
+ const [account] = await this.db.select().from(this.accounts).where(and6(eq9(this.accounts.provider, provider), eq9(this.accounts.providerAccountId, providerAccountId))).limit(1);
5055
6026
  return account;
5056
6027
  }
5057
6028
  async getByUserProvider(userId, provider) {
5058
- const [account] = await this.db.select().from(this.accounts).where(and4(eq7(this.accounts.userId, userId), eq7(this.accounts.provider, provider))).limit(1);
6029
+ const [account] = await this.db.select().from(this.accounts).where(and6(eq9(this.accounts.userId, userId), eq9(this.accounts.provider, provider))).limit(1);
5059
6030
  return account;
5060
6031
  }
5061
6032
  async create(data) {
@@ -5063,35 +6034,35 @@ var OAuthAccountRepository = class OAuthAccountRepository2 {
5063
6034
  return account;
5064
6035
  }
5065
6036
  };
5066
- __decorate28([
5067
- DB5(),
5068
- __metadata28("design:type", Object)
6037
+ __decorate34([
6038
+ DB7(),
6039
+ __metadata34("design:type", Object)
5069
6040
  ], OAuthAccountRepository.prototype, "db", void 0);
5070
- __decorate28([
5071
- Inject15(AUTH_SCHEMA),
5072
- __metadata28("design:type", Object)
6041
+ __decorate34([
6042
+ Inject19(AUTH_SCHEMA),
6043
+ __metadata34("design:type", Object)
5073
6044
  ], OAuthAccountRepository.prototype, "schema", void 0);
5074
- OAuthAccountRepository = __decorate28([
5075
- Repository5()
6045
+ OAuthAccountRepository = __decorate34([
6046
+ Repository7()
5076
6047
  ], OAuthAccountRepository);
5077
6048
 
5078
6049
  // src/oauth/OAuthAccountService.ts
5079
- import { randomBytes as randomBytes2 } from "crypto";
5080
- import { Inject as Inject16, Injectable as Injectable16 } from "najm-core";
5081
- import { Transaction as Transaction2 } from "najm-database";
5082
- var __decorate29 = function(decorators, target, key, desc) {
6050
+ import { randomBytes as randomBytes3 } from "crypto";
6051
+ import { Inject as Inject20, Injectable as Injectable19 } from "najm-core";
6052
+ import { Transaction as Transaction5 } from "najm-database";
6053
+ var __decorate35 = function(decorators, target, key, desc) {
5083
6054
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5084
6055
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5085
6056
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5086
6057
  return c > 3 && r && Object.defineProperty(target, key, r), r;
5087
6058
  };
5088
- var __metadata29 = function(k, v) {
6059
+ var __metadata35 = function(k, v) {
5089
6060
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
5090
6061
  };
5091
- var _a18;
5092
- var _b9;
5093
- var _c6;
5094
- var _d3;
6062
+ var _a21;
6063
+ var _b12;
6064
+ var _c9;
6065
+ var _d7;
5095
6066
  var OAuthAccountService = class OAuthAccountService2 {
5096
6067
  static {
5097
6068
  __name(this, "OAuthAccountService");
@@ -5118,7 +6089,7 @@ var OAuthAccountService = class OAuthAccountService2 {
5118
6089
  if (!this.googleConfig().allowSignup) {
5119
6090
  throw new OAuthFlowError("oauth_signup_disabled", 403);
5120
6091
  }
5121
- const password = `${randomBytes2(32).toString("base64url")}Aa1`;
6092
+ const password = `${randomBytes3(32).toString("base64url")}Aa1`;
5122
6093
  const user = await this.users.create({
5123
6094
  name: identity.name,
5124
6095
  email: identity.email,
@@ -5167,50 +6138,50 @@ var OAuthAccountService = class OAuthAccountService2 {
5167
6138
  return google;
5168
6139
  }
5169
6140
  };
5170
- __decorate29([
5171
- Inject16(AUTH_CONFIG),
5172
- __metadata29("design:type", Object)
6141
+ __decorate35([
6142
+ Inject20(AUTH_CONFIG),
6143
+ __metadata35("design:type", Object)
5173
6144
  ], OAuthAccountService.prototype, "config", void 0);
5174
- __decorate29([
5175
- Transaction2(),
5176
- __metadata29("design:type", Function),
5177
- __metadata29("design:paramtypes", [Object]),
5178
- __metadata29("design:returntype", typeof (_c6 = typeof Promise !== "undefined" && Promise) === "function" ? _c6 : Object)
6145
+ __decorate35([
6146
+ Transaction5(),
6147
+ __metadata35("design:type", Function),
6148
+ __metadata35("design:paramtypes", [Object]),
6149
+ __metadata35("design:returntype", typeof (_c9 = typeof Promise !== "undefined" && Promise) === "function" ? _c9 : Object)
5179
6150
  ], OAuthAccountService.prototype, "resolveForLogin", null);
5180
- __decorate29([
5181
- Transaction2(),
5182
- __metadata29("design:type", Function),
5183
- __metadata29("design:paramtypes", [String, Object]),
5184
- __metadata29("design:returntype", typeof (_d3 = typeof Promise !== "undefined" && Promise) === "function" ? _d3 : Object)
6151
+ __decorate35([
6152
+ Transaction5(),
6153
+ __metadata35("design:type", Function),
6154
+ __metadata35("design:paramtypes", [String, Object]),
6155
+ __metadata35("design:returntype", typeof (_d7 = typeof Promise !== "undefined" && Promise) === "function" ? _d7 : Object)
5185
6156
  ], OAuthAccountService.prototype, "linkUser", null);
5186
- OAuthAccountService = __decorate29([
5187
- Injectable16(),
5188
- __metadata29("design:paramtypes", [typeof (_a18 = typeof OAuthAccountRepository !== "undefined" && OAuthAccountRepository) === "function" ? _a18 : Object, typeof (_b9 = typeof UserService !== "undefined" && UserService) === "function" ? _b9 : Object])
6157
+ OAuthAccountService = __decorate35([
6158
+ Injectable19(),
6159
+ __metadata35("design:paramtypes", [typeof (_a21 = typeof OAuthAccountRepository !== "undefined" && OAuthAccountRepository) === "function" ? _a21 : Object, typeof (_b12 = typeof UserService !== "undefined" && UserService) === "function" ? _b12 : Object])
5189
6160
  ], OAuthAccountService);
5190
6161
 
5191
6162
  // src/oauth/OAuthController.ts
5192
- import { createHash as createHash4 } from "crypto";
6163
+ import { createHash as createHash5 } from "crypto";
5193
6164
  import { Controller as Controller5, Ctx as Ctx2, Get as Get5, Post as Post5, Query as Query2, User as User5 } from "najm-core";
5194
6165
  import { RateLimit as RateLimit2 } from "najm-rate";
5195
6166
 
5196
6167
  // src/oauth/OAuthService.ts
5197
- import { Inject as Inject17, Injectable as Injectable18, Log as Log2 } from "najm-core";
6168
+ import { Inject as Inject21, Injectable as Injectable21, Log as Log2 } from "najm-core";
5198
6169
 
5199
6170
  // src/oauth/OAuthStateService.ts
5200
- import { createHash as createHash3, randomBytes as randomBytes3, timingSafeEqual } from "crypto";
5201
- import { Injectable as Injectable17 } from "najm-core";
5202
- import { CookieService as CookieService2 } from "najm-cookies";
5203
- var __decorate30 = function(decorators, target, key, desc) {
6171
+ import { createHash as createHash4, randomBytes as randomBytes4, timingSafeEqual } from "crypto";
6172
+ import { Injectable as Injectable20 } from "najm-core";
6173
+ import { CookieService as CookieService3 } from "najm-cookies";
6174
+ var __decorate36 = function(decorators, target, key, desc) {
5204
6175
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5205
6176
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5206
6177
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5207
6178
  return c > 3 && r && Object.defineProperty(target, key, r), r;
5208
6179
  };
5209
- var __metadata30 = function(k, v) {
6180
+ var __metadata36 = function(k, v) {
5210
6181
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
5211
6182
  };
5212
- var _a19;
5213
- var _b10;
6183
+ var _a22;
6184
+ var _b13;
5214
6185
  var ATTEMPT_TTL_MS = 10 * 60 * 1e3;
5215
6186
  var COOKIE_PREFIX = "najm.oauth.google.";
5216
6187
  var OAuthStateService = class OAuthStateService2 {
@@ -5224,13 +6195,13 @@ var OAuthStateService = class OAuthStateService2 {
5224
6195
  this.encryption = encryption;
5225
6196
  }
5226
6197
  create(input) {
5227
- const state = randomBytes3(32).toString("base64url");
5228
- const codeVerifier = randomBytes3(48).toString("base64url");
6198
+ const state = randomBytes4(32).toString("base64url");
6199
+ const codeVerifier = randomBytes4(48).toString("base64url");
5229
6200
  const attempt = {
5230
6201
  provider: "google",
5231
6202
  intent: input.intent,
5232
6203
  state,
5233
- nonce: randomBytes3(32).toString("base64url"),
6204
+ nonce: randomBytes4(32).toString("base64url"),
5234
6205
  codeVerifier,
5235
6206
  returnTo: this.validateReturnTo(input.returnTo),
5236
6207
  userId: input.userId,
@@ -5245,7 +6216,7 @@ var OAuthStateService = class OAuthStateService2 {
5245
6216
  });
5246
6217
  return {
5247
6218
  attempt,
5248
- codeChallenge: createHash3("sha256").update(codeVerifier).digest("base64url")
6219
+ codeChallenge: createHash4("sha256").update(codeVerifier).digest("base64url")
5249
6220
  };
5250
6221
  }
5251
6222
  consume(state) {
@@ -5299,27 +6270,28 @@ var OAuthStateService = class OAuthStateService2 {
5299
6270
  return /^[A-Za-z0-9_-]{40,128}$/.test(state);
5300
6271
  }
5301
6272
  };
5302
- OAuthStateService = __decorate30([
5303
- Injectable17(),
5304
- __metadata30("design:paramtypes", [typeof (_a19 = typeof CookieService2 !== "undefined" && CookieService2) === "function" ? _a19 : Object, typeof (_b10 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _b10 : Object])
6273
+ OAuthStateService = __decorate36([
6274
+ Injectable20(),
6275
+ __metadata36("design:paramtypes", [typeof (_a22 = typeof CookieService3 !== "undefined" && CookieService3) === "function" ? _a22 : Object, typeof (_b13 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _b13 : Object])
5305
6276
  ], OAuthStateService);
5306
6277
 
5307
6278
  // src/oauth/OAuthService.ts
5308
- var __decorate31 = function(decorators, target, key, desc) {
6279
+ var __decorate37 = function(decorators, target, key, desc) {
5309
6280
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5310
6281
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5311
6282
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5312
6283
  return c > 3 && r && Object.defineProperty(target, key, r), r;
5313
6284
  };
5314
- var __metadata31 = function(k, v) {
6285
+ var __metadata37 = function(k, v) {
5315
6286
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
5316
6287
  };
5317
- var _a20;
5318
- var _b11;
5319
- var _c7;
5320
- var _d4;
5321
- var _e3;
5322
- var _f3;
6288
+ var _a23;
6289
+ var _b14;
6290
+ var _c10;
6291
+ var _d8;
6292
+ var _e5;
6293
+ var _f5;
6294
+ var _g4;
5323
6295
  var OAuthService = class OAuthService2 {
5324
6296
  static {
5325
6297
  __name(this, "OAuthService");
@@ -5330,15 +6302,17 @@ var OAuthService = class OAuthService2 {
5330
6302
  sessions;
5331
6303
  tokens;
5332
6304
  users;
6305
+ requirements;
5333
6306
  config;
5334
6307
  logger;
5335
- constructor(state, google, accounts, sessions, tokens, users) {
6308
+ constructor(state, google, accounts, sessions, tokens, users, requirements) {
5336
6309
  this.state = state;
5337
6310
  this.google = google;
5338
6311
  this.accounts = accounts;
5339
6312
  this.sessions = sessions;
5340
6313
  this.tokens = tokens;
5341
6314
  this.users = users;
6315
+ this.requirements = requirements;
5342
6316
  }
5343
6317
  startGoogleLogin(returnTo) {
5344
6318
  this.googleConfig();
@@ -5382,6 +6356,9 @@ var OAuthService = class OAuthService2 {
5382
6356
  await this.accounts.linkUser(attempt.userId, identity);
5383
6357
  } else {
5384
6358
  const user = await this.accounts.resolveForLogin(identity);
6359
+ if (await this.requirements?.isRequired(user.id, PASSWORD_SETUP_PURPOSE)) {
6360
+ throw new OAuthFlowError(CREDENTIAL_SETUP_CODES.OAUTH_BLOCKED, 403);
6361
+ }
5385
6362
  await this.sessions.establish(user);
5386
6363
  }
5387
6364
  return this.frontendSuccessUrl(attempt.returnTo, attempt.intent);
@@ -5419,39 +6396,39 @@ var OAuthService = class OAuthService2 {
5419
6396
  return google;
5420
6397
  }
5421
6398
  };
5422
- __decorate31([
5423
- Inject17(AUTH_CONFIG),
5424
- __metadata31("design:type", Object)
6399
+ __decorate37([
6400
+ Inject21(AUTH_CONFIG),
6401
+ __metadata37("design:type", Object)
5425
6402
  ], OAuthService.prototype, "config", void 0);
5426
- __decorate31([
6403
+ __decorate37([
5427
6404
  Log2(),
5428
- __metadata31("design:type", Object)
6405
+ __metadata37("design:type", Object)
5429
6406
  ], OAuthService.prototype, "logger", void 0);
5430
- OAuthService = __decorate31([
5431
- Injectable18(),
5432
- __metadata31("design:paramtypes", [typeof (_a20 = typeof OAuthStateService !== "undefined" && OAuthStateService) === "function" ? _a20 : Object, typeof (_b11 = typeof GoogleOAuthProvider !== "undefined" && GoogleOAuthProvider) === "function" ? _b11 : Object, typeof (_c7 = typeof OAuthAccountService !== "undefined" && OAuthAccountService) === "function" ? _c7 : Object, typeof (_d4 = typeof AuthSessionService !== "undefined" && AuthSessionService) === "function" ? _d4 : Object, typeof (_e3 = typeof TokenService !== "undefined" && TokenService) === "function" ? _e3 : Object, typeof (_f3 = typeof UserService !== "undefined" && UserService) === "function" ? _f3 : Object])
6407
+ OAuthService = __decorate37([
6408
+ Injectable21(),
6409
+ __metadata37("design:paramtypes", [typeof (_a23 = typeof OAuthStateService !== "undefined" && OAuthStateService) === "function" ? _a23 : Object, typeof (_b14 = typeof GoogleOAuthProvider !== "undefined" && GoogleOAuthProvider) === "function" ? _b14 : Object, typeof (_c10 = typeof OAuthAccountService !== "undefined" && OAuthAccountService) === "function" ? _c10 : Object, typeof (_d8 = typeof AuthSessionService !== "undefined" && AuthSessionService) === "function" ? _d8 : Object, typeof (_e5 = typeof TokenService !== "undefined" && TokenService) === "function" ? _e5 : Object, typeof (_f5 = typeof UserService !== "undefined" && UserService) === "function" ? _f5 : Object, typeof (_g4 = typeof CredentialSetupRequirementService !== "undefined" && CredentialSetupRequirementService) === "function" ? _g4 : Object])
5433
6410
  ], OAuthService);
5434
6411
 
5435
6412
  // src/oauth/OAuthController.ts
5436
- var __decorate32 = function(decorators, target, key, desc) {
6413
+ var __decorate38 = function(decorators, target, key, desc) {
5437
6414
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5438
6415
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5439
6416
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5440
6417
  return c > 3 && r && Object.defineProperty(target, key, r), r;
5441
6418
  };
5442
- var __metadata32 = function(k, v) {
6419
+ var __metadata38 = function(k, v) {
5443
6420
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
5444
6421
  };
5445
- var __param11 = function(paramIndex, decorator) {
6422
+ var __param12 = function(paramIndex, decorator) {
5446
6423
  return function(target, key) {
5447
6424
  decorator(target, key, paramIndex);
5448
6425
  };
5449
6426
  };
5450
- var _a21;
6427
+ var _a24;
5451
6428
  var callbackKey = /* @__PURE__ */ __name((ctx) => {
5452
6429
  const ip = ctx.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? ctx.req.header("x-real-ip") ?? "unknown";
5453
6430
  const state = ctx.req.query("state") ?? "none";
5454
- const fingerprint = createHash4("sha256").update(state).digest("base64url").slice(0, 24);
6431
+ const fingerprint = createHash5("sha256").update(state).digest("base64url").slice(0, 24);
5455
6432
  return `${ip}:${fingerprint}`;
5456
6433
  }, "callbackKey");
5457
6434
  var OAuthController = class OAuthController2 {
@@ -5473,39 +6450,39 @@ var OAuthController = class OAuthController2 {
5473
6450
  return this.oauth.startGoogleLink(userId, returnTo);
5474
6451
  }
5475
6452
  };
5476
- __decorate32([
6453
+ __decorate38([
5477
6454
  Get5("/start"),
5478
6455
  RateLimit2({ limit: 20, window: "15m", key: "ip" }),
5479
- __param11(0, Ctx2()),
5480
- __param11(1, Query2("returnTo")),
5481
- __metadata32("design:type", Function),
5482
- __metadata32("design:paramtypes", [Object, String]),
5483
- __metadata32("design:returntype", void 0)
6456
+ __param12(0, Ctx2()),
6457
+ __param12(1, Query2("returnTo")),
6458
+ __metadata38("design:type", Function),
6459
+ __metadata38("design:paramtypes", [Object, String]),
6460
+ __metadata38("design:returntype", void 0)
5484
6461
  ], OAuthController.prototype, "start", null);
5485
- __decorate32([
6462
+ __decorate38([
5486
6463
  Get5("/callback"),
5487
6464
  RateLimit2({ limit: 20, window: "15m", key: callbackKey }),
5488
- __param11(0, Ctx2()),
5489
- __param11(1, Query2("code")),
5490
- __param11(2, Query2("state")),
5491
- __param11(3, Query2("error")),
5492
- __metadata32("design:type", Function),
5493
- __metadata32("design:paramtypes", [Object, String, String, String]),
5494
- __metadata32("design:returntype", Promise)
6465
+ __param12(0, Ctx2()),
6466
+ __param12(1, Query2("code")),
6467
+ __param12(2, Query2("state")),
6468
+ __param12(3, Query2("error")),
6469
+ __metadata38("design:type", Function),
6470
+ __metadata38("design:paramtypes", [Object, String, String, String]),
6471
+ __metadata38("design:returntype", Promise)
5495
6472
  ], OAuthController.prototype, "callback", null);
5496
- __decorate32([
6473
+ __decorate38([
5497
6474
  Post5("/link"),
5498
6475
  isAuth(),
5499
6476
  RateLimit2({ limit: 10, window: "15m", key: "user" }),
5500
- __param11(0, User5("id")),
5501
- __param11(1, Query2("returnTo")),
5502
- __metadata32("design:type", Function),
5503
- __metadata32("design:paramtypes", [String, String]),
5504
- __metadata32("design:returntype", void 0)
6477
+ __param12(0, User5("id")),
6478
+ __param12(1, Query2("returnTo")),
6479
+ __metadata38("design:type", Function),
6480
+ __metadata38("design:paramtypes", [String, String]),
6481
+ __metadata38("design:returntype", void 0)
5505
6482
  ], OAuthController.prototype, "link", null);
5506
- OAuthController = __decorate32([
6483
+ OAuthController = __decorate38([
5507
6484
  Controller5("/auth/oauth/google"),
5508
- __metadata32("design:paramtypes", [typeof (_a21 = typeof OAuthService !== "undefined" && OAuthService) === "function" ? _a21 : Object])
6485
+ __metadata38("design:paramtypes", [typeof (_a24 = typeof OAuthService !== "undefined" && OAuthService) === "function" ? _a24 : Object])
5509
6486
  ], OAuthController);
5510
6487
 
5511
6488
  // src/oauth/index.ts
@@ -5519,250 +6496,91 @@ var OAUTH_MODULE = [
5519
6496
  OAuthController
5520
6497
  ];
5521
6498
 
5522
- // src/credentialSetup/CredentialSetupRepository.ts
5523
- import { and as and5, eq as eq8, gt, isNull as isNull2, lt as lt2 } from "drizzle-orm";
5524
- import { Err as Err11, Inject as Inject18, Repository as Repository6 } from "najm-core";
5525
- import { DB as DB6 } from "najm-database";
5526
- var __decorate33 = function(decorators, target, key, desc) {
5527
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5528
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5529
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5530
- return c > 3 && r && Object.defineProperty(target, key, r), r;
5531
- };
5532
- var __metadata33 = function(k, v) {
5533
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
5534
- };
5535
- var CredentialSetupRepository = class CredentialSetupRepository2 {
5536
- static {
5537
- __name(this, "CredentialSetupRepository");
5538
- }
5539
- db;
5540
- schema;
5541
- get sessions() {
5542
- const sessions = this.schema.credentialSetupSessions;
5543
- if (!sessions) {
5544
- Err11.invalidOperation("auth.schema.credentialSetupSessions is required to use CredentialSetupService");
5545
- }
5546
- return sessions;
5547
- }
5548
- async replaceActive(data) {
5549
- const now = (/* @__PURE__ */ new Date()).toISOString();
5550
- await this.db.update(this.sessions).set({ revokedAt: now, updatedAt: now }).where(and5(eq8(this.sessions.userId, data.userId), eq8(this.sessions.purpose, data.purpose), isNull2(this.sessions.consumedAt), isNull2(this.sessions.revokedAt)));
5551
- const [session] = await this.db.insert(this.sessions).values(data).returning({
5552
- userId: this.sessions.userId,
5553
- purpose: this.sessions.purpose,
5554
- expiresAt: this.sessions.expiresAt
5555
- });
5556
- return session;
5557
- }
5558
- async findActive(tokenHash, purpose) {
5559
- const [session] = await this.db.select({
5560
- userId: this.sessions.userId,
5561
- purpose: this.sessions.purpose,
5562
- expiresAt: this.sessions.expiresAt
5563
- }).from(this.sessions).where(and5(eq8(this.sessions.tokenHash, tokenHash), eq8(this.sessions.purpose, purpose), isNull2(this.sessions.consumedAt), isNull2(this.sessions.revokedAt), gt(this.sessions.expiresAt, (/* @__PURE__ */ new Date()).toISOString()))).limit(1);
5564
- return session;
5565
- }
5566
- async consume(tokenHash, purpose) {
5567
- const now = (/* @__PURE__ */ new Date()).toISOString();
5568
- const [session] = await this.db.update(this.sessions).set({ consumedAt: now, updatedAt: now }).where(and5(eq8(this.sessions.tokenHash, tokenHash), eq8(this.sessions.purpose, purpose), isNull2(this.sessions.consumedAt), isNull2(this.sessions.revokedAt), gt(this.sessions.expiresAt, now))).returning({
5569
- userId: this.sessions.userId,
5570
- purpose: this.sessions.purpose,
5571
- expiresAt: this.sessions.expiresAt
5572
- });
5573
- return session;
5574
- }
5575
- async revoke(tokenHash, purpose) {
5576
- const now = (/* @__PURE__ */ new Date()).toISOString();
5577
- const [session] = await this.db.update(this.sessions).set({ revokedAt: now, updatedAt: now }).where(and5(eq8(this.sessions.tokenHash, tokenHash), eq8(this.sessions.purpose, purpose), isNull2(this.sessions.consumedAt), isNull2(this.sessions.revokedAt))).returning({ userId: this.sessions.userId });
5578
- return session;
5579
- }
5580
- async deleteExpired() {
5581
- return this.db.delete(this.sessions).where(lt2(this.sessions.expiresAt, (/* @__PURE__ */ new Date()).toISOString())).returning({ userId: this.sessions.userId });
5582
- }
5583
- };
5584
- __decorate33([
5585
- DB6(),
5586
- __metadata33("design:type", Object)
5587
- ], CredentialSetupRepository.prototype, "db", void 0);
5588
- __decorate33([
5589
- Inject18(AUTH_SCHEMA),
5590
- __metadata33("design:type", Object)
5591
- ], CredentialSetupRepository.prototype, "schema", void 0);
5592
- CredentialSetupRepository = __decorate33([
5593
- Repository6()
5594
- ], CredentialSetupRepository);
6499
+ // src/credentialSetup/CredentialSetupController.ts
6500
+ import { Body as Body6, Controller as Controller6, Get as Get6, Post as Post6, ResMsg as ResMsg5 } from "najm-core";
6501
+ import { RateLimit as RateLimit3 } from "najm-rate";
6502
+ import { Validate as Validate5 } from "najm-validation";
5595
6503
 
5596
- // src/credentialSetup/CredentialSetupService.ts
5597
- import { createHash as createHash5, randomBytes as randomBytes4 } from "crypto";
5598
- import { CookieService as CookieService3 } from "najm-cookies";
5599
- import { Err as Err12, Injectable as Injectable19 } from "najm-core";
5600
- import { Transaction as Transaction3 } from "najm-database";
5601
- var __decorate34 = function(decorators, target, key, desc) {
6504
+ // src/credentialSetup/CredentialSetupDto.ts
6505
+ import { z as z5 } from "zod";
6506
+ var defaultCredentialSetupPasswordSchema = z5.string().min(8, "Password must be at least 8 characters").refine((v) => new TextEncoder().encode(v).length <= 72, "Password must be at most 72 bytes").regex(/[a-zA-Z]/, "Password must contain at least one letter").regex(/\d/, "Password must contain at least one number");
6507
+ var credentialSetupChangeDto = z5.object({
6508
+ newPassword: z5.string().min(1, "A new password is required").max(256)
6509
+ });
6510
+
6511
+ // src/credentialSetup/CredentialSetupController.ts
6512
+ var __decorate39 = function(decorators, target, key, desc) {
5602
6513
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5603
6514
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5604
6515
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5605
6516
  return c > 3 && r && Object.defineProperty(target, key, r), r;
5606
6517
  };
5607
- var __metadata34 = function(k, v) {
6518
+ var __metadata39 = function(k, v) {
5608
6519
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
5609
6520
  };
5610
- var _a22;
5611
- var _b12;
5612
- var _c8;
5613
- var _d5;
5614
- var _e4;
5615
- var _f4;
5616
- var _g3;
5617
- var DEFAULT_COOKIE_NAME = "najm.credential-setup";
5618
- var DEFAULT_TTL_MS = 10 * 60 * 1e3;
5619
- var MAX_TTL_MS = 24 * 60 * 60 * 1e3;
5620
- var PURPOSE_PATTERN = /^[a-z0-9](?:[a-z0-9:_-]{0,62}[a-z0-9])?$/;
5621
- var COOKIE_NAME_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
5622
- var CredentialSetupService = class CredentialSetupService2 {
6521
+ var __param13 = function(paramIndex, decorator) {
6522
+ return function(target, key) {
6523
+ decorator(target, key, paramIndex);
6524
+ };
6525
+ };
6526
+ var _a25;
6527
+ var CredentialSetupController = class CredentialSetupController2 {
5623
6528
  static {
5624
- __name(this, "CredentialSetupService");
5625
- }
5626
- repository;
5627
- tokens;
5628
- authCookies;
5629
- cookies;
5630
- constructor(repository, tokens, authCookies, cookies2) {
5631
- this.repository = repository;
5632
- this.tokens = tokens;
5633
- this.authCookies = authCookies;
5634
- this.cookies = cookies2;
5635
- }
5636
- /**
5637
- * Revoke normal auth sessions and issue a single-purpose, short-lived,
5638
- * browser-session cookie. No access or refresh token is minted.
5639
- */
5640
- async begin(userId, options) {
5641
- const resolved = this.resolveOptions(options);
5642
- const token = randomBytes4(32).toString("base64url");
5643
- const expiresAt = new Date(Date.now() + resolved.ttlMs).toISOString();
5644
- await this.repository.deleteExpired();
5645
- await this.repository.replaceActive({
5646
- userId,
5647
- purpose: resolved.purpose,
5648
- tokenHash: this.hashToken(token),
5649
- expiresAt
5650
- });
5651
- await this.tokens.invalidateUserAccessTokens(userId);
5652
- await this.tokens.revokeAllForUser(userId);
5653
- this.authCookies.clearRefreshToken();
5654
- this.authCookies.clearSessionCookie();
5655
- this.setCookie(token, resolved);
5656
- return { purpose: resolved.purpose, expiresAt };
5657
- }
5658
- /** Validate and return the current active setup session without consuming it. */
5659
- async require(options) {
5660
- const resolved = this.resolveOptions(options);
5661
- const token = this.cookies.get(resolved.cookieName);
5662
- if (!token)
5663
- Err12("Credential setup session is required", 401);
5664
- const session = await this.repository.findActive(this.hashToken(token), resolved.purpose);
5665
- if (!session) {
5666
- this.clearCookie(resolved);
5667
- Err12("Credential setup session is invalid or expired", 401);
5668
- }
5669
- return session;
5670
- }
5671
- /**
5672
- * Atomically consume the setup session and execute the application-owned
5673
- * credential mutation in the same database transaction. If the callback
5674
- * fails, consumption rolls back and the browser may safely retry.
5675
- */
5676
- async consume(options, complete) {
5677
- const resolved = this.resolveOptions(options);
5678
- const token = this.cookies.get(resolved.cookieName);
5679
- if (!token)
5680
- Err12("Credential setup session is required", 401);
5681
- const session = await this.repository.consume(this.hashToken(token), resolved.purpose);
5682
- if (!session) {
5683
- this.clearCookie(resolved);
5684
- Err12("Credential setup session is invalid or expired", 401);
5685
- }
5686
- const result = await complete(session);
5687
- this.clearCookie(resolved);
5688
- return result;
5689
- }
5690
- async cancel(options) {
5691
- const resolved = this.resolveOptions(options);
5692
- const token = this.cookies.get(resolved.cookieName);
5693
- if (token) {
5694
- await this.repository.revoke(this.hashToken(token), resolved.purpose);
5695
- }
5696
- this.clearCookie(resolved);
5697
- return { cancelled: true };
5698
- }
5699
- async pruneExpired() {
5700
- await this.repository.deleteExpired();
6529
+ __name(this, "CredentialSetupController");
5701
6530
  }
5702
- resolveOptions(options) {
5703
- const purpose = options.purpose?.trim().toLowerCase();
5704
- const cookieName = options.cookieName?.trim() || DEFAULT_COOKIE_NAME;
5705
- const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
5706
- const cookiePath = options.cookiePath ?? "/";
5707
- if (!purpose || !PURPOSE_PATTERN.test(purpose)) {
5708
- Err12("Credential setup purpose must be 1-64 lowercase letters, numbers, colon, underscore, or hyphen", 500);
5709
- }
5710
- if (!COOKIE_NAME_PATTERN.test(cookieName) || cookieName.length > 128) {
5711
- Err12("Credential setup cookie name is invalid", 500);
5712
- }
5713
- if (!Number.isInteger(ttlMs) || ttlMs < 1e3 || ttlMs > MAX_TTL_MS) {
5714
- Err12("Credential setup ttlMs must be an integer between 1000 and 86400000", 500);
5715
- }
5716
- if (!cookiePath.startsWith("/") || cookiePath.includes(";") || cookiePath.includes("\\")) {
5717
- Err12("Credential setup cookiePath must be a same-origin path", 500);
5718
- }
5719
- return { purpose, cookieName, ttlMs, cookiePath };
6531
+ passwords;
6532
+ constructor(passwords) {
6533
+ this.passwords = passwords;
5720
6534
  }
5721
- hashToken(token) {
5722
- return createHash5("sha256").update(token).digest("hex");
6535
+ status() {
6536
+ return this.passwords.status();
5723
6537
  }
5724
- setCookie(token, options) {
5725
- this.cookies.setSession(options.cookieName, token, {
5726
- httpOnly: true,
5727
- path: options.cookiePath,
5728
- sameSite: "Strict",
5729
- secure: process.env.NODE_ENV === "production"
5730
- });
6538
+ change(body) {
6539
+ return this.passwords.change(body.newPassword);
5731
6540
  }
5732
- clearCookie(options) {
5733
- this.cookies.delete(options.cookieName, {
5734
- path: options.cookiePath,
5735
- secure: process.env.NODE_ENV === "production"
5736
- });
6541
+ cancel() {
6542
+ return this.passwords.cancel();
5737
6543
  }
5738
6544
  };
5739
- __decorate34([
5740
- Transaction3({ retries: 2 }),
5741
- __metadata34("design:type", Function),
5742
- __metadata34("design:paramtypes", [String, Object]),
5743
- __metadata34("design:returntype", typeof (_e4 = typeof Promise !== "undefined" && Promise) === "function" ? _e4 : Object)
5744
- ], CredentialSetupService.prototype, "begin", null);
5745
- __decorate34([
5746
- Transaction3({ retries: 2 }),
5747
- __metadata34("design:type", Function),
5748
- __metadata34("design:paramtypes", [Object, Function]),
5749
- __metadata34("design:returntype", typeof (_f4 = typeof Promise !== "undefined" && Promise) === "function" ? _f4 : Object)
5750
- ], CredentialSetupService.prototype, "consume", null);
5751
- __decorate34([
5752
- Transaction3({ retries: 2 }),
5753
- __metadata34("design:type", Function),
5754
- __metadata34("design:paramtypes", [Object]),
5755
- __metadata34("design:returntype", typeof (_g3 = typeof Promise !== "undefined" && Promise) === "function" ? _g3 : Object)
5756
- ], CredentialSetupService.prototype, "cancel", null);
5757
- CredentialSetupService = __decorate34([
5758
- Injectable19(),
5759
- __metadata34("design:paramtypes", [typeof (_a22 = typeof CredentialSetupRepository !== "undefined" && CredentialSetupRepository) === "function" ? _a22 : Object, typeof (_b12 = typeof TokenService !== "undefined" && TokenService) === "function" ? _b12 : Object, typeof (_c8 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _c8 : Object, typeof (_d5 = typeof CookieService3 !== "undefined" && CookieService3) === "function" ? _d5 : Object])
5760
- ], CredentialSetupService);
6545
+ __decorate39([
6546
+ Get6("/setup"),
6547
+ RateLimit3({ limit: 30, window: "15m", key: "ip" }),
6548
+ ResMsg5("auth.success.credentialSetupPending"),
6549
+ __metadata39("design:type", Function),
6550
+ __metadata39("design:paramtypes", []),
6551
+ __metadata39("design:returntype", void 0)
6552
+ ], CredentialSetupController.prototype, "status", null);
6553
+ __decorate39([
6554
+ Post6("/change"),
6555
+ RateLimit3({ limit: 5, window: "15m", key: "ip" }),
6556
+ Validate5(credentialSetupChangeDto),
6557
+ ResMsg5("auth.success.credentialSetupPasswordReplaced"),
6558
+ __param13(0, Body6()),
6559
+ __metadata39("design:type", Function),
6560
+ __metadata39("design:paramtypes", [Object]),
6561
+ __metadata39("design:returntype", void 0)
6562
+ ], CredentialSetupController.prototype, "change", null);
6563
+ __decorate39([
6564
+ Post6("/cancel"),
6565
+ RateLimit3({ limit: 10, window: "15m", key: "ip" }),
6566
+ ResMsg5("auth.success.credentialSetupCancelled"),
6567
+ __metadata39("design:type", Function),
6568
+ __metadata39("design:paramtypes", []),
6569
+ __metadata39("design:returntype", void 0)
6570
+ ], CredentialSetupController.prototype, "cancel", null);
6571
+ CredentialSetupController = __decorate39([
6572
+ Controller6("/auth/credential-setup"),
6573
+ __metadata39("design:paramtypes", [typeof (_a25 = typeof PasswordSetupService !== "undefined" && PasswordSetupService) === "function" ? _a25 : Object])
6574
+ ], CredentialSetupController);
5761
6575
 
5762
6576
  // src/credentialSetup/index.ts
5763
6577
  var CREDENTIAL_SETUP_MODULE = [
5764
6578
  CredentialSetupRepository,
5765
- CredentialSetupService
6579
+ CredentialSetupRequirementRepository,
6580
+ CredentialSetupService,
6581
+ CredentialSetupRequirementService,
6582
+ PasswordSetupService,
6583
+ CredentialSetupController
5766
6584
  ];
5767
6585
 
5768
6586
  // src/AuthPlugin.ts
@@ -5786,9 +6604,9 @@ var resolveGoogleConfig = /* @__PURE__ */ __name((config) => {
5786
6604
  const clientId = google.clientId ?? process.env.GOOGLE_CLIENT_ID ?? "";
5787
6605
  const clientSecret = google.clientSecret ?? process.env.GOOGLE_CLIENT_SECRET ?? "";
5788
6606
  if (!clientId)
5789
- throw Err13.configRequired("auth.oauth.google", "GOOGLE_CLIENT_ID");
6607
+ throw Err15.configRequired("auth.oauth.google", "GOOGLE_CLIENT_ID");
5790
6608
  if (!clientSecret)
5791
- throw Err13.configRequired("auth.oauth.google", "GOOGLE_CLIENT_SECRET");
6609
+ throw Err15.configRequired("auth.oauth.google", "GOOGLE_CLIENT_SECRET");
5792
6610
  const frontendUrl = config?.frontendUrl ?? process.env.FRONTEND_URL ?? "http://localhost:3000";
5793
6611
  const callbackUrl = google.callbackUrl ?? process.env.GOOGLE_CALLBACK_URL ?? `${frontendUrl.replace(/\/$/, "")}/api/auth/oauth/google/callback`;
5794
6612
  let callback;
@@ -5812,6 +6630,20 @@ var resolveGoogleConfig = /* @__PURE__ */ __name((config) => {
5812
6630
  allowedHostedDomains: [...new Set((google.allowedHostedDomains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean))]
5813
6631
  };
5814
6632
  }, "resolveGoogleConfig");
6633
+ var resolveCredentialSetupConfig = /* @__PURE__ */ __name((config) => {
6634
+ const password = config?.credentialSetup?.password ?? {};
6635
+ const ttlMs = password.ttlMs ?? DEFAULT_CREDENTIAL_SETUP_TTL_MS;
6636
+ if (!Number.isInteger(ttlMs) || ttlMs < 1e3 || ttlMs > 24 * 60 * 60 * 1e3) {
6637
+ throw new Error("auth.credentialSetup.password.ttlMs must be an integer between 1000 and 86400000");
6638
+ }
6639
+ return {
6640
+ password: {
6641
+ ttlMs,
6642
+ cookieName: password.cookieName?.trim() || DEFAULT_CREDENTIAL_SETUP_COOKIE_NAME,
6643
+ passwordSchema: password.passwordSchema ?? defaultCredentialSetupPasswordSchema
6644
+ }
6645
+ };
6646
+ }, "resolveCredentialSetupConfig");
5815
6647
  var resolveAuthConfig = /* @__PURE__ */ __name((config) => {
5816
6648
  const bcryptRounds = config?.bcryptRounds ?? 10;
5817
6649
  if (!Number.isInteger(bcryptRounds) || bcryptRounds < 4 || bcryptRounds > 31) {
@@ -5835,6 +6667,9 @@ var resolveAuthConfig = /* @__PURE__ */ __name((config) => {
5835
6667
  duration: config?.lockout?.duration ?? "15m"
5836
6668
  },
5837
6669
  bcryptRounds,
6670
+ identity: {
6671
+ resolve: createIdentityResolver(config?.identity)
6672
+ },
5838
6673
  session: {
5839
6674
  name: config?.session?.name ?? "najm.session",
5840
6675
  maxAge: config?.session?.maxAge ?? 300,
@@ -5842,15 +6677,16 @@ var resolveAuthConfig = /* @__PURE__ */ __name((config) => {
5842
6677
  // CookieManager falls back to jwt.accessSecret when this is undefined.
5843
6678
  secret: config?.session?.secret ?? process.env.NAJM_SESSION_SECRET
5844
6679
  },
6680
+ credentialSetup: resolveCredentialSetupConfig(config),
5845
6681
  oauth: {
5846
6682
  google: resolveGoogleConfig(config)
5847
6683
  }
5848
6684
  };
5849
6685
  if (!finalConfig.jwt.accessSecret) {
5850
- throw Err13.configRequired("auth", "JWT_ACCESS_SECRET");
6686
+ throw Err15.configRequired("auth", "JWT_ACCESS_SECRET");
5851
6687
  }
5852
6688
  if (!finalConfig.jwt.refreshSecret) {
5853
- throw Err13.configRequired("auth", "JWT_REFRESH_SECRET");
6689
+ throw Err15.configRequired("auth", "JWT_REFRESH_SECRET");
5854
6690
  }
5855
6691
  return finalConfig;
5856
6692
  }, "resolveAuthConfig");
@@ -5859,6 +6695,12 @@ var selectAuthSchema = /* @__PURE__ */ __name((config) => {
5859
6695
  if (config.oauth?.google && !config.schema.oauthAccounts) {
5860
6696
  throw new Error("auth.schema.oauthAccounts is required when Google OAuth is enabled");
5861
6697
  }
6698
+ if (!config.schema.credentialSetupSessions) {
6699
+ throw new Error("auth.schema.credentialSetupSessions is required \u2014 re-export it from najm-auth/pg or najm-auth/sqlite");
6700
+ }
6701
+ if (!config.schema.credentialSetupRequirements) {
6702
+ throw new Error("auth.schema.credentialSetupRequirements is required \u2014 re-export it from najm-auth/pg or najm-auth/sqlite");
6703
+ }
5862
6704
  return config.schema;
5863
6705
  }
5864
6706
  const dialect = config?.dialect ?? "pg";
@@ -6017,6 +6859,7 @@ export {
6017
6859
  AuthResolver,
6018
6860
  AuthService,
6019
6861
  AuthSessionService,
6862
+ CREDENTIAL_SETUP_CODES,
6020
6863
  CREDENTIAL_SETUP_MODULE,
6021
6864
  Can,
6022
6865
  CanCreate,
@@ -6025,11 +6868,22 @@ export {
6025
6868
  CanRead,
6026
6869
  CanUpdate,
6027
6870
  CookieManager,
6871
+ CredentialSetupController,
6028
6872
  CredentialSetupRepository,
6873
+ CredentialSetupRequirementRepository,
6874
+ CredentialSetupRequirementService,
6029
6875
  CredentialSetupService,
6876
+ DEFAULT_CREDENTIAL_SETUP_COOKIE_NAME,
6877
+ DEFAULT_CREDENTIAL_SETUP_TTL_MS,
6878
+ DEFAULT_IDENTITY_PRESET,
6879
+ EXACT_TEMPORARY_CREDENTIAL_KIND,
6030
6880
  EncryptionService,
6881
+ IDENTITY_PRESETS,
6882
+ MOROCCAN_CIN_TEMPORARY_CREDENTIAL_KIND,
6031
6883
  Owned,
6032
6884
  OwnershipToken,
6885
+ PASSWORD_SETUP_PURPOSE,
6886
+ PasswordSetupService,
6033
6887
  PermissionController,
6034
6888
  PermissionGuard,
6035
6889
  PermissionRepository,
@@ -6068,13 +6922,19 @@ export {
6068
6922
  changePasswordDto,
6069
6923
  checkPermissionDto,
6070
6924
  clean,
6925
+ compactPhone,
6071
6926
  configureOwnership,
6072
6927
  confirmResetPasswordDto,
6928
+ createIdentityResolver,
6073
6929
  createPermissionDto,
6074
6930
  createRoleDto,
6075
6931
  createTokenDto,
6076
6932
  createUserDto,
6933
+ credentialSetupChangeDto,
6934
+ credentialSetupError,
6935
+ credentialSetupRequirementsTable,
6077
6936
  credentialSetupSessionsTable,
6937
+ defaultCredentialSetupPasswordSchema,
6078
6938
  defineRoles,
6079
6939
  emailParam,
6080
6940
  formatDate,
@@ -6087,11 +6947,19 @@ export {
6087
6947
  isEmailIdentifier,
6088
6948
  isEmpty,
6089
6949
  isFile,
6950
+ isMoroccanCin,
6090
6951
  isPath,
6952
+ isTemporaryCredentialKind,
6091
6953
  join2 as join,
6092
6954
  languageParam,
6093
6955
  loginDto,
6956
+ moroccanCinTemporaryCredential,
6957
+ moroccoIdentityPreset,
6094
6958
  normalizeAuthIdentifier,
6959
+ normalizeMoroccanCin,
6960
+ normalizeMoroccanPhone,
6961
+ normalizeSetupPurpose,
6962
+ normalizeTunisianPhone,
6095
6963
  oauthAccountsTable,
6096
6964
  own,
6097
6965
  parseSchema,
@@ -6101,16 +6969,19 @@ export {
6101
6969
  refreshTokenDto,
6102
6970
  registerDto,
6103
6971
  resetPasswordDto,
6972
+ resolveTemporaryCredentialKind,
6104
6973
  revokeTokenDto,
6105
6974
  roleIdParam,
6106
6975
  rolePermissionsTable,
6107
6976
  rolesTable,
6108
6977
  runAsUser,
6109
6978
  seedAuthData,
6979
+ toTemporaryCredential,
6110
6980
  tokenIdParam,
6111
6981
  tokenStatusEnum,
6112
6982
  tokenTypeEnum,
6113
6983
  tokensTable,
6984
+ tunisiaIdentityPreset,
6114
6985
  updatePermissionDto,
6115
6986
  updateRoleDto,
6116
6987
  updateTokenDto,