najm-auth 0.1.10 → 0.1.12

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.

Potentially problematic release.


This version of najm-auth might be problematic. Click here for more details.

Files changed (2) hide show
  1. package/dist/index.mjs +1894 -1518
  2. package/package.json +5 -4
package/dist/index.mjs CHANGED
@@ -1,23 +1,25 @@
1
1
  var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __decorateClass = (decorators, target, key, kind) => {
4
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
- if (decorator = decorators[i])
7
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
- if (kind && result) __defProp(target, key, result);
9
- return result;
10
- };
11
- var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
12
3
 
13
4
  // src/auth/EncryptionService.ts
14
5
  import { Injectable } from "najm-api";
15
6
  import bcrypt from "bcrypt";
16
- var EncryptionService = class {
7
+ var __decorate = function(decorators, target, key, desc) {
8
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
10
+ 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;
11
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
12
+ };
13
+ var __metadata = function(k, v) {
14
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
15
+ };
16
+ var _a;
17
+ var EncryptionService = (_a = class {
17
18
  constructor() {
18
19
  }
19
20
  async hashPassword(password) {
20
- if (!password) return null;
21
+ if (!password)
22
+ return null;
21
23
  if (typeof password !== "string" || password.trim().length === 0) {
22
24
  return null;
23
25
  }
@@ -26,15 +28,23 @@ var EncryptionService = class {
26
28
  async comparePassword(password, hashedPassword) {
27
29
  return bcrypt.compare(password, hashedPassword);
28
30
  }
29
- };
30
- EncryptionService = __decorateClass([
31
- Injectable()
31
+ }, __name(_a, "EncryptionService"), _a);
32
+ EncryptionService = __decorate([
33
+ Injectable(),
34
+ __metadata("design:paramtypes", [])
32
35
  ], EncryptionService);
33
36
 
34
37
  // src/auth/CookieService.ts
35
38
  import { setCookie, Injectable as Injectable2, deleteCookie } from "najm-api";
36
39
  import timestring from "timestring";
37
- var CookieService = class {
40
+ var __decorate2 = function(decorators, target, key, desc) {
41
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
42
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
43
+ 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;
44
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
45
+ };
46
+ var _a2;
47
+ var CookieService = (_a2 = class {
38
48
  setRefreshCookie(refreshToken) {
39
49
  const maxAge = timestring(process.env.REFRESH_EXPIRES_IN, "s");
40
50
  setCookie("refreshToken", refreshToken, {
@@ -52,229 +62,22 @@ var CookieService = class {
52
62
  maxAge: 0
53
63
  });
54
64
  }
55
- };
56
- CookieService = __decorateClass([
65
+ }, __name(_a2, "CookieService"), _a2);
66
+ CookieService = __decorate2([
57
67
  Injectable2()
58
68
  ], CookieService);
59
69
 
60
70
  // src/auth/AuthController.ts
61
- import { Controller, Get, Post, Params, Body, User, t } from "najm-api";
62
-
63
- // src/roles/RoleGuards.ts
64
- import { Injectable as Injectable3, Headers, createGuard, GuardParams, Ctx } from "najm-api";
65
- var ROLES = {
66
- ADMIN: "admin",
67
- PRINCIPAL: "principal",
68
- ACCOUNTING: "accounting",
69
- SECRETARY: "secretary",
70
- TEACHER: "teacher",
71
- STUDENT: "student",
72
- PARENT: "parent"
73
- };
74
- var ROLE_GROUPS = {
75
- ADMINISTRATORS: [ROLES.ADMIN, ROLES.PRINCIPAL],
76
- FINANCIAL: [ROLES.ADMIN, ROLES.ACCOUNTING],
77
- STAFF: [ROLES.ADMIN, ROLES.PRINCIPAL, ROLES.ACCOUNTING, ROLES.SECRETARY, ROLES.TEACHER],
78
- END_USERS: [ROLES.STUDENT, ROLES.PARENT],
79
- ALL: [ROLES.ADMIN, ROLES.PRINCIPAL, ROLES.ACCOUNTING, ROLES.SECRETARY, ROLES.TEACHER, ROLES.STUDENT, ROLES.PARENT]
80
- };
81
- var RoleChecker = class {
82
- isInGroup(userRole, group) {
83
- return group.includes(userRole?.toLowerCase());
84
- }
85
- isAdministrator(userRole) {
86
- return this.isInGroup(userRole, ROLE_GROUPS.ADMINISTRATORS);
87
- }
88
- isStaff(userRole) {
89
- return this.isInGroup(userRole, ROLE_GROUPS.STAFF);
90
- }
91
- hasAnyRole(userRole, roles) {
92
- return roles.includes(userRole?.toLowerCase());
93
- }
94
- hasExactRole(userRole, requiredRole) {
95
- return userRole?.toLowerCase() === requiredRole?.toLowerCase();
96
- }
97
- };
98
- RoleChecker = __decorateClass([
99
- Injectable3()
100
- ], RoleChecker);
101
- var RoleGuards = class {
102
- constructor(roleChecker, tokenService) {
103
- this.roleChecker = roleChecker;
104
- this.tokenService = tokenService;
105
- }
106
- async isAuth(auth, ctx) {
107
- const user = await this.tokenService.storeUserInCache(auth, ctx);
108
- return !!user;
109
- }
110
- async hasRoles(auth, ctx, roles) {
111
- try {
112
- const user = await this.tokenService.storeUserInCache(auth, ctx);
113
- if (!user?.role) return false;
114
- const roleArray = Array.isArray(roles) ? roles : [roles];
115
- return this.roleChecker.hasAnyRole(user.role, roleArray);
116
- } catch {
117
- return false;
118
- }
119
- }
120
- };
121
- __decorateClass([
122
- __decorateParam(0, Headers("authorization")),
123
- __decorateParam(1, Ctx())
124
- ], RoleGuards.prototype, "isAuth", 1);
125
- __decorateClass([
126
- __decorateParam(0, Headers("authorization")),
127
- __decorateParam(1, Ctx()),
128
- __decorateParam(2, GuardParams())
129
- ], RoleGuards.prototype, "hasRoles", 1);
130
- RoleGuards = __decorateClass([
131
- Injectable3()
132
- ], RoleGuards);
133
- var isAdmin = () => Role("admin");
134
- var isPrincipal = () => Role("principal");
135
- var isAccounting = () => Role("accounting");
136
- var isSecretary = () => Role("secretary");
137
- var isTeacher = () => Role("teacher");
138
- var isParent = () => Role("parent");
139
- var isStudent = () => Role("student");
140
- var isAdministrator = () => Role("admin", "principal");
141
- var isFinancial = () => Role("admin", "accounting");
142
- var isStaff = () => Role("admin", "principal", "accounting", "secretary", "teacher");
143
- var isAuth = createGuard(RoleGuards, "isAuth");
144
- var Role = (...roles) => createGuard(RoleGuards, "hasRoles")(...roles);
145
-
146
- // src/auth/AuthController.ts
147
- var AuthController = class {
148
- constructor(authService) {
149
- this.authService = authService;
150
- }
151
- async registerUser(body) {
152
- const data = await this.authService.registerUser(body);
153
- return {
154
- data,
155
- message: t("auth.success.register"),
156
- status: "success"
157
- };
158
- }
159
- async loginUser(body) {
160
- const data = await this.authService.loginUser(body);
161
- return {
162
- data,
163
- message: t("auth.success.login"),
164
- status: "success"
165
- };
166
- }
167
- async refreshTokens() {
168
- const data = await this.authService.refreshTokens();
169
- return {
170
- data,
171
- message: t("auth.success.tokenRefreshed"),
172
- status: "success"
173
- };
174
- }
175
- async logoutUser(id) {
176
- const data = await this.authService.logoutUser(id);
177
- return {
178
- data,
179
- message: t("auth.success.logout"),
180
- status: "success"
181
- };
182
- }
183
- async userProfile(user) {
184
- const data = await this.authService.getUserProfile(user);
185
- return {
186
- data,
187
- message: t("users.success.retrieved"),
188
- status: "success"
189
- };
190
- }
191
- async forgotPassword(body) {
192
- const data = await this.authService.forgotPassword(body.email);
193
- return {
194
- data,
195
- message: t("auth.success.passwordReset"),
196
- status: "success"
197
- };
198
- }
199
- };
200
- __decorateClass([
201
- Post("/register"),
202
- __decorateParam(0, Body())
203
- ], AuthController.prototype, "registerUser", 1);
204
- __decorateClass([
205
- Post("/login"),
206
- __decorateParam(0, Body())
207
- ], AuthController.prototype, "loginUser", 1);
208
- __decorateClass([
209
- Get("/refresh")
210
- ], AuthController.prototype, "refreshTokens", 1);
211
- __decorateClass([
212
- Get("/logout/:id"),
213
- __decorateParam(0, Params("id"))
214
- ], AuthController.prototype, "logoutUser", 1);
215
- __decorateClass([
216
- Get("/me"),
217
- isAuth(),
218
- __decorateParam(0, User())
219
- ], AuthController.prototype, "userProfile", 1);
220
- __decorateClass([
221
- Post("/forgot-password"),
222
- isAuth(),
223
- __decorateParam(0, Body())
224
- ], AuthController.prototype, "forgotPassword", 1);
225
- AuthController = __decorateClass([
226
- Controller("/auth")
227
- ], AuthController);
71
+ import { Controller as Controller3, Get as Get3, Post as Post3, Params as Params3, Body as Body3, User, t as t7 } from "najm-api";
228
72
 
229
73
  // src/auth/AuthService.ts
230
- import { t as t2 } from "najm-api";
231
- import { Injectable as Injectable4, getCurrentLanguage } from "najm-api";
232
- var AuthService = class {
233
- constructor(tokenService, userService, userValidator, cookieService) {
234
- this.tokenService = tokenService;
235
- this.userService = userService;
236
- this.userValidator = userValidator;
237
- this.cookieService = cookieService;
238
- }
239
- async registerUser(body) {
240
- return await this.userService.create(body);
241
- }
242
- async loginUser(body) {
243
- const { email, password } = body;
244
- if (!email || !password) {
245
- throw new Error(t2("auth.errors.invalidCredentials"));
246
- }
247
- const existingPassword = await this.userService.getPassword(email);
248
- const { id } = await this.userService.getByEmail(email);
249
- await this.userValidator.checkPasswordValid(password, existingPassword);
250
- const data = await this.tokenService.generateTokens(id);
251
- this.cookieService.setRefreshCookie(data.refreshToken);
252
- return data;
253
- }
254
- async refreshTokens() {
255
- const data = await this.tokenService.refreshTokens();
256
- this.cookieService.setRefreshCookie(data.refreshToken);
257
- return data;
258
- }
259
- async logoutUser(userId) {
260
- await this.userValidator.checkUserExists(userId);
261
- await this.tokenService.revokeToken(userId);
262
- this.cookieService.clearRefreshCookie();
263
- return { data: null, message: t2("auth.success.logout") };
264
- }
265
- async getUserProfile(userData) {
266
- const lang = getCurrentLanguage();
267
- return {
268
- ...userData,
269
- language: lang
270
- };
271
- }
272
- async forgotPassword(email) {
273
- }
274
- };
275
- AuthService = __decorateClass([
276
- Injectable4()
277
- ], AuthService);
74
+ import { t as t6 } from "najm-api";
75
+ import { Injectable as Injectable9, getCurrentLanguage as getCurrentLanguage2 } from "najm-api";
76
+
77
+ // src/database/schema/index.ts
78
+ import { pgTable, text, boolean, timestamp } from "drizzle-orm/pg-core";
79
+ import { nanoid } from "nanoid";
80
+ import { sql } from "drizzle-orm";
278
81
 
279
82
  // src/lib/ENUMS.ts
280
83
  var ENUMS = {
@@ -509,128 +312,374 @@ var ENUMS = {
509
312
  translationKey: "parents.maritalStatus"
510
313
  }
511
314
  };
512
- var getEnumConfig = (enumKey) => ENUMS[enumKey];
513
- var getEnumValues = (enumKey) => ENUMS[enumKey]?.values || [];
514
-
515
- // src/lib/validations.ts
516
- import { z as z2 } from "zod";
315
+ var getEnumConfig = /* @__PURE__ */ __name((enumKey) => ENUMS[enumKey], "getEnumConfig");
316
+ var getEnumValues = /* @__PURE__ */ __name((enumKey) => ENUMS[enumKey]?.values || [], "getEnumValues");
517
317
 
518
- // src/lib/ZodEnum.ts
519
- import { z } from "zod";
520
- var createZodEnum = (enumKey) => {
521
- const values = ENUMS[enumKey]?.values;
522
- if (!values) throw new Error(`Enum ${enumKey} not found`);
523
- return z.enum(values);
524
- };
525
- var userTypeEnum = createZodEnum("userType");
526
- var userStatusEnum = createZodEnum("userStatus");
527
- var tokenStatusEnum = createZodEnum("tokenStatus");
528
- var tokenTypeEnum = createZodEnum("tokenType");
529
- var fileStatusEnum = createZodEnum("fileStatus");
530
- var genderEnum = createZodEnum("gender");
531
- var studentStatusEnum = createZodEnum("studentStatus");
532
- var teacherStatusEnum = createZodEnum("teacherStatus");
533
- var employmentTypeEnum = createZodEnum("employmentType");
534
- var relationshipTypeEnum = createZodEnum("relationshipType");
535
- var semesterEnum = createZodEnum("semester");
536
- var classStatusEnum = createZodEnum("classStatus");
537
- var sectionStatusEnum = createZodEnum("sectionStatus");
538
- var languageEnum = createZodEnum("language");
539
- var enrollmentStatusEnum = createZodEnum("enrollmentStatus");
540
- var assignmentStatusEnum = createZodEnum("assignmentStatus");
541
- var calendarSystemEnum = createZodEnum("calendarSystem");
542
- var assessmentTypeEnum = createZodEnum("assessmentType");
543
- var assessmentStatusEnum = createZodEnum("assessmentStatus");
544
- var submissionTypeEnum = createZodEnum("submissionType");
545
- var examTypeEnum = createZodEnum("examType");
546
- var examSecurityEnum = createZodEnum("examSecurity");
547
- var examStatusEnum = createZodEnum("examStatus");
548
- var gradeStatusEnum = createZodEnum("gradeStatus");
549
- var attendanceStatusEnum = createZodEnum("attendanceStatus");
550
- var proficiencyLevelEnum = createZodEnum("proficiencyLevel");
551
- var dayOfWeekEnum = createZodEnum("dayOfWeek");
552
- var alertTypeEnum = createZodEnum("alertType");
553
- var alertPriorityEnum = createZodEnum("alertPriority");
554
- var alertStatusEnum = createZodEnum("alertStatus");
555
- var feeTypeStatusEnum = createZodEnum("feeTypeStatus");
556
- var paymentTypeEnum = createZodEnum("paymentType");
557
- var scheduleEnum = createZodEnum("schedule");
558
- var feeStatusEnum = createZodEnum("feeStatus");
559
- var feeInstallmentStatusEnum = createZodEnum("feeInstallmentStatus");
560
- var paymentMethodEnum = createZodEnum("paymentMethod");
561
- var paymentStatusEnum = createZodEnum("paymentStatus");
562
- var eventTypeEnum = createZodEnum("eventType");
563
- var eventStatusEnum = createZodEnum("eventStatus");
564
- var eventVisibilityEnum = createZodEnum("eventVisibility");
565
- var participantTypeEnum = createZodEnum("participantType");
566
- var expenseCategoryEnum = createZodEnum("expenseCategory");
567
- var expenseStatusEnum = createZodEnum("expenseStatus");
568
- var trackerModeEnum = createZodEnum("trackerMode");
569
- var driverStatusEnum = createZodEnum("driverStatus");
570
- var vehicleStatusEnum = createZodEnum("vehicleStatus");
571
- var vehicleTypeEnum = createZodEnum("vehicleType");
572
- var vehicleDocumentTypeEnum = createZodEnum("vehicleDocumentType");
573
- var busStatusEnum = createZodEnum("busStatus");
574
- var refuelStatusEnum = createZodEnum("refuelStatus");
575
- var fuelTypeEnum = createZodEnum("fuelType");
576
- var maintenanceTypeEnum = createZodEnum("maintenanceType");
577
- var maintenanceStatusEnum = createZodEnum("maintenanceStatus");
578
- var maritalStatusEnum = createZodEnum("maritalStatus");
318
+ // src/database/schema/PgEnum.ts
319
+ import { pgEnum } from "drizzle-orm/pg-core";
320
+ var createPgEnum = /* @__PURE__ */ __name((enumKey) => {
321
+ const config = getEnumConfig(enumKey);
322
+ if (!config)
323
+ throw new Error(`Enum ${enumKey} not found`);
324
+ const enumName = config.name || enumKey;
325
+ return pgEnum(enumName, config.values);
326
+ }, "createPgEnum");
327
+ var userStatusEnum = createPgEnum("userStatus");
328
+ var tokenStatusEnum = createPgEnum("tokenStatus");
329
+ var tokenTypeEnum = createPgEnum("tokenType");
330
+ var studentStatusEnum = createPgEnum("studentStatus");
579
331
 
580
- // src/lib/validations.ts
581
- var requiredId = z2.preprocess((val) => val ?? "", z2.string().min(1, "ID is required"));
582
- var optionalId = z2.string().min(1, "ID cannot be empty").nullish().optional();
583
- var emailField = z2.string().email("Invalid email format").or(z2.literal(""));
584
- var phoneField = z2.string().regex(/^[\+]?[1-9][\d]{0,15}$/, "Invalid phone number");
585
- var nameField = z2.string().min(2, "Name must be at least 2 characters").max(100, "Name too long");
586
- var dateField = z2.string().regex(/^(\d{4}-\d{2}-\d{2}|\d{2}\/\d{2}\/\d{4}|\d{2}-\d{2}-\d{2}|\d{2}-\d{2}-\d{4})$/, "Date must be in YYYY-MM-DD, MM/DD/YYYY, DD/MM/YYYY, DD-MM-YY, or DD-MM-YYYY format");
587
- var optionalDateField = z2.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").nullable().optional();
588
- var timeField = z2.string().regex(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/, "Time must be in HH:MM format").optional().nullable();
589
- var cinField = z2.string().min(8, "CIN must be at least 8 characters").max(20, "CIN too long");
590
- var addressField = z2.string().max(500, "Address too long").optional();
591
- var academicYearField = z2.string().min(9, "Academic year is required").regex(/^\d{4}-\d{4}$/, "Academic year must be in YYYY-YYYY format");
592
- var num = () => {
593
- const createChainable = (currentSchema) => {
594
- const methods = {
595
- positive: (msg = "Must be positive") => createChainable(currentSchema.refine((val) => val > 0, { message: msg })),
596
- min: (value, msg) => createChainable(currentSchema.refine(
597
- (val) => val >= value,
598
- { message: msg || `Must be at least ${value}` }
599
- )),
600
- max: (value, msg) => createChainable(currentSchema.refine(
601
- (val) => val <= value,
602
- { message: msg || `Cannot exceed ${value}` }
603
- )),
604
- int: (msg = "Must be an integer") => createChainable(currentSchema.refine(
605
- (val) => Number.isInteger(val),
606
- { message: msg }
607
- ))
608
- };
609
- return Object.assign(currentSchema, methods);
610
- };
611
- const isValidNumber = (val) => {
612
- if (val === null || val === void 0 || Number.isNaN(val)) return false;
613
- if (typeof val === "number") return true;
614
- if (typeof val === "string") {
615
- const trimmed = val.trim();
616
- return trimmed !== "" && !isNaN(Number(trimmed));
617
- }
618
- return false;
619
- };
620
- const baseSchema = z2.any().refine(isValidNumber, { message: "Must be a valid number" }).transform((val) => typeof val === "string" ? Number(val) : val);
621
- return createChainable(baseSchema);
332
+ // src/database/schema/index.ts
333
+ var timestamps = {
334
+ createdAt: timestamp("created_at", { mode: "string" }).defaultNow(),
335
+ updatedAt: timestamp("updated_at", { mode: "string" }).defaultNow().$onUpdate(() => sql`CURRENT_TIMESTAMP`)
622
336
  };
623
- var userSchema = z2.object({
624
- id: optionalId,
625
- username: nameField.max(50).optional(),
626
- email: emailField,
627
- password: z2.string().min(8, "Password must be at least 8 characters"),
628
- roleId: optionalId,
337
+ var idField = /* @__PURE__ */ __name((length = 5) => text("id").primaryKey().notNull().$defaultFn(() => nanoid(length)), "idField");
338
+ var rolesTable = pgTable("roles", {
339
+ id: idField(),
340
+ name: text("name").notNull(),
341
+ description: text("description")
342
+ });
343
+ var usersTable = pgTable("users", {
344
+ id: idField(8),
345
+ email: text("email").notNull().unique(),
346
+ emailVerified: boolean("email_verified").default(false),
347
+ password: text("password").notNull(),
348
+ image: text("image").default("noavatar.png"),
349
+ status: userStatusEnum("status").default("pending"),
350
+ roleId: text("role_id").references(() => rolesTable.id),
351
+ lastLogin: timestamp("last_login", { mode: "string" }),
352
+ ...timestamps
353
+ });
354
+ var tokensTable = pgTable("tokens", {
355
+ id: idField(10),
356
+ userId: text("user_id").references(() => usersTable.id, { onDelete: "cascade" }).unique().notNull(),
357
+ token: text("token").notNull(),
358
+ type: tokenTypeEnum("type").default("refresh"),
359
+ status: tokenStatusEnum("status").default("active"),
360
+ expiresAt: timestamp("expires_at", { mode: "string" }).notNull(),
361
+ ...timestamps
362
+ });
363
+ var permissionsTable = pgTable("permissions", {
364
+ id: idField(),
365
+ name: text("name").notNull().unique(),
366
+ description: text("description"),
367
+ resource: text("resource").notNull(),
368
+ action: text("action").notNull(),
369
+ ...timestamps
370
+ });
371
+ var rolePermissionsTable = pgTable("role_permissions", {
372
+ id: idField(),
373
+ roleId: text("role_id").references(() => rolesTable.id).notNull(),
374
+ permissionId: text("permission_id").references(() => permissionsTable.id).notNull(),
375
+ ...timestamps
376
+ });
377
+
378
+ // src/users/UserRepository.ts
379
+ import { eq, ne } from "drizzle-orm";
380
+ import { Repository } from "najm-api";
381
+ var __decorate3 = function(decorators, target, key, desc) {
382
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
383
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
384
+ 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;
385
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
386
+ };
387
+ var _a3;
388
+ var UserRepository = (_a3 = class {
389
+ getUser() {
390
+ return {
391
+ id: usersTable.id,
392
+ email: usersTable.email,
393
+ emailVerified: usersTable.emailVerified,
394
+ image: usersTable.image,
395
+ status: usersTable.status,
396
+ roleId: usersTable.roleId,
397
+ role: rolesTable.name,
398
+ createdAt: usersTable.createdAt,
399
+ updatedAt: usersTable.updatedAt
400
+ };
401
+ }
402
+ async getAll() {
403
+ const allUsers = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq(usersTable.roleId, rolesTable.id));
404
+ return Promise.all(allUsers.map(async (user) => ({
405
+ ...user,
406
+ permissions: await this.getUserPermissions(user.id)
407
+ })));
408
+ }
409
+ async getById(id) {
410
+ const [user] = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq(usersTable.roleId, rolesTable.id)).where(eq(usersTable.id, id)).limit(1);
411
+ if (!user)
412
+ return user;
413
+ return {
414
+ ...user,
415
+ permissions: await this.getUserPermissions(user.id)
416
+ };
417
+ }
418
+ async getByEmail(email) {
419
+ const [existingUser] = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq(usersTable.roleId, rolesTable.id)).where(eq(usersTable.email, email));
420
+ return existingUser;
421
+ }
422
+ async create(data) {
423
+ const [newUser] = await this.db.insert(usersTable).values(data).returning();
424
+ return newUser;
425
+ }
426
+ async update(id, data) {
427
+ const [updatedUser] = await this.db.update(usersTable).set(data).where(eq(usersTable.id, id)).returning();
428
+ return updatedUser;
429
+ }
430
+ async delete(id) {
431
+ const [deletedUser] = await this.db.delete(usersTable).where(eq(usersTable.id, id)).returning();
432
+ return deletedUser;
433
+ }
434
+ async deleteAll() {
435
+ const adminRole = await this.db.select({ id: rolesTable.id }).from(rolesTable).where(eq(rolesTable.name, "admin")).limit(1);
436
+ if (adminRole.length === 0) {
437
+ const deletedUsers2 = await this.db.delete(usersTable).returning();
438
+ return deletedUsers2;
439
+ }
440
+ const deletedUsers = await this.db.delete(usersTable).where(ne(usersTable.roleId, adminRole[0].id)).returning();
441
+ return deletedUsers;
442
+ }
443
+ async getRoleNameById(userId) {
444
+ const [role] = await this.db.select({
445
+ roleName: rolesTable.name
446
+ }).from(usersTable).leftJoin(rolesTable, eq(usersTable.roleId, rolesTable.id)).where(eq(usersTable.id, userId));
447
+ return role.roleName;
448
+ }
449
+ async getUserPassword(email) {
450
+ const [user] = await this.db.select({
451
+ id: usersTable.id,
452
+ email: usersTable.email,
453
+ password: usersTable.password
454
+ }).from(usersTable).where(eq(usersTable.email, email)).limit(1);
455
+ return user.password;
456
+ }
457
+ async getUserPermissions(userId) {
458
+ const [user] = await this.db.select({ roleId: usersTable.roleId }).from(usersTable).where(eq(usersTable.id, userId)).limit(1);
459
+ if (!user || !user.roleId)
460
+ return [];
461
+ const userPermissions = await this.db.select({
462
+ name: permissionsTable.name
463
+ }).from(rolePermissionsTable).leftJoin(permissionsTable, eq(rolePermissionsTable.permissionId, permissionsTable.id)).where(eq(rolePermissionsTable.roleId, user.roleId));
464
+ return userPermissions.map((p) => p.name).filter((name) => name);
465
+ }
466
+ }, __name(_a3, "UserRepository"), _a3);
467
+ UserRepository = __decorate3([
468
+ Repository()
469
+ ], UserRepository);
470
+
471
+ // src/users/UserValidator.ts
472
+ import { Injectable as Injectable3, t } from "najm-api";
473
+
474
+ // src/shared/index.ts
475
+ import * as fs from "fs/promises";
476
+ import * as path from "path";
477
+ import _isEmpty from "lodash.isempty";
478
+ var avatarsPath = path.join(process.cwd(), "avatars");
479
+ var parseSchema = /* @__PURE__ */ __name(async (schema, data) => {
480
+ try {
481
+ return await schema.parseAsync(data);
482
+ } catch (error) {
483
+ const errors = error.issues || error.errors || [];
484
+ const errorMessage = errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
485
+ throw new Error(errorMessage);
486
+ }
487
+ }, "parseSchema");
488
+ var clean = /* @__PURE__ */ __name((obj) => {
489
+ const cleaned = {};
490
+ for (const [key, value] of Object.entries(obj)) {
491
+ if (value !== null && value !== void 0 && value !== "") {
492
+ cleaned[key] = value;
493
+ }
494
+ }
495
+ return cleaned;
496
+ }, "clean");
497
+ var getAvatarFile = /* @__PURE__ */ __name(async (fileName) => {
498
+ try {
499
+ const filePath = path.join(avatarsPath, fileName);
500
+ const buffer = await fs.readFile(filePath);
501
+ const file = new File([buffer], fileName, {
502
+ type: "image/png"
503
+ });
504
+ return file;
505
+ } catch (error) {
506
+ return null;
507
+ }
508
+ }, "getAvatarFile");
509
+ var formatDate = /* @__PURE__ */ __name((dateValue) => {
510
+ if (!dateValue)
511
+ return null;
512
+ let date;
513
+ if (dateValue instanceof Date) {
514
+ date = dateValue;
515
+ } else if (typeof dateValue === "string") {
516
+ date = new Date(dateValue);
517
+ } else {
518
+ return null;
519
+ }
520
+ if (isNaN(date.getTime()))
521
+ return null;
522
+ return date.toISOString().split("T")[0];
523
+ }, "formatDate");
524
+ function calculateAge(dateOfBirth) {
525
+ if (!dateOfBirth)
526
+ return null;
527
+ const formattedDate = formatDate(dateOfBirth);
528
+ if (!formattedDate)
529
+ return null;
530
+ const birth = new Date(formattedDate);
531
+ const today = /* @__PURE__ */ new Date();
532
+ let age = today.getFullYear() - birth.getFullYear();
533
+ const monthDiff = today.getMonth() - birth.getMonth();
534
+ if (monthDiff < 0 || monthDiff === 0 && today.getDate() < birth.getDate()) {
535
+ age--;
536
+ }
537
+ return age;
538
+ }
539
+ __name(calculateAge, "calculateAge");
540
+ function calculateYearsOfExperience(hireDate) {
541
+ if (!hireDate)
542
+ return null;
543
+ const formattedDate = formatDate(hireDate);
544
+ if (!formattedDate)
545
+ return null;
546
+ const hire = new Date(formattedDate);
547
+ const today = /* @__PURE__ */ new Date();
548
+ let years = today.getFullYear() - hire.getFullYear();
549
+ const monthDiff = today.getMonth() - hire.getMonth();
550
+ if (monthDiff < 0 || monthDiff === 0 && today.getDate() < hire.getDate()) {
551
+ years--;
552
+ }
553
+ return years;
554
+ }
555
+ __name(calculateYearsOfExperience, "calculateYearsOfExperience");
556
+ function pickProps(source, keys) {
557
+ const result = {};
558
+ for (const key of keys) {
559
+ if (source[key] !== void 0) {
560
+ result[key] = source[key];
561
+ }
562
+ }
563
+ return result;
564
+ }
565
+ __name(pickProps, "pickProps");
566
+ var isEmpty = _isEmpty;
567
+ var isPath = /* @__PURE__ */ __name((img) => typeof img === "string" && img.trim().length > 0 && (img.startsWith("/") || img.startsWith("http") || img.startsWith("storage/")), "isPath");
568
+ var isFile = /* @__PURE__ */ __name((img) => !!img && typeof img !== "string" && img instanceof File, "isFile");
569
+
570
+ // src/lib/validations.ts
571
+ import { z as z2 } from "zod";
572
+
573
+ // src/lib/ZodEnum.ts
574
+ import { z } from "zod";
575
+ var createZodEnum = /* @__PURE__ */ __name((enumKey) => {
576
+ const values = ENUMS[enumKey]?.values;
577
+ if (!values)
578
+ throw new Error(`Enum ${enumKey} not found`);
579
+ return z.enum(values);
580
+ }, "createZodEnum");
581
+ var userTypeEnum = createZodEnum("userType");
582
+ var userStatusEnum2 = createZodEnum("userStatus");
583
+ var tokenStatusEnum2 = createZodEnum("tokenStatus");
584
+ var tokenTypeEnum2 = createZodEnum("tokenType");
585
+ var fileStatusEnum = createZodEnum("fileStatus");
586
+ var genderEnum = createZodEnum("gender");
587
+ var studentStatusEnum2 = createZodEnum("studentStatus");
588
+ var teacherStatusEnum = createZodEnum("teacherStatus");
589
+ var employmentTypeEnum = createZodEnum("employmentType");
590
+ var relationshipTypeEnum = createZodEnum("relationshipType");
591
+ var semesterEnum = createZodEnum("semester");
592
+ var classStatusEnum = createZodEnum("classStatus");
593
+ var sectionStatusEnum = createZodEnum("sectionStatus");
594
+ var languageEnum = createZodEnum("language");
595
+ var enrollmentStatusEnum = createZodEnum("enrollmentStatus");
596
+ var assignmentStatusEnum = createZodEnum("assignmentStatus");
597
+ var calendarSystemEnum = createZodEnum("calendarSystem");
598
+ var assessmentTypeEnum = createZodEnum("assessmentType");
599
+ var assessmentStatusEnum = createZodEnum("assessmentStatus");
600
+ var submissionTypeEnum = createZodEnum("submissionType");
601
+ var examTypeEnum = createZodEnum("examType");
602
+ var examSecurityEnum = createZodEnum("examSecurity");
603
+ var examStatusEnum = createZodEnum("examStatus");
604
+ var gradeStatusEnum = createZodEnum("gradeStatus");
605
+ var attendanceStatusEnum = createZodEnum("attendanceStatus");
606
+ var proficiencyLevelEnum = createZodEnum("proficiencyLevel");
607
+ var dayOfWeekEnum = createZodEnum("dayOfWeek");
608
+ var alertTypeEnum = createZodEnum("alertType");
609
+ var alertPriorityEnum = createZodEnum("alertPriority");
610
+ var alertStatusEnum = createZodEnum("alertStatus");
611
+ var feeTypeStatusEnum = createZodEnum("feeTypeStatus");
612
+ var paymentTypeEnum = createZodEnum("paymentType");
613
+ var scheduleEnum = createZodEnum("schedule");
614
+ var feeStatusEnum = createZodEnum("feeStatus");
615
+ var feeInstallmentStatusEnum = createZodEnum("feeInstallmentStatus");
616
+ var paymentMethodEnum = createZodEnum("paymentMethod");
617
+ var paymentStatusEnum = createZodEnum("paymentStatus");
618
+ var eventTypeEnum = createZodEnum("eventType");
619
+ var eventStatusEnum = createZodEnum("eventStatus");
620
+ var eventVisibilityEnum = createZodEnum("eventVisibility");
621
+ var participantTypeEnum = createZodEnum("participantType");
622
+ var expenseCategoryEnum = createZodEnum("expenseCategory");
623
+ var expenseStatusEnum = createZodEnum("expenseStatus");
624
+ var trackerModeEnum = createZodEnum("trackerMode");
625
+ var driverStatusEnum = createZodEnum("driverStatus");
626
+ var vehicleStatusEnum = createZodEnum("vehicleStatus");
627
+ var vehicleTypeEnum = createZodEnum("vehicleType");
628
+ var vehicleDocumentTypeEnum = createZodEnum("vehicleDocumentType");
629
+ var busStatusEnum = createZodEnum("busStatus");
630
+ var refuelStatusEnum = createZodEnum("refuelStatus");
631
+ var fuelTypeEnum = createZodEnum("fuelType");
632
+ var maintenanceTypeEnum = createZodEnum("maintenanceType");
633
+ var maintenanceStatusEnum = createZodEnum("maintenanceStatus");
634
+ var maritalStatusEnum = createZodEnum("maritalStatus");
635
+
636
+ // src/lib/validations.ts
637
+ var requiredId = z2.preprocess((val) => val ?? "", z2.string().min(1, "ID is required"));
638
+ var optionalId = z2.string().min(1, "ID cannot be empty").nullish().optional();
639
+ var emailField = z2.string().email("Invalid email format").or(z2.literal(""));
640
+ var phoneField = z2.string().regex(/^[\+]?[1-9][\d]{0,15}$/, "Invalid phone number");
641
+ var nameField = z2.string().min(2, "Name must be at least 2 characters").max(100, "Name too long");
642
+ var dateField = z2.string().regex(/^(\d{4}-\d{2}-\d{2}|\d{2}\/\d{2}\/\d{4}|\d{2}-\d{2}-\d{2}|\d{2}-\d{2}-\d{4})$/, "Date must be in YYYY-MM-DD, MM/DD/YYYY, DD/MM/YYYY, DD-MM-YY, or DD-MM-YYYY format");
643
+ var optionalDateField = z2.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").nullable().optional();
644
+ var timeField = z2.string().regex(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/, "Time must be in HH:MM format").optional().nullable();
645
+ var cinField = z2.string().min(8, "CIN must be at least 8 characters").max(20, "CIN too long");
646
+ var addressField = z2.string().max(500, "Address too long").optional();
647
+ var academicYearField = z2.string().min(9, "Academic year is required").regex(/^\d{4}-\d{4}$/, "Academic year must be in YYYY-YYYY format");
648
+ var num = /* @__PURE__ */ __name(() => {
649
+ const createChainable = /* @__PURE__ */ __name((currentSchema) => {
650
+ const methods = {
651
+ positive: /* @__PURE__ */ __name((msg = "Must be positive") => createChainable(currentSchema.refine((val) => val > 0, { message: msg })), "positive"),
652
+ min: /* @__PURE__ */ __name((value, msg) => createChainable(currentSchema.refine((val) => val >= value, { message: msg || `Must be at least ${value}` })), "min"),
653
+ max: /* @__PURE__ */ __name((value, msg) => createChainable(currentSchema.refine((val) => val <= value, { message: msg || `Cannot exceed ${value}` })), "max"),
654
+ int: /* @__PURE__ */ __name((msg = "Must be an integer") => createChainable(currentSchema.refine((val) => Number.isInteger(val), { message: msg })), "int")
655
+ };
656
+ return Object.assign(currentSchema, methods);
657
+ }, "createChainable");
658
+ const isValidNumber = /* @__PURE__ */ __name((val) => {
659
+ if (val === null || val === void 0 || Number.isNaN(val))
660
+ return false;
661
+ if (typeof val === "number")
662
+ return true;
663
+ if (typeof val === "string") {
664
+ const trimmed = val.trim();
665
+ return trimmed !== "" && !isNaN(Number(trimmed));
666
+ }
667
+ return false;
668
+ }, "isValidNumber");
669
+ const baseSchema = z2.any().refine(isValidNumber, { message: "Must be a valid number" }).transform((val) => typeof val === "string" ? Number(val) : val);
670
+ return createChainable(baseSchema);
671
+ }, "num");
672
+ var userSchema = z2.object({
673
+ id: optionalId,
674
+ username: nameField.max(50).optional(),
675
+ email: emailField,
676
+ password: z2.string().min(8, "Password must be at least 8 characters"),
677
+ roleId: optionalId,
629
678
  roleName: nameField.max(50).optional(),
630
679
  lastLogin: optionalDateField,
631
680
  image: z2.union([z2.string(), z2.instanceof(File), z2.undefined()]).optional(),
632
681
  emailVerified: z2.boolean().default(false),
633
- status: userStatusEnum,
682
+ status: userStatusEnum2,
634
683
  createdAt: optionalDateField
635
684
  });
636
685
  var roleSchema = z2.object({
@@ -654,7 +703,7 @@ var studentSchema = z2.object({
654
703
  medicalConditions: z2.string().max(1e3, "Medical conditions description too long").nullish().optional(),
655
704
  previousSchool: z2.string().max(500, "Previous school name too long").optional().nullable(),
656
705
  image: z2.union([z2.string(), z2.instanceof(File), z2.null()]).optional(),
657
- status: studentStatusEnum.default("active")
706
+ status: studentStatusEnum2.default("active")
658
707
  });
659
708
  var parentSchema = z2.object({
660
709
  id: optionalId,
@@ -1075,648 +1124,612 @@ var dateRangeSchema = z2.object({
1075
1124
  dateTo: dateField
1076
1125
  });
1077
1126
 
1078
- // src/database/schema/index.ts
1079
- import { pgTable, text, boolean, timestamp } from "drizzle-orm/pg-core";
1080
- import { nanoid } from "nanoid";
1081
- import { sql } from "drizzle-orm";
1082
-
1083
- // src/database/schema/PgEnum.ts
1084
- import { pgEnum } from "drizzle-orm/pg-core";
1085
- var createPgEnum = (enumKey) => {
1086
- const config = getEnumConfig(enumKey);
1087
- if (!config) throw new Error(`Enum ${enumKey} not found`);
1088
- const enumName = config.name || enumKey;
1089
- return pgEnum(enumName, config.values);
1127
+ // src/users/UserValidator.ts
1128
+ var __decorate4 = function(decorators, target, key, desc) {
1129
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1130
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1131
+ 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;
1132
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1090
1133
  };
1091
- var userStatusEnum2 = createPgEnum("userStatus");
1092
- var tokenStatusEnum2 = createPgEnum("tokenStatus");
1093
- var tokenTypeEnum2 = createPgEnum("tokenType");
1094
- var studentStatusEnum2 = createPgEnum("studentStatus");
1095
-
1096
- // src/database/schema/index.ts
1097
- var timestamps = {
1098
- createdAt: timestamp("created_at", { mode: "string" }).defaultNow(),
1099
- updatedAt: timestamp("updated_at", { mode: "string" }).defaultNow().$onUpdate(() => sql`CURRENT_TIMESTAMP`)
1134
+ var __metadata2 = function(k, v) {
1135
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1100
1136
  };
1101
- var idField = (length = 5) => text("id").primaryKey().notNull().$defaultFn(() => nanoid(length));
1102
- var rolesTable = pgTable("roles", {
1103
- id: idField(),
1104
- name: text("name").notNull(),
1105
- description: text("description")
1106
- });
1107
- var usersTable = pgTable("users", {
1108
- id: idField(8),
1109
- email: text("email").notNull().unique(),
1110
- emailVerified: boolean("email_verified").default(false),
1111
- password: text("password").notNull(),
1112
- image: text("image").default("noavatar.png"),
1113
- status: userStatusEnum2("status").default("pending"),
1114
- roleId: text("role_id").references(() => rolesTable.id),
1115
- lastLogin: timestamp("last_login", { mode: "string" }),
1116
- ...timestamps
1117
- });
1118
- var tokensTable = pgTable("tokens", {
1119
- id: idField(10),
1120
- userId: text("user_id").references(() => usersTable.id, { onDelete: "cascade" }).unique().notNull(),
1121
- token: text("token").notNull(),
1122
- type: tokenTypeEnum2("type").default("refresh"),
1123
- status: tokenStatusEnum2("status").default("active"),
1124
- expiresAt: timestamp("expires_at", { mode: "string" }).notNull(),
1125
- ...timestamps
1126
- });
1127
- var permissionsTable = pgTable("permissions", {
1128
- id: idField(),
1129
- name: text("name").notNull().unique(),
1130
- description: text("description"),
1131
- resource: text("resource").notNull(),
1132
- action: text("action").notNull(),
1133
- ...timestamps
1134
- });
1135
- var rolePermissionsTable = pgTable("role_permissions", {
1136
- id: idField(),
1137
- roleId: text("role_id").references(() => rolesTable.id).notNull(),
1138
- permissionId: text("permission_id").references(() => permissionsTable.id).notNull(),
1139
- ...timestamps
1140
- });
1141
-
1142
- // src/permissions/PermissionRepository.ts
1143
- import { eq, and } from "drizzle-orm";
1144
- import { Repository } from "najm-api";
1145
- var PermissionRepository = class {
1146
- async getAll() {
1147
- return await this.db.select().from(permissionsTable);
1148
- }
1149
- async getById(id) {
1150
- const [existingPermission] = await this.db.select().from(permissionsTable).where(eq(permissionsTable.id, id));
1151
- return existingPermission;
1152
- }
1153
- async getByName(name) {
1154
- const [existingPermission] = await this.db.select().from(permissionsTable).where(eq(permissionsTable.name, name));
1155
- return existingPermission;
1156
- }
1157
- async create(data) {
1158
- const [newPermission] = await this.db.insert(permissionsTable).values(data).returning();
1159
- return newPermission;
1160
- }
1161
- async update(id, data) {
1162
- const [updatedPermission] = await this.db.update(permissionsTable).set(data).where(eq(permissionsTable.id, id)).returning();
1163
- return updatedPermission;
1164
- }
1165
- async delete(id) {
1166
- const [deletedPermission] = await this.db.delete(permissionsTable).where(eq(permissionsTable.id, id)).returning();
1167
- return deletedPermission;
1168
- }
1169
- async getPermissionsByRole(roleId) {
1170
- return await this.db.select({
1171
- id: permissionsTable.id,
1172
- name: permissionsTable.name,
1173
- description: permissionsTable.description,
1174
- resource: permissionsTable.resource,
1175
- action: permissionsTable.action
1176
- }).from(rolePermissionsTable).leftJoin(permissionsTable, eq(rolePermissionsTable.permissionId, permissionsTable.id)).where(eq(rolePermissionsTable.roleId, roleId));
1177
- }
1178
- async getRolesByPermission(permissionId) {
1179
- return await this.db.select({
1180
- id: rolesTable.id,
1181
- name: rolesTable.name,
1182
- description: rolesTable.description
1183
- }).from(rolePermissionsTable).leftJoin(rolesTable, eq(rolePermissionsTable.roleId, rolesTable.id)).where(eq(rolePermissionsTable.permissionId, permissionId));
1137
+ var _a4;
1138
+ var _b;
1139
+ var _a5;
1140
+ var UserValidator = (_a5 = class {
1141
+ constructor(userRepository, encryptionService) {
1142
+ this.userRepository = userRepository;
1143
+ this.encryptionService = encryptionService;
1184
1144
  }
1185
- async assignPermissionToRole(roleId, permissionId) {
1186
- const [newRolePermission] = await this.db.insert(rolePermissionsTable).values({ roleId, permissionId }).returning();
1187
- return newRolePermission;
1145
+ async validateCreateUser(data) {
1146
+ return parseSchema(userSchema, data);
1188
1147
  }
1189
- async removePermissionFromRole(roleId, permissionId) {
1190
- const [deletedRolePermission] = await this.db.delete(rolePermissionsTable).where(and(eq(rolePermissionsTable.roleId, roleId), eq(rolePermissionsTable.permissionId, permissionId))).returning();
1191
- return deletedRolePermission;
1148
+ async isEmailExists(email) {
1149
+ const existingUser = await this.userRepository.getByEmail(email);
1150
+ return !!existingUser;
1192
1151
  }
1193
- async checkRoleHasPermission(roleId, permissionId) {
1194
- const [rolePermission] = await this.db.select().from(rolePermissionsTable).where(and(eq(rolePermissionsTable.roleId, roleId), eq(rolePermissionsTable.permissionId, permissionId)));
1195
- return !!rolePermission;
1152
+ async isPasswordValid(password, hashedPassword) {
1153
+ const isPasswordValid = await this.encryptionService.comparePassword(password, hashedPassword);
1154
+ return !!isPasswordValid;
1196
1155
  }
1197
- async deleteAll() {
1198
- await this.db.delete(rolePermissionsTable);
1199
- const deletedPermissions = await this.db.delete(permissionsTable).returning();
1200
- return deletedPermissions;
1156
+ async isUserExist(id) {
1157
+ const existingUser = await this.userRepository.getById(id);
1158
+ return !!existingUser;
1201
1159
  }
1202
- };
1203
- PermissionRepository = __decorateClass([
1204
- Repository()
1205
- ], PermissionRepository);
1206
-
1207
- // src/permissions/PermissionGuards.ts
1208
- import { createGuard as createGuard2, Injectable as Injectable5, GuardParams as GuardParams2, Headers as Headers2, Ctx as Ctx2 } from "najm-api";
1209
- var PermissionGuards = class {
1210
- constructor(tokenService) {
1211
- this.tokenService = tokenService;
1160
+ async checkUserIdIsUnique(id) {
1161
+ if (!id)
1162
+ return;
1163
+ const existingUser = await this.userRepository.getById(id);
1164
+ if (existingUser) {
1165
+ throw new Error(t("users.errors.idExists"));
1166
+ }
1212
1167
  }
1213
- async getUserPermissions(auth) {
1214
- const permissions = await this.tokenService.getUserPermissions(auth);
1215
- if (!permissions || !Array.isArray(permissions)) return null;
1216
- return permissions;
1168
+ async isCorrectPass(password) {
1169
+ return password && typeof password === "string" && password.trim().length > 0;
1217
1170
  }
1218
- checkPermissionMatch(permissions, requiredPermission) {
1219
- if (permissions.includes(requiredPermission)) {
1220
- return true;
1221
- }
1222
- const [requiredAction, requiredResource] = requiredPermission.split(":");
1223
- if (requiredAction && requiredResource) {
1224
- if (permissions.includes(`${requiredAction}:*`)) {
1225
- return true;
1226
- }
1227
- if (permissions.includes(`*:${requiredResource}`)) {
1228
- return true;
1229
- }
1171
+ async hasRole(userId, roles) {
1172
+ const roleName = await this.userRepository.getRoleNameById(userId);
1173
+ if (!roleName) {
1174
+ throw Error(t("auth.errors.accessDenied"));
1230
1175
  }
1231
- if (permissions.includes("*:*")) {
1232
- return true;
1176
+ const hasRole = roles.some((item) => roleName.toLowerCase() === item.toLowerCase());
1177
+ if (!hasRole) {
1178
+ throw Error(t("auth.errors.accessDenied"));
1233
1179
  }
1234
- return false;
1235
- }
1236
- async hasPermission(auth, ctx, requiredPermission) {
1237
- await this.tokenService.storeUserInCache(auth, ctx);
1238
- const permissions = await this.getUserPermissions(auth);
1239
- if (!permissions) return false;
1240
- const check = this.checkPermissionMatch(permissions, requiredPermission);
1241
- return check;
1242
- }
1243
- };
1244
- __decorateClass([
1245
- __decorateParam(0, Headers2("authorization")),
1246
- __decorateParam(1, Ctx2()),
1247
- __decorateParam(2, GuardParams2())
1248
- ], PermissionGuards.prototype, "hasPermission", 1);
1249
- PermissionGuards = __decorateClass([
1250
- Injectable5()
1251
- ], PermissionGuards);
1252
- var Permission = (...permissions) => createGuard2(PermissionGuards, "hasPermission")(...permissions);
1253
-
1254
- // src/permissions/PermissionController.ts
1255
- import { Controller as Controller2, Get as Get2, Post as Post2, Put, Delete, Params as Params2, Body as Body2, t as t3 } from "najm-api";
1256
- var PermissionController = class {
1257
- constructor(permissionService) {
1258
- this.permissionService = permissionService;
1259
- }
1260
- async getPermissions() {
1261
- const permissions = await this.permissionService.getAll();
1262
- return {
1263
- data: permissions,
1264
- message: t3("permissions.success.retrieved"),
1265
- status: "success"
1266
- };
1267
- }
1268
- async getPermission(id) {
1269
- const permission = await this.permissionService.getById(id);
1270
- return {
1271
- data: permission,
1272
- message: t3("permissions.success.retrieved"),
1273
- status: "success"
1274
- };
1275
- }
1276
- async create(body) {
1277
- const newPermission = await this.permissionService.create(body);
1278
- return {
1279
- data: newPermission,
1280
- message: t3("permissions.success.created"),
1281
- status: "success"
1282
- };
1283
- }
1284
- async update(id, body) {
1285
- const updatedPermission = await this.permissionService.update(id, body);
1286
- return {
1287
- data: updatedPermission,
1288
- message: t3("permissions.success.updated"),
1289
- status: "success"
1290
- };
1291
- }
1292
- async delete(id) {
1293
- const result = await this.permissionService.delete(id);
1294
- return {
1295
- data: result,
1296
- message: t3("permissions.success.deleted"),
1297
- status: "success"
1298
- };
1299
- }
1300
- async getByRole(roleId) {
1301
- const permissions = await this.permissionService.getPermissionsByRole(roleId);
1302
- return {
1303
- data: permissions,
1304
- message: t3("permissions.success.retrieved"),
1305
- status: "success"
1306
- };
1180
+ return true;
1307
1181
  }
1308
- async getRolesByPermission(permissionId) {
1309
- const roles = await this.permissionService.getRolesByPermission(permissionId);
1310
- return {
1311
- data: roles,
1312
- message: t3("permissions.success.retrieved"),
1313
- status: "success"
1314
- };
1182
+ //======================= throw errors
1183
+ async checkUserExistsByEmail(email) {
1184
+ const user = await this.userRepository.getByEmail(email);
1185
+ if (!user) {
1186
+ throw new Error(t("auth.errors.invalidCredentials"));
1187
+ }
1188
+ return user;
1315
1189
  }
1316
- async assignToRole(roleId, permissionId) {
1317
- const result = await this.permissionService.assignPermissionToRole(roleId, permissionId);
1318
- return {
1319
- data: result,
1320
- message: t3("permissions.success.assigned"),
1321
- status: "success"
1322
- };
1190
+ async checkUserExists(id) {
1191
+ const userExists = await this.isUserExist(id);
1192
+ if (!userExists) {
1193
+ throw new Error(t("users.errors.notFound"));
1194
+ }
1195
+ return userExists;
1323
1196
  }
1324
- async removeFromRole(roleId, permissionId) {
1325
- const result = await this.permissionService.removePermissionFromRole(roleId, permissionId);
1326
- return {
1327
- data: result,
1328
- message: t3("permissions.success.removed"),
1329
- status: "success"
1330
- };
1197
+ async checkEmailUnique(email, excludeId = null) {
1198
+ if (!email)
1199
+ return;
1200
+ const existingUser = await this.userRepository.getByEmail(email);
1201
+ if (existingUser && existingUser.id !== excludeId) {
1202
+ throw new Error(t("auth.errors.emailExists"));
1203
+ }
1331
1204
  }
1332
- async deleteAll() {
1333
- const result = await this.permissionService.deleteAll();
1334
- return {
1335
- data: result,
1336
- message: t3("permissions.success.allDeleted"),
1337
- status: "success"
1338
- };
1205
+ async checkEmailExists(email) {
1206
+ const user = await this.userRepository.getByEmail(email);
1207
+ if (!user) {
1208
+ throw new Error(t("users.errors.notFound"));
1209
+ }
1210
+ return user;
1339
1211
  }
1340
- };
1341
- __decorateClass([
1342
- Get2()
1343
- ], PermissionController.prototype, "getPermissions", 1);
1344
- __decorateClass([
1345
- Get2("/:id"),
1346
- __decorateParam(0, Params2("id"))
1347
- ], PermissionController.prototype, "getPermission", 1);
1348
- __decorateClass([
1349
- Post2(),
1350
- __decorateParam(0, Body2())
1351
- ], PermissionController.prototype, "create", 1);
1352
- __decorateClass([
1353
- Put("/:id"),
1354
- __decorateParam(0, Params2("id")),
1355
- __decorateParam(1, Body2())
1356
- ], PermissionController.prototype, "update", 1);
1357
- __decorateClass([
1358
- Delete("/:id"),
1359
- __decorateParam(0, Params2("id"))
1360
- ], PermissionController.prototype, "delete", 1);
1361
- __decorateClass([
1362
- Get2("/role/:roleId"),
1363
- __decorateParam(0, Params2("roleId"))
1364
- ], PermissionController.prototype, "getByRole", 1);
1365
- __decorateClass([
1366
- Get2("/roles/:permissionId"),
1367
- __decorateParam(0, Params2("permissionId"))
1368
- ], PermissionController.prototype, "getRolesByPermission", 1);
1369
- __decorateClass([
1370
- Post2("/assign/:roleId/:permissionId"),
1371
- __decorateParam(0, Params2("roleId")),
1372
- __decorateParam(1, Params2("permissionId"))
1373
- ], PermissionController.prototype, "assignToRole", 1);
1374
- __decorateClass([
1375
- Delete("/remove/:roleId/:permissionId"),
1376
- __decorateParam(0, Params2("roleId")),
1377
- __decorateParam(1, Params2("permissionId"))
1378
- ], PermissionController.prototype, "removeFromRole", 1);
1379
- __decorateClass([
1380
- Delete(),
1381
- isAdmin()
1382
- ], PermissionController.prototype, "deleteAll", 1);
1383
- PermissionController = __decorateClass([
1384
- Controller2("/permissions"),
1385
- isAdmin()
1386
- ], PermissionController);
1387
-
1388
- // src/permissions/PermissionService.ts
1389
- import { Injectable as Injectable6 } from "najm-api";
1390
- var PermissionService = class {
1391
- constructor(permissionRepository, permissionValidator, roleService) {
1392
- this.permissionRepository = permissionRepository;
1393
- this.permissionValidator = permissionValidator;
1394
- this.roleService = roleService;
1212
+ async checkPasswordValid(password, hashedPassword) {
1213
+ const isPasswordValid = await this.isPasswordValid(password, hashedPassword);
1214
+ if (!isPasswordValid) {
1215
+ throw new Error(t("auth.errors.invalidCredentials"));
1216
+ }
1395
1217
  }
1218
+ }, __name(_a5, "UserValidator"), _a5);
1219
+ UserValidator = __decorate4([
1220
+ Injectable3(),
1221
+ __metadata2("design:paramtypes", [typeof (_a4 = typeof UserRepository !== "undefined" && UserRepository) === "function" ? _a4 : Object, typeof (_b = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _b : Object])
1222
+ ], UserValidator);
1223
+
1224
+ // src/users/UserService.ts
1225
+ import { Injectable as Injectable8, setLanguage, getCurrentLanguage, Transactional } from "najm-api";
1226
+
1227
+ // src/roles/RoleRepository.ts
1228
+ import { eq as eq2 } from "drizzle-orm";
1229
+ import { Repository as Repository2 } from "najm-api";
1230
+ var __decorate5 = function(decorators, target, key, desc) {
1231
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1232
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1233
+ 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;
1234
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1235
+ };
1236
+ var _a6;
1237
+ var RoleRepository = (_a6 = class {
1396
1238
  async getAll() {
1397
- return await this.permissionRepository.getAll();
1239
+ return await this.db.select().from(rolesTable);
1398
1240
  }
1399
1241
  async getById(id) {
1400
- await this.permissionValidator.checkPermissionExists(id);
1401
- return await this.permissionRepository.getById(id);
1242
+ const [existingRole] = await this.db.select().from(rolesTable).where(eq2(rolesTable.id, id));
1243
+ return existingRole;
1402
1244
  }
1403
1245
  async getByName(name) {
1404
- return await this.permissionRepository.getByName(name);
1405
- }
1406
- async getByResource(resource) {
1407
- return await this.permissionRepository.getAll().then(
1408
- (permissions) => permissions.filter((p) => p.resource === resource)
1409
- );
1246
+ const [existingRole] = await this.db.select().from(rolesTable).where(eq2(rolesTable.name, name));
1247
+ return existingRole;
1410
1248
  }
1411
1249
  async create(data) {
1412
- await this.permissionValidator.validateCreatePermission(data);
1413
- await this.permissionValidator.checkPermissionNameUnique(data.name);
1414
- return await this.permissionRepository.create(data);
1250
+ const [newRole] = await this.db.insert(rolesTable).values(data).returning();
1251
+ return newRole;
1415
1252
  }
1416
1253
  async update(id, data) {
1417
- await this.permissionValidator.checkPermissionExists(id);
1418
- await this.permissionValidator.checkPermissionNameUnique(data.name, id);
1419
- return await this.permissionRepository.update(id, data);
1254
+ const [updatedRole] = await this.db.update(rolesTable).set(data).where(eq2(rolesTable.id, id)).returning();
1255
+ return updatedRole;
1420
1256
  }
1421
1257
  async delete(id) {
1422
- await this.permissionValidator.checkPermissionExists(id);
1423
- return await this.permissionRepository.delete(id);
1258
+ const [deletedRole] = await this.db.delete(rolesTable).where(eq2(rolesTable.id, id)).returning();
1259
+ return deletedRole;
1424
1260
  }
1425
- async getPermissionsByRole(roleId) {
1426
- return await this.permissionRepository.getPermissionsByRole(roleId);
1261
+ }, __name(_a6, "RoleRepository"), _a6);
1262
+ RoleRepository = __decorate5([
1263
+ Repository2()
1264
+ ], RoleRepository);
1265
+
1266
+ // src/roles/RoleValidator.ts
1267
+ import { Injectable as Injectable4, t as t2 } from "najm-api";
1268
+ var __decorate6 = function(decorators, target, key, desc) {
1269
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1270
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1271
+ 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;
1272
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1273
+ };
1274
+ var __metadata3 = function(k, v) {
1275
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1276
+ };
1277
+ var _a7;
1278
+ var _a8;
1279
+ var RoleValidator = (_a8 = class {
1280
+ constructor(roleRepository) {
1281
+ this.roleRepository = roleRepository;
1427
1282
  }
1428
- async getRolesByPermission(permissionId) {
1429
- await this.permissionValidator.checkPermissionExists(permissionId);
1430
- return await this.permissionRepository.getRolesByPermission(permissionId);
1283
+ async validateCreateRole(data) {
1284
+ return parseSchema(roleSchema, data);
1431
1285
  }
1432
- async assignPermissionToRole(roleId, permissionId) {
1433
- await this.permissionValidator.checkRoleHasPermission(roleId, permissionId);
1434
- return await this.permissionRepository.assignPermissionToRole(roleId, permissionId);
1286
+ async isRoleNameExists(roleName) {
1287
+ const existingRole = await this.roleRepository.getByName(roleName);
1288
+ return !!existingRole;
1435
1289
  }
1436
- async removePermissionFromRole(roleId, permissionId) {
1437
- return await this.permissionRepository.removePermissionFromRole(roleId, permissionId);
1290
+ async isRoleIdExists(id) {
1291
+ const existingRole = await this.roleRepository.getById(id);
1292
+ return !!existingRole;
1438
1293
  }
1439
- async seedDefaultPermissions(defaultPermissions) {
1440
- const createdPermissions = [];
1441
- for (const permission of defaultPermissions) {
1442
- try {
1443
- const permissionEntity = await this.create(permission);
1444
- createdPermissions.push(permissionEntity);
1445
- } catch (error) {
1446
- continue;
1447
- }
1294
+ async checkNameUnique(roleName, excludeId = null) {
1295
+ if (!roleName)
1296
+ return;
1297
+ const existingRole = await this.roleRepository.getByName(roleName);
1298
+ if (existingRole && existingRole.id !== excludeId) {
1299
+ throw new Error(t2("roles.errors.exists"));
1448
1300
  }
1449
- return createdPermissions;
1450
1301
  }
1451
- async seedDefaultRolePermissions(defaultRolePermissions) {
1452
- const results = [];
1453
- for (const { roleName, permissions } of defaultRolePermissions) {
1454
- try {
1455
- await this.permissionValidator.checkRoleExistsByName(roleName);
1456
- const role = await this.roleService.getByName(roleName);
1457
- for (const permissionName of permissions) {
1458
- try {
1459
- await this.permissionValidator.checkPermissionExistsByName(permissionName);
1460
- const permission = await this.getByName(permissionName);
1461
- await this.permissionValidator.checkRoleHasPermission(role.id, permission.id);
1462
- await this.assignPermissionToRole(role.id, permission.id);
1463
- results.push({ role: roleName, permission: permissionName });
1464
- } catch (error) {
1465
- continue;
1466
- }
1467
- }
1468
- } catch (error) {
1469
- continue;
1470
- }
1302
+ async checkRoleExists(id) {
1303
+ const roleIdExists = await this.isRoleIdExists(id);
1304
+ if (!roleIdExists) {
1305
+ throw new Error(t2("roles.errors.notFound"));
1471
1306
  }
1472
- return results;
1473
1307
  }
1474
- async deleteAll() {
1475
- return await this.permissionRepository.deleteAll();
1308
+ async checkRoleExistsByName(roleName) {
1309
+ const roleNameExists = await this.isRoleNameExists(roleName);
1310
+ if (!roleNameExists) {
1311
+ throw new Error(t2("roles.errors.notFound"));
1312
+ }
1476
1313
  }
1477
- };
1478
- PermissionService = __decorateClass([
1479
- Injectable6()
1480
- ], PermissionService);
1314
+ async checkAdminRoleExists() {
1315
+ const adminRole = await this.roleRepository.getByName("admin");
1316
+ if (!adminRole) {
1317
+ throw new Error(t2("users.errors.adminRoleNotFound"));
1318
+ }
1319
+ return adminRole;
1320
+ }
1321
+ }, __name(_a8, "RoleValidator"), _a8);
1322
+ RoleValidator = __decorate6([
1323
+ Injectable4(),
1324
+ __metadata3("design:paramtypes", [typeof (_a7 = typeof RoleRepository !== "undefined" && RoleRepository) === "function" ? _a7 : Object])
1325
+ ], RoleValidator);
1481
1326
 
1482
- // src/permissions/PermissionValidator.ts
1483
- import { Injectable as Injectable7, t as t4 } from "najm-api";
1327
+ // src/roles/RoleGuards.ts
1328
+ import { Injectable as Injectable6, Headers, createGuard, GuardParams, Ctx } from "najm-api";
1484
1329
 
1485
- // src/shared/index.ts
1486
- import * as fs from "fs/promises";
1487
- import * as path from "path";
1488
- import _isEmpty from "lodash.isempty";
1489
- var avatarsPath = path.join(process.cwd(), "avatars");
1490
- var parseSchema = async (schema, data) => {
1491
- try {
1492
- return await schema.parseAsync(data);
1493
- } catch (error) {
1494
- const errors = error.issues || error.errors || [];
1495
- const errorMessage = errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
1496
- throw new Error(errorMessage);
1497
- }
1330
+ // src/tokens/TokenRepository.ts
1331
+ import { eq as eq3 } from "drizzle-orm";
1332
+ import { Repository as Repository3 } from "najm-api";
1333
+ var __decorate7 = function(decorators, target, key, desc) {
1334
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1335
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1336
+ 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;
1337
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1498
1338
  };
1499
- var clean = (obj) => {
1500
- const cleaned = {};
1501
- for (const [key, value] of Object.entries(obj)) {
1502
- if (value !== null && value !== void 0 && value !== "") {
1503
- cleaned[key] = value;
1504
- }
1339
+ var _a9;
1340
+ var TokenRepository = (_a9 = class {
1341
+ async storeRefreshToken(tokenData) {
1342
+ return await this.db.insert(tokensTable).values(tokenData).onConflictDoUpdate({
1343
+ target: tokensTable.userId,
1344
+ set: {
1345
+ token: tokenData.token,
1346
+ expiresAt: tokenData.expiresAt
1347
+ }
1348
+ }).returning();
1505
1349
  }
1506
- return cleaned;
1507
- };
1508
- var getAvatarFile = async (fileName) => {
1509
- try {
1510
- const filePath = path.join(avatarsPath, fileName);
1511
- const buffer = await fs.readFile(filePath);
1512
- const file = new File([buffer], fileName, {
1513
- type: "image/png"
1514
- });
1515
- return file;
1516
- } catch (error) {
1517
- return null;
1350
+ async getRefreshToken(userId) {
1351
+ const [token] = await this.db.select().from(tokensTable).where(eq3(tokensTable.userId, userId));
1352
+ return token?.token;
1518
1353
  }
1519
- };
1520
- var formatDate = (dateValue) => {
1521
- if (!dateValue) return null;
1522
- let date;
1523
- if (dateValue instanceof Date) {
1524
- date = dateValue;
1525
- } else if (typeof dateValue === "string") {
1526
- date = new Date(dateValue);
1527
- } else {
1528
- return null;
1354
+ async revokeToken(userId) {
1355
+ const [deletedToken] = await this.db.delete(tokensTable).where(eq3(tokensTable.userId, userId)).returning();
1356
+ return deletedToken;
1529
1357
  }
1530
- if (isNaN(date.getTime())) return null;
1531
- return date.toISOString().split("T")[0];
1358
+ async isUserExists(userId) {
1359
+ const [user] = await this.db.select({ id: usersTable.id }).from(usersTable).where(eq3(usersTable.id, userId)).limit(1);
1360
+ return !!user;
1361
+ }
1362
+ async getRoleNameById(userId) {
1363
+ const [role] = await this.db.select({
1364
+ roleName: rolesTable.name
1365
+ }).from(usersTable).leftJoin(rolesTable, eq3(usersTable.roleId, rolesTable.id)).where(eq3(usersTable.id, userId)).limit(1);
1366
+ return role?.roleName;
1367
+ }
1368
+ async getUserPermissions(userId) {
1369
+ const [user] = await this.db.select({ roleId: usersTable.roleId }).from(usersTable).where(eq3(usersTable.id, userId)).limit(1);
1370
+ if (!user || !user.roleId)
1371
+ return [];
1372
+ const userPermissions = await this.db.select({
1373
+ name: permissionsTable.name
1374
+ }).from(rolePermissionsTable).leftJoin(permissionsTable, eq3(rolePermissionsTable.permissionId, permissionsTable.id)).where(eq3(rolePermissionsTable.roleId, user.roleId));
1375
+ return userPermissions.map((p) => p.name).filter((name) => name);
1376
+ }
1377
+ async getUser(userId) {
1378
+ const [user] = await this.db.select({
1379
+ id: usersTable.id,
1380
+ email: usersTable.email,
1381
+ status: usersTable.status,
1382
+ roleId: usersTable.roleId,
1383
+ roleName: rolesTable.name,
1384
+ createdAt: usersTable.createdAt,
1385
+ updatedAt: usersTable.updatedAt
1386
+ }).from(usersTable).leftJoin(rolesTable, eq3(usersTable.roleId, rolesTable.id)).where(eq3(usersTable.id, userId)).limit(1);
1387
+ return user ? { ...user, role: user.roleName } : null;
1388
+ }
1389
+ }, __name(_a9, "TokenRepository"), _a9);
1390
+ TokenRepository = __decorate7([
1391
+ Repository3()
1392
+ ], TokenRepository);
1393
+
1394
+ // src/tokens/TokenService.ts
1395
+ import { t as t3 } from "najm-api";
1396
+ import { getCookie, Injectable as Injectable5 } from "najm-api";
1397
+ import jwt from "jsonwebtoken";
1398
+ import { jwtDecode } from "jwt-decode";
1399
+ import timestring2 from "timestring";
1400
+ var __decorate8 = function(decorators, target, key, desc) {
1401
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1402
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1403
+ 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;
1404
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1405
+ };
1406
+ var __metadata4 = function(k, v) {
1407
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1532
1408
  };
1533
- function calculateAge(dateOfBirth) {
1534
- if (!dateOfBirth) return null;
1535
- const formattedDate = formatDate(dateOfBirth);
1536
- if (!formattedDate) return null;
1537
- const birth = new Date(formattedDate);
1538
- const today = /* @__PURE__ */ new Date();
1539
- let age = today.getFullYear() - birth.getFullYear();
1540
- const monthDiff = today.getMonth() - birth.getMonth();
1541
- if (monthDiff < 0 || monthDiff === 0 && today.getDate() < birth.getDate()) {
1542
- age--;
1409
+ var _a10;
1410
+ var _a11;
1411
+ var TokenService = (_a11 = class {
1412
+ constructor(tokenRepository) {
1413
+ this.tokenRepository = tokenRepository;
1414
+ this.accessSecretKey = process.env.JWT_ACCESS_SECRET;
1415
+ this.accessExpiresIn = process.env.ACCESS_EXPIRES_IN;
1416
+ this.refreshSecretKey = process.env.JWT_REFRESH_SECRET;
1417
+ this.refreshExpiresIn = process.env.REFRESH_EXPIRES_IN;
1543
1418
  }
1544
- return age;
1545
- }
1546
- function calculateYearsOfExperience(hireDate) {
1547
- if (!hireDate) return null;
1548
- const formattedDate = formatDate(hireDate);
1549
- if (!formattedDate) return null;
1550
- const hire = new Date(formattedDate);
1551
- const today = /* @__PURE__ */ new Date();
1552
- let years = today.getFullYear() - hire.getFullYear();
1553
- const monthDiff = today.getMonth() - hire.getMonth();
1554
- if (monthDiff < 0 || monthDiff === 0 && today.getDate() < hire.getDate()) {
1555
- years--;
1419
+ //==== Validate tokens
1420
+ extractAccessToken(authorization) {
1421
+ if (authorization && authorization.startsWith("Bearer")) {
1422
+ return authorization.split(" ")[1];
1423
+ }
1424
+ throw new Error(t3("auth.errors.tokenMissing"));
1556
1425
  }
1557
- return years;
1558
- }
1559
- function pickProps(source, keys) {
1560
- const result = {};
1561
- for (const key of keys) {
1562
- if (source[key] !== void 0) {
1563
- result[key] = source[key];
1426
+ verifyAccessToken(token) {
1427
+ try {
1428
+ return jwt.verify(token, this.accessSecretKey);
1429
+ } catch (error) {
1430
+ throw new Error(t3("auth.errors.tokenVerificationFailed"));
1564
1431
  }
1565
1432
  }
1566
- return result;
1567
- }
1568
- var isEmpty = _isEmpty;
1569
- var isPath = (img) => typeof img === "string" && img.trim().length > 0 && (img.startsWith("/") || img.startsWith("http") || img.startsWith("storage/"));
1570
- var isFile = (img) => !!img && typeof img !== "string" && img instanceof File;
1571
-
1572
- // src/permissions/PermissionValidator.ts
1573
- import { z as z3 } from "zod";
1574
- var permissionSchema = z3.object({
1575
- name: z3.string().min(1, "Permission name is required"),
1576
- description: z3.string().optional(),
1577
- resource: z3.string().min(1, "Resource is required"),
1578
- action: z3.string().min(1, "Action is required")
1579
- });
1580
- var PermissionValidator = class {
1581
- constructor(permissionRepository, roleValidator) {
1582
- this.permissionRepository = permissionRepository;
1583
- this.roleValidator = roleValidator;
1433
+ verifyRefreshToken(token) {
1434
+ try {
1435
+ const decoded = jwt.verify(token, this.refreshSecretKey);
1436
+ return decoded.userId;
1437
+ } catch (error) {
1438
+ throw new Error(t3("auth.errors.tokenVerificationFailed"));
1439
+ }
1584
1440
  }
1585
- async validateCreatePermission(data) {
1586
- return parseSchema(permissionSchema, data);
1441
+ async getUserIdByAccessToken(header) {
1442
+ const token = this.extractAccessToken(header);
1443
+ const decodedToken = this.verifyAccessToken(token);
1444
+ const userId = decodedToken.userId;
1445
+ const userExists = await this.tokenRepository.isUserExists(userId);
1446
+ if (!userExists) {
1447
+ throw new Error(t3("users.errors.notFound"));
1448
+ }
1449
+ return userId;
1587
1450
  }
1588
- async isPermissionExists(id) {
1589
- const existingPermission = await this.permissionRepository.getById(id);
1590
- return !!existingPermission;
1451
+ //=== Generate tokens
1452
+ async storeRefreshToken(userId, refreshToken) {
1453
+ const expireInSecond = timestring2(this.refreshExpiresIn, "s");
1454
+ const tokenData = {
1455
+ userId,
1456
+ token: refreshToken,
1457
+ expiresAt: new Date(Date.now() + expireInSecond * 1e3).toISOString()
1458
+ };
1459
+ await this.tokenRepository.storeRefreshToken(tokenData);
1591
1460
  }
1592
- async isPermissionNameExists(name) {
1593
- const existingPermission = await this.permissionRepository.getByName(name);
1594
- return !!existingPermission;
1461
+ getTokenExpire(token) {
1462
+ return jwtDecode(token).exp;
1595
1463
  }
1596
- //======================= throw errors
1597
- async checkPermissionExists(id) {
1598
- const permissionExists = await this.isPermissionExists(id);
1599
- if (!permissionExists) {
1600
- throw new Error(t4("permissions.errors.notFound"));
1601
- }
1602
- return permissionExists;
1464
+ generateAccessToken(data) {
1465
+ const options = { expiresIn: this.accessExpiresIn };
1466
+ return jwt.sign(data, this.accessSecretKey, options);
1603
1467
  }
1604
- async checkPermissionExistsByName(name) {
1605
- const permissionExists = await this.isPermissionNameExists(name);
1606
- if (!permissionExists) {
1607
- throw new Error(t4("permissions.errors.notFound"));
1608
- }
1609
- return permissionExists;
1468
+ generateRefreshToken(data) {
1469
+ const options = { expiresIn: this.refreshExpiresIn };
1470
+ return jwt.sign(data, this.refreshSecretKey, options);
1610
1471
  }
1611
- async checkPermissionNameUnique(name, excludeId = null) {
1612
- if (!name) return;
1613
- const existingPermission = await this.permissionRepository.getByName(name);
1614
- if (existingPermission && existingPermission.id !== excludeId) {
1615
- throw new Error(t4("permissions.errors.nameExists"));
1472
+ async generateTokens(userId) {
1473
+ const tokenData = { userId };
1474
+ const accessToken = await this.generateAccessToken(tokenData);
1475
+ const refreshToken = await this.generateRefreshToken(tokenData);
1476
+ const accessTokenExpiresAt = this.getTokenExpire(accessToken);
1477
+ const refreshTokenExpiresAt = this.getTokenExpire(refreshToken);
1478
+ await this.storeRefreshToken(userId, refreshToken);
1479
+ return {
1480
+ accessToken,
1481
+ refreshToken,
1482
+ accessTokenExpiresAt,
1483
+ refreshTokenExpiresAt
1484
+ };
1485
+ }
1486
+ async refreshTokens() {
1487
+ const newRefreshToken = getCookie("refreshToken");
1488
+ const userId = this.verifyRefreshToken(newRefreshToken);
1489
+ const userExists = await this.tokenRepository.isUserExists(userId);
1490
+ if (!userExists) {
1491
+ throw new Error(t3("users.errors.notFound"));
1492
+ }
1493
+ const storedRefreshToken = await this.tokenRepository.getRefreshToken(userId);
1494
+ if (newRefreshToken != storedRefreshToken) {
1495
+ throw new Error(t3("auth.errors.refreshTokenInvalid"));
1616
1496
  }
1497
+ return await this.generateTokens(userId);
1617
1498
  }
1618
- async checkRoleExists(id) {
1619
- return await this.roleValidator.checkRoleExists(id);
1499
+ async revokeToken(userId) {
1500
+ return await this.tokenRepository.revokeToken(userId);
1620
1501
  }
1621
- async checkRoleExistsByName(name) {
1622
- return await this.roleValidator.checkRoleExistsByName(name);
1502
+ async getUserPermissions(auth) {
1503
+ if (!auth)
1504
+ return;
1505
+ const userId = await this.getUserIdByAccessToken(auth);
1506
+ const permissions = await this.tokenRepository.getUserPermissions(userId);
1507
+ return permissions;
1623
1508
  }
1624
- async checkRoleHasPermission(roleId, permissionId) {
1625
- await this.roleValidator.checkRoleExists(roleId);
1626
- await this.checkPermissionExists(permissionId);
1627
- const hasPermission = await this.permissionRepository.checkRoleHasPermission(roleId, permissionId);
1628
- if (hasPermission) {
1629
- throw new Error(t4("permissions.errors.roleAlreadyHasPermission"));
1509
+ async getUserRole(auth) {
1510
+ if (!auth)
1511
+ return;
1512
+ const userId = await this.getUserIdByAccessToken(auth);
1513
+ const roleName = await this.tokenRepository.getRoleNameById(userId);
1514
+ return roleName;
1515
+ }
1516
+ async getUser(auth) {
1517
+ if (!auth)
1518
+ return;
1519
+ const userId = await this.getUserIdByAccessToken(auth);
1520
+ const user = await this.tokenRepository.getUser(userId);
1521
+ if (!user)
1522
+ return null;
1523
+ return user;
1524
+ }
1525
+ async storeUserInCache(auth, ctx) {
1526
+ const cachedUser = ctx.get("user");
1527
+ if (cachedUser)
1528
+ return cachedUser;
1529
+ const user = await this.getUser(auth);
1530
+ if (user) {
1531
+ ctx.set("user", user);
1630
1532
  }
1533
+ return user;
1631
1534
  }
1632
- };
1633
- PermissionValidator = __decorateClass([
1634
- Injectable7()
1635
- ], PermissionValidator);
1535
+ }, __name(_a11, "TokenService"), _a11);
1536
+ TokenService = __decorate8([
1537
+ Injectable5(),
1538
+ __metadata4("design:paramtypes", [typeof (_a10 = typeof TokenRepository !== "undefined" && TokenRepository) === "function" ? _a10 : Object])
1539
+ ], TokenService);
1636
1540
 
1637
- // src/roles/RoleRepository.ts
1638
- import { eq as eq2 } from "drizzle-orm";
1639
- import { Repository as Repository2 } from "najm-api";
1640
- var RoleRepository = class {
1641
- async getAll() {
1642
- return await this.db.select().from(rolesTable);
1541
+ // src/roles/RoleGuards.ts
1542
+ var __decorate9 = function(decorators, target, key, desc) {
1543
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1544
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1545
+ 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;
1546
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1547
+ };
1548
+ var __metadata5 = function(k, v) {
1549
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1550
+ };
1551
+ var __param = function(paramIndex, decorator) {
1552
+ return function(target, key) {
1553
+ decorator(target, key, paramIndex);
1554
+ };
1555
+ };
1556
+ var _a12;
1557
+ var ROLES = {
1558
+ ADMIN: "admin",
1559
+ PRINCIPAL: "principal",
1560
+ ACCOUNTING: "accounting",
1561
+ SECRETARY: "secretary",
1562
+ TEACHER: "teacher",
1563
+ STUDENT: "student",
1564
+ PARENT: "parent"
1565
+ };
1566
+ var ROLE_GROUPS = {
1567
+ ADMINISTRATORS: [ROLES.ADMIN, ROLES.PRINCIPAL],
1568
+ FINANCIAL: [ROLES.ADMIN, ROLES.ACCOUNTING],
1569
+ STAFF: [ROLES.ADMIN, ROLES.PRINCIPAL, ROLES.ACCOUNTING, ROLES.SECRETARY, ROLES.TEACHER],
1570
+ END_USERS: [ROLES.STUDENT, ROLES.PARENT],
1571
+ ALL: [ROLES.ADMIN, ROLES.PRINCIPAL, ROLES.ACCOUNTING, ROLES.SECRETARY, ROLES.TEACHER, ROLES.STUDENT, ROLES.PARENT]
1572
+ };
1573
+ var _a13;
1574
+ var RoleChecker = (_a13 = class {
1575
+ isInGroup(userRole, group) {
1576
+ return group.includes(userRole?.toLowerCase());
1643
1577
  }
1644
- async getById(id) {
1645
- const [existingRole] = await this.db.select().from(rolesTable).where(eq2(rolesTable.id, id));
1646
- return existingRole;
1578
+ isAdministrator(userRole) {
1579
+ return this.isInGroup(userRole, ROLE_GROUPS.ADMINISTRATORS);
1647
1580
  }
1648
- async getByName(name) {
1649
- const [existingRole] = await this.db.select().from(rolesTable).where(eq2(rolesTable.name, name));
1650
- return existingRole;
1581
+ isStaff(userRole) {
1582
+ return this.isInGroup(userRole, ROLE_GROUPS.STAFF);
1651
1583
  }
1652
- async create(data) {
1653
- const [newRole] = await this.db.insert(rolesTable).values(data).returning();
1654
- return newRole;
1584
+ hasAnyRole(userRole, roles) {
1585
+ return roles.includes(userRole?.toLowerCase());
1655
1586
  }
1656
- async update(id, data) {
1657
- const [updatedRole] = await this.db.update(rolesTable).set(data).where(eq2(rolesTable.id, id)).returning();
1658
- return updatedRole;
1587
+ hasExactRole(userRole, requiredRole) {
1588
+ return userRole?.toLowerCase() === requiredRole?.toLowerCase();
1659
1589
  }
1660
- async delete(id) {
1661
- const [deletedRole] = await this.db.delete(rolesTable).where(eq2(rolesTable.id, id)).returning();
1662
- return deletedRole;
1590
+ }, __name(_a13, "RoleChecker"), _a13);
1591
+ RoleChecker = __decorate9([
1592
+ Injectable6()
1593
+ ], RoleChecker);
1594
+ var _a14;
1595
+ var RoleGuards = (_a14 = class {
1596
+ constructor(roleChecker, tokenService) {
1597
+ this.roleChecker = roleChecker;
1598
+ this.tokenService = tokenService;
1663
1599
  }
1664
- };
1665
- RoleRepository = __decorateClass([
1666
- Repository2()
1667
- ], RoleRepository);
1600
+ async isAuth(auth, ctx) {
1601
+ const user = await this.tokenService.storeUserInCache(auth, ctx);
1602
+ return !!user;
1603
+ }
1604
+ async hasRoles(auth, ctx, roles) {
1605
+ try {
1606
+ const user = await this.tokenService.storeUserInCache(auth, ctx);
1607
+ if (!user?.role)
1608
+ return false;
1609
+ const roleArray = Array.isArray(roles) ? roles : [roles];
1610
+ return this.roleChecker.hasAnyRole(user.role, roleArray);
1611
+ } catch {
1612
+ return false;
1613
+ }
1614
+ }
1615
+ }, __name(_a14, "RoleGuards"), _a14);
1616
+ __decorate9([
1617
+ __param(0, Headers("authorization")),
1618
+ __param(1, Ctx()),
1619
+ __metadata5("design:type", Function),
1620
+ __metadata5("design:paramtypes", [Object, Object]),
1621
+ __metadata5("design:returntype", Promise)
1622
+ ], RoleGuards.prototype, "isAuth", null);
1623
+ __decorate9([
1624
+ __param(0, Headers("authorization")),
1625
+ __param(1, Ctx()),
1626
+ __param(2, GuardParams()),
1627
+ __metadata5("design:type", Function),
1628
+ __metadata5("design:paramtypes", [Object, Object, Object]),
1629
+ __metadata5("design:returntype", Promise)
1630
+ ], RoleGuards.prototype, "hasRoles", null);
1631
+ RoleGuards = __decorate9([
1632
+ Injectable6(),
1633
+ __metadata5("design:paramtypes", [RoleChecker, typeof (_a12 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a12 : Object])
1634
+ ], RoleGuards);
1635
+ var isAdmin = /* @__PURE__ */ __name(() => Role("admin"), "isAdmin");
1636
+ var isPrincipal = /* @__PURE__ */ __name(() => Role("principal"), "isPrincipal");
1637
+ var isAccounting = /* @__PURE__ */ __name(() => Role("accounting"), "isAccounting");
1638
+ var isSecretary = /* @__PURE__ */ __name(() => Role("secretary"), "isSecretary");
1639
+ var isTeacher = /* @__PURE__ */ __name(() => Role("teacher"), "isTeacher");
1640
+ var isParent = /* @__PURE__ */ __name(() => Role("parent"), "isParent");
1641
+ var isStudent = /* @__PURE__ */ __name(() => Role("student"), "isStudent");
1642
+ var isAdministrator = /* @__PURE__ */ __name(() => Role("admin", "principal"), "isAdministrator");
1643
+ var isFinancial = /* @__PURE__ */ __name(() => Role("admin", "accounting"), "isFinancial");
1644
+ var isStaff = /* @__PURE__ */ __name(() => Role("admin", "principal", "accounting", "secretary", "teacher"), "isStaff");
1645
+ var isAuth = createGuard(RoleGuards, "isAuth");
1646
+ var Role = /* @__PURE__ */ __name((...roles) => createGuard(RoleGuards, "hasRoles")(...roles), "Role");
1668
1647
 
1669
- // src/roles/RoleValidator.ts
1670
- import { Injectable as Injectable8, t as t5 } from "najm-api";
1671
- var RoleValidator = class {
1672
- constructor(roleRepository) {
1648
+ // src/roles/RoleController.ts
1649
+ import { Controller, Get, Post, Put, Delete, Params, Body, t as t4 } from "najm-api";
1650
+
1651
+ // src/roles/RoleService.ts
1652
+ import { Injectable as Injectable7 } from "najm-api";
1653
+ var __decorate10 = function(decorators, target, key, desc) {
1654
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1655
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1656
+ 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;
1657
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1658
+ };
1659
+ var __metadata6 = function(k, v) {
1660
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1661
+ };
1662
+ var _a15;
1663
+ var _b2;
1664
+ var _a16;
1665
+ var RoleService = (_a16 = class {
1666
+ constructor(roleRepository, roleValidator) {
1673
1667
  this.roleRepository = roleRepository;
1668
+ this.roleValidator = roleValidator;
1674
1669
  }
1675
- async validateCreateRole(data) {
1676
- return parseSchema(roleSchema, data);
1670
+ async getAll() {
1671
+ return await this.roleRepository.getAll();
1672
+ }
1673
+ async getById(id) {
1674
+ await this.roleValidator.checkRoleExists(id);
1675
+ return await this.roleRepository.getById(id);
1677
1676
  }
1678
- async isRoleNameExists(roleName) {
1679
- const existingRole = await this.roleRepository.getByName(roleName);
1680
- return !!existingRole;
1677
+ async getByName(name) {
1678
+ return await this.roleRepository.getByName(name);
1681
1679
  }
1682
- async isRoleIdExists(id) {
1683
- const existingRole = await this.roleRepository.getById(id);
1684
- return !!existingRole;
1680
+ async create(data) {
1681
+ await this.roleValidator.validateCreateRole(data);
1682
+ await this.roleValidator.checkNameUnique(data.name);
1683
+ return await this.roleRepository.create(data);
1685
1684
  }
1686
- async checkNameUnique(roleName, excludeId = null) {
1687
- if (!roleName) return;
1688
- const existingRole = await this.roleRepository.getByName(roleName);
1689
- if (existingRole && existingRole.id !== excludeId) {
1690
- throw new Error(t5("roles.errors.exists"));
1691
- }
1685
+ async update(id, data) {
1686
+ await this.roleValidator.checkRoleExists(id);
1687
+ await this.roleValidator.checkNameUnique(data.name, id);
1688
+ return await this.roleRepository.update(id, data);
1692
1689
  }
1693
- async checkRoleExists(id) {
1694
- const roleIdExists = await this.isRoleIdExists(id);
1695
- if (!roleIdExists) {
1696
- throw new Error(t5("roles.errors.notFound"));
1697
- }
1690
+ async delete(id) {
1691
+ await this.roleValidator.checkRoleExists(id);
1692
+ return await this.roleRepository.delete(id);
1698
1693
  }
1699
- async checkRoleExistsByName(roleName) {
1700
- const roleNameExists = await this.isRoleNameExists(roleName);
1701
- if (!roleNameExists) {
1702
- throw new Error(t5("roles.errors.notFound"));
1694
+ async seedDefaultRoles(defaultRoles) {
1695
+ const rolesToCreate = [];
1696
+ for (const role of defaultRoles) {
1697
+ const exists = await this.roleValidator.isRoleNameExists(role.name);
1698
+ if (!exists) {
1699
+ rolesToCreate.push(role);
1700
+ }
1703
1701
  }
1702
+ const createdRoles = await Promise.all(rolesToCreate.map((role) => this.roleRepository.create(role)));
1703
+ return createdRoles;
1704
1704
  }
1705
- async checkAdminRoleExists() {
1706
- const adminRole = await this.roleRepository.getByName("admin");
1707
- if (!adminRole) {
1708
- throw new Error(t5("users.errors.adminRoleNotFound"));
1709
- }
1710
- return adminRole;
1705
+ async getRoleIdByName(name) {
1706
+ const teacherRole = await this.getByName(name);
1707
+ return teacherRole?.id;
1711
1708
  }
1712
- };
1713
- RoleValidator = __decorateClass([
1714
- Injectable8()
1715
- ], RoleValidator);
1709
+ }, __name(_a16, "RoleService"), _a16);
1710
+ RoleService = __decorate10([
1711
+ Injectable7(),
1712
+ __metadata6("design:paramtypes", [typeof (_a15 = typeof RoleRepository !== "undefined" && RoleRepository) === "function" ? _a15 : Object, typeof (_b2 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _b2 : Object])
1713
+ ], RoleService);
1716
1714
 
1717
1715
  // src/roles/RoleController.ts
1718
- import { Controller as Controller3, Get as Get3, Post as Post3, Put as Put2, Delete as Delete2, Params as Params3, Body as Body3, t as t6 } from "najm-api";
1719
- var RoleController = class {
1716
+ var __decorate11 = function(decorators, target, key, desc) {
1717
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1718
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1719
+ 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;
1720
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1721
+ };
1722
+ var __metadata7 = function(k, v) {
1723
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1724
+ };
1725
+ var __param2 = function(paramIndex, decorator) {
1726
+ return function(target, key) {
1727
+ decorator(target, key, paramIndex);
1728
+ };
1729
+ };
1730
+ var _a17;
1731
+ var _a18;
1732
+ var RoleController = (_a18 = class {
1720
1733
  constructor(roleService) {
1721
1734
  this.roleService = roleService;
1722
1735
  }
@@ -1724,7 +1737,7 @@ var RoleController = class {
1724
1737
  const roles = await this.roleService.getAll();
1725
1738
  return {
1726
1739
  data: roles,
1727
- message: t6("roles.success.retrieved"),
1740
+ message: t4("roles.success.retrieved"),
1728
1741
  status: "success"
1729
1742
  };
1730
1743
  }
@@ -1732,7 +1745,7 @@ var RoleController = class {
1732
1745
  const role = await this.roleService.getById(id);
1733
1746
  return {
1734
1747
  data: role,
1735
- message: t6("roles.success.retrieved"),
1748
+ message: t4("roles.success.retrieved"),
1736
1749
  status: "success"
1737
1750
  };
1738
1751
  }
@@ -1740,7 +1753,7 @@ var RoleController = class {
1740
1753
  const newRole = await this.roleService.create(body);
1741
1754
  return {
1742
1755
  data: newRole,
1743
- message: t6("roles.success.created"),
1756
+ message: t4("roles.success.created"),
1744
1757
  status: "success"
1745
1758
  };
1746
1759
  }
@@ -1748,7 +1761,7 @@ var RoleController = class {
1748
1761
  const updatedRole = await this.roleService.update(id, body);
1749
1762
  return {
1750
1763
  data: updatedRole,
1751
- message: t6("roles.success.updated"),
1764
+ message: t4("roles.success.updated"),
1752
1765
  status: "success"
1753
1766
  };
1754
1767
  }
@@ -1756,761 +1769,1133 @@ var RoleController = class {
1756
1769
  const result = await this.roleService.delete(id);
1757
1770
  return {
1758
1771
  data: result,
1759
- message: t6("roles.success.deleted"),
1772
+ message: t4("roles.success.deleted"),
1760
1773
  status: "success"
1761
1774
  };
1762
1775
  }
1763
- };
1764
- __decorateClass([
1765
- Get3(),
1766
- isAdmin()
1767
- ], RoleController.prototype, "getRoles", 1);
1768
- __decorateClass([
1769
- Get3("/:id"),
1776
+ }, __name(_a18, "RoleController"), _a18);
1777
+ __decorate11([
1778
+ Get(),
1770
1779
  isAdmin(),
1771
- __decorateParam(0, Params3("id"))
1772
- ], RoleController.prototype, "getRole", 1);
1773
- __decorateClass([
1774
- Post3(),
1780
+ __metadata7("design:type", Function),
1781
+ __metadata7("design:paramtypes", []),
1782
+ __metadata7("design:returntype", Promise)
1783
+ ], RoleController.prototype, "getRoles", null);
1784
+ __decorate11([
1785
+ Get("/:id"),
1775
1786
  isAdmin(),
1776
- __decorateParam(0, Body3())
1777
- ], RoleController.prototype, "createRole", 1);
1778
- __decorateClass([
1779
- Put2("/:id"),
1787
+ __param2(0, Params("id")),
1788
+ __metadata7("design:type", Function),
1789
+ __metadata7("design:paramtypes", [Object]),
1790
+ __metadata7("design:returntype", Promise)
1791
+ ], RoleController.prototype, "getRole", null);
1792
+ __decorate11([
1793
+ Post(),
1780
1794
  isAdmin(),
1781
- __decorateParam(0, Params3("id")),
1782
- __decorateParam(1, Body3())
1783
- ], RoleController.prototype, "updateRole", 1);
1784
- __decorateClass([
1785
- Delete2("/:id"),
1795
+ __param2(0, Body()),
1796
+ __metadata7("design:type", Function),
1797
+ __metadata7("design:paramtypes", [Object]),
1798
+ __metadata7("design:returntype", Promise)
1799
+ ], RoleController.prototype, "createRole", null);
1800
+ __decorate11([
1801
+ Put("/:id"),
1802
+ isAdmin(),
1803
+ __param2(0, Params("id")),
1804
+ __param2(1, Body()),
1805
+ __metadata7("design:type", Function),
1806
+ __metadata7("design:paramtypes", [Object, Object]),
1807
+ __metadata7("design:returntype", Promise)
1808
+ ], RoleController.prototype, "updateRole", null);
1809
+ __decorate11([
1810
+ Delete("/:id"),
1786
1811
  isAdmin(),
1787
- __decorateParam(0, Params3("id"))
1788
- ], RoleController.prototype, "deleteRole", 1);
1789
- RoleController = __decorateClass([
1790
- Controller3("/roles")
1812
+ __param2(0, Params("id")),
1813
+ __metadata7("design:type", Function),
1814
+ __metadata7("design:paramtypes", [Object]),
1815
+ __metadata7("design:returntype", Promise)
1816
+ ], RoleController.prototype, "deleteRole", null);
1817
+ RoleController = __decorate11([
1818
+ Controller("/roles"),
1819
+ __metadata7("design:paramtypes", [typeof (_a17 = typeof RoleService !== "undefined" && RoleService) === "function" ? _a17 : Object])
1791
1820
  ], RoleController);
1792
1821
 
1793
- // src/roles/RoleService.ts
1794
- import { Injectable as Injectable9 } from "najm-api";
1795
- var RoleService = class {
1796
- constructor(roleRepository, roleValidator) {
1797
- this.roleRepository = roleRepository;
1822
+ // src/users/UserService.ts
1823
+ import { nanoid as nanoid2 } from "nanoid";
1824
+ var __decorate12 = function(decorators, target, key, desc) {
1825
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1826
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1827
+ 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;
1828
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1829
+ };
1830
+ var __metadata8 = function(k, v) {
1831
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1832
+ };
1833
+ var _a19;
1834
+ var _b3;
1835
+ var _c;
1836
+ var _d;
1837
+ var _e;
1838
+ var _a20;
1839
+ var UserService = (_a20 = class {
1840
+ constructor(roleValidator, roleService, userRepository, userValidator, encryptionService) {
1798
1841
  this.roleValidator = roleValidator;
1842
+ this.roleService = roleService;
1843
+ this.userRepository = userRepository;
1844
+ this.userValidator = userValidator;
1845
+ this.encryptionService = encryptionService;
1846
+ }
1847
+ sanitizeUser(user) {
1848
+ if (!user)
1849
+ return user;
1850
+ const { password, ...sanitizedUser } = user;
1851
+ return sanitizedUser;
1852
+ }
1853
+ sanitizeUsers(users) {
1854
+ return users.map((user) => this.sanitizeUser(user));
1855
+ }
1856
+ async resolveUserRole(roleId, roleName) {
1857
+ if (roleId) {
1858
+ await this.roleValidator.checkRoleExists(roleId);
1859
+ return roleId;
1860
+ }
1861
+ if (roleName) {
1862
+ const roleByName = await this.roleService.getByName(roleName);
1863
+ if (roleByName) {
1864
+ return roleByName.id;
1865
+ }
1866
+ throw new Error(`Role '${roleName}' not found`);
1867
+ }
1868
+ const defaultRole = await this.roleService.getByName("Student");
1869
+ return defaultRole.id;
1799
1870
  }
1800
1871
  async getAll() {
1801
- return await this.roleRepository.getAll();
1872
+ const users = await this.userRepository.getAll();
1873
+ return this.sanitizeUsers(users);
1802
1874
  }
1803
1875
  async getById(id) {
1804
- await this.roleValidator.checkRoleExists(id);
1805
- return await this.roleRepository.getById(id);
1876
+ await this.userValidator.checkUserExists(id);
1877
+ const user = await this.userRepository.getById(id);
1878
+ return this.sanitizeUser(user);
1806
1879
  }
1807
- async getByName(name) {
1808
- return await this.roleRepository.getByName(name);
1880
+ async getByEmail(email) {
1881
+ const user = await this.userValidator.checkUserExistsByEmail(email);
1882
+ return this.sanitizeUser(user);
1809
1883
  }
1810
1884
  async create(data) {
1811
- await this.roleValidator.validateCreateRole(data);
1812
- await this.roleValidator.checkNameUnique(data.name);
1813
- return await this.roleRepository.create(data);
1885
+ const { id, email, image, emailVerified, password, roleId, role } = data;
1886
+ let userId = id || nanoid2(5);
1887
+ let pass = password || "12345678";
1888
+ await this.userValidator.checkEmailUnique(data.email);
1889
+ await this.userValidator.checkUserIdIsUnique(id);
1890
+ const hashedPassword = await this.encryptionService.hashPassword(pass);
1891
+ const resolvedRoleId = await this.resolveUserRole(roleId, role);
1892
+ const userDetails = {
1893
+ id: userId,
1894
+ email,
1895
+ image,
1896
+ password: hashedPassword,
1897
+ roleId: resolvedRoleId,
1898
+ emailVerified,
1899
+ status: "pending"
1900
+ };
1901
+ await this.userValidator.validateCreateUser(userDetails);
1902
+ const newUser = await this.userRepository.create(userDetails);
1903
+ return this.sanitizeUser(newUser);
1814
1904
  }
1815
1905
  async update(id, data) {
1816
- await this.roleValidator.checkRoleExists(id);
1817
- await this.roleValidator.checkNameUnique(data.name, id);
1818
- return await this.roleRepository.update(id, data);
1906
+ const { password, image } = data;
1907
+ await this.userValidator.checkUserExists(id);
1908
+ await this.userValidator.checkEmailUnique(data.email, id);
1909
+ const currentUser = await this.userRepository.getById(id);
1910
+ const hashedPassword = await this.encryptionService.hashPassword(password);
1911
+ const updateData = {
1912
+ ...data,
1913
+ image,
1914
+ ...hashedPassword && { password: hashedPassword }
1915
+ };
1916
+ const cleanedUpdateData = clean(updateData);
1917
+ const updatedUser = await this.userRepository.update(id, cleanedUpdateData);
1918
+ return this.sanitizeUser(updatedUser);
1819
1919
  }
1820
1920
  async delete(id) {
1821
- await this.roleValidator.checkRoleExists(id);
1822
- return await this.roleRepository.delete(id);
1921
+ await this.userValidator.checkUserExists(id);
1922
+ const user = await this.userRepository.delete(id);
1923
+ return this.sanitizeUser(user);
1823
1924
  }
1824
- async seedDefaultRoles(defaultRoles) {
1825
- const rolesToCreate = [];
1826
- for (const role of defaultRoles) {
1827
- const exists = await this.roleValidator.isRoleNameExists(role.name);
1828
- if (!exists) {
1829
- rolesToCreate.push(role);
1830
- }
1925
+ async deleteAll() {
1926
+ const deletedUsers = await this.userRepository.deleteAll();
1927
+ return this.sanitizeUsers(deletedUsers);
1928
+ }
1929
+ async getRoleName(id) {
1930
+ await this.userValidator.checkUserExists(id);
1931
+ return await this.userRepository.getRoleNameById(id);
1932
+ }
1933
+ async getPassword(email) {
1934
+ await this.userValidator.checkUserExistsByEmail(email);
1935
+ return await this.userRepository.getUserPassword(email);
1936
+ }
1937
+ async assignRole(id, roleId, roleName) {
1938
+ await this.userValidator.checkUserExists(id);
1939
+ const resolvedRoleId = await this.resolveUserRole(roleId, roleName);
1940
+ const updatedUser = await this.userRepository.update(id, { roleId: resolvedRoleId });
1941
+ return this.sanitizeUser(updatedUser);
1942
+ }
1943
+ async removeRole(id) {
1944
+ await this.userValidator.checkUserExists(id);
1945
+ const updatedUser = await this.userRepository.update(id, { roleId: null });
1946
+ return this.sanitizeUser(updatedUser);
1947
+ }
1948
+ async seedAdminUser() {
1949
+ const email = "admin@admin.com";
1950
+ const adminRole = await this.roleValidator.checkAdminRoleExists();
1951
+ const existingUser = await this.userRepository.getByEmail(email);
1952
+ if (existingUser) {
1953
+ await this.delete(existingUser.id);
1831
1954
  }
1832
- const createdRoles = await Promise.all(
1833
- rolesToCreate.map((role) => this.roleRepository.create(role))
1834
- );
1835
- return createdRoles;
1955
+ const newAdminUser = await this.create({
1956
+ id: "USR00",
1957
+ name: "System Administrator",
1958
+ email,
1959
+ password: "12345678",
1960
+ image: null,
1961
+ roleId: adminRole.id,
1962
+ status: "active",
1963
+ emailVerified: true
1964
+ });
1965
+ return this.sanitizeUser(newAdminUser);
1836
1966
  }
1837
- async getRoleIdByName(name) {
1838
- const teacherRole = await this.getByName(name);
1839
- return teacherRole?.id;
1967
+ async updateLang(language) {
1968
+ setLanguage(language);
1969
+ return language;
1840
1970
  }
1841
- };
1842
- RoleService = __decorateClass([
1843
- Injectable9()
1844
- ], RoleService);
1971
+ async getLang() {
1972
+ return getCurrentLanguage();
1973
+ }
1974
+ }, __name(_a20, "UserService"), _a20);
1975
+ __decorate12([
1976
+ Transactional(),
1977
+ __metadata8("design:type", Function),
1978
+ __metadata8("design:paramtypes", [Object]),
1979
+ __metadata8("design:returntype", Promise)
1980
+ ], UserService.prototype, "create", null);
1981
+ UserService = __decorate12([
1982
+ Injectable8(),
1983
+ __metadata8("design:paramtypes", [typeof (_a19 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _a19 : 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])
1984
+ ], UserService);
1845
1985
 
1846
- // src/tokens/TokenRepository.ts
1847
- import { eq as eq3 } from "drizzle-orm";
1848
- import { Repository as Repository3 } from "najm-api";
1849
- var TokenRepository = class {
1850
- async storeRefreshToken(tokenData) {
1851
- return await this.db.insert(tokensTable).values(tokenData).onConflictDoUpdate({
1852
- target: tokensTable.userId,
1853
- set: {
1854
- token: tokenData.token,
1855
- expiresAt: tokenData.expiresAt
1856
- }
1857
- }).returning();
1986
+ // src/users/UserController.ts
1987
+ import { Controller as Controller2, Get as Get2, Post as Post2, Put as Put2, Delete as Delete2, Params as Params2, Body as Body2, t as t5 } from "najm-api";
1988
+ var __decorate13 = function(decorators, target, key, desc) {
1989
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1990
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1991
+ 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;
1992
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1993
+ };
1994
+ var __metadata9 = function(k, v) {
1995
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1996
+ };
1997
+ var __param3 = function(paramIndex, decorator) {
1998
+ return function(target, key) {
1999
+ decorator(target, key, paramIndex);
2000
+ };
2001
+ };
2002
+ var _a21;
2003
+ var _a22;
2004
+ var UserController = (_a22 = class {
2005
+ constructor(userService) {
2006
+ this.userService = userService;
2007
+ }
2008
+ async getUsers() {
2009
+ const users = await this.userService.getAll();
2010
+ return {
2011
+ data: users,
2012
+ message: t5("users.success.retrieved"),
2013
+ status: "success"
2014
+ };
2015
+ }
2016
+ async getLang() {
2017
+ const language = await this.userService.getLang();
2018
+ return {
2019
+ data: { language },
2020
+ message: t5("users.success.retrieved"),
2021
+ status: "success"
2022
+ };
2023
+ }
2024
+ async updateLang(language) {
2025
+ const data = await this.userService.updateLang(language);
2026
+ return {
2027
+ data,
2028
+ message: t5("users.success.updated"),
2029
+ status: "success"
2030
+ };
2031
+ }
2032
+ async getUser(id) {
2033
+ const user = await this.userService.getById(id);
2034
+ return {
2035
+ data: user,
2036
+ message: t5("users.success.retrieved"),
2037
+ status: "success"
2038
+ };
2039
+ }
2040
+ async getByEmail(email) {
2041
+ const user = await this.userService.getByEmail(email);
2042
+ return {
2043
+ data: user,
2044
+ message: t5("users.success.retrieved"),
2045
+ status: "success"
2046
+ };
1858
2047
  }
1859
- async getRefreshToken(userId) {
1860
- const [token] = await this.db.select().from(tokensTable).where(eq3(tokensTable.userId, userId));
1861
- return token?.token;
2048
+ async getRole(userId) {
2049
+ const role = await this.userService.getRoleName(userId);
2050
+ return {
2051
+ data: role,
2052
+ message: t5("users.success.retrieved"),
2053
+ status: "success"
2054
+ };
1862
2055
  }
1863
- async revokeToken(userId) {
1864
- const [deletedToken] = await this.db.delete(tokensTable).where(eq3(tokensTable.userId, userId)).returning();
1865
- return deletedToken;
2056
+ async create(body) {
2057
+ const newUser = await this.userService.create(body);
2058
+ return {
2059
+ data: newUser,
2060
+ message: t5("users.success.created"),
2061
+ status: "success"
2062
+ };
1866
2063
  }
1867
- async isUserExists(userId) {
1868
- const [user] = await this.db.select({ id: usersTable.id }).from(usersTable).where(eq3(usersTable.id, userId)).limit(1);
1869
- return !!user;
2064
+ async update(id, body) {
2065
+ const updatedUser = await this.userService.update(id, body);
2066
+ return {
2067
+ data: updatedUser,
2068
+ message: t5("users.success.updated"),
2069
+ status: "success"
2070
+ };
1870
2071
  }
1871
- async getRoleNameById(userId) {
1872
- const [role] = await this.db.select({
1873
- roleName: rolesTable.name
1874
- }).from(usersTable).leftJoin(rolesTable, eq3(usersTable.roleId, rolesTable.id)).where(eq3(usersTable.id, userId)).limit(1);
1875
- return role?.roleName;
2072
+ async delete(id) {
2073
+ const result = await this.userService.delete(id);
2074
+ return {
2075
+ data: result,
2076
+ message: t5("users.success.deleted"),
2077
+ status: "success"
2078
+ };
1876
2079
  }
1877
- async getUserPermissions(userId) {
1878
- const [user] = await this.db.select({ roleId: usersTable.roleId }).from(usersTable).where(eq3(usersTable.id, userId)).limit(1);
1879
- if (!user || !user.roleId) return [];
1880
- const userPermissions = await this.db.select({
1881
- name: permissionsTable.name
1882
- }).from(rolePermissionsTable).leftJoin(permissionsTable, eq3(rolePermissionsTable.permissionId, permissionsTable.id)).where(eq3(rolePermissionsTable.roleId, user.roleId));
1883
- return userPermissions.map((p) => p.name).filter((name) => name);
2080
+ async deleteAll() {
2081
+ const result = await this.userService.deleteAll();
2082
+ return {
2083
+ data: result,
2084
+ message: t5("users.success.allDeleted"),
2085
+ status: "success"
2086
+ };
1884
2087
  }
1885
- async getUser(userId) {
1886
- const [user] = await this.db.select({
1887
- id: usersTable.id,
1888
- email: usersTable.email,
1889
- status: usersTable.status,
1890
- roleId: usersTable.roleId,
1891
- roleName: rolesTable.name,
1892
- createdAt: usersTable.createdAt,
1893
- updatedAt: usersTable.updatedAt
1894
- }).from(usersTable).leftJoin(rolesTable, eq3(usersTable.roleId, rolesTable.id)).where(eq3(usersTable.id, userId)).limit(1);
1895
- return user ? { ...user, role: user.roleName } : null;
2088
+ async assignRole(userId, roleId) {
2089
+ await this.userService.assignRole(userId, roleId);
2090
+ return {
2091
+ message: t5("users.success.updated"),
2092
+ status: "success"
2093
+ };
1896
2094
  }
1897
- };
1898
- TokenRepository = __decorateClass([
1899
- Repository3()
1900
- ], TokenRepository);
2095
+ async removeRole(userId) {
2096
+ await this.userService.removeRole(userId);
2097
+ return {
2098
+ message: t5("users.success.updated"),
2099
+ status: "success"
2100
+ };
2101
+ }
2102
+ }, __name(_a22, "UserController"), _a22);
2103
+ __decorate13([
2104
+ Get2(),
2105
+ isAdmin(),
2106
+ __metadata9("design:type", Function),
2107
+ __metadata9("design:paramtypes", []),
2108
+ __metadata9("design:returntype", Promise)
2109
+ ], UserController.prototype, "getUsers", null);
2110
+ __decorate13([
2111
+ Get2("/lang"),
2112
+ isAuth(),
2113
+ __metadata9("design:type", Function),
2114
+ __metadata9("design:paramtypes", []),
2115
+ __metadata9("design:returntype", Promise)
2116
+ ], UserController.prototype, "getLang", null);
2117
+ __decorate13([
2118
+ Post2("/lang/:language"),
2119
+ isAuth(),
2120
+ __param3(0, Params2("language")),
2121
+ __metadata9("design:type", Function),
2122
+ __metadata9("design:paramtypes", [Object]),
2123
+ __metadata9("design:returntype", Promise)
2124
+ ], UserController.prototype, "updateLang", null);
2125
+ __decorate13([
2126
+ Get2("/:id"),
2127
+ isAdmin(),
2128
+ __param3(0, Params2("id")),
2129
+ __metadata9("design:type", Function),
2130
+ __metadata9("design:paramtypes", [Object]),
2131
+ __metadata9("design:returntype", Promise)
2132
+ ], UserController.prototype, "getUser", null);
2133
+ __decorate13([
2134
+ Get2("/email/:email"),
2135
+ isAdmin(),
2136
+ __param3(0, Params2("email")),
2137
+ __metadata9("design:type", Function),
2138
+ __metadata9("design:paramtypes", [Object]),
2139
+ __metadata9("design:returntype", Promise)
2140
+ ], UserController.prototype, "getByEmail", null);
2141
+ __decorate13([
2142
+ Get2("/role/:userId"),
2143
+ isAdmin(),
2144
+ __param3(0, Params2("userId")),
2145
+ __metadata9("design:type", Function),
2146
+ __metadata9("design:paramtypes", [Object]),
2147
+ __metadata9("design:returntype", Promise)
2148
+ ], UserController.prototype, "getRole", null);
2149
+ __decorate13([
2150
+ Post2(),
2151
+ isAdmin(),
2152
+ __param3(0, Body2()),
2153
+ __metadata9("design:type", Function),
2154
+ __metadata9("design:paramtypes", [Object]),
2155
+ __metadata9("design:returntype", Promise)
2156
+ ], UserController.prototype, "create", null);
2157
+ __decorate13([
2158
+ Put2("/:id"),
2159
+ isAdmin(),
2160
+ __param3(0, Params2("id")),
2161
+ __param3(1, Body2()),
2162
+ __metadata9("design:type", Function),
2163
+ __metadata9("design:paramtypes", [Object, Object]),
2164
+ __metadata9("design:returntype", Promise)
2165
+ ], UserController.prototype, "update", null);
2166
+ __decorate13([
2167
+ Delete2("/:id"),
2168
+ isAdmin(),
2169
+ __param3(0, Params2("id")),
2170
+ __metadata9("design:type", Function),
2171
+ __metadata9("design:paramtypes", [Object]),
2172
+ __metadata9("design:returntype", Promise)
2173
+ ], UserController.prototype, "delete", null);
2174
+ __decorate13([
2175
+ Delete2(),
2176
+ isAdmin(),
2177
+ __metadata9("design:type", Function),
2178
+ __metadata9("design:paramtypes", []),
2179
+ __metadata9("design:returntype", Promise)
2180
+ ], UserController.prototype, "deleteAll", null);
2181
+ __decorate13([
2182
+ Post2("/assign/:userId/:roleId"),
2183
+ isAdmin(),
2184
+ __param3(0, Params2("userId")),
2185
+ __param3(1, Params2("roleId")),
2186
+ __metadata9("design:type", Function),
2187
+ __metadata9("design:paramtypes", [Object, Object]),
2188
+ __metadata9("design:returntype", Promise)
2189
+ ], UserController.prototype, "assignRole", null);
2190
+ __decorate13([
2191
+ Delete2("/remove/:userId"),
2192
+ isAdmin(),
2193
+ __param3(0, Params2("userId")),
2194
+ __metadata9("design:type", Function),
2195
+ __metadata9("design:paramtypes", [Object]),
2196
+ __metadata9("design:returntype", Promise)
2197
+ ], UserController.prototype, "removeRole", null);
2198
+ UserController = __decorate13([
2199
+ Controller2("/users"),
2200
+ __metadata9("design:paramtypes", [typeof (_a21 = typeof UserService !== "undefined" && UserService) === "function" ? _a21 : Object])
2201
+ ], UserController);
1901
2202
 
1902
- // src/tokens/TokenService.ts
1903
- import { t as t7 } from "najm-api";
1904
- import { getCookie, Injectable as Injectable10 } from "najm-api";
1905
- import jwt from "jsonwebtoken";
1906
- import { jwtDecode } from "jwt-decode";
1907
- import timestring2 from "timestring";
1908
- var TokenService = class {
1909
- constructor(tokenRepository) {
1910
- this.tokenRepository = tokenRepository;
1911
- this.accessSecretKey = process.env.JWT_ACCESS_SECRET;
1912
- this.accessExpiresIn = process.env.ACCESS_EXPIRES_IN;
1913
- this.refreshSecretKey = process.env.JWT_REFRESH_SECRET;
1914
- this.refreshExpiresIn = process.env.REFRESH_EXPIRES_IN;
2203
+ // src/auth/AuthService.ts
2204
+ var __decorate14 = function(decorators, target, key, desc) {
2205
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2206
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2207
+ 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;
2208
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2209
+ };
2210
+ var __metadata10 = function(k, v) {
2211
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2212
+ };
2213
+ var _a23;
2214
+ var _b4;
2215
+ var _c2;
2216
+ var _d2;
2217
+ var _a24;
2218
+ var AuthService = (_a24 = class {
2219
+ constructor(tokenService, userService, userValidator, cookieService) {
2220
+ this.tokenService = tokenService;
2221
+ this.userService = userService;
2222
+ this.userValidator = userValidator;
2223
+ this.cookieService = cookieService;
1915
2224
  }
1916
- //==== Validate tokens
1917
- extractAccessToken(authorization) {
1918
- if (authorization && authorization.startsWith("Bearer")) {
1919
- return authorization.split(" ")[1];
1920
- }
1921
- throw new Error(t7("auth.errors.tokenMissing"));
2225
+ async registerUser(body) {
2226
+ return await this.userService.create(body);
1922
2227
  }
1923
- verifyAccessToken(token) {
1924
- try {
1925
- return jwt.verify(token, this.accessSecretKey);
1926
- } catch (error) {
1927
- throw new Error(t7("auth.errors.tokenVerificationFailed"));
2228
+ async loginUser(body) {
2229
+ const { email, password } = body;
2230
+ if (!email || !password) {
2231
+ throw new Error(t6("auth.errors.invalidCredentials"));
1928
2232
  }
2233
+ const existingPassword = await this.userService.getPassword(email);
2234
+ const { id } = await this.userService.getByEmail(email);
2235
+ await this.userValidator.checkPasswordValid(password, existingPassword);
2236
+ const data = await this.tokenService.generateTokens(id);
2237
+ this.cookieService.setRefreshCookie(data.refreshToken);
2238
+ return data;
1929
2239
  }
1930
- verifyRefreshToken(token) {
1931
- try {
1932
- const decoded = jwt.verify(token, this.refreshSecretKey);
1933
- return decoded.userId;
1934
- } catch (error) {
1935
- throw new Error(t7("auth.errors.tokenVerificationFailed"));
1936
- }
2240
+ async refreshTokens() {
2241
+ const data = await this.tokenService.refreshTokens();
2242
+ this.cookieService.setRefreshCookie(data.refreshToken);
2243
+ return data;
1937
2244
  }
1938
- async getUserIdByAccessToken(header) {
1939
- const token = this.extractAccessToken(header);
1940
- const decodedToken = this.verifyAccessToken(token);
1941
- const userId = decodedToken.userId;
1942
- const userExists = await this.tokenRepository.isUserExists(userId);
1943
- if (!userExists) {
1944
- throw new Error(t7("users.errors.notFound"));
1945
- }
1946
- return userId;
2245
+ async logoutUser(userId) {
2246
+ await this.userValidator.checkUserExists(userId);
2247
+ await this.tokenService.revokeToken(userId);
2248
+ this.cookieService.clearRefreshCookie();
2249
+ return { data: null, message: t6("auth.success.logout") };
1947
2250
  }
1948
- //=== Generate tokens
1949
- async storeRefreshToken(userId, refreshToken) {
1950
- const expireInSecond = timestring2(this.refreshExpiresIn, "s");
1951
- const tokenData = {
1952
- userId,
1953
- token: refreshToken,
1954
- expiresAt: new Date(Date.now() + expireInSecond * 1e3).toISOString()
2251
+ async getUserProfile(userData) {
2252
+ const lang = getCurrentLanguage2();
2253
+ return {
2254
+ ...userData,
2255
+ language: lang
1955
2256
  };
1956
- await this.tokenRepository.storeRefreshToken(tokenData);
1957
2257
  }
1958
- getTokenExpire(token) {
1959
- return jwtDecode(token).exp;
2258
+ async forgotPassword(email) {
1960
2259
  }
1961
- generateAccessToken(data) {
1962
- const options = { expiresIn: this.accessExpiresIn };
1963
- return jwt.sign(data, this.accessSecretKey, options);
2260
+ }, __name(_a24, "AuthService"), _a24);
2261
+ AuthService = __decorate14([
2262
+ Injectable9(),
2263
+ __metadata10("design:paramtypes", [typeof (_a23 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a23 : Object, typeof (_b4 = typeof UserService !== "undefined" && UserService) === "function" ? _b4 : Object, typeof (_c2 = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _c2 : Object, typeof (_d2 = typeof CookieService !== "undefined" && CookieService) === "function" ? _d2 : Object])
2264
+ ], AuthService);
2265
+
2266
+ // src/auth/AuthController.ts
2267
+ var __decorate15 = function(decorators, target, key, desc) {
2268
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2269
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2270
+ 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;
2271
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2272
+ };
2273
+ var __metadata11 = function(k, v) {
2274
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2275
+ };
2276
+ var __param4 = function(paramIndex, decorator) {
2277
+ return function(target, key) {
2278
+ decorator(target, key, paramIndex);
2279
+ };
2280
+ };
2281
+ var _a25;
2282
+ var _a26;
2283
+ var AuthController = (_a26 = class {
2284
+ constructor(authService) {
2285
+ this.authService = authService;
1964
2286
  }
1965
- generateRefreshToken(data) {
1966
- const options = { expiresIn: this.refreshExpiresIn };
1967
- return jwt.sign(data, this.refreshSecretKey, options);
2287
+ async registerUser(body) {
2288
+ const data = await this.authService.registerUser(body);
2289
+ return {
2290
+ data,
2291
+ message: t7("auth.success.register"),
2292
+ status: "success"
2293
+ };
1968
2294
  }
1969
- async generateTokens(userId) {
1970
- const tokenData = { userId };
1971
- const accessToken = await this.generateAccessToken(tokenData);
1972
- const refreshToken = await this.generateRefreshToken(tokenData);
1973
- const accessTokenExpiresAt = this.getTokenExpire(accessToken);
1974
- const refreshTokenExpiresAt = this.getTokenExpire(refreshToken);
1975
- await this.storeRefreshToken(userId, refreshToken);
2295
+ async loginUser(body) {
2296
+ const data = await this.authService.loginUser(body);
1976
2297
  return {
1977
- accessToken,
1978
- refreshToken,
1979
- accessTokenExpiresAt,
1980
- refreshTokenExpiresAt
2298
+ data,
2299
+ message: t7("auth.success.login"),
2300
+ status: "success"
1981
2301
  };
1982
2302
  }
1983
2303
  async refreshTokens() {
1984
- const newRefreshToken = getCookie("refreshToken");
1985
- const userId = this.verifyRefreshToken(newRefreshToken);
1986
- const userExists = await this.tokenRepository.isUserExists(userId);
1987
- if (!userExists) {
1988
- throw new Error(t7("users.errors.notFound"));
1989
- }
1990
- const storedRefreshToken = await this.tokenRepository.getRefreshToken(userId);
1991
- if (newRefreshToken != storedRefreshToken) {
1992
- throw new Error(t7("auth.errors.refreshTokenInvalid"));
1993
- }
1994
- return await this.generateTokens(userId);
1995
- }
1996
- async revokeToken(userId) {
1997
- return await this.tokenRepository.revokeToken(userId);
1998
- }
1999
- async getUserPermissions(auth) {
2000
- if (!auth) return;
2001
- const userId = await this.getUserIdByAccessToken(auth);
2002
- const permissions = await this.tokenRepository.getUserPermissions(userId);
2003
- return permissions;
2004
- }
2005
- async getUserRole(auth) {
2006
- if (!auth) return;
2007
- const userId = await this.getUserIdByAccessToken(auth);
2008
- const roleName = await this.tokenRepository.getRoleNameById(userId);
2009
- return roleName;
2304
+ const data = await this.authService.refreshTokens();
2305
+ return {
2306
+ data,
2307
+ message: t7("auth.success.tokenRefreshed"),
2308
+ status: "success"
2309
+ };
2010
2310
  }
2011
- async getUser(auth) {
2012
- if (!auth) return;
2013
- const userId = await this.getUserIdByAccessToken(auth);
2014
- const user = await this.tokenRepository.getUser(userId);
2015
- if (!user) return null;
2016
- return user;
2311
+ async logoutUser(id) {
2312
+ const data = await this.authService.logoutUser(id);
2313
+ return {
2314
+ data,
2315
+ message: t7("auth.success.logout"),
2316
+ status: "success"
2317
+ };
2017
2318
  }
2018
- async storeUserInCache(auth, ctx) {
2019
- const cachedUser = ctx.get("user");
2020
- if (cachedUser) return cachedUser;
2021
- const user = await this.getUser(auth);
2022
- if (user) {
2023
- ctx.set("user", user);
2024
- }
2025
- return user;
2319
+ async userProfile(user) {
2320
+ const data = await this.authService.getUserProfile(user);
2321
+ return {
2322
+ data,
2323
+ message: t7("users.success.retrieved"),
2324
+ status: "success"
2325
+ };
2026
2326
  }
2027
- };
2028
- TokenService = __decorateClass([
2029
- Injectable10()
2030
- ], TokenService);
2031
-
2032
- // src/users/UserRepository.ts
2033
- import { eq as eq4, ne } from "drizzle-orm";
2034
- import { Repository as Repository4 } from "najm-api";
2035
- var UserRepository = class {
2036
- getUser() {
2327
+ async forgotPassword(body) {
2328
+ const data = await this.authService.forgotPassword(body.email);
2037
2329
  return {
2038
- id: usersTable.id,
2039
- email: usersTable.email,
2040
- emailVerified: usersTable.emailVerified,
2041
- image: usersTable.image,
2042
- status: usersTable.status,
2043
- roleId: usersTable.roleId,
2044
- role: rolesTable.name,
2045
- createdAt: usersTable.createdAt,
2046
- updatedAt: usersTable.updatedAt
2330
+ data,
2331
+ message: t7("auth.success.passwordReset"),
2332
+ status: "success"
2047
2333
  };
2048
2334
  }
2335
+ }, __name(_a26, "AuthController"), _a26);
2336
+ __decorate15([
2337
+ Post3("/register"),
2338
+ __param4(0, Body3()),
2339
+ __metadata11("design:type", Function),
2340
+ __metadata11("design:paramtypes", [Object]),
2341
+ __metadata11("design:returntype", Promise)
2342
+ ], AuthController.prototype, "registerUser", null);
2343
+ __decorate15([
2344
+ Post3("/login"),
2345
+ __param4(0, Body3()),
2346
+ __metadata11("design:type", Function),
2347
+ __metadata11("design:paramtypes", [Object]),
2348
+ __metadata11("design:returntype", Promise)
2349
+ ], AuthController.prototype, "loginUser", null);
2350
+ __decorate15([
2351
+ Get3("/refresh"),
2352
+ __metadata11("design:type", Function),
2353
+ __metadata11("design:paramtypes", []),
2354
+ __metadata11("design:returntype", Promise)
2355
+ ], AuthController.prototype, "refreshTokens", null);
2356
+ __decorate15([
2357
+ Get3("/logout/:id"),
2358
+ __param4(0, Params3("id")),
2359
+ __metadata11("design:type", Function),
2360
+ __metadata11("design:paramtypes", [Object]),
2361
+ __metadata11("design:returntype", Promise)
2362
+ ], AuthController.prototype, "logoutUser", null);
2363
+ __decorate15([
2364
+ Get3("/me"),
2365
+ isAuth(),
2366
+ __param4(0, User()),
2367
+ __metadata11("design:type", Function),
2368
+ __metadata11("design:paramtypes", [Object]),
2369
+ __metadata11("design:returntype", Promise)
2370
+ ], AuthController.prototype, "userProfile", null);
2371
+ __decorate15([
2372
+ Post3("/forgot-password"),
2373
+ isAuth(),
2374
+ __param4(0, Body3()),
2375
+ __metadata11("design:type", Function),
2376
+ __metadata11("design:paramtypes", [Object]),
2377
+ __metadata11("design:returntype", Promise)
2378
+ ], AuthController.prototype, "forgotPassword", null);
2379
+ AuthController = __decorate15([
2380
+ Controller3("/auth"),
2381
+ __metadata11("design:paramtypes", [typeof (_a25 = typeof AuthService !== "undefined" && AuthService) === "function" ? _a25 : Object])
2382
+ ], AuthController);
2383
+
2384
+ // src/permissions/PermissionRepository.ts
2385
+ import { eq as eq4, and } from "drizzle-orm";
2386
+ import { Repository as Repository4 } from "najm-api";
2387
+ var __decorate16 = function(decorators, target, key, desc) {
2388
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2389
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2390
+ 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;
2391
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2392
+ };
2393
+ var _a27;
2394
+ var PermissionRepository = (_a27 = class {
2049
2395
  async getAll() {
2050
- const allUsers = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq4(usersTable.roleId, rolesTable.id));
2051
- return Promise.all(allUsers.map(async (user) => ({
2052
- ...user,
2053
- permissions: await this.getUserPermissions(user.id)
2054
- })));
2396
+ return await this.db.select().from(permissionsTable);
2055
2397
  }
2056
2398
  async getById(id) {
2057
- const [user] = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq4(usersTable.roleId, rolesTable.id)).where(eq4(usersTable.id, id)).limit(1);
2058
- if (!user) return user;
2059
- return {
2060
- ...user,
2061
- permissions: await this.getUserPermissions(user.id)
2062
- };
2399
+ const [existingPermission] = await this.db.select().from(permissionsTable).where(eq4(permissionsTable.id, id));
2400
+ return existingPermission;
2063
2401
  }
2064
- async getByEmail(email) {
2065
- const [existingUser] = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq4(usersTable.roleId, rolesTable.id)).where(eq4(usersTable.email, email));
2066
- return existingUser;
2402
+ async getByName(name) {
2403
+ const [existingPermission] = await this.db.select().from(permissionsTable).where(eq4(permissionsTable.name, name));
2404
+ return existingPermission;
2067
2405
  }
2068
2406
  async create(data) {
2069
- const [newUser] = await this.db.insert(usersTable).values(data).returning();
2070
- return newUser;
2407
+ const [newPermission] = await this.db.insert(permissionsTable).values(data).returning();
2408
+ return newPermission;
2071
2409
  }
2072
2410
  async update(id, data) {
2073
- const [updatedUser] = await this.db.update(usersTable).set(data).where(eq4(usersTable.id, id)).returning();
2074
- return updatedUser;
2411
+ const [updatedPermission] = await this.db.update(permissionsTable).set(data).where(eq4(permissionsTable.id, id)).returning();
2412
+ return updatedPermission;
2075
2413
  }
2076
2414
  async delete(id) {
2077
- const [deletedUser] = await this.db.delete(usersTable).where(eq4(usersTable.id, id)).returning();
2078
- return deletedUser;
2415
+ const [deletedPermission] = await this.db.delete(permissionsTable).where(eq4(permissionsTable.id, id)).returning();
2416
+ return deletedPermission;
2079
2417
  }
2080
- async deleteAll() {
2081
- const adminRole = await this.db.select({ id: rolesTable.id }).from(rolesTable).where(eq4(rolesTable.name, "admin")).limit(1);
2082
- if (adminRole.length === 0) {
2083
- const deletedUsers2 = await this.db.delete(usersTable).returning();
2084
- return deletedUsers2;
2085
- }
2086
- const deletedUsers = await this.db.delete(usersTable).where(ne(usersTable.roleId, adminRole[0].id)).returning();
2087
- return deletedUsers;
2418
+ async getPermissionsByRole(roleId) {
2419
+ return await this.db.select({
2420
+ id: permissionsTable.id,
2421
+ name: permissionsTable.name,
2422
+ description: permissionsTable.description,
2423
+ resource: permissionsTable.resource,
2424
+ action: permissionsTable.action
2425
+ }).from(rolePermissionsTable).leftJoin(permissionsTable, eq4(rolePermissionsTable.permissionId, permissionsTable.id)).where(eq4(rolePermissionsTable.roleId, roleId));
2088
2426
  }
2089
- async getRoleNameById(userId) {
2090
- const [role] = await this.db.select({
2091
- roleName: rolesTable.name
2092
- }).from(usersTable).leftJoin(rolesTable, eq4(usersTable.roleId, rolesTable.id)).where(eq4(usersTable.id, userId));
2093
- return role.roleName;
2427
+ async getRolesByPermission(permissionId) {
2428
+ return await this.db.select({
2429
+ id: rolesTable.id,
2430
+ name: rolesTable.name,
2431
+ description: rolesTable.description
2432
+ }).from(rolePermissionsTable).leftJoin(rolesTable, eq4(rolePermissionsTable.roleId, rolesTable.id)).where(eq4(rolePermissionsTable.permissionId, permissionId));
2094
2433
  }
2095
- async getUserPassword(email) {
2096
- const [user] = await this.db.select({
2097
- id: usersTable.id,
2098
- email: usersTable.email,
2099
- password: usersTable.password
2100
- }).from(usersTable).where(eq4(usersTable.email, email)).limit(1);
2101
- return user.password;
2434
+ async assignPermissionToRole(roleId, permissionId) {
2435
+ const [newRolePermission] = await this.db.insert(rolePermissionsTable).values({ roleId, permissionId }).returning();
2436
+ return newRolePermission;
2102
2437
  }
2103
- async getUserPermissions(userId) {
2104
- const [user] = await this.db.select({ roleId: usersTable.roleId }).from(usersTable).where(eq4(usersTable.id, userId)).limit(1);
2105
- if (!user || !user.roleId) return [];
2106
- const userPermissions = await this.db.select({
2107
- name: permissionsTable.name
2108
- }).from(rolePermissionsTable).leftJoin(permissionsTable, eq4(rolePermissionsTable.permissionId, permissionsTable.id)).where(eq4(rolePermissionsTable.roleId, user.roleId));
2109
- return userPermissions.map((p) => p.name).filter((name) => name);
2438
+ async removePermissionFromRole(roleId, permissionId) {
2439
+ const [deletedRolePermission] = await this.db.delete(rolePermissionsTable).where(and(eq4(rolePermissionsTable.roleId, roleId), eq4(rolePermissionsTable.permissionId, permissionId))).returning();
2440
+ return deletedRolePermission;
2110
2441
  }
2111
- };
2112
- UserRepository = __decorateClass([
2442
+ async checkRoleHasPermission(roleId, permissionId) {
2443
+ const [rolePermission] = await this.db.select().from(rolePermissionsTable).where(and(eq4(rolePermissionsTable.roleId, roleId), eq4(rolePermissionsTable.permissionId, permissionId)));
2444
+ return !!rolePermission;
2445
+ }
2446
+ async deleteAll() {
2447
+ await this.db.delete(rolePermissionsTable);
2448
+ const deletedPermissions = await this.db.delete(permissionsTable).returning();
2449
+ return deletedPermissions;
2450
+ }
2451
+ }, __name(_a27, "PermissionRepository"), _a27);
2452
+ PermissionRepository = __decorate16([
2113
2453
  Repository4()
2114
- ], UserRepository);
2454
+ ], PermissionRepository);
2115
2455
 
2116
- // src/users/UserValidator.ts
2117
- import { Injectable as Injectable11, t as t8 } from "najm-api";
2118
- var UserValidator = class {
2119
- constructor(userRepository, encryptionService) {
2120
- this.userRepository = userRepository;
2121
- this.encryptionService = encryptionService;
2456
+ // src/permissions/PermissionGuards.ts
2457
+ import { createGuard as createGuard2, Injectable as Injectable10, GuardParams as GuardParams2, Headers as Headers2, Ctx as Ctx2 } from "najm-api";
2458
+ var __decorate17 = function(decorators, target, key, desc) {
2459
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2460
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2461
+ 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;
2462
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2463
+ };
2464
+ var __metadata12 = function(k, v) {
2465
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2466
+ };
2467
+ var __param5 = function(paramIndex, decorator) {
2468
+ return function(target, key) {
2469
+ decorator(target, key, paramIndex);
2470
+ };
2471
+ };
2472
+ var _a28;
2473
+ var _a29;
2474
+ var PermissionGuards = (_a29 = class {
2475
+ constructor(tokenService) {
2476
+ this.tokenService = tokenService;
2122
2477
  }
2123
- async validateCreateUser(data) {
2124
- return parseSchema(userSchema, data);
2478
+ async getUserPermissions(auth) {
2479
+ const permissions = await this.tokenService.getUserPermissions(auth);
2480
+ if (!permissions || !Array.isArray(permissions))
2481
+ return null;
2482
+ return permissions;
2125
2483
  }
2126
- async isEmailExists(email) {
2127
- const existingUser = await this.userRepository.getByEmail(email);
2128
- return !!existingUser;
2484
+ checkPermissionMatch(permissions, requiredPermission) {
2485
+ if (permissions.includes(requiredPermission)) {
2486
+ return true;
2487
+ }
2488
+ const [requiredAction, requiredResource] = requiredPermission.split(":");
2489
+ if (requiredAction && requiredResource) {
2490
+ if (permissions.includes(`${requiredAction}:*`)) {
2491
+ return true;
2492
+ }
2493
+ if (permissions.includes(`*:${requiredResource}`)) {
2494
+ return true;
2495
+ }
2496
+ }
2497
+ if (permissions.includes("*:*")) {
2498
+ return true;
2499
+ }
2500
+ return false;
2129
2501
  }
2130
- async isPasswordValid(password, hashedPassword) {
2131
- const isPasswordValid = await this.encryptionService.comparePassword(password, hashedPassword);
2132
- return !!isPasswordValid;
2502
+ async hasPermission(auth, ctx, requiredPermission) {
2503
+ await this.tokenService.storeUserInCache(auth, ctx);
2504
+ const permissions = await this.getUserPermissions(auth);
2505
+ if (!permissions)
2506
+ return false;
2507
+ const check = this.checkPermissionMatch(permissions, requiredPermission);
2508
+ return check;
2133
2509
  }
2134
- async isUserExist(id) {
2135
- const existingUser = await this.userRepository.getById(id);
2136
- return !!existingUser;
2510
+ }, __name(_a29, "PermissionGuards"), _a29);
2511
+ __decorate17([
2512
+ __param5(0, Headers2("authorization")),
2513
+ __param5(1, Ctx2()),
2514
+ __param5(2, GuardParams2()),
2515
+ __metadata12("design:type", Function),
2516
+ __metadata12("design:paramtypes", [Object, Object, Object]),
2517
+ __metadata12("design:returntype", Promise)
2518
+ ], PermissionGuards.prototype, "hasPermission", null);
2519
+ PermissionGuards = __decorate17([
2520
+ Injectable10(),
2521
+ __metadata12("design:paramtypes", [typeof (_a28 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a28 : Object])
2522
+ ], PermissionGuards);
2523
+ var Permission = /* @__PURE__ */ __name((...permissions) => createGuard2(PermissionGuards, "hasPermission")(...permissions), "Permission");
2524
+
2525
+ // src/permissions/PermissionController.ts
2526
+ import { Controller as Controller4, Get as Get4, Post as Post4, Put as Put3, Delete as Delete3, Params as Params4, Body as Body4, t as t9 } from "najm-api";
2527
+
2528
+ // src/permissions/PermissionService.ts
2529
+ import { Injectable as Injectable12 } from "najm-api";
2530
+
2531
+ // src/permissions/PermissionValidator.ts
2532
+ import { Injectable as Injectable11, t as t8 } from "najm-api";
2533
+ import { z as z3 } from "zod";
2534
+ var __decorate18 = function(decorators, target, key, desc) {
2535
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2536
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2537
+ 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;
2538
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2539
+ };
2540
+ var __metadata13 = function(k, v) {
2541
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2542
+ };
2543
+ var _a30;
2544
+ var _b5;
2545
+ var permissionSchema = z3.object({
2546
+ name: z3.string().min(1, "Permission name is required"),
2547
+ description: z3.string().optional(),
2548
+ resource: z3.string().min(1, "Resource is required"),
2549
+ action: z3.string().min(1, "Action is required")
2550
+ });
2551
+ var _a31;
2552
+ var PermissionValidator = (_a31 = class {
2553
+ constructor(permissionRepository, roleValidator) {
2554
+ this.permissionRepository = permissionRepository;
2555
+ this.roleValidator = roleValidator;
2137
2556
  }
2138
- async checkUserIdIsUnique(id) {
2139
- if (!id) return;
2140
- const existingUser = await this.userRepository.getById(id);
2141
- if (existingUser) {
2142
- throw new Error(t8("users.errors.idExists"));
2143
- }
2557
+ async validateCreatePermission(data) {
2558
+ return parseSchema(permissionSchema, data);
2144
2559
  }
2145
- async isCorrectPass(password) {
2146
- return password && typeof password === "string" && password.trim().length > 0;
2560
+ async isPermissionExists(id) {
2561
+ const existingPermission = await this.permissionRepository.getById(id);
2562
+ return !!existingPermission;
2147
2563
  }
2148
- async hasRole(userId, roles) {
2149
- const roleName = await this.userRepository.getRoleNameById(userId);
2150
- if (!roleName) {
2151
- throw Error(t8("auth.errors.accessDenied"));
2152
- }
2153
- const hasRole = roles.some(
2154
- (item) => roleName.toLowerCase() === item.toLowerCase()
2155
- );
2156
- if (!hasRole) {
2157
- throw Error(t8("auth.errors.accessDenied"));
2158
- }
2159
- return true;
2564
+ async isPermissionNameExists(name) {
2565
+ const existingPermission = await this.permissionRepository.getByName(name);
2566
+ return !!existingPermission;
2160
2567
  }
2161
2568
  //======================= throw errors
2162
- async checkUserExistsByEmail(email) {
2163
- const user = await this.userRepository.getByEmail(email);
2164
- if (!user) {
2165
- throw new Error(t8("auth.errors.invalidCredentials"));
2166
- }
2167
- return user;
2168
- }
2169
- async checkUserExists(id) {
2170
- const userExists = await this.isUserExist(id);
2171
- if (!userExists) {
2172
- throw new Error(t8("users.errors.notFound"));
2173
- }
2174
- return userExists;
2175
- }
2176
- async checkEmailUnique(email, excludeId = null) {
2177
- if (!email) return;
2178
- const existingUser = await this.userRepository.getByEmail(email);
2179
- if (existingUser && existingUser.id !== excludeId) {
2180
- throw new Error(t8("auth.errors.emailExists"));
2569
+ async checkPermissionExists(id) {
2570
+ const permissionExists = await this.isPermissionExists(id);
2571
+ if (!permissionExists) {
2572
+ throw new Error(t8("permissions.errors.notFound"));
2181
2573
  }
2574
+ return permissionExists;
2182
2575
  }
2183
- async checkEmailExists(email) {
2184
- const user = await this.userRepository.getByEmail(email);
2185
- if (!user) {
2186
- throw new Error(t8("users.errors.notFound"));
2576
+ async checkPermissionExistsByName(name) {
2577
+ const permissionExists = await this.isPermissionNameExists(name);
2578
+ if (!permissionExists) {
2579
+ throw new Error(t8("permissions.errors.notFound"));
2187
2580
  }
2188
- return user;
2581
+ return permissionExists;
2189
2582
  }
2190
- async checkPasswordValid(password, hashedPassword) {
2191
- const isPasswordValid = await this.isPasswordValid(password, hashedPassword);
2192
- if (!isPasswordValid) {
2193
- throw new Error(t8("auth.errors.invalidCredentials"));
2583
+ async checkPermissionNameUnique(name, excludeId = null) {
2584
+ if (!name)
2585
+ return;
2586
+ const existingPermission = await this.permissionRepository.getByName(name);
2587
+ if (existingPermission && existingPermission.id !== excludeId) {
2588
+ throw new Error(t8("permissions.errors.nameExists"));
2194
2589
  }
2195
2590
  }
2196
- };
2197
- UserValidator = __decorateClass([
2198
- Injectable11()
2199
- ], UserValidator);
2200
-
2201
- // src/users/UserService.ts
2202
- import { Injectable as Injectable12, setLanguage, getCurrentLanguage as getCurrentLanguage2, Transactional } from "najm-api";
2203
- import { nanoid as nanoid2 } from "nanoid";
2204
- var UserService = class {
2205
- constructor(roleValidator, roleService, userRepository, userValidator, encryptionService) {
2206
- this.roleValidator = roleValidator;
2207
- this.roleService = roleService;
2208
- this.userRepository = userRepository;
2209
- this.userValidator = userValidator;
2210
- this.encryptionService = encryptionService;
2211
- }
2212
- sanitizeUser(user) {
2213
- if (!user) return user;
2214
- const { password, ...sanitizedUser } = user;
2215
- return sanitizedUser;
2216
- }
2217
- sanitizeUsers(users) {
2218
- return users.map((user) => this.sanitizeUser(user));
2219
- }
2220
- async resolveUserRole(roleId, roleName) {
2221
- if (roleId) {
2222
- await this.roleValidator.checkRoleExists(roleId);
2223
- return roleId;
2224
- }
2225
- if (roleName) {
2226
- const roleByName = await this.roleService.getByName(roleName);
2227
- if (roleByName) {
2228
- return roleByName.id;
2229
- }
2230
- throw new Error(`Role '${roleName}' not found`);
2591
+ async checkRoleExists(id) {
2592
+ return await this.roleValidator.checkRoleExists(id);
2593
+ }
2594
+ async checkRoleExistsByName(name) {
2595
+ return await this.roleValidator.checkRoleExistsByName(name);
2596
+ }
2597
+ async checkRoleHasPermission(roleId, permissionId) {
2598
+ await this.roleValidator.checkRoleExists(roleId);
2599
+ await this.checkPermissionExists(permissionId);
2600
+ const hasPermission = await this.permissionRepository.checkRoleHasPermission(roleId, permissionId);
2601
+ if (hasPermission) {
2602
+ throw new Error(t8("permissions.errors.roleAlreadyHasPermission"));
2231
2603
  }
2232
- const defaultRole = await this.roleService.getByName("Student");
2233
- return defaultRole.id;
2604
+ }
2605
+ }, __name(_a31, "PermissionValidator"), _a31);
2606
+ PermissionValidator = __decorate18([
2607
+ Injectable11(),
2608
+ __metadata13("design:paramtypes", [typeof (_a30 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a30 : Object, typeof (_b5 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _b5 : Object])
2609
+ ], PermissionValidator);
2610
+
2611
+ // src/permissions/PermissionService.ts
2612
+ var __decorate19 = function(decorators, target, key, desc) {
2613
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2614
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2615
+ 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;
2616
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2617
+ };
2618
+ var __metadata14 = function(k, v) {
2619
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2620
+ };
2621
+ var _a32;
2622
+ var _b6;
2623
+ var _c3;
2624
+ var _a33;
2625
+ var PermissionService = (_a33 = class {
2626
+ constructor(permissionRepository, permissionValidator, roleService) {
2627
+ this.permissionRepository = permissionRepository;
2628
+ this.permissionValidator = permissionValidator;
2629
+ this.roleService = roleService;
2234
2630
  }
2235
2631
  async getAll() {
2236
- const users = await this.userRepository.getAll();
2237
- return this.sanitizeUsers(users);
2632
+ return await this.permissionRepository.getAll();
2238
2633
  }
2239
2634
  async getById(id) {
2240
- await this.userValidator.checkUserExists(id);
2241
- const user = await this.userRepository.getById(id);
2242
- return this.sanitizeUser(user);
2635
+ await this.permissionValidator.checkPermissionExists(id);
2636
+ return await this.permissionRepository.getById(id);
2243
2637
  }
2244
- async getByEmail(email) {
2245
- const user = await this.userValidator.checkUserExistsByEmail(email);
2246
- return this.sanitizeUser(user);
2638
+ async getByName(name) {
2639
+ return await this.permissionRepository.getByName(name);
2640
+ }
2641
+ async getByResource(resource) {
2642
+ return await this.permissionRepository.getAll().then((permissions) => permissions.filter((p) => p.resource === resource));
2247
2643
  }
2248
2644
  async create(data) {
2249
- const { id, email, image, emailVerified, password, roleId, role } = data;
2250
- let userId = id || nanoid2(5);
2251
- let pass = password || "12345678";
2252
- await this.userValidator.checkEmailUnique(data.email);
2253
- await this.userValidator.checkUserIdIsUnique(id);
2254
- const hashedPassword = await this.encryptionService.hashPassword(pass);
2255
- const resolvedRoleId = await this.resolveUserRole(roleId, role);
2256
- const userDetails = {
2257
- id: userId,
2258
- email,
2259
- image,
2260
- password: hashedPassword,
2261
- roleId: resolvedRoleId,
2262
- emailVerified,
2263
- status: "pending"
2264
- };
2265
- await this.userValidator.validateCreateUser(userDetails);
2266
- const newUser = await this.userRepository.create(userDetails);
2267
- return this.sanitizeUser(newUser);
2645
+ await this.permissionValidator.validateCreatePermission(data);
2646
+ await this.permissionValidator.checkPermissionNameUnique(data.name);
2647
+ return await this.permissionRepository.create(data);
2268
2648
  }
2269
2649
  async update(id, data) {
2270
- const { password, image } = data;
2271
- await this.userValidator.checkUserExists(id);
2272
- await this.userValidator.checkEmailUnique(data.email, id);
2273
- const currentUser = await this.userRepository.getById(id);
2274
- const hashedPassword = await this.encryptionService.hashPassword(password);
2275
- const updateData = {
2276
- ...data,
2277
- image,
2278
- ...hashedPassword && { password: hashedPassword }
2279
- };
2280
- const cleanedUpdateData = clean(updateData);
2281
- const updatedUser = await this.userRepository.update(id, cleanedUpdateData);
2282
- return this.sanitizeUser(updatedUser);
2650
+ await this.permissionValidator.checkPermissionExists(id);
2651
+ await this.permissionValidator.checkPermissionNameUnique(data.name, id);
2652
+ return await this.permissionRepository.update(id, data);
2283
2653
  }
2284
2654
  async delete(id) {
2285
- await this.userValidator.checkUserExists(id);
2286
- const user = await this.userRepository.delete(id);
2287
- return this.sanitizeUser(user);
2288
- }
2289
- async deleteAll() {
2290
- const deletedUsers = await this.userRepository.deleteAll();
2291
- return this.sanitizeUsers(deletedUsers);
2655
+ await this.permissionValidator.checkPermissionExists(id);
2656
+ return await this.permissionRepository.delete(id);
2292
2657
  }
2293
- async getRoleName(id) {
2294
- await this.userValidator.checkUserExists(id);
2295
- return await this.userRepository.getRoleNameById(id);
2658
+ async getPermissionsByRole(roleId) {
2659
+ return await this.permissionRepository.getPermissionsByRole(roleId);
2296
2660
  }
2297
- async getPassword(email) {
2298
- await this.userValidator.checkUserExistsByEmail(email);
2299
- return await this.userRepository.getUserPassword(email);
2661
+ async getRolesByPermission(permissionId) {
2662
+ await this.permissionValidator.checkPermissionExists(permissionId);
2663
+ return await this.permissionRepository.getRolesByPermission(permissionId);
2300
2664
  }
2301
- async assignRole(id, roleId, roleName) {
2302
- await this.userValidator.checkUserExists(id);
2303
- const resolvedRoleId = await this.resolveUserRole(roleId, roleName);
2304
- const updatedUser = await this.userRepository.update(id, { roleId: resolvedRoleId });
2305
- return this.sanitizeUser(updatedUser);
2665
+ async assignPermissionToRole(roleId, permissionId) {
2666
+ await this.permissionValidator.checkRoleHasPermission(roleId, permissionId);
2667
+ return await this.permissionRepository.assignPermissionToRole(roleId, permissionId);
2306
2668
  }
2307
- async removeRole(id) {
2308
- await this.userValidator.checkUserExists(id);
2309
- const updatedUser = await this.userRepository.update(id, { roleId: null });
2310
- return this.sanitizeUser(updatedUser);
2669
+ async removePermissionFromRole(roleId, permissionId) {
2670
+ return await this.permissionRepository.removePermissionFromRole(roleId, permissionId);
2311
2671
  }
2312
- async seedAdminUser() {
2313
- const email = "admin@admin.com";
2314
- const adminRole = await this.roleValidator.checkAdminRoleExists();
2315
- const existingUser = await this.userRepository.getByEmail(email);
2316
- if (existingUser) {
2317
- await this.delete(existingUser.id);
2672
+ async seedDefaultPermissions(defaultPermissions) {
2673
+ const createdPermissions = [];
2674
+ for (const permission of defaultPermissions) {
2675
+ try {
2676
+ const permissionEntity = await this.create(permission);
2677
+ createdPermissions.push(permissionEntity);
2678
+ } catch (error) {
2679
+ continue;
2680
+ }
2318
2681
  }
2319
- const newAdminUser = await this.create({
2320
- id: "USR00",
2321
- name: "System Administrator",
2322
- email,
2323
- password: "12345678",
2324
- image: null,
2325
- roleId: adminRole.id,
2326
- status: "active",
2327
- emailVerified: true
2328
- });
2329
- return this.sanitizeUser(newAdminUser);
2682
+ return createdPermissions;
2330
2683
  }
2331
- async updateLang(language) {
2332
- setLanguage(language);
2333
- return language;
2684
+ async seedDefaultRolePermissions(defaultRolePermissions) {
2685
+ const results = [];
2686
+ for (const { roleName, permissions } of defaultRolePermissions) {
2687
+ try {
2688
+ await this.permissionValidator.checkRoleExistsByName(roleName);
2689
+ const role = await this.roleService.getByName(roleName);
2690
+ for (const permissionName of permissions) {
2691
+ try {
2692
+ await this.permissionValidator.checkPermissionExistsByName(permissionName);
2693
+ const permission = await this.getByName(permissionName);
2694
+ await this.permissionValidator.checkRoleHasPermission(role.id, permission.id);
2695
+ await this.assignPermissionToRole(role.id, permission.id);
2696
+ results.push({ role: roleName, permission: permissionName });
2697
+ } catch (error) {
2698
+ continue;
2699
+ }
2700
+ }
2701
+ } catch (error) {
2702
+ continue;
2703
+ }
2704
+ }
2705
+ return results;
2334
2706
  }
2335
- async getLang() {
2336
- return getCurrentLanguage2();
2707
+ async deleteAll() {
2708
+ return await this.permissionRepository.deleteAll();
2337
2709
  }
2338
- };
2339
- __decorateClass([
2340
- Transactional()
2341
- ], UserService.prototype, "create", 1);
2342
- UserService = __decorateClass([
2343
- Injectable12()
2344
- ], UserService);
2710
+ }, __name(_a33, "PermissionService"), _a33);
2711
+ PermissionService = __decorate19([
2712
+ Injectable12(),
2713
+ __metadata14("design:paramtypes", [typeof (_a32 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a32 : Object, typeof (_b6 = typeof PermissionValidator !== "undefined" && PermissionValidator) === "function" ? _b6 : Object, typeof (_c3 = typeof RoleService !== "undefined" && RoleService) === "function" ? _c3 : Object])
2714
+ ], PermissionService);
2345
2715
 
2346
- // src/users/UserController.ts
2347
- import { Controller as Controller4, Get as Get4, Post as Post4, Put as Put3, Delete as Delete3, Params as Params4, Body as Body4, t as t9 } from "najm-api";
2348
- var UserController = class {
2349
- constructor(userService) {
2350
- this.userService = userService;
2716
+ // src/permissions/PermissionController.ts
2717
+ var __decorate20 = function(decorators, target, key, desc) {
2718
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2719
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2720
+ 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;
2721
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2722
+ };
2723
+ var __metadata15 = function(k, v) {
2724
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2725
+ };
2726
+ var __param6 = function(paramIndex, decorator) {
2727
+ return function(target, key) {
2728
+ decorator(target, key, paramIndex);
2729
+ };
2730
+ };
2731
+ var _a34;
2732
+ var _a35;
2733
+ var PermissionController = (_a35 = class {
2734
+ constructor(permissionService) {
2735
+ this.permissionService = permissionService;
2351
2736
  }
2352
- async getUsers() {
2353
- const users = await this.userService.getAll();
2737
+ async getPermissions() {
2738
+ const permissions = await this.permissionService.getAll();
2354
2739
  return {
2355
- data: users,
2356
- message: t9("users.success.retrieved"),
2740
+ data: permissions,
2741
+ message: t9("permissions.success.retrieved"),
2357
2742
  status: "success"
2358
2743
  };
2359
2744
  }
2360
- async getLang() {
2361
- const language = await this.userService.getLang();
2745
+ async getPermission(id) {
2746
+ const permission = await this.permissionService.getById(id);
2362
2747
  return {
2363
- data: { language },
2364
- message: t9("users.success.retrieved"),
2748
+ data: permission,
2749
+ message: t9("permissions.success.retrieved"),
2365
2750
  status: "success"
2366
2751
  };
2367
2752
  }
2368
- async updateLang(language) {
2369
- const data = await this.userService.updateLang(language);
2753
+ async create(body) {
2754
+ const newPermission = await this.permissionService.create(body);
2370
2755
  return {
2371
- data,
2372
- message: t9("users.success.updated"),
2756
+ data: newPermission,
2757
+ message: t9("permissions.success.created"),
2373
2758
  status: "success"
2374
2759
  };
2375
2760
  }
2376
- async getUser(id) {
2377
- const user = await this.userService.getById(id);
2761
+ async update(id, body) {
2762
+ const updatedPermission = await this.permissionService.update(id, body);
2378
2763
  return {
2379
- data: user,
2380
- message: t9("users.success.retrieved"),
2764
+ data: updatedPermission,
2765
+ message: t9("permissions.success.updated"),
2381
2766
  status: "success"
2382
2767
  };
2383
2768
  }
2384
- async getByEmail(email) {
2385
- const user = await this.userService.getByEmail(email);
2769
+ async delete(id) {
2770
+ const result = await this.permissionService.delete(id);
2386
2771
  return {
2387
- data: user,
2388
- message: t9("users.success.retrieved"),
2772
+ data: result,
2773
+ message: t9("permissions.success.deleted"),
2389
2774
  status: "success"
2390
2775
  };
2391
2776
  }
2392
- async getRole(userId) {
2393
- const role = await this.userService.getRoleName(userId);
2777
+ async getByRole(roleId) {
2778
+ const permissions = await this.permissionService.getPermissionsByRole(roleId);
2394
2779
  return {
2395
- data: role,
2396
- message: t9("users.success.retrieved"),
2780
+ data: permissions,
2781
+ message: t9("permissions.success.retrieved"),
2397
2782
  status: "success"
2398
2783
  };
2399
2784
  }
2400
- async create(body) {
2401
- const newUser = await this.userService.create(body);
2785
+ async getRolesByPermission(permissionId) {
2786
+ const roles = await this.permissionService.getRolesByPermission(permissionId);
2402
2787
  return {
2403
- data: newUser,
2404
- message: t9("users.success.created"),
2788
+ data: roles,
2789
+ message: t9("permissions.success.retrieved"),
2405
2790
  status: "success"
2406
2791
  };
2407
2792
  }
2408
- async update(id, body) {
2409
- const updatedUser = await this.userService.update(id, body);
2793
+ async assignToRole(roleId, permissionId) {
2794
+ const result = await this.permissionService.assignPermissionToRole(roleId, permissionId);
2410
2795
  return {
2411
- data: updatedUser,
2412
- message: t9("users.success.updated"),
2796
+ data: result,
2797
+ message: t9("permissions.success.assigned"),
2413
2798
  status: "success"
2414
2799
  };
2415
2800
  }
2416
- async delete(id) {
2417
- const result = await this.userService.delete(id);
2801
+ async removeFromRole(roleId, permissionId) {
2802
+ const result = await this.permissionService.removePermissionFromRole(roleId, permissionId);
2418
2803
  return {
2419
2804
  data: result,
2420
- message: t9("users.success.deleted"),
2805
+ message: t9("permissions.success.removed"),
2421
2806
  status: "success"
2422
2807
  };
2423
2808
  }
2424
2809
  async deleteAll() {
2425
- const result = await this.userService.deleteAll();
2810
+ const result = await this.permissionService.deleteAll();
2426
2811
  return {
2427
2812
  data: result,
2428
- message: t9("users.success.allDeleted"),
2429
- status: "success"
2430
- };
2431
- }
2432
- async assignRole(userId, roleId) {
2433
- await this.userService.assignRole(userId, roleId);
2434
- return {
2435
- message: t9("users.success.updated"),
2436
- status: "success"
2437
- };
2438
- }
2439
- async removeRole(userId) {
2440
- await this.userService.removeRole(userId);
2441
- return {
2442
- message: t9("users.success.updated"),
2813
+ message: t9("permissions.success.allDeleted"),
2443
2814
  status: "success"
2444
2815
  };
2445
2816
  }
2446
- };
2447
- __decorateClass([
2817
+ }, __name(_a35, "PermissionController"), _a35);
2818
+ __decorate20([
2448
2819
  Get4(),
2449
- isAdmin()
2450
- ], UserController.prototype, "getUsers", 1);
2451
- __decorateClass([
2452
- Get4("/lang"),
2453
- isAuth()
2454
- ], UserController.prototype, "getLang", 1);
2455
- __decorateClass([
2456
- Post4("/lang/:language"),
2457
- isAuth(),
2458
- __decorateParam(0, Params4("language"))
2459
- ], UserController.prototype, "updateLang", 1);
2460
- __decorateClass([
2820
+ __metadata15("design:type", Function),
2821
+ __metadata15("design:paramtypes", []),
2822
+ __metadata15("design:returntype", Promise)
2823
+ ], PermissionController.prototype, "getPermissions", null);
2824
+ __decorate20([
2461
2825
  Get4("/:id"),
2462
- isAdmin(),
2463
- __decorateParam(0, Params4("id"))
2464
- ], UserController.prototype, "getUser", 1);
2465
- __decorateClass([
2466
- Get4("/email/:email"),
2467
- isAdmin(),
2468
- __decorateParam(0, Params4("email"))
2469
- ], UserController.prototype, "getByEmail", 1);
2470
- __decorateClass([
2471
- Get4("/role/:userId"),
2472
- isAdmin(),
2473
- __decorateParam(0, Params4("userId"))
2474
- ], UserController.prototype, "getRole", 1);
2475
- __decorateClass([
2826
+ __param6(0, Params4("id")),
2827
+ __metadata15("design:type", Function),
2828
+ __metadata15("design:paramtypes", [String]),
2829
+ __metadata15("design:returntype", Promise)
2830
+ ], PermissionController.prototype, "getPermission", null);
2831
+ __decorate20([
2476
2832
  Post4(),
2477
- isAdmin(),
2478
- __decorateParam(0, Body4())
2479
- ], UserController.prototype, "create", 1);
2480
- __decorateClass([
2833
+ __param6(0, Body4()),
2834
+ __metadata15("design:type", Function),
2835
+ __metadata15("design:paramtypes", [Object]),
2836
+ __metadata15("design:returntype", Promise)
2837
+ ], PermissionController.prototype, "create", null);
2838
+ __decorate20([
2481
2839
  Put3("/:id"),
2482
- isAdmin(),
2483
- __decorateParam(0, Params4("id")),
2484
- __decorateParam(1, Body4())
2485
- ], UserController.prototype, "update", 1);
2486
- __decorateClass([
2840
+ __param6(0, Params4("id")),
2841
+ __param6(1, Body4()),
2842
+ __metadata15("design:type", Function),
2843
+ __metadata15("design:paramtypes", [String, Object]),
2844
+ __metadata15("design:returntype", Promise)
2845
+ ], PermissionController.prototype, "update", null);
2846
+ __decorate20([
2487
2847
  Delete3("/:id"),
2488
- isAdmin(),
2489
- __decorateParam(0, Params4("id"))
2490
- ], UserController.prototype, "delete", 1);
2491
- __decorateClass([
2848
+ __param6(0, Params4("id")),
2849
+ __metadata15("design:type", Function),
2850
+ __metadata15("design:paramtypes", [String]),
2851
+ __metadata15("design:returntype", Promise)
2852
+ ], PermissionController.prototype, "delete", null);
2853
+ __decorate20([
2854
+ Get4("/role/:roleId"),
2855
+ __param6(0, Params4("roleId")),
2856
+ __metadata15("design:type", Function),
2857
+ __metadata15("design:paramtypes", [String]),
2858
+ __metadata15("design:returntype", Promise)
2859
+ ], PermissionController.prototype, "getByRole", null);
2860
+ __decorate20([
2861
+ Get4("/roles/:permissionId"),
2862
+ __param6(0, Params4("permissionId")),
2863
+ __metadata15("design:type", Function),
2864
+ __metadata15("design:paramtypes", [String]),
2865
+ __metadata15("design:returntype", Promise)
2866
+ ], PermissionController.prototype, "getRolesByPermission", null);
2867
+ __decorate20([
2868
+ Post4("/assign/:roleId/:permissionId"),
2869
+ __param6(0, Params4("roleId")),
2870
+ __param6(1, Params4("permissionId")),
2871
+ __metadata15("design:type", Function),
2872
+ __metadata15("design:paramtypes", [String, String]),
2873
+ __metadata15("design:returntype", Promise)
2874
+ ], PermissionController.prototype, "assignToRole", null);
2875
+ __decorate20([
2876
+ Delete3("/remove/:roleId/:permissionId"),
2877
+ __param6(0, Params4("roleId")),
2878
+ __param6(1, Params4("permissionId")),
2879
+ __metadata15("design:type", Function),
2880
+ __metadata15("design:paramtypes", [String, String]),
2881
+ __metadata15("design:returntype", Promise)
2882
+ ], PermissionController.prototype, "removeFromRole", null);
2883
+ __decorate20([
2492
2884
  Delete3(),
2493
- isAdmin()
2494
- ], UserController.prototype, "deleteAll", 1);
2495
- __decorateClass([
2496
- Post4("/assign/:userId/:roleId"),
2497
2885
  isAdmin(),
2498
- __decorateParam(0, Params4("userId")),
2499
- __decorateParam(1, Params4("roleId"))
2500
- ], UserController.prototype, "assignRole", 1);
2501
- __decorateClass([
2502
- Delete3("/remove/:userId"),
2886
+ __metadata15("design:type", Function),
2887
+ __metadata15("design:paramtypes", []),
2888
+ __metadata15("design:returntype", Promise)
2889
+ ], PermissionController.prototype, "deleteAll", null);
2890
+ PermissionController = __decorate20([
2891
+ Controller4("/permissions"),
2503
2892
  isAdmin(),
2504
- __decorateParam(0, Params4("userId"))
2505
- ], UserController.prototype, "removeRole", 1);
2506
- UserController = __decorateClass([
2507
- Controller4("/users")
2508
- ], UserController);
2893
+ __metadata15("design:paramtypes", [typeof (_a34 = typeof PermissionService !== "undefined" && PermissionService) === "function" ? _a34 : Object])
2894
+ ], PermissionController);
2509
2895
 
2510
2896
  // src/plugin.ts
2511
2897
  var AuthPlugin = {
2512
2898
  name: "najm-auth",
2513
- version: "0.1.3",
2514
2899
  database: "default",
2515
2900
  controllers: [
2516
2901
  UserController,
@@ -2539,16 +2924,7 @@ var AuthPlugin = {
2539
2924
  PermissionValidator,
2540
2925
  RoleGuards,
2541
2926
  PermissionGuards
2542
- ],
2543
- onSetup: async () => {
2544
- console.log(" \u2713 najm-auth plugin initialized");
2545
- console.log(" - Authentication endpoints ready");
2546
- console.log(" - Authorization system active");
2547
- console.log(" - Database connection established");
2548
- },
2549
- onTeardown: async () => {
2550
- console.log(" \u2713 najm-auth plugin cleanup complete");
2551
- }
2927
+ ]
2552
2928
  };
2553
2929
  export {
2554
2930
  AuthController,
@@ -2684,19 +3060,19 @@ export {
2684
3060
  semesterEnum,
2685
3061
  settingsSchema,
2686
3062
  studentSchema,
2687
- studentStatusEnum,
3063
+ studentStatusEnum2 as studentStatusEnum,
2688
3064
  subjectSchema,
2689
3065
  submissionTypeEnum,
2690
3066
  teacherFullSchema,
2691
3067
  teacherPersonalSchema,
2692
3068
  teacherProfessionalSchema,
2693
3069
  teacherStatusEnum,
2694
- tokenStatusEnum,
2695
- tokenTypeEnum,
3070
+ tokenStatusEnum2 as tokenStatusEnum,
3071
+ tokenTypeEnum2 as tokenTypeEnum,
2696
3072
  tokensTable,
2697
3073
  trackerModeEnum,
2698
3074
  userSchema,
2699
- userStatusEnum,
3075
+ userStatusEnum2 as userStatusEnum,
2700
3076
  userTypeEnum,
2701
3077
  usersTable,
2702
3078
  vehicleDocumentTypeEnum,