najm-auth 1.1.31 → 1.1.33

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/README.md CHANGED
@@ -198,13 +198,13 @@ class PostController {
198
198
  ```typescript
199
199
  import { defineRoles } from 'najm-auth';
200
200
 
201
- const roles = defineRoles({
202
- ADMIN: 'admin',
203
- MODERATOR: 'moderator',
204
- USER: 'user',
205
- }, {
206
- superRoles: ['ADMIN'], // admin also passes moderator/user role guards
207
- });
201
+ const roles = defineRoles({
202
+ ADMIN: 'admin',
203
+ MODERATOR: 'moderator',
204
+ USER: 'user',
205
+ }, {
206
+ superRoles: ['ADMIN'], // admin also passes moderator/user role guards
207
+ });
208
208
 
209
209
  export const { isAdmin, isModerator, isUser } = roles;
210
210
 
@@ -7,7 +7,19 @@ import { useEffect, useRef } from "react";
7
7
 
8
8
  // src/client/react/context.ts
9
9
  import { createContext, useContext } from "react";
10
- var AuthClientContext = createContext(null);
10
+ var KEY = /* @__PURE__ */ Symbol.for("najm:auth:client:context");
11
+ var contextStore = globalThis;
12
+ function getAuthClientContext() {
13
+ const existing = contextStore[KEY];
14
+ if (existing) {
15
+ return existing;
16
+ }
17
+ const context = createContext(null);
18
+ contextStore[KEY] = context;
19
+ return context;
20
+ }
21
+ __name(getAuthClientContext, "getAuthClientContext");
22
+ var AuthClientContext = getAuthClientContext();
11
23
  function useAuthClient() {
12
24
  const client = useContext(AuthClientContext);
13
25
  if (!client) {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as najm_core from 'najm-core';
2
+ import { Container } from 'najm-core';
2
3
  import { ValidationPluginConfig } from 'najm-validation';
3
4
  import { RateLimitPluginConfig } from 'najm-rate';
4
5
  import { I18nService } from 'najm-i18n';
@@ -109,6 +110,8 @@ type AuthPluginConfig = {
109
110
  validation?: ValidationPluginConfig;
110
111
  /** Optional config forwarded to rateLimit() dependency */
111
112
  rateLimit?: RateLimitPluginConfig;
113
+ /** AES-256-GCM key for reversible encryption (e.g. API keys). Falls back to NAJM_ENCRYPTION_KEY env var. */
114
+ encryptionKey?: string;
112
115
  };
113
116
  /**
114
117
  * JWT payload structure
@@ -339,14 +342,13 @@ declare function getAuthLocale(lang: string): Record<string, any>;
339
342
  */
340
343
  declare const AUTH_SUPPORTED_LANGUAGES: string[];
341
344
 
342
- /**
343
- * EncryptionService - Pure hashing utility
344
- * Validation is handled by UserValidator (single source of truth)
345
- */
346
345
  declare class EncryptionService {
347
- constructor();
346
+ private encryptionKey;
347
+ constructor(encryptionKey?: string | null);
348
348
  hashPassword(password: string): Promise<string>;
349
349
  comparePassword(password: string, hashedPassword: string): Promise<boolean>;
350
+ encrypt(plaintext: string): string;
351
+ decrypt(ciphertext: string): string;
350
352
  }
351
353
 
352
354
  interface SessionCookieData {
@@ -416,8 +418,10 @@ declare class UserRepository {
416
418
  delete(id: string): Promise<User>;
417
419
  deleteAll(): Promise<User[]>;
418
420
  getRoleNameById(userId: string): Promise<string | null>;
421
+ findByPhone(phone: string): Promise<UserWithPermissions | undefined>;
419
422
  getUserPassword(email: string): Promise<string | undefined>;
420
423
  getUserPermissions(userId: string): Promise<string[]>;
424
+ updatePhone(id: string, phone: string): Promise<User>;
421
425
  }
422
426
 
423
427
  /**
@@ -448,6 +452,8 @@ declare class UserValidator {
448
452
  updatedAt: string;
449
453
  email: string;
450
454
  emailVerified: boolean;
455
+ phone: string;
456
+ phoneVerified: boolean;
451
457
  password: string;
452
458
  image: string;
453
459
  status: "active" | "pending" | "inactive";
@@ -468,6 +474,8 @@ declare class UserValidator {
468
474
  updatedAt: string;
469
475
  email: string;
470
476
  emailVerified: boolean;
477
+ phone: string;
478
+ phoneVerified: boolean;
471
479
  password: string;
472
480
  image: string;
473
481
  status: "active" | "pending" | "inactive";
@@ -968,6 +976,8 @@ declare class AuthController {
968
976
  updatedAt: string;
969
977
  email: string;
970
978
  emailVerified: boolean;
979
+ phone: string;
980
+ phoneVerified: boolean;
971
981
  password: string;
972
982
  image: string;
973
983
  status: "active" | "pending" | "inactive";
@@ -1006,6 +1016,10 @@ declare class AuthResolver {
1006
1016
  /**
1007
1017
  * Resolve the current user from the refresh cookie (cookie-only flow,
1008
1018
  * e.g. Next.js Server Components calling /auth/me with just the cookie).
1019
+ *
1020
+ * Read-only: does NOT rotate the refresh token. Rotation is reserved for
1021
+ * the /auth/refresh handler. Mutating here races with /auth/refresh when
1022
+ * requests are concurrent.
1009
1023
  */
1010
1024
  resolveFromCookie(): Promise<{
1011
1025
  user: any;
@@ -1015,6 +1029,13 @@ declare class AuthResolver {
1015
1029
  activate(): Promise<void>;
1016
1030
  }
1017
1031
 
1032
+ interface RunAsUser {
1033
+ id: string;
1034
+ role?: string | null;
1035
+ permissions?: string[];
1036
+ }
1037
+ declare function runAsUser<T>(container: Container, user: RunAsUser, fn: () => Promise<T> | T): Promise<T>;
1038
+
1018
1039
  declare const AUTH_MODULE: readonly [typeof AuthService, typeof CookieManager, typeof EncryptionService, typeof AuthGuard, typeof AuthController, typeof AuthResolver];
1019
1040
 
1020
1041
  declare class PermissionRepository {
@@ -1901,4 +1922,4 @@ declare const authSeed: (config: AuthSeedConfig) => Record<string, SeedEntry>;
1901
1922
  */
1902
1923
  declare function seedAuthData(config: SeedAuthDataConfig): Promise<SeedAuthDataResult>;
1903
1924
 
1904
- export { AUTH_CONFIG, en as AUTH_EN, AUTH_LOCALES, AUTH_MODULE, AUTH_PERMISSIONS, AUTH_ROLE, AUTH_SCHEMA, AUTH_SUPPORTED_LANGUAGES, AUTH_USER, type AssignPermissionDto, type AssignRoleDto, type AssignRoleParams, type AuthConfig, AuthController, AuthGuard, type AuthPluginConfig, AuthQueries, AuthResolver, type AuthSchema, type AuthSeedConfig, AuthService, type AuthUser, Can, CanCreate, CanDelete, CanList, CanRead, CanUpdate, type ChainableGuard, type ChangePasswordDto, type CheckPermissionDto, type ConfiguredOwnership, type ConfirmResetPasswordDto, CookieManager, type CreatePermissionDto, type CreateRoleDto, type CreateTokenDto, type CreateUserDto, type DefineRolesOptions, type EmailParam, EncryptionService, type JwtConfig, type JwtPayload, type LanguageParam, type LoginDto, NewPermission, NewRoleEntity, NewUser, Owned, type OwnedMethods, type OwnershipConfig, type OwnershipProvider, type OwnershipRule, OwnershipToken, type OwnershipTokenOptions, Permission, PermissionController, PermissionGuard, type PermissionIdParam, PermissionRepository, PermissionService, PermissionValidator, Policy, ROLES, ROLE_GROUPS, type RefreshTokenDto, type ResetPasswordDto, type ResourceAccessor, type ResourceGuards, type ResourceGuardsOptions, type RevokeTokenDto, Role, RoleController, RoleEntity, RoleGuard, type RoleIdParam, type RoleInput, RolePermission, RoleRepository, RoleService, type RoleType, RoleValidator, type SanitizedUser, ScopeContext, type ScopeResult, type SeedAuthDataConfig, type SeedAuthDataResult, type SeedUserConfig, type SessionCookieData, TOKEN_STATUS, TOKEN_TYPE, type TokenIdParam, type TokenPair, TokenRepository, TokenService, USER_STATUS, type UpdatePermissionDto, type UpdateRoleDto, type UpdateTokenDto, type UpdateUserDto, User, UserController, type UserIdInParam, type UserIdParam, UserRepository, UserService, UserValidator, type UserWithPermissions, type VerifyTokenDto, assignPermissionDto, assignRoleDto, assignRoleParams, auth$1 as auth, authSeed, avatarsPath, calculateAge, calculateYearsOfExperience, changePasswordDto, checkPermissionDto, clean, configureOwnership, confirmResetPasswordDto, createPermissionDto, createRoleDto, createTokenDto, createUserDto, defineRoles, emailParam, formatDate, getAuthLocale, getAvatarFile, isAdmin, isAdministrator, isAuth, isEmpty, isFile, isPath, join, languageParam, loginDto, own, parseSchema, permissionIdParam, pickProps, refreshTokenDto, resetPasswordDto, revokeTokenDto, roleIdParam, seedAuthData, setConfiguredCookieName, tokenIdParam, updatePermissionDto, updateRoleDto, updateTokenDto, updateUserDto, userIdInParam, userIdParam, verifyTokenDto, where };
1925
+ export { AUTH_CONFIG, en as AUTH_EN, AUTH_LOCALES, AUTH_MODULE, AUTH_PERMISSIONS, AUTH_ROLE, AUTH_SCHEMA, AUTH_SUPPORTED_LANGUAGES, AUTH_USER, type AssignPermissionDto, type AssignRoleDto, type AssignRoleParams, type AuthConfig, AuthController, AuthGuard, type AuthPluginConfig, AuthQueries, AuthResolver, type AuthSchema, type AuthSeedConfig, AuthService, type AuthUser, Can, CanCreate, CanDelete, CanList, CanRead, CanUpdate, type ChainableGuard, type ChangePasswordDto, type CheckPermissionDto, type ConfiguredOwnership, type ConfirmResetPasswordDto, CookieManager, type CreatePermissionDto, type CreateRoleDto, type CreateTokenDto, type CreateUserDto, type DefineRolesOptions, type EmailParam, EncryptionService, type JwtConfig, type JwtPayload, type LanguageParam, type LoginDto, NewPermission, NewRoleEntity, NewUser, Owned, type OwnedMethods, type OwnershipConfig, type OwnershipProvider, type OwnershipRule, OwnershipToken, type OwnershipTokenOptions, Permission, PermissionController, PermissionGuard, type PermissionIdParam, PermissionRepository, PermissionService, PermissionValidator, Policy, ROLES, ROLE_GROUPS, type RefreshTokenDto, type ResetPasswordDto, type ResourceAccessor, type ResourceGuards, type ResourceGuardsOptions, type RevokeTokenDto, Role, RoleController, RoleEntity, RoleGuard, type RoleIdParam, type RoleInput, RolePermission, RoleRepository, RoleService, type RoleType, RoleValidator, type RunAsUser, type SanitizedUser, ScopeContext, type ScopeResult, type SeedAuthDataConfig, type SeedAuthDataResult, type SeedUserConfig, type SessionCookieData, TOKEN_STATUS, TOKEN_TYPE, type TokenIdParam, type TokenPair, TokenRepository, TokenService, USER_STATUS, type UpdatePermissionDto, type UpdateRoleDto, type UpdateTokenDto, type UpdateUserDto, User, UserController, type UserIdInParam, type UserIdParam, UserRepository, UserService, UserValidator, type UserWithPermissions, type VerifyTokenDto, assignPermissionDto, assignRoleDto, assignRoleParams, auth$1 as auth, authSeed, avatarsPath, calculateAge, calculateYearsOfExperience, changePasswordDto, checkPermissionDto, clean, configureOwnership, confirmResetPasswordDto, createPermissionDto, createRoleDto, createTokenDto, createUserDto, defineRoles, emailParam, formatDate, getAuthLocale, getAvatarFile, isAdmin, isAdministrator, isAuth, isEmpty, isFile, isPath, join, languageParam, loginDto, own, parseSchema, permissionIdParam, pickProps, refreshTokenDto, resetPasswordDto, revokeTokenDto, roleIdParam, runAsUser, seedAuthData, setConfiguredCookieName, tokenIdParam, updatePermissionDto, updateRoleDto, updateTokenDto, updateUserDto, userIdInParam, userIdParam, verifyTokenDto, where };
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ var AUTH_SCHEMA = /* @__PURE__ */ Symbol.for("najm:auth:schema");
15
15
  var AUTH_USER = /* @__PURE__ */ Symbol.for("najm:auth:user");
16
16
  var AUTH_ROLE = /* @__PURE__ */ Symbol.for("najm:auth:role");
17
17
  var AUTH_PERMISSIONS = /* @__PURE__ */ Symbol.for("najm:auth:permissions");
18
+ var AUTH_ENCRYPTION_KEY = /* @__PURE__ */ Symbol.for("najm:auth:encryption-key");
18
19
 
19
20
  // src/schema/pg.ts
20
21
  import { pgTable, text, boolean, timestamp, pgEnum, primaryKey, integer, index } from "drizzle-orm/pg-core";
@@ -45,6 +46,8 @@ var usersTable = pgTable("users", {
45
46
  name: text("name"),
46
47
  email: text("email").notNull().unique(),
47
48
  emailVerified: boolean("email_verified").default(false),
49
+ phone: text("phone").unique(),
50
+ phoneVerified: boolean("phone_verified").default(false),
48
51
  password: text("password").notNull(),
49
52
  image: text("image").default("noavatar.png"),
50
53
  status: userStatusEnum("status").default("pending"),
@@ -110,6 +113,8 @@ var usersTable2 = sqliteTable("users", {
110
113
  name: text2("name"),
111
114
  email: text2("email").notNull().unique(),
112
115
  emailVerified: integer2("email_verified", { mode: "boolean" }).default(false),
116
+ phone: text2("phone").unique(),
117
+ phoneVerified: integer2("phone_verified", { mode: "boolean" }).default(false),
113
118
  password: text2("password").notNull(),
114
119
  image: text2("image").default("noavatar.png"),
115
120
  status: text2("status").$type().default("pending"),
@@ -175,6 +180,8 @@ var usersTable3 = mysqlTable("users", {
175
180
  name: varchar("name", { length: 255 }),
176
181
  email: varchar("email", { length: 255 }).notNull().unique(),
177
182
  emailVerified: boolean2("email_verified").default(false),
183
+ phone: varchar("phone", { length: 255 }).unique(),
184
+ phoneVerified: boolean2("phone_verified").default(false),
178
185
  password: varchar("password", { length: 255 }).notNull(),
179
186
  image: varchar("image", { length: 255 }).default("noavatar.png"),
180
187
  status: mysqlEnum("status", [...USER_STATUS]).default("pending"),
@@ -227,13 +234,13 @@ import { Get, Post, ResMsg } from "najm-core";
227
234
  import { Body, User as User2, Headers } from "najm-core";
228
235
 
229
236
  // src/auth/AuthService.ts
230
- import { Injectable as Injectable7, Inject as Inject7 } from "najm-core";
237
+ import { Injectable as Injectable7, Inject as Inject8 } from "najm-core";
231
238
  import { Err as Err6, Log } from "najm-core";
232
239
  import { I18n as I18n4, I18nService as I18nService2 } from "najm-i18n";
233
240
  import { EmailService, passwordResetTemplate } from "najm-email";
234
241
 
235
242
  // src/users/UserService.ts
236
- import { Injectable as Injectable5, Inject as Inject3 } from "najm-core";
243
+ import { Injectable as Injectable5, Inject as Inject4 } from "najm-core";
237
244
  import { Transaction } from "najm-database";
238
245
  import { I18nService } from "najm-i18n";
239
246
 
@@ -432,6 +439,15 @@ var UserRepository = class UserRepository2 {
432
439
  async getRoleNameById(userId) {
433
440
  return this.q.getRoleName(userId);
434
441
  }
442
+ async findByPhone(phone) {
443
+ const [user] = await this.db.select(this.q.userSelection()).from(this.users).leftJoin(this.roles, eq2(this.users.roleId, this.roles.id)).where(eq2(this.users.phone, phone)).limit(1);
444
+ if (!user)
445
+ return void 0;
446
+ return {
447
+ ...user,
448
+ permissions: await this.q.getUserPermissions(user.id)
449
+ };
450
+ }
435
451
  async getUserPassword(email2) {
436
452
  const [user] = await this.db.select({
437
453
  id: this.users.id,
@@ -443,6 +459,10 @@ var UserRepository = class UserRepository2 {
443
459
  async getUserPermissions(userId) {
444
460
  return this.q.getUserPermissions(userId);
445
461
  }
462
+ async updatePhone(id, phone) {
463
+ const [updatedUser] = await this.db.update(this.users).set({ phone, phoneVerified: true }).where(eq2(this.users.id, id)).returning();
464
+ return updatedUser;
465
+ }
446
466
  };
447
467
  __decorate([
448
468
  DB(),
@@ -462,8 +482,9 @@ import { Err } from "najm-core";
462
482
  import { I18n } from "najm-i18n";
463
483
 
464
484
  // src/auth/EncryptionService.ts
465
- import { Injectable } from "najm-core";
485
+ import { Inject as Inject2, Injectable } from "najm-core";
466
486
  import bcrypt from "bcryptjs";
487
+ import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
467
488
  var __decorate2 = function(decorators, target, key, desc) {
468
489
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
469
490
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -473,11 +494,38 @@ var __decorate2 = function(decorators, target, key, desc) {
473
494
  var __metadata2 = function(k, v) {
474
495
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
475
496
  };
497
+ var __param = function(paramIndex, decorator) {
498
+ return function(target, key) {
499
+ decorator(target, key, paramIndex);
500
+ };
501
+ };
502
+ var REQUIRED_KEY_BYTES = 32;
503
+ function decodeKey(raw) {
504
+ if (/^[0-9a-fA-F]{64}$/.test(raw)) {
505
+ return Buffer.from(raw, "hex");
506
+ }
507
+ if (/^[A-Za-z0-9+/]+=*$/.test(raw) || /^[A-Za-z0-9_-]+=*$/.test(raw)) {
508
+ const decoded = Buffer.from(raw, raw.includes("-") || raw.includes("_") ? "base64url" : "base64");
509
+ if (decoded.length === REQUIRED_KEY_BYTES)
510
+ return decoded;
511
+ }
512
+ if (Buffer.byteLength(raw, "utf8") === REQUIRED_KEY_BYTES) {
513
+ return Buffer.from(raw, "utf8");
514
+ }
515
+ throw new Error(`Encryption key must decode to ${REQUIRED_KEY_BYTES} bytes. Provide hex (64 chars) or base64 (32 bytes decoded).`);
516
+ }
517
+ __name(decodeKey, "decodeKey");
476
518
  var EncryptionService = class EncryptionService2 {
477
519
  static {
478
520
  __name(this, "EncryptionService");
479
521
  }
480
- constructor() {
522
+ encryptionKey;
523
+ constructor(encryptionKey) {
524
+ const raw = encryptionKey ?? process.env.NAJM_ENCRYPTION_KEY ?? "";
525
+ if (!raw) {
526
+ throw new Error("Encryption key missing. Set NAJM_ENCRYPTION_KEY (base64 or hex, 32 bytes) or pass auth({ encryptionKey })");
527
+ }
528
+ this.encryptionKey = decodeKey(raw);
481
529
  }
482
530
  async hashPassword(password) {
483
531
  return bcrypt.hash(password, 10);
@@ -485,10 +533,27 @@ var EncryptionService = class EncryptionService2 {
485
533
  async comparePassword(password, hashedPassword) {
486
534
  return bcrypt.compare(password, hashedPassword);
487
535
  }
536
+ encrypt(plaintext) {
537
+ const iv = randomBytes(12);
538
+ const cipher = createCipheriv("aes-256-gcm", this.encryptionKey, iv);
539
+ const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
540
+ const tag = cipher.getAuthTag();
541
+ return Buffer.concat([iv, tag, encrypted]).toString("base64url");
542
+ }
543
+ decrypt(ciphertext) {
544
+ const raw = Buffer.from(ciphertext, "base64url");
545
+ const iv = raw.subarray(0, 12);
546
+ const tag = raw.subarray(12, 28);
547
+ const encrypted = raw.subarray(28);
548
+ const decipher = createDecipheriv("aes-256-gcm", this.encryptionKey, iv);
549
+ decipher.setAuthTag(tag);
550
+ return decipher.update(encrypted) + decipher.final("utf8");
551
+ }
488
552
  };
489
553
  EncryptionService = __decorate2([
490
554
  Injectable(),
491
- __metadata2("design:paramtypes", [])
555
+ __param(0, Inject2(AUTH_ENCRYPTION_KEY)),
556
+ __metadata2("design:paramtypes", [String])
492
557
  ], EncryptionService);
493
558
 
494
559
  // src/users/UserValidator.ts
@@ -640,7 +705,7 @@ import { Injectable as Injectable4 } from "najm-core";
640
705
 
641
706
  // src/roles/RoleRepository.ts
642
707
  import { eq as eq3 } from "drizzle-orm";
643
- import { Repository as Repository2, Inject as Inject2 } from "najm-core";
708
+ import { Repository as Repository2, Inject as Inject3 } from "najm-core";
644
709
  import { DB as DB2 } from "najm-database";
645
710
  var __decorate4 = function(decorators, target, key, desc) {
646
711
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -689,7 +754,7 @@ __decorate4([
689
754
  __metadata4("design:type", Object)
690
755
  ], RoleRepository.prototype, "db", void 0);
691
756
  __decorate4([
692
- Inject2(AUTH_SCHEMA),
757
+ Inject3(AUTH_SCHEMA),
693
758
  __metadata4("design:type", Object)
694
759
  ], RoleRepository.prototype, "schema", void 0);
695
760
  RoleRepository = __decorate4([
@@ -954,7 +1019,7 @@ var __decorate7 = function(decorators, target, key, desc) {
954
1019
  var __metadata7 = function(k, v) {
955
1020
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
956
1021
  };
957
- var __param = function(paramIndex, decorator) {
1022
+ var __param2 = function(paramIndex, decorator) {
958
1023
  return function(target, key) {
959
1024
  decorator(target, key, paramIndex);
960
1025
  };
@@ -1165,12 +1230,12 @@ __decorate7([
1165
1230
  ], UserService.prototype, "create", null);
1166
1231
  UserService = __decorate7([
1167
1232
  Injectable5(),
1168
- __param(6, Inject3(AUTH_CONFIG)),
1233
+ __param2(6, Inject4(AUTH_CONFIG)),
1169
1234
  __metadata7("design:paramtypes", [typeof (_a4 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _a4 : Object, typeof (_b3 = typeof RoleService !== "undefined" && RoleService) === "function" ? _b3 : Object, typeof (_c = typeof UserRepository !== "undefined" && UserRepository) === "function" ? _c : Object, typeof (_d = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _d : Object, typeof (_e = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _e : Object, typeof (_f = typeof I18nService !== "undefined" && I18nService) === "function" ? _f : Object, Object])
1170
1235
  ], UserService);
1171
1236
 
1172
1237
  // src/auth/CookieManager.ts
1173
- import { Service, Inject as Inject4 } from "najm-core";
1238
+ import { Service, Inject as Inject5 } from "najm-core";
1174
1239
  import { CookieService } from "najm-cookies";
1175
1240
  import timestring from "timestring";
1176
1241
  var __decorate8 = function(decorators, target, key, desc) {
@@ -1263,11 +1328,11 @@ var CookieManager = class CookieManager2 {
1263
1328
  }
1264
1329
  };
1265
1330
  __decorate8([
1266
- Inject4(AUTH_CONFIG),
1331
+ Inject5(AUTH_CONFIG),
1267
1332
  __metadata8("design:type", Object)
1268
1333
  ], CookieManager.prototype, "config", void 0);
1269
1334
  __decorate8([
1270
- Inject4(CookieService),
1335
+ Inject5(CookieService),
1271
1336
  __metadata8("design:type", typeof (_a5 = typeof CookieService !== "undefined" && CookieService) === "function" ? _a5 : Object)
1272
1337
  ], CookieManager.prototype, "cookieService", void 0);
1273
1338
  CookieManager = __decorate8([
@@ -1275,7 +1340,7 @@ CookieManager = __decorate8([
1275
1340
  ], CookieManager);
1276
1341
 
1277
1342
  // src/tokens/TokenService.ts
1278
- import { Injectable as Injectable6, Inject as Inject6 } from "najm-core";
1343
+ import { Injectable as Injectable6, Inject as Inject7 } from "najm-core";
1279
1344
  import { I18n as I18n3 } from "najm-i18n";
1280
1345
  import { CacheService } from "najm-cache";
1281
1346
  import { createHash } from "crypto";
@@ -1284,7 +1349,7 @@ import { nanoid as nanoid5 } from "nanoid";
1284
1349
 
1285
1350
  // src/tokens/TokenRepository.ts
1286
1351
  import { eq as eq4 } from "drizzle-orm";
1287
- import { Repository as Repository3, Inject as Inject5 } from "najm-core";
1352
+ import { Repository as Repository3, Inject as Inject6 } from "najm-core";
1288
1353
  import { DB as DB3 } from "najm-database";
1289
1354
  var __decorate9 = function(decorators, target, key, desc) {
1290
1355
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -1369,7 +1434,7 @@ __decorate9([
1369
1434
  __metadata9("design:type", Object)
1370
1435
  ], TokenRepository.prototype, "db", void 0);
1371
1436
  __decorate9([
1372
- Inject5(AUTH_SCHEMA),
1437
+ Inject6(AUTH_SCHEMA),
1373
1438
  __metadata9("design:type", Object)
1374
1439
  ], TokenRepository.prototype, "schema", void 0);
1375
1440
  TokenRepository = __decorate9([
@@ -1730,7 +1795,7 @@ var TokenService = class TokenService2 {
1730
1795
  }
1731
1796
  };
1732
1797
  __decorate10([
1733
- Inject6(AUTH_CONFIG),
1798
+ Inject7(AUTH_CONFIG),
1734
1799
  __metadata10("design:type", Object)
1735
1800
  ], TokenService.prototype, "config", void 0);
1736
1801
  __decorate10([
@@ -1968,7 +2033,7 @@ var AuthService = class AuthService2 {
1968
2033
  }
1969
2034
  };
1970
2035
  __decorate11([
1971
- Inject7(AUTH_CONFIG),
2036
+ Inject8(AUTH_CONFIG),
1972
2037
  __metadata11("design:type", Object)
1973
2038
  ], AuthService.prototype, "config", void 0);
1974
2039
  __decorate11([
@@ -1996,7 +2061,7 @@ var __decorate12 = function(decorators, target, key, desc) {
1996
2061
  var __metadata12 = function(k, v) {
1997
2062
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1998
2063
  };
1999
- var __param2 = function(paramIndex, decorator) {
2064
+ var __param3 = function(paramIndex, decorator) {
2000
2065
  return function(target, key) {
2001
2066
  decorator(target, key, paramIndex);
2002
2067
  };
@@ -2010,7 +2075,7 @@ var AuthGuard = class AuthGuard2 {
2010
2075
  }
2011
2076
  };
2012
2077
  __decorate12([
2013
- __param2(0, User()),
2078
+ __param3(0, User()),
2014
2079
  __metadata12("design:type", Function),
2015
2080
  __metadata12("design:paramtypes", [Object]),
2016
2081
  __metadata12("design:returntype", Boolean)
@@ -2081,7 +2146,7 @@ var __decorate13 = function(decorators, target, key, desc) {
2081
2146
  var __metadata13 = function(k, v) {
2082
2147
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2083
2148
  };
2084
- var __param3 = function(paramIndex, decorator) {
2149
+ var __param4 = function(paramIndex, decorator) {
2085
2150
  return function(target, key) {
2086
2151
  decorator(target, key, paramIndex);
2087
2152
  };
@@ -2148,7 +2213,7 @@ __decorate13([
2148
2213
  RateLimit({ limit: 5, window: "15m", key: ipAndEmail }),
2149
2214
  Validate(createUserDto),
2150
2215
  ResMsg("auth.success.register"),
2151
- __param3(0, Body()),
2216
+ __param4(0, Body()),
2152
2217
  __metadata13("design:type", Function),
2153
2218
  __metadata13("design:paramtypes", [Object]),
2154
2219
  __metadata13("design:returntype", Promise)
@@ -2158,7 +2223,7 @@ __decorate13([
2158
2223
  RateLimit({ limit: 5, window: "15m", key: ipAndEmail, message: "Too many login attempts. Please try again later." }),
2159
2224
  Validate(loginDto),
2160
2225
  ResMsg("auth.success.login"),
2161
- __param3(0, Body()),
2226
+ __param4(0, Body()),
2162
2227
  __metadata13("design:type", Function),
2163
2228
  __metadata13("design:paramtypes", [Object]),
2164
2229
  __metadata13("design:returntype", Promise)
@@ -2175,8 +2240,8 @@ __decorate13([
2175
2240
  Post("/logout"),
2176
2241
  isAuth(),
2177
2242
  RateLimit({ limit: 10, window: "15m", key: "user" }),
2178
- __param3(0, User2("id")),
2179
- __param3(1, Headers("authorization")),
2243
+ __param4(0, User2("id")),
2244
+ __param4(1, Headers("authorization")),
2180
2245
  __metadata13("design:type", Function),
2181
2246
  __metadata13("design:paramtypes", [String, String]),
2182
2247
  __metadata13("design:returntype", Promise)
@@ -2186,8 +2251,8 @@ __decorate13([
2186
2251
  isAuth(),
2187
2252
  Validate(changePasswordDto),
2188
2253
  ResMsg("auth.success.passwordChanged"),
2189
- __param3(0, User2("id")),
2190
- __param3(1, Body()),
2254
+ __param4(0, User2("id")),
2255
+ __param4(1, Body()),
2191
2256
  __metadata13("design:type", Function),
2192
2257
  __metadata13("design:paramtypes", [String, Object]),
2193
2258
  __metadata13("design:returntype", Promise)
@@ -2196,7 +2261,7 @@ __decorate13([
2196
2261
  Get("/me"),
2197
2262
  RateLimit({ limit: 30, window: "1m", key: cookieFingerprint() }),
2198
2263
  ResMsg("auth.users.success.retrieved"),
2199
- __param3(0, Headers("authorization")),
2264
+ __param4(0, Headers("authorization")),
2200
2265
  __metadata13("design:type", Function),
2201
2266
  __metadata13("design:paramtypes", [String]),
2202
2267
  __metadata13("design:returntype", Promise)
@@ -2206,7 +2271,7 @@ __decorate13([
2206
2271
  RateLimit({ limit: 3, window: "15m", key: ipAndEmail, message: "Too many password reset requests. Please try again later." }),
2207
2272
  Validate(resetPasswordDto),
2208
2273
  ResMsg("auth.success.passwordResetSent"),
2209
- __param3(0, Body()),
2274
+ __param4(0, Body()),
2210
2275
  __metadata13("design:type", Function),
2211
2276
  __metadata13("design:paramtypes", [Object]),
2212
2277
  __metadata13("design:returntype", Promise)
@@ -2216,7 +2281,7 @@ __decorate13([
2216
2281
  RateLimit({ limit: 5, window: "15m", key: "ip", message: "Too many password reset attempts. Please try again later." }),
2217
2282
  Validate(confirmResetPasswordDto),
2218
2283
  ResMsg("auth.success.passwordReset"),
2219
- __param3(0, Body()),
2284
+ __param4(0, Body()),
2220
2285
  __metadata13("design:type", Function),
2221
2286
  __metadata13("design:paramtypes", [Object]),
2222
2287
  __metadata13("design:returntype", Promise)
@@ -2237,11 +2302,12 @@ __export(auth_exports, {
2237
2302
  CookieManager: () => CookieManager,
2238
2303
  EncryptionService: () => EncryptionService,
2239
2304
  isAuth: () => isAuth,
2305
+ runAsUser: () => runAsUser,
2240
2306
  setConfiguredCookieName: () => setConfiguredCookieName
2241
2307
  });
2242
2308
 
2243
2309
  // src/auth/AuthResolver.ts
2244
- import { APP, Container, DI, Inject as Inject8, LOGGER, Meta, Service as Service3 } from "najm-core";
2310
+ import { APP, Container, DI, Inject as Inject9, LOGGER, Meta, Service as Service3 } from "najm-core";
2245
2311
  import { USER, ROLE, PERMISSIONS } from "najm-guard";
2246
2312
  var __decorate14 = function(decorators, target, key, desc) {
2247
2313
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2282,22 +2348,19 @@ var AuthResolver = class AuthResolver2 {
2282
2348
  /**
2283
2349
  * Resolve the current user from the refresh cookie (cookie-only flow,
2284
2350
  * e.g. Next.js Server Components calling /auth/me with just the cookie).
2351
+ *
2352
+ * Read-only: does NOT rotate the refresh token. Rotation is reserved for
2353
+ * the /auth/refresh handler. Mutating here races with /auth/refresh when
2354
+ * requests are concurrent.
2285
2355
  */
2286
2356
  async resolveFromCookie() {
2287
2357
  try {
2288
- const cookieManager = await this.container.resolve(CookieManager);
2289
- const refreshToken = cookieManager.getRefreshToken();
2290
- if (!refreshToken)
2291
- return false;
2292
2358
  const tokenService = await this.container.resolve(TokenService);
2293
- const result = await tokenService.validateRefreshSession(refreshToken);
2294
- if (!result.userId)
2359
+ const userId = await tokenService.resolveUserFromCookie();
2360
+ if (!userId)
2295
2361
  return false;
2296
- if (result.rotatedTokens) {
2297
- cookieManager.setRefreshToken(result.rotatedTokens.refreshToken);
2298
- }
2299
2362
  const userService = await this.container.resolve(UserService);
2300
- const user = await userService.getById(result.userId);
2363
+ const user = await userService.getById(userId);
2301
2364
  if (!user)
2302
2365
  return false;
2303
2366
  return {
@@ -2351,11 +2414,11 @@ __decorate14([
2351
2414
  __metadata14("design:type", typeof (_a9 = typeof Container !== "undefined" && Container) === "function" ? _a9 : Object)
2352
2415
  ], AuthResolver.prototype, "container", void 0);
2353
2416
  __decorate14([
2354
- Inject8(APP),
2417
+ Inject9(APP),
2355
2418
  __metadata14("design:type", Object)
2356
2419
  ], AuthResolver.prototype, "app", void 0);
2357
2420
  __decorate14([
2358
- Inject8(LOGGER),
2421
+ Inject9(LOGGER),
2359
2422
  __metadata14("design:type", Object)
2360
2423
  ], AuthResolver.prototype, "log", void 0);
2361
2424
  AuthResolver = __decorate14([
@@ -2363,6 +2426,29 @@ AuthResolver = __decorate14([
2363
2426
  Meta({ layer: "plugin", order: 30 })
2364
2427
  ], AuthResolver);
2365
2428
 
2429
+ // src/auth/runAsUser.ts
2430
+ import { randomUUID } from "crypto";
2431
+ function runAsUser(container, user, fn) {
2432
+ const requestId = `runAs:${randomUUID()}`;
2433
+ const role = user.role ?? "user";
2434
+ const store = {
2435
+ requestId,
2436
+ user,
2437
+ role
2438
+ };
2439
+ if (user.permissions !== void 0) {
2440
+ store.permissions = user.permissions;
2441
+ }
2442
+ return container.run(store, async () => {
2443
+ try {
2444
+ return await fn();
2445
+ } finally {
2446
+ await container.cleanupReq(requestId);
2447
+ }
2448
+ });
2449
+ }
2450
+ __name(runAsUser, "runAsUser");
2451
+
2366
2452
  // src/auth/index.ts
2367
2453
  var AUTH_MODULE = [
2368
2454
  AuthService,
@@ -2434,7 +2520,7 @@ var __decorate15 = function(decorators, target, key, desc) {
2434
2520
  var __metadata15 = function(k, v) {
2435
2521
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2436
2522
  };
2437
- var __param4 = function(paramIndex, decorator) {
2523
+ var __param5 = function(paramIndex, decorator) {
2438
2524
  return function(target, key) {
2439
2525
  decorator(target, key, paramIndex);
2440
2526
  };
@@ -2455,8 +2541,8 @@ var RoleGuard = class RoleGuard2 {
2455
2541
  }
2456
2542
  };
2457
2543
  __decorate15([
2458
- __param4(0, GuardParams()),
2459
- __param4(1, User3("role")),
2544
+ __param5(0, GuardParams()),
2545
+ __param5(1, User3("role")),
2460
2546
  __metadata15("design:type", Function),
2461
2547
  __metadata15("design:paramtypes", [Object, String]),
2462
2548
  __metadata15("design:returntype", void 0)
@@ -2536,7 +2622,7 @@ var __decorate16 = function(decorators, target, key, desc) {
2536
2622
  var __metadata16 = function(k, v) {
2537
2623
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2538
2624
  };
2539
- var __param5 = function(paramIndex, decorator) {
2625
+ var __param6 = function(paramIndex, decorator) {
2540
2626
  return function(target, key) {
2541
2627
  decorator(target, key, paramIndex);
2542
2628
  };
@@ -2579,7 +2665,7 @@ __decorate16([
2579
2665
  isAdmin(),
2580
2666
  Validate2({ params: roleIdParam }),
2581
2667
  ResMsg2("roles.success.retrieved"),
2582
- __param5(0, Params()),
2668
+ __param6(0, Params()),
2583
2669
  __metadata16("design:type", Function),
2584
2670
  __metadata16("design:paramtypes", [Object]),
2585
2671
  __metadata16("design:returntype", Promise)
@@ -2589,7 +2675,7 @@ __decorate16([
2589
2675
  isAdmin(),
2590
2676
  Validate2(createRoleDto),
2591
2677
  ResMsg2("roles.success.created"),
2592
- __param5(0, Body2()),
2678
+ __param6(0, Body2()),
2593
2679
  __metadata16("design:type", Function),
2594
2680
  __metadata16("design:paramtypes", [Object]),
2595
2681
  __metadata16("design:returntype", Promise)
@@ -2602,8 +2688,8 @@ __decorate16([
2602
2688
  body: updateRoleDto
2603
2689
  }),
2604
2690
  ResMsg2("roles.success.updated"),
2605
- __param5(0, Params()),
2606
- __param5(1, Body2()),
2691
+ __param6(0, Params()),
2692
+ __param6(1, Body2()),
2607
2693
  __metadata16("design:type", Function),
2608
2694
  __metadata16("design:paramtypes", [Object, Object]),
2609
2695
  __metadata16("design:returntype", Promise)
@@ -2613,7 +2699,7 @@ __decorate16([
2613
2699
  isAdmin(),
2614
2700
  Validate2({ params: roleIdParam }),
2615
2701
  ResMsg2("roles.success.deleted"),
2616
- __param5(0, Params()),
2702
+ __param6(0, Params()),
2617
2703
  __metadata16("design:type", Function),
2618
2704
  __metadata16("design:paramtypes", [Object]),
2619
2705
  __metadata16("design:returntype", Promise)
@@ -2634,7 +2720,7 @@ var __decorate17 = function(decorators, target, key, desc) {
2634
2720
  var __metadata17 = function(k, v) {
2635
2721
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2636
2722
  };
2637
- var __param6 = function(paramIndex, decorator) {
2723
+ var __param7 = function(paramIndex, decorator) {
2638
2724
  return function(target, key) {
2639
2725
  decorator(target, key, paramIndex);
2640
2726
  };
@@ -2707,7 +2793,7 @@ __decorate17([
2707
2793
  isAuth(),
2708
2794
  Validate3({ params: languageParam }),
2709
2795
  ResMsg3("users.success.updated"),
2710
- __param6(0, Params2()),
2796
+ __param7(0, Params2()),
2711
2797
  __metadata17("design:type", Function),
2712
2798
  __metadata17("design:paramtypes", [Object]),
2713
2799
  __metadata17("design:returntype", Promise)
@@ -2717,7 +2803,7 @@ __decorate17([
2717
2803
  isAdmin(),
2718
2804
  Validate3({ params: userIdParam }),
2719
2805
  ResMsg3("users.success.retrieved"),
2720
- __param6(0, Params2()),
2806
+ __param7(0, Params2()),
2721
2807
  __metadata17("design:type", Function),
2722
2808
  __metadata17("design:paramtypes", [Object]),
2723
2809
  __metadata17("design:returntype", Promise)
@@ -2727,7 +2813,7 @@ __decorate17([
2727
2813
  isAdmin(),
2728
2814
  Validate3({ params: emailParam }),
2729
2815
  ResMsg3("users.success.retrieved"),
2730
- __param6(0, Params2()),
2816
+ __param7(0, Params2()),
2731
2817
  __metadata17("design:type", Function),
2732
2818
  __metadata17("design:paramtypes", [Object]),
2733
2819
  __metadata17("design:returntype", Promise)
@@ -2737,7 +2823,7 @@ __decorate17([
2737
2823
  isAdmin(),
2738
2824
  Validate3({ params: userIdInParam }),
2739
2825
  ResMsg3("users.success.retrieved"),
2740
- __param6(0, Params2()),
2826
+ __param7(0, Params2()),
2741
2827
  __metadata17("design:type", Function),
2742
2828
  __metadata17("design:paramtypes", [Object]),
2743
2829
  __metadata17("design:returntype", Promise)
@@ -2747,7 +2833,7 @@ __decorate17([
2747
2833
  isAdmin(),
2748
2834
  Validate3(createUserDto),
2749
2835
  ResMsg3("users.success.created"),
2750
- __param6(0, Body3()),
2836
+ __param7(0, Body3()),
2751
2837
  __metadata17("design:type", Function),
2752
2838
  __metadata17("design:paramtypes", [Object]),
2753
2839
  __metadata17("design:returntype", Promise)
@@ -2760,8 +2846,8 @@ __decorate17([
2760
2846
  body: updateUserDto
2761
2847
  }),
2762
2848
  ResMsg3("users.success.updated"),
2763
- __param6(0, Params2()),
2764
- __param6(1, Body3()),
2849
+ __param7(0, Params2()),
2850
+ __param7(1, Body3()),
2765
2851
  __metadata17("design:type", Function),
2766
2852
  __metadata17("design:paramtypes", [Object, Object]),
2767
2853
  __metadata17("design:returntype", Promise)
@@ -2771,7 +2857,7 @@ __decorate17([
2771
2857
  isAdmin(),
2772
2858
  Validate3({ params: userIdParam }),
2773
2859
  ResMsg3("users.success.deleted"),
2774
- __param6(0, Params2()),
2860
+ __param7(0, Params2()),
2775
2861
  __metadata17("design:type", Function),
2776
2862
  __metadata17("design:paramtypes", [Object]),
2777
2863
  __metadata17("design:returntype", Promise)
@@ -2789,7 +2875,7 @@ __decorate17([
2789
2875
  isAdmin(),
2790
2876
  Validate3({ params: assignRoleParams }),
2791
2877
  ResMsg3("users.success.updated"),
2792
- __param6(0, Params2()),
2878
+ __param7(0, Params2()),
2793
2879
  __metadata17("design:type", Function),
2794
2880
  __metadata17("design:paramtypes", [Object]),
2795
2881
  __metadata17("design:returntype", Promise)
@@ -2799,7 +2885,7 @@ __decorate17([
2799
2885
  isAdmin(),
2800
2886
  Validate3({ params: userIdInParam }),
2801
2887
  ResMsg3("users.success.updated"),
2802
- __param6(0, Params2()),
2888
+ __param7(0, Params2()),
2803
2889
  __metadata17("design:type", Function),
2804
2890
  __metadata17("design:paramtypes", [Object]),
2805
2891
  __metadata17("design:returntype", Promise)
@@ -2827,7 +2913,7 @@ __export(permissions_exports, {
2827
2913
 
2828
2914
  // src/permissions/PermissionRepository.ts
2829
2915
  import { eq as eq5, and } from "drizzle-orm";
2830
- import { Repository as Repository4, Inject as Inject9 } from "najm-core";
2916
+ import { Repository as Repository4, Inject as Inject10 } from "najm-core";
2831
2917
  import { DB as DB4 } from "najm-database";
2832
2918
  var __decorate18 = function(decorators, target, key, desc) {
2833
2919
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2918,7 +3004,7 @@ __decorate18([
2918
3004
  __metadata18("design:type", Object)
2919
3005
  ], PermissionRepository.prototype, "db", void 0);
2920
3006
  __decorate18([
2921
- Inject9(AUTH_SCHEMA),
3007
+ Inject10(AUTH_SCHEMA),
2922
3008
  __metadata18("design:type", Object)
2923
3009
  ], PermissionRepository.prototype, "schema", void 0);
2924
3010
  PermissionRepository = __decorate18([
@@ -2938,7 +3024,7 @@ var __decorate19 = function(decorators, target, key, desc) {
2938
3024
  var __metadata19 = function(k, v) {
2939
3025
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2940
3026
  };
2941
- var __param7 = function(paramIndex, decorator) {
3027
+ var __param8 = function(paramIndex, decorator) {
2942
3028
  return function(target, key) {
2943
3029
  decorator(target, key, paramIndex);
2944
3030
  };
@@ -2972,8 +3058,8 @@ var PermissionGuard = class PermissionGuard2 {
2972
3058
  }
2973
3059
  };
2974
3060
  __decorate19([
2975
- __param7(0, GuardParams2()),
2976
- __param7(1, User4("permissions")),
3061
+ __param8(0, GuardParams2()),
3062
+ __param8(1, User4("permissions")),
2977
3063
  __metadata19("design:type", Function),
2978
3064
  __metadata19("design:paramtypes", [String, Array]),
2979
3065
  __metadata19("design:returntype", Object)
@@ -3243,7 +3329,7 @@ var __decorate22 = function(decorators, target, key, desc) {
3243
3329
  var __metadata22 = function(k, v) {
3244
3330
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3245
3331
  };
3246
- var __param8 = function(paramIndex, decorator) {
3332
+ var __param9 = function(paramIndex, decorator) {
3247
3333
  return function(target, key) {
3248
3334
  decorator(target, key, paramIndex);
3249
3335
  };
@@ -3305,7 +3391,7 @@ __decorate22([
3305
3391
  Get4("/:id"),
3306
3392
  Validate4({ params: permissionIdParam }),
3307
3393
  ResMsg4("permissions.success.retrieved"),
3308
- __param8(0, Params3()),
3394
+ __param9(0, Params3()),
3309
3395
  __metadata22("design:type", Function),
3310
3396
  __metadata22("design:paramtypes", [Object]),
3311
3397
  __metadata22("design:returntype", Promise)
@@ -3314,7 +3400,7 @@ __decorate22([
3314
3400
  Post4(),
3315
3401
  Validate4(createPermissionDto),
3316
3402
  ResMsg4({ message: "Permission created successfully", status: 201 }),
3317
- __param8(0, Body4()),
3403
+ __param9(0, Body4()),
3318
3404
  __metadata22("design:type", Function),
3319
3405
  __metadata22("design:paramtypes", [Object]),
3320
3406
  __metadata22("design:returntype", Promise)
@@ -3326,8 +3412,8 @@ __decorate22([
3326
3412
  body: updatePermissionDto
3327
3413
  }),
3328
3414
  ResMsg4("permissions.success.updated"),
3329
- __param8(0, Params3()),
3330
- __param8(1, Body4()),
3415
+ __param9(0, Params3()),
3416
+ __param9(1, Body4()),
3331
3417
  __metadata22("design:type", Function),
3332
3418
  __metadata22("design:paramtypes", [Object, Object]),
3333
3419
  __metadata22("design:returntype", Promise)
@@ -3336,7 +3422,7 @@ __decorate22([
3336
3422
  Delete3("/:id"),
3337
3423
  Validate4({ params: permissionIdParam }),
3338
3424
  ResMsg4("permissions.success.deleted"),
3339
- __param8(0, Params3()),
3425
+ __param9(0, Params3()),
3340
3426
  __metadata22("design:type", Function),
3341
3427
  __metadata22("design:paramtypes", [Object]),
3342
3428
  __metadata22("design:returntype", Promise)
@@ -3345,7 +3431,7 @@ __decorate22([
3345
3431
  Get4("/role/:id"),
3346
3432
  Validate4({ params: roleIdParam }),
3347
3433
  ResMsg4("permissions.success.retrieved"),
3348
- __param8(0, Params3()),
3434
+ __param9(0, Params3()),
3349
3435
  __metadata22("design:type", Function),
3350
3436
  __metadata22("design:paramtypes", [Object]),
3351
3437
  __metadata22("design:returntype", Promise)
@@ -3354,7 +3440,7 @@ __decorate22([
3354
3440
  Get4("/roles/:id"),
3355
3441
  Validate4({ params: permissionIdParam }),
3356
3442
  ResMsg4("permissions.success.retrieved"),
3357
- __param8(0, Params3()),
3443
+ __param9(0, Params3()),
3358
3444
  __metadata22("design:type", Function),
3359
3445
  __metadata22("design:paramtypes", [Object]),
3360
3446
  __metadata22("design:returntype", Promise)
@@ -3363,7 +3449,7 @@ __decorate22([
3363
3449
  Post4("/assign/:roleId/:permissionId"),
3364
3450
  Validate4({ params: assignPermissionDto }),
3365
3451
  ResMsg4("permissions.success.assigned"),
3366
- __param8(0, Params3()),
3452
+ __param9(0, Params3()),
3367
3453
  __metadata22("design:type", Function),
3368
3454
  __metadata22("design:paramtypes", [Object]),
3369
3455
  __metadata22("design:returntype", Promise)
@@ -3372,7 +3458,7 @@ __decorate22([
3372
3458
  Delete3("/remove/:roleId/:permissionId"),
3373
3459
  Validate4({ params: assignPermissionDto }),
3374
3460
  ResMsg4("permissions.success.removed"),
3375
- __param8(0, Params3()),
3461
+ __param9(0, Params3()),
3376
3462
  __metadata22("design:type", Function),
3377
3463
  __metadata22("design:paramtypes", [Object]),
3378
3464
  __metadata22("design:returntype", Promise)
@@ -3595,7 +3681,7 @@ function own(table, opts) {
3595
3681
  __name(own, "own");
3596
3682
 
3597
3683
  // src/ownership/configureOwnership.ts
3598
- import { Injectable as Injectable11, Inject as Inject10, User as User5, Body as Body5, Params as Params4 } from "najm-core";
3684
+ import { Injectable as Injectable11, Inject as Inject11, User as User5, Body as Body5, Params as Params4 } from "najm-core";
3599
3685
  import { createGuard as createGuard5, composeGuards as composeGuards4 } from "najm-guard";
3600
3686
  var __decorate23 = function(decorators, target, key, desc) {
3601
3687
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -3606,7 +3692,7 @@ var __decorate23 = function(decorators, target, key, desc) {
3606
3692
  var __metadata23 = function(k, v) {
3607
3693
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3608
3694
  };
3609
- var __param9 = function(paramIndex, decorator) {
3695
+ var __param10 = function(paramIndex, decorator) {
3610
3696
  return function(target, key) {
3611
3697
  decorator(target, key, paramIndex);
3612
3698
  };
@@ -3636,12 +3722,12 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
3636
3722
  }
3637
3723
  };
3638
3724
  __decorate23([
3639
- Inject10(ownershipClass),
3725
+ Inject11(ownershipClass),
3640
3726
  __metadata23("design:type", Object)
3641
3727
  ], AccessGuard.prototype, "ownership", void 0);
3642
3728
  __decorate23([
3643
- __param9(0, User5()),
3644
- __param9(1, Params4("id")),
3729
+ __param10(0, User5()),
3730
+ __param10(1, Params4("id")),
3645
3731
  __metadata23("design:type", Function),
3646
3732
  __metadata23("design:paramtypes", [Object, String]),
3647
3733
  __metadata23("design:returntype", typeof (_a16 = typeof Promise !== "undefined" && Promise) === "function" ? _a16 : Object)
@@ -3660,11 +3746,11 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
3660
3746
  }
3661
3747
  };
3662
3748
  __decorate23([
3663
- Inject10(ownershipClass),
3749
+ Inject11(ownershipClass),
3664
3750
  __metadata23("design:type", Object)
3665
3751
  ], ListGuard.prototype, "ownership", void 0);
3666
3752
  __decorate23([
3667
- __param9(0, User5()),
3753
+ __param10(0, User5()),
3668
3754
  __metadata23("design:type", Function),
3669
3755
  __metadata23("design:paramtypes", [Object]),
3670
3756
  __metadata23("design:returntype", typeof (_b8 = typeof Promise !== "undefined" && Promise) === "function" ? _b8 : Object)
@@ -3819,12 +3905,12 @@ function configureOwnership(config) {
3819
3905
  }
3820
3906
  };
3821
3907
  __decorate23([
3822
- Inject10(GeneratedOwnershipService),
3908
+ Inject11(GeneratedOwnershipService),
3823
3909
  __metadata23("design:type", GeneratedOwnershipService)
3824
3910
  ], BodyAccessGuard.prototype, "ownership", void 0);
3825
3911
  __decorate23([
3826
- __param9(0, User5()),
3827
- __param9(1, Body5()),
3912
+ __param10(0, User5()),
3913
+ __param10(1, Body5()),
3828
3914
  __metadata23("design:type", Function),
3829
3915
  __metadata23("design:paramtypes", [Object, Object]),
3830
3916
  __metadata23("design:returntype", typeof (_a16 = typeof Promise !== "undefined" && Promise) === "function" ? _a16 : Object)
@@ -3945,7 +4031,7 @@ __name(Policy, "Policy");
3945
4031
  // src/ownership/OwnedDecorator.ts
3946
4032
  import "reflect-metadata";
3947
4033
  import { sql as sql5, and as and2 } from "drizzle-orm";
3948
- import { Injectable as Injectable12, Inject as Inject11, DI as DI2, Container as Container2, REQUEST_ID } from "najm-core";
4034
+ import { Injectable as Injectable12, Inject as Inject12, DI as DI2, Container as Container2, REQUEST_ID } from "najm-core";
3949
4035
  import { USER as USER2 } from "najm-guard";
3950
4036
  var __decorate24 = function(decorators, target, key, desc) {
3951
4037
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -3999,7 +4085,7 @@ function Owned(token) {
3999
4085
  return function(target) {
4000
4086
  Reflect.defineMetadata(OWNED_META, token, target);
4001
4087
  const proto = target.prototype;
4002
- Inject11(ScopeContext)(proto, "_scopeCtx");
4088
+ Inject12(ScopeContext)(proto, "_scopeCtx");
4003
4089
  function getUser(self) {
4004
4090
  return self._scopeCtx?.getUser() ?? null;
4005
4091
  }
@@ -4224,7 +4310,7 @@ var selectSchema = /* @__PURE__ */ __name((config) => {
4224
4310
  return authSchema;
4225
4311
  }
4226
4312
  }, "selectSchema");
4227
- var auth = /* @__PURE__ */ __name((config) => plugin("auth").version("1.0.0").depends(cache(), cookies(), i18n(), guards(), validation(config?.validation), rateLimit(config?.rateLimit), email()).requires("database").contributes(I18N_CONTRIBUTIONS, AUTH_LOCALES).services(auth_exports, users_exports, roles_exports, permissions_exports, tokens_exports, ScopeContext).config(AUTH_CONFIG, mergeConfig(config)).set(AUTH_SCHEMA, selectSchema(config)).build(), "auth");
4313
+ var auth = /* @__PURE__ */ __name((config) => plugin("auth").version("1.0.0").depends(cache(), cookies(), i18n(), guards(), validation(config?.validation), rateLimit(config?.rateLimit), email()).requires("database").contributes(I18N_CONTRIBUTIONS, AUTH_LOCALES).services(auth_exports, users_exports, roles_exports, permissions_exports, tokens_exports, ScopeContext).config(AUTH_CONFIG, mergeConfig(config)).set(AUTH_SCHEMA, selectSchema(config)).set(AUTH_ENCRYPTION_KEY, config?.encryptionKey ?? null).build(), "auth");
4228
4314
 
4229
4315
  // src/seed.ts
4230
4316
  import { hash } from "bcryptjs";
@@ -4448,6 +4534,7 @@ export {
4448
4534
  roleIdParam,
4449
4535
  rolePermissionsTable,
4450
4536
  rolesTable,
4537
+ runAsUser,
4451
4538
  seedAuthData,
4452
4539
  setConfiguredCookieName,
4453
4540
  tokenIdParam,
@@ -159,6 +159,40 @@ declare const usersTable: drizzle_orm_mysql_core.MySqlTableWithColumns<{
159
159
  identity: undefined;
160
160
  generated: undefined;
161
161
  }, {}, {}>;
162
+ phone: drizzle_orm_mysql_core.MySqlColumn<{
163
+ name: "phone";
164
+ tableName: "users";
165
+ dataType: "string";
166
+ columnType: "MySqlVarChar";
167
+ data: string;
168
+ driverParam: string | number;
169
+ notNull: false;
170
+ hasDefault: false;
171
+ isPrimaryKey: false;
172
+ isAutoincrement: false;
173
+ hasRuntimeDefault: false;
174
+ enumValues: [string, ...string[]];
175
+ baseColumn: never;
176
+ identity: undefined;
177
+ generated: undefined;
178
+ }, {}, {}>;
179
+ phoneVerified: drizzle_orm_mysql_core.MySqlColumn<{
180
+ name: "phone_verified";
181
+ tableName: "users";
182
+ dataType: "boolean";
183
+ columnType: "MySqlBoolean";
184
+ data: boolean;
185
+ driverParam: number | boolean;
186
+ notNull: false;
187
+ hasDefault: true;
188
+ isPrimaryKey: false;
189
+ isAutoincrement: false;
190
+ hasRuntimeDefault: false;
191
+ enumValues: undefined;
192
+ baseColumn: never;
193
+ identity: undefined;
194
+ generated: undefined;
195
+ }, {}, {}>;
162
196
  password: drizzle_orm_mysql_core.MySqlColumn<{
163
197
  name: "password";
164
198
  tableName: "users";
@@ -792,6 +826,40 @@ declare const authSchema: {
792
826
  identity: undefined;
793
827
  generated: undefined;
794
828
  }, {}, {}>;
829
+ phone: drizzle_orm_mysql_core.MySqlColumn<{
830
+ name: "phone";
831
+ tableName: "users";
832
+ dataType: "string";
833
+ columnType: "MySqlVarChar";
834
+ data: string;
835
+ driverParam: string | number;
836
+ notNull: false;
837
+ hasDefault: false;
838
+ isPrimaryKey: false;
839
+ isAutoincrement: false;
840
+ hasRuntimeDefault: false;
841
+ enumValues: [string, ...string[]];
842
+ baseColumn: never;
843
+ identity: undefined;
844
+ generated: undefined;
845
+ }, {}, {}>;
846
+ phoneVerified: drizzle_orm_mysql_core.MySqlColumn<{
847
+ name: "phone_verified";
848
+ tableName: "users";
849
+ dataType: "boolean";
850
+ columnType: "MySqlBoolean";
851
+ data: boolean;
852
+ driverParam: number | boolean;
853
+ notNull: false;
854
+ hasDefault: true;
855
+ isPrimaryKey: false;
856
+ isAutoincrement: false;
857
+ hasRuntimeDefault: false;
858
+ enumValues: undefined;
859
+ baseColumn: never;
860
+ identity: undefined;
861
+ generated: undefined;
862
+ }, {}, {}>;
795
863
  password: drizzle_orm_mysql_core.MySqlColumn<{
796
864
  name: "password";
797
865
  tableName: "users";
@@ -27,6 +27,8 @@ var usersTable = mysqlTable("users", {
27
27
  name: varchar("name", { length: 255 }),
28
28
  email: varchar("email", { length: 255 }).notNull().unique(),
29
29
  emailVerified: boolean("email_verified").default(false),
30
+ phone: varchar("phone", { length: 255 }).unique(),
31
+ phoneVerified: boolean("phone_verified").default(false),
30
32
  password: varchar("password", { length: 255 }).notNull(),
31
33
  image: varchar("image", { length: 255 }).default("noavatar.png"),
32
34
  status: mysqlEnum("status", [...USER_STATUS]).default("pending"),
@@ -162,6 +162,40 @@ declare const usersTable: drizzle_orm_pg_core.PgTableWithColumns<{
162
162
  identity: undefined;
163
163
  generated: undefined;
164
164
  }, {}, {}>;
165
+ phone: drizzle_orm_pg_core.PgColumn<{
166
+ name: "phone";
167
+ tableName: "users";
168
+ dataType: "string";
169
+ columnType: "PgText";
170
+ data: string;
171
+ driverParam: string;
172
+ notNull: false;
173
+ hasDefault: false;
174
+ isPrimaryKey: false;
175
+ isAutoincrement: false;
176
+ hasRuntimeDefault: false;
177
+ enumValues: [string, ...string[]];
178
+ baseColumn: never;
179
+ identity: undefined;
180
+ generated: undefined;
181
+ }, {}, {}>;
182
+ phoneVerified: drizzle_orm_pg_core.PgColumn<{
183
+ name: "phone_verified";
184
+ tableName: "users";
185
+ dataType: "boolean";
186
+ columnType: "PgBoolean";
187
+ data: boolean;
188
+ driverParam: boolean;
189
+ notNull: false;
190
+ hasDefault: true;
191
+ isPrimaryKey: false;
192
+ isAutoincrement: false;
193
+ hasRuntimeDefault: false;
194
+ enumValues: undefined;
195
+ baseColumn: never;
196
+ identity: undefined;
197
+ generated: undefined;
198
+ }, {}, {}>;
165
199
  password: drizzle_orm_pg_core.PgColumn<{
166
200
  name: "password";
167
201
  tableName: "users";
@@ -795,6 +829,40 @@ declare const authSchema: {
795
829
  identity: undefined;
796
830
  generated: undefined;
797
831
  }, {}, {}>;
832
+ phone: drizzle_orm_pg_core.PgColumn<{
833
+ name: "phone";
834
+ tableName: "users";
835
+ dataType: "string";
836
+ columnType: "PgText";
837
+ data: string;
838
+ driverParam: string;
839
+ notNull: false;
840
+ hasDefault: false;
841
+ isPrimaryKey: false;
842
+ isAutoincrement: false;
843
+ hasRuntimeDefault: false;
844
+ enumValues: [string, ...string[]];
845
+ baseColumn: never;
846
+ identity: undefined;
847
+ generated: undefined;
848
+ }, {}, {}>;
849
+ phoneVerified: drizzle_orm_pg_core.PgColumn<{
850
+ name: "phone_verified";
851
+ tableName: "users";
852
+ dataType: "boolean";
853
+ columnType: "PgBoolean";
854
+ data: boolean;
855
+ driverParam: boolean;
856
+ notNull: false;
857
+ hasDefault: true;
858
+ isPrimaryKey: false;
859
+ isAutoincrement: false;
860
+ hasRuntimeDefault: false;
861
+ enumValues: undefined;
862
+ baseColumn: never;
863
+ identity: undefined;
864
+ generated: undefined;
865
+ }, {}, {}>;
798
866
  password: drizzle_orm_pg_core.PgColumn<{
799
867
  name: "password";
800
868
  tableName: "users";
package/dist/schema/pg.js CHANGED
@@ -30,6 +30,8 @@ var usersTable = pgTable("users", {
30
30
  name: text("name"),
31
31
  email: text("email").notNull().unique(),
32
32
  emailVerified: boolean("email_verified").default(false),
33
+ phone: text("phone").unique(),
34
+ phoneVerified: boolean("phone_verified").default(false),
33
35
  password: text("password").notNull(),
34
36
  image: text("image").default("noavatar.png"),
35
37
  status: userStatusEnum("status").default("pending"),
@@ -173,6 +173,42 @@ declare const usersTable: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
173
173
  identity: undefined;
174
174
  generated: undefined;
175
175
  }, {}, {}>;
176
+ phone: drizzle_orm_sqlite_core.SQLiteColumn<{
177
+ name: "phone";
178
+ tableName: "users";
179
+ dataType: "string";
180
+ columnType: "SQLiteText";
181
+ data: string;
182
+ driverParam: string;
183
+ notNull: false;
184
+ hasDefault: false;
185
+ isPrimaryKey: false;
186
+ isAutoincrement: false;
187
+ hasRuntimeDefault: false;
188
+ enumValues: [string, ...string[]];
189
+ baseColumn: never;
190
+ identity: undefined;
191
+ generated: undefined;
192
+ }, {}, {
193
+ length: number;
194
+ }>;
195
+ phoneVerified: drizzle_orm_sqlite_core.SQLiteColumn<{
196
+ name: "phone_verified";
197
+ tableName: "users";
198
+ dataType: "boolean";
199
+ columnType: "SQLiteBoolean";
200
+ data: boolean;
201
+ driverParam: number;
202
+ notNull: false;
203
+ hasDefault: true;
204
+ isPrimaryKey: false;
205
+ isAutoincrement: false;
206
+ hasRuntimeDefault: false;
207
+ enumValues: undefined;
208
+ baseColumn: never;
209
+ identity: undefined;
210
+ generated: undefined;
211
+ }, {}, {}>;
176
212
  password: drizzle_orm_sqlite_core.SQLiteColumn<{
177
213
  name: "password";
178
214
  tableName: "users";
@@ -913,6 +949,42 @@ declare const authSchema: {
913
949
  identity: undefined;
914
950
  generated: undefined;
915
951
  }, {}, {}>;
952
+ phone: drizzle_orm_sqlite_core.SQLiteColumn<{
953
+ name: "phone";
954
+ tableName: "users";
955
+ dataType: "string";
956
+ columnType: "SQLiteText";
957
+ data: string;
958
+ driverParam: string;
959
+ notNull: false;
960
+ hasDefault: false;
961
+ isPrimaryKey: false;
962
+ isAutoincrement: false;
963
+ hasRuntimeDefault: false;
964
+ enumValues: [string, ...string[]];
965
+ baseColumn: never;
966
+ identity: undefined;
967
+ generated: undefined;
968
+ }, {}, {
969
+ length: number;
970
+ }>;
971
+ phoneVerified: drizzle_orm_sqlite_core.SQLiteColumn<{
972
+ name: "phone_verified";
973
+ tableName: "users";
974
+ dataType: "boolean";
975
+ columnType: "SQLiteBoolean";
976
+ data: boolean;
977
+ driverParam: number;
978
+ notNull: false;
979
+ hasDefault: true;
980
+ isPrimaryKey: false;
981
+ isAutoincrement: false;
982
+ hasRuntimeDefault: false;
983
+ enumValues: undefined;
984
+ baseColumn: never;
985
+ identity: undefined;
986
+ generated: undefined;
987
+ }, {}, {}>;
916
988
  password: drizzle_orm_sqlite_core.SQLiteColumn<{
917
989
  name: "password";
918
990
  tableName: "users";
@@ -20,6 +20,8 @@ var usersTable = sqliteTable("users", {
20
20
  name: text("name"),
21
21
  email: text("email").notNull().unique(),
22
22
  emailVerified: integer("email_verified", { mode: "boolean" }).default(false),
23
+ phone: text("phone").unique(),
24
+ phoneVerified: integer("phone_verified", { mode: "boolean" }).default(false),
23
25
  password: text("password").notNull(),
24
26
  image: text("image").default("noavatar.png"),
25
27
  status: text("status").$type().default("pending"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-auth",
3
- "version": "1.1.31",
3
+ "version": "1.1.33",
4
4
  "description": "Authentication and authorization library for najm framework",
5
5
  "type": "module",
6
6
  "files": [
@@ -73,15 +73,15 @@
73
73
  },
74
74
  "dependencies": {
75
75
  "bcryptjs": "^3.0.2",
76
- "najm-cookies": "^1.1.6",
77
- "najm-core": "^1.2.3",
78
- "najm-database": "^1.1.7",
79
- "najm-guard": "^1.1.6",
80
- "najm-i18n": "^1.1.6",
81
- "najm-cache": "^1.2.3",
82
- "najm-email": "^1.1.6",
83
- "najm-rate": "^1.1.6",
84
- "najm-validation": "^1.1.7",
76
+ "najm-cookies": "^1.1.7",
77
+ "najm-core": "^1.2.4",
78
+ "najm-database": "^1.1.8",
79
+ "najm-guard": "^1.1.7",
80
+ "najm-i18n": "^1.1.7",
81
+ "najm-cache": "^1.2.4",
82
+ "najm-email": "^1.1.7",
83
+ "najm-rate": "^1.1.7",
84
+ "najm-validation": "^1.1.8",
85
85
  "hono": "^4.0.0",
86
86
  "jsonwebtoken": "^9.0.3",
87
87
  "lodash.isempty": "^4.4.0",