najm-auth 1.1.44 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +765 -664
- package/dist/{NajmAuthClient-D08--i69.d.ts → NajmAuthClient-B9dGk9MH.d.ts} +12 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +50 -1
- package/dist/client/react/index.d.ts +41 -2
- package/dist/client/react/index.js +129 -5
- package/dist/client/server/index.d.ts +1 -1
- package/dist/client/server/index.js +49 -0
- package/dist/index.d.ts +171 -14
- package/dist/index.js +1470 -589
- package/dist/schema/pg.d.ts +222 -1
- package/dist/schema/pg.js +13 -1
- package/dist/schema/sqlite.d.ts +246 -1
- package/dist/schema/sqlite.js +12 -0
- package/package.json +13 -10
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/AuthPlugin.ts
|
|
9
|
-
import { Err as
|
|
9
|
+
import { Err as Err10, plugin } from "najm-core";
|
|
10
10
|
import { cache } from "najm-cache";
|
|
11
11
|
|
|
12
12
|
// src/auth.tokens.ts
|
|
@@ -18,7 +18,7 @@ var AUTH_PERMISSIONS = /* @__PURE__ */ Symbol.for("najm:auth:permissions");
|
|
|
18
18
|
var AUTH_ENCRYPTION_KEY = /* @__PURE__ */ Symbol.for("najm:auth:encryption-key");
|
|
19
19
|
|
|
20
20
|
// src/schema/pg.ts
|
|
21
|
-
import { pgTable, text, boolean, timestamp, pgEnum, primaryKey, integer, index } from "drizzle-orm/pg-core";
|
|
21
|
+
import { pgTable, text, boolean, timestamp, pgEnum, primaryKey, integer, index, uniqueIndex } from "drizzle-orm/pg-core";
|
|
22
22
|
import { sql } from "drizzle-orm";
|
|
23
23
|
import { nanoid } from "nanoid";
|
|
24
24
|
|
|
@@ -58,6 +58,16 @@ var usersTable = pgTable("users", {
|
|
|
58
58
|
}, (table) => ({
|
|
59
59
|
roleIdx: index("users_role_id_idx").on(table.roleId)
|
|
60
60
|
}));
|
|
61
|
+
var oauthAccountsTable = pgTable("oauth_accounts", {
|
|
62
|
+
...baseFields(10),
|
|
63
|
+
userId: text("user_id").notNull().references(() => usersTable.id, { onDelete: "cascade" }),
|
|
64
|
+
provider: text("provider").notNull(),
|
|
65
|
+
providerAccountId: text("provider_account_id").notNull()
|
|
66
|
+
}, (table) => ({
|
|
67
|
+
providerAccountUnique: uniqueIndex("oauth_accounts_provider_account_unique").on(table.provider, table.providerAccountId),
|
|
68
|
+
userProviderUnique: uniqueIndex("oauth_accounts_user_provider_unique").on(table.userId, table.provider),
|
|
69
|
+
userIdIdx: index("oauth_accounts_user_id_idx").on(table.userId)
|
|
70
|
+
}));
|
|
61
71
|
var permissionsTable = pgTable("permissions", {
|
|
62
72
|
...baseFields(5),
|
|
63
73
|
name: text("name").notNull().unique(),
|
|
@@ -89,6 +99,7 @@ var rolePermissionsTable = pgTable("role_permissions", {
|
|
|
89
99
|
}));
|
|
90
100
|
var authSchema = {
|
|
91
101
|
users: usersTable,
|
|
102
|
+
oauthAccounts: oauthAccountsTable,
|
|
92
103
|
tokens: tokensTable,
|
|
93
104
|
roles: rolesTable,
|
|
94
105
|
permissions: permissionsTable,
|
|
@@ -96,7 +107,7 @@ var authSchema = {
|
|
|
96
107
|
};
|
|
97
108
|
|
|
98
109
|
// src/schema/sqlite.ts
|
|
99
|
-
import { sqliteTable, text as text2, integer as integer2, uniqueIndex, index as index2 } from "drizzle-orm/sqlite-core";
|
|
110
|
+
import { sqliteTable, text as text2, integer as integer2, uniqueIndex as uniqueIndex2, index as index2 } from "drizzle-orm/sqlite-core";
|
|
100
111
|
import { sql as sql2 } from "drizzle-orm";
|
|
101
112
|
import { nanoid as nanoid2 } from "nanoid";
|
|
102
113
|
var baseFields2 = /* @__PURE__ */ __name((idLength = 5) => ({
|
|
@@ -126,6 +137,16 @@ var usersTable2 = sqliteTable("users", {
|
|
|
126
137
|
}, (table) => ({
|
|
127
138
|
roleIdx: index2("users_role_id_idx").on(table.roleId)
|
|
128
139
|
}));
|
|
140
|
+
var oauthAccountsTable2 = sqliteTable("oauth_accounts", {
|
|
141
|
+
...baseFields2(10),
|
|
142
|
+
userId: text2("user_id").notNull().references(() => usersTable2.id, { onDelete: "cascade" }),
|
|
143
|
+
provider: text2("provider").notNull(),
|
|
144
|
+
providerAccountId: text2("provider_account_id").notNull()
|
|
145
|
+
}, (table) => ({
|
|
146
|
+
providerAccountUnique: uniqueIndex2("oauth_accounts_provider_account_unique").on(table.provider, table.providerAccountId),
|
|
147
|
+
userProviderUnique: uniqueIndex2("oauth_accounts_user_provider_unique").on(table.userId, table.provider),
|
|
148
|
+
userIdIdx: index2("oauth_accounts_user_id_idx").on(table.userId)
|
|
149
|
+
}));
|
|
129
150
|
var permissionsTable2 = sqliteTable("permissions", {
|
|
130
151
|
...baseFields2(5),
|
|
131
152
|
name: text2("name").notNull().unique(),
|
|
@@ -153,10 +174,11 @@ var rolePermissionsTable2 = sqliteTable("role_permissions", {
|
|
|
153
174
|
roleId: text2("role_id").notNull().references(() => rolesTable2.id, { onDelete: "cascade" }),
|
|
154
175
|
permissionId: text2("permission_id").notNull().references(() => permissionsTable2.id, { onDelete: "cascade" })
|
|
155
176
|
}, (table) => ({
|
|
156
|
-
uniq:
|
|
177
|
+
uniq: uniqueIndex2("role_permission_unique").on(table.roleId, table.permissionId)
|
|
157
178
|
}));
|
|
158
179
|
var authSchema2 = {
|
|
159
180
|
users: usersTable2,
|
|
181
|
+
oauthAccounts: oauthAccountsTable2,
|
|
160
182
|
tokens: tokensTable2,
|
|
161
183
|
roles: rolesTable2,
|
|
162
184
|
permissions: permissionsTable2,
|
|
@@ -290,6 +312,9 @@ var CookieManager = class CookieManager2 {
|
|
|
290
312
|
get cookieName() {
|
|
291
313
|
return this.config.refreshCookieName || "refreshToken";
|
|
292
314
|
}
|
|
315
|
+
get refreshCookiePath() {
|
|
316
|
+
return this.config.refreshCookiePath || "/";
|
|
317
|
+
}
|
|
293
318
|
get sessionCookieName() {
|
|
294
319
|
return this.config.session.name;
|
|
295
320
|
}
|
|
@@ -304,10 +329,10 @@ var CookieManager = class CookieManager2 {
|
|
|
304
329
|
// =========================================================================
|
|
305
330
|
setRefreshToken(refreshToken) {
|
|
306
331
|
const maxAge = timestring(this.config.jwt.refreshExpiresIn, "s");
|
|
307
|
-
this.cookieService.set(this.cookieName, refreshToken, { maxAge });
|
|
332
|
+
this.cookieService.set(this.cookieName, refreshToken, { maxAge, path: this.refreshCookiePath });
|
|
308
333
|
}
|
|
309
334
|
clearRefreshToken() {
|
|
310
|
-
this.cookieService.delete(this.cookieName);
|
|
335
|
+
this.cookieService.delete(this.cookieName, { path: this.refreshCookiePath });
|
|
311
336
|
}
|
|
312
337
|
getRefreshToken() {
|
|
313
338
|
return this.cookieService.get(this.cookieName);
|
|
@@ -373,14 +398,14 @@ CookieManager = __decorate2([
|
|
|
373
398
|
], CookieManager);
|
|
374
399
|
|
|
375
400
|
// src/auth/AuthController.ts
|
|
376
|
-
import { Controller
|
|
377
|
-
import { Get
|
|
378
|
-
import { Body
|
|
401
|
+
import { Controller } from "najm-core";
|
|
402
|
+
import { Get, Post, ResMsg } from "najm-core";
|
|
403
|
+
import { Body, User as User3, Headers } from "najm-core";
|
|
379
404
|
|
|
380
405
|
// src/auth/AuthService.ts
|
|
381
|
-
import { Injectable as
|
|
382
|
-
import { Err as
|
|
383
|
-
import { I18n as
|
|
406
|
+
import { Injectable as Injectable8, Inject as Inject8 } from "najm-core";
|
|
407
|
+
import { Err as Err8, Log } from "najm-core";
|
|
408
|
+
import { I18n as I18n6, I18nService as I18nService2 } from "najm-i18n";
|
|
384
409
|
import { EmailService, passwordResetTemplate, accountInviteTemplate } from "najm-email";
|
|
385
410
|
import { nanoid as nanoid5 } from "nanoid";
|
|
386
411
|
|
|
@@ -388,7 +413,7 @@ import { nanoid as nanoid5 } from "nanoid";
|
|
|
388
413
|
import { Injectable as Injectable5, Inject as Inject5 } from "najm-core";
|
|
389
414
|
import { Transaction } from "najm-database";
|
|
390
415
|
import { I18nService } from "najm-i18n";
|
|
391
|
-
import { I18n as
|
|
416
|
+
import { I18n as I18n4 } from "najm-i18n";
|
|
392
417
|
|
|
393
418
|
// src/users/UserRepository.ts
|
|
394
419
|
import { eq as eq2, ne, sql as sql3 } from "drizzle-orm";
|
|
@@ -548,6 +573,15 @@ var UserRepository = class UserRepository2 {
|
|
|
548
573
|
}).from(this.users).leftJoin(this.roles, eq2(this.users.roleId, this.roles.id)).where(eq2(this.users.email, email2));
|
|
549
574
|
return existingUser;
|
|
550
575
|
}
|
|
576
|
+
async getByEmailInsensitive(email2) {
|
|
577
|
+
const [existingUser] = await this.db.select({
|
|
578
|
+
...this.q.userSelection(),
|
|
579
|
+
password: this.users.password,
|
|
580
|
+
failedLoginAttempts: this.users.failedLoginAttempts,
|
|
581
|
+
lockoutUntil: this.users.lockoutUntil
|
|
582
|
+
}).from(this.users).leftJoin(this.roles, eq2(this.users.roleId, this.roles.id)).where(sql3`lower(${this.users.email}) = ${email2.trim().toLowerCase()}`).limit(1);
|
|
583
|
+
return existingUser;
|
|
584
|
+
}
|
|
551
585
|
async create(data) {
|
|
552
586
|
const [newUser] = await this.db.insert(this.users).values(data).returning();
|
|
553
587
|
return newUser;
|
|
@@ -758,7 +792,8 @@ UserValidator = __decorate4([
|
|
|
758
792
|
], UserValidator);
|
|
759
793
|
|
|
760
794
|
// src/roles/RoleService.ts
|
|
761
|
-
import { Injectable as Injectable4 } from "najm-core";
|
|
795
|
+
import { Injectable as Injectable4, Err as Err3 } from "najm-core";
|
|
796
|
+
import { I18n as I18n3 } from "najm-i18n";
|
|
762
797
|
|
|
763
798
|
// src/roles/RoleRepository.ts
|
|
764
799
|
import { eq as eq3 } from "drizzle-orm";
|
|
@@ -782,6 +817,14 @@ var RoleRepository = class RoleRepository2 {
|
|
|
782
817
|
get roles() {
|
|
783
818
|
return this.schema.roles;
|
|
784
819
|
}
|
|
820
|
+
get users() {
|
|
821
|
+
return this.schema.users;
|
|
822
|
+
}
|
|
823
|
+
/** True if any user currently references this role (blocks deletion). */
|
|
824
|
+
async hasUsers(roleId) {
|
|
825
|
+
const rows = await this.db.select({ id: this.users.id }).from(this.users).where(eq3(this.users.roleId, roleId)).limit(1);
|
|
826
|
+
return rows.length > 0;
|
|
827
|
+
}
|
|
785
828
|
async getAll() {
|
|
786
829
|
return await this.db.select().from(this.roles);
|
|
787
830
|
}
|
|
@@ -917,6 +960,7 @@ var RoleService = class RoleService2 {
|
|
|
917
960
|
}
|
|
918
961
|
roleRepository;
|
|
919
962
|
roleValidator;
|
|
963
|
+
t;
|
|
920
964
|
constructor(roleRepository, roleValidator) {
|
|
921
965
|
this.roleRepository = roleRepository;
|
|
922
966
|
this.roleValidator = roleValidator;
|
|
@@ -936,12 +980,21 @@ var RoleService = class RoleService2 {
|
|
|
936
980
|
return await this.roleRepository.create(data);
|
|
937
981
|
}
|
|
938
982
|
async update(id, data) {
|
|
939
|
-
await this.roleValidator.checkRoleExists(id);
|
|
983
|
+
const role = await this.roleValidator.checkRoleExists(id);
|
|
984
|
+
if (role.name === ROLES.ADMIN && data.name && data.name !== ROLES.ADMIN) {
|
|
985
|
+
Err3(this.t("errors.cannotRenameSystem"), 403);
|
|
986
|
+
}
|
|
940
987
|
await this.roleValidator.checkNameUnique(data.name, id);
|
|
941
988
|
return await this.roleRepository.update(id, data);
|
|
942
989
|
}
|
|
943
990
|
async delete(id) {
|
|
944
|
-
await this.roleValidator.checkRoleExists(id);
|
|
991
|
+
const role = await this.roleValidator.checkRoleExists(id);
|
|
992
|
+
if (role.name === ROLES.ADMIN) {
|
|
993
|
+
Err3(this.t("errors.cannotDeleteSystem"), 403);
|
|
994
|
+
}
|
|
995
|
+
if (await this.roleRepository.hasUsers(id)) {
|
|
996
|
+
Err3(this.t("errors.roleInUse"), 409);
|
|
997
|
+
}
|
|
945
998
|
return await this.roleRepository.delete(id);
|
|
946
999
|
}
|
|
947
1000
|
async seedDefaultRoles(defaultRoles) {
|
|
@@ -960,6 +1013,10 @@ var RoleService = class RoleService2 {
|
|
|
960
1013
|
return role?.id;
|
|
961
1014
|
}
|
|
962
1015
|
};
|
|
1016
|
+
__decorate7([
|
|
1017
|
+
I18n3("roles"),
|
|
1018
|
+
__metadata7("design:type", Object)
|
|
1019
|
+
], RoleService.prototype, "t", void 0);
|
|
963
1020
|
RoleService = __decorate7([
|
|
964
1021
|
Injectable4(),
|
|
965
1022
|
__metadata7("design:paramtypes", [typeof (_a4 = typeof RoleRepository !== "undefined" && RoleRepository) === "function" ? _a4 : Object, typeof (_b2 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _b2 : Object])
|
|
@@ -972,7 +1029,7 @@ import { nanoid as nanoid3 } from "nanoid";
|
|
|
972
1029
|
import * as fs from "fs/promises";
|
|
973
1030
|
import * as path from "path";
|
|
974
1031
|
import _isEmpty from "lodash.isempty";
|
|
975
|
-
import { Err as
|
|
1032
|
+
import { Err as Err4 } from "najm-core";
|
|
976
1033
|
var avatarsPath = path.join(process.cwd(), "avatars");
|
|
977
1034
|
var parseSchema = /* @__PURE__ */ __name(async (schema, data) => {
|
|
978
1035
|
try {
|
|
@@ -980,7 +1037,7 @@ var parseSchema = /* @__PURE__ */ __name(async (schema, data) => {
|
|
|
980
1037
|
} catch (error) {
|
|
981
1038
|
const errors = error.issues || error.errors || [];
|
|
982
1039
|
const errorMessage = errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
|
|
983
|
-
|
|
1040
|
+
Err4(errorMessage);
|
|
984
1041
|
}
|
|
985
1042
|
}, "parseSchema");
|
|
986
1043
|
var clean = /* @__PURE__ */ __name((obj) => {
|
|
@@ -1066,7 +1123,7 @@ var isPath = /* @__PURE__ */ __name((img) => typeof img === "string" && img.trim
|
|
|
1066
1123
|
var isFile = /* @__PURE__ */ __name((img) => !!img && typeof img !== "string" && img instanceof File, "isFile");
|
|
1067
1124
|
|
|
1068
1125
|
// src/users/UserService.ts
|
|
1069
|
-
import { Err as
|
|
1126
|
+
import { Err as Err5 } from "najm-core";
|
|
1070
1127
|
var __decorate8 = function(decorators, target, key, desc) {
|
|
1071
1128
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1072
1129
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1121,7 +1178,7 @@ var UserService = class UserService2 {
|
|
|
1121
1178
|
}
|
|
1122
1179
|
requireUser(user) {
|
|
1123
1180
|
if (!user) {
|
|
1124
|
-
|
|
1181
|
+
Err5(this.t("errors.notFound"), 404);
|
|
1125
1182
|
}
|
|
1126
1183
|
return user;
|
|
1127
1184
|
}
|
|
@@ -1135,12 +1192,12 @@ var UserService = class UserService2 {
|
|
|
1135
1192
|
if (roleByName) {
|
|
1136
1193
|
return roleByName.id;
|
|
1137
1194
|
}
|
|
1138
|
-
|
|
1195
|
+
Err5(`Role '${roleName}' not found`);
|
|
1139
1196
|
}
|
|
1140
1197
|
if (this.authConfig.defaultRole) {
|
|
1141
1198
|
const defaultRole = await this.roleService.getByName(this.authConfig.defaultRole);
|
|
1142
1199
|
if (!defaultRole) {
|
|
1143
|
-
|
|
1200
|
+
Err5(`Default role '${this.authConfig.defaultRole}' not found. Create it first or set defaultRole to null in auth config.`);
|
|
1144
1201
|
}
|
|
1145
1202
|
return defaultRole.id;
|
|
1146
1203
|
}
|
|
@@ -1167,13 +1224,16 @@ var UserService = class UserService2 {
|
|
|
1167
1224
|
async findByEmail(email2) {
|
|
1168
1225
|
return await this.userRepository.getByEmail(email2);
|
|
1169
1226
|
}
|
|
1227
|
+
async findByEmailInsensitive(email2) {
|
|
1228
|
+
return await this.userRepository.getByEmailInsensitive(email2);
|
|
1229
|
+
}
|
|
1170
1230
|
async getAuthRecordById(id) {
|
|
1171
1231
|
return await this.userRepository.getRawById(id);
|
|
1172
1232
|
}
|
|
1173
1233
|
async create(data) {
|
|
1174
1234
|
const { id, email: email2, name, image, emailVerified, password, roleId, role } = data;
|
|
1175
1235
|
if (!password || typeof password !== "string" || password.trim().length === 0) {
|
|
1176
|
-
|
|
1236
|
+
Err5("Password is required");
|
|
1177
1237
|
}
|
|
1178
1238
|
this.userValidator.validatePasswordStrength(password);
|
|
1179
1239
|
let userId = id || nanoid3(10);
|
|
@@ -1247,10 +1307,10 @@ var UserService = class UserService2 {
|
|
|
1247
1307
|
}
|
|
1248
1308
|
async seedAdminUser(config) {
|
|
1249
1309
|
if (!config?.email || !config?.password) {
|
|
1250
|
-
|
|
1310
|
+
Err5("Admin email and password must be provided via config parameter");
|
|
1251
1311
|
}
|
|
1252
1312
|
if (config.password.length < 12) {
|
|
1253
|
-
|
|
1313
|
+
Err5("Admin password must be at least 12 characters");
|
|
1254
1314
|
}
|
|
1255
1315
|
const adminRole = await this.roleValidator.checkAdminRoleExists();
|
|
1256
1316
|
const existingUser = await this.userRepository.getByEmail(config.email);
|
|
@@ -1279,7 +1339,7 @@ var UserService = class UserService2 {
|
|
|
1279
1339
|
}
|
|
1280
1340
|
};
|
|
1281
1341
|
__decorate8([
|
|
1282
|
-
|
|
1342
|
+
I18n4("users"),
|
|
1283
1343
|
__metadata8("design:type", Object)
|
|
1284
1344
|
], UserService.prototype, "t", void 0);
|
|
1285
1345
|
__decorate8([
|
|
@@ -1296,7 +1356,7 @@ UserService = __decorate8([
|
|
|
1296
1356
|
|
|
1297
1357
|
// src/tokens/TokenService.ts
|
|
1298
1358
|
import { Injectable as Injectable6, Inject as Inject7 } from "najm-core";
|
|
1299
|
-
import { I18n as
|
|
1359
|
+
import { I18n as I18n5 } from "najm-i18n";
|
|
1300
1360
|
import { CacheService } from "najm-cache";
|
|
1301
1361
|
import { createHash } from "crypto";
|
|
1302
1362
|
import jwt from "jsonwebtoken";
|
|
@@ -1413,7 +1473,7 @@ TokenRepository = __decorate9([
|
|
|
1413
1473
|
|
|
1414
1474
|
// src/tokens/TokenService.ts
|
|
1415
1475
|
import timestring2 from "timestring";
|
|
1416
|
-
import { Err as
|
|
1476
|
+
import { Err as Err6 } from "najm-core";
|
|
1417
1477
|
var __decorate10 = function(decorators, target, key, desc) {
|
|
1418
1478
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1419
1479
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1482,7 +1542,7 @@ var TokenService = class TokenService2 {
|
|
|
1482
1542
|
if (authorization?.startsWith("Bearer ")) {
|
|
1483
1543
|
return authorization.split(" ")[1];
|
|
1484
1544
|
}
|
|
1485
|
-
|
|
1545
|
+
Err6(this.t("errors.tokenMissing"));
|
|
1486
1546
|
}
|
|
1487
1547
|
/**
|
|
1488
1548
|
* Verify access token and check blacklist
|
|
@@ -1493,7 +1553,7 @@ var TokenService = class TokenService2 {
|
|
|
1493
1553
|
try {
|
|
1494
1554
|
payload = jwt.verify(token, this.config.jwt.accessSecret);
|
|
1495
1555
|
} catch {
|
|
1496
|
-
|
|
1556
|
+
Err6(this.t("errors.tokenVerificationFailed"));
|
|
1497
1557
|
}
|
|
1498
1558
|
const sessionKey = this.sessionVersionKey(payload.userId);
|
|
1499
1559
|
const blacklistKey = payload.jti ? `${this.blacklistPrefix}${payload.jti}` : null;
|
|
@@ -1506,15 +1566,15 @@ var TokenService = class TokenService2 {
|
|
|
1506
1566
|
const values = await this.getCacheValues(keys);
|
|
1507
1567
|
const valueByKey = new Map(keys.map((key, i) => [key, values[i]]));
|
|
1508
1568
|
if (blacklistKey && valueByKey.get(blacklistKey) != null) {
|
|
1509
|
-
|
|
1569
|
+
Err6(this.t("errors.tokenRevoked"));
|
|
1510
1570
|
}
|
|
1511
1571
|
if (familyKey && valueByKey.get(familyKey) != null) {
|
|
1512
|
-
|
|
1572
|
+
Err6(this.t("errors.tokenRevoked"));
|
|
1513
1573
|
}
|
|
1514
1574
|
const activeSessionVersion = this.parseSessionVersion(valueByKey.get(sessionKey) ?? null);
|
|
1515
1575
|
const tokenSessionVersion = payload.sessionVersion ?? 0;
|
|
1516
1576
|
if (tokenSessionVersion !== activeSessionVersion) {
|
|
1517
|
-
|
|
1577
|
+
Err6(this.t("errors.tokenRevoked"));
|
|
1518
1578
|
}
|
|
1519
1579
|
return payload;
|
|
1520
1580
|
}
|
|
@@ -1523,13 +1583,13 @@ var TokenService = class TokenService2 {
|
|
|
1523
1583
|
try {
|
|
1524
1584
|
decoded = jwt.verify(token, this.config.jwt.refreshSecret);
|
|
1525
1585
|
} catch {
|
|
1526
|
-
|
|
1586
|
+
Err6(this.t("errors.tokenVerificationFailed"));
|
|
1527
1587
|
}
|
|
1528
1588
|
if (decoded.type && decoded.type !== "refresh") {
|
|
1529
|
-
|
|
1589
|
+
Err6(this.t("errors.tokenVerificationFailed"));
|
|
1530
1590
|
}
|
|
1531
1591
|
if (!decoded.tokenFamily) {
|
|
1532
|
-
|
|
1592
|
+
Err6(this.t("errors.tokenVerificationFailed"));
|
|
1533
1593
|
}
|
|
1534
1594
|
return { userId: decoded.userId, tokenFamily: decoded.tokenFamily };
|
|
1535
1595
|
}
|
|
@@ -1548,12 +1608,12 @@ var TokenService = class TokenService2 {
|
|
|
1548
1608
|
async resolveUserFromCookie() {
|
|
1549
1609
|
const refreshToken = this.cookieManager.getRefreshToken();
|
|
1550
1610
|
if (!refreshToken) {
|
|
1551
|
-
|
|
1611
|
+
Err6(this.t("errors.refreshTokenMissing"));
|
|
1552
1612
|
}
|
|
1553
1613
|
const { userId, tokenFamily } = this.verifyRefreshToken(refreshToken);
|
|
1554
1614
|
const stored = await this.tokenRepository.getByFamily(tokenFamily);
|
|
1555
1615
|
if (!stored || stored.userId !== userId) {
|
|
1556
|
-
|
|
1616
|
+
Err6(this.t("errors.refreshTokenInvalid"));
|
|
1557
1617
|
}
|
|
1558
1618
|
const presentedHash = this.hashToken(refreshToken);
|
|
1559
1619
|
if (presentedHash === stored.token) {
|
|
@@ -1563,7 +1623,7 @@ var TokenService = class TokenService2 {
|
|
|
1563
1623
|
if (canRecover) {
|
|
1564
1624
|
return userId;
|
|
1565
1625
|
}
|
|
1566
|
-
|
|
1626
|
+
Err6(this.t("errors.refreshTokenInvalid"));
|
|
1567
1627
|
}
|
|
1568
1628
|
// ============ USER RETRIEVAL (MAIN METHOD) ============
|
|
1569
1629
|
async getUser(auth2) {
|
|
@@ -1604,7 +1664,15 @@ var TokenService = class TokenService2 {
|
|
|
1604
1664
|
await this.cache.set(this.sessionVersionKey(data.userId), String(sessionVersion), this.accessTokenTtlMs());
|
|
1605
1665
|
}
|
|
1606
1666
|
const token = jwt.sign({ ...data, jti, sessionVersion, exp: expiresAt }, this.config.jwt.accessSecret);
|
|
1607
|
-
return { token, expiresAt };
|
|
1667
|
+
return { token, expiresAt, sessionVersion };
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Current per-user session version (0 when never invalidated). The signed
|
|
1671
|
+
* session cookie stamps this so a fast-path reader can reject a cookie whose
|
|
1672
|
+
* session was invalidated after it was written.
|
|
1673
|
+
*/
|
|
1674
|
+
async getSessionVersion(userId) {
|
|
1675
|
+
return this.getUserSessionVersion(userId);
|
|
1608
1676
|
}
|
|
1609
1677
|
/**
|
|
1610
1678
|
* Generate access token with unique jti for blacklist support.
|
|
@@ -1643,6 +1711,7 @@ var TokenService = class TokenService2 {
|
|
|
1643
1711
|
tokenFamily: family,
|
|
1644
1712
|
roles: accessTokenData.roles,
|
|
1645
1713
|
permissions: accessTokenData.permissions,
|
|
1714
|
+
sessionVersion: access.sessionVersion,
|
|
1646
1715
|
accessToken: access.token,
|
|
1647
1716
|
refreshToken: refresh.token,
|
|
1648
1717
|
accessTokenExpiresAt: access.expiresAt,
|
|
@@ -1710,12 +1779,12 @@ var TokenService = class TokenService2 {
|
|
|
1710
1779
|
async refreshTokens() {
|
|
1711
1780
|
const refreshToken = this.cookieManager.getRefreshToken();
|
|
1712
1781
|
if (!refreshToken) {
|
|
1713
|
-
|
|
1782
|
+
Err6(this.t("errors.refreshTokenMissing"));
|
|
1714
1783
|
}
|
|
1715
1784
|
const { userId, tokenFamily } = this.verifyRefreshToken(refreshToken);
|
|
1716
1785
|
const stored = await this.tokenRepository.getByFamily(tokenFamily);
|
|
1717
1786
|
if (!stored || stored.userId !== userId) {
|
|
1718
|
-
|
|
1787
|
+
Err6(this.t("errors.refreshTokenInvalid"));
|
|
1719
1788
|
}
|
|
1720
1789
|
const presentedHash = this.hashToken(refreshToken);
|
|
1721
1790
|
if (presentedHash === stored.token) {
|
|
@@ -1725,12 +1794,12 @@ var TokenService = class TokenService2 {
|
|
|
1725
1794
|
if (canRecover) {
|
|
1726
1795
|
const claimed = await this.tokenRepository.markPreviousUsed(tokenFamily, presentedHash);
|
|
1727
1796
|
if (!claimed?.length) {
|
|
1728
|
-
|
|
1797
|
+
Err6(this.t("errors.refreshTokenInvalid"));
|
|
1729
1798
|
}
|
|
1730
1799
|
return this.generateTokens(userId, tokenFamily);
|
|
1731
1800
|
}
|
|
1732
1801
|
await this.revokeSuspectRefreshFamily(userId, tokenFamily);
|
|
1733
|
-
|
|
1802
|
+
Err6(this.t("errors.refreshTokenInvalid"));
|
|
1734
1803
|
}
|
|
1735
1804
|
/** Revoke every refresh session for a user (password change/reset, logout-all). */
|
|
1736
1805
|
async revokeAllForUser(userId) {
|
|
@@ -1762,7 +1831,7 @@ var TokenService = class TokenService2 {
|
|
|
1762
1831
|
const userId = await this.resolveUserFromCookie();
|
|
1763
1832
|
const user = await this.getUserById(userId);
|
|
1764
1833
|
if (!user) {
|
|
1765
|
-
|
|
1834
|
+
Err6(this.t("errors.refreshTokenInvalid"));
|
|
1766
1835
|
}
|
|
1767
1836
|
return user;
|
|
1768
1837
|
}
|
|
@@ -1904,15 +1973,15 @@ var TokenService = class TokenService2 {
|
|
|
1904
1973
|
try {
|
|
1905
1974
|
decoded = jwt.verify(token, this.config.jwt.refreshSecret);
|
|
1906
1975
|
} catch {
|
|
1907
|
-
|
|
1976
|
+
Err6(this.t("errors.resetTokenExpired"));
|
|
1908
1977
|
}
|
|
1909
1978
|
if (decoded.type !== "reset" && decoded.type !== "invite" || !decoded.jti) {
|
|
1910
|
-
|
|
1979
|
+
Err6(this.t("errors.invalidResetToken"));
|
|
1911
1980
|
}
|
|
1912
1981
|
const key = `${this.resetTokenPrefix}${decoded.userId}`;
|
|
1913
1982
|
const storedJti = await this.cache.get(key);
|
|
1914
1983
|
if (!storedJti || storedJti !== decoded.jti) {
|
|
1915
|
-
|
|
1984
|
+
Err6(this.t("errors.invalidResetToken"));
|
|
1916
1985
|
}
|
|
1917
1986
|
await this.cache.del(key);
|
|
1918
1987
|
return decoded.userId;
|
|
@@ -1926,7 +1995,7 @@ __decorate10([
|
|
|
1926
1995
|
__metadata10("design:type", Object)
|
|
1927
1996
|
], TokenService.prototype, "config", void 0);
|
|
1928
1997
|
__decorate10([
|
|
1929
|
-
|
|
1998
|
+
I18n5("auth"),
|
|
1930
1999
|
__metadata10("design:type", Object)
|
|
1931
2000
|
], TokenService.prototype, "t", void 0);
|
|
1932
2001
|
TokenService = TokenService_1 = __decorate10([
|
|
@@ -1936,6 +2005,10 @@ TokenService = TokenService_1 = __decorate10([
|
|
|
1936
2005
|
|
|
1937
2006
|
// src/auth/AuthService.ts
|
|
1938
2007
|
import timestring3 from "timestring";
|
|
2008
|
+
|
|
2009
|
+
// src/auth/AuthSessionService.ts
|
|
2010
|
+
import { Injectable as Injectable7 } from "najm-core";
|
|
2011
|
+
import { Err as Err7 } from "najm-core";
|
|
1939
2012
|
var __decorate11 = function(decorators, target, key, desc) {
|
|
1940
2013
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1941
2014
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1948,10 +2021,66 @@ var __metadata11 = function(k, v) {
|
|
|
1948
2021
|
var _a7;
|
|
1949
2022
|
var _b5;
|
|
1950
2023
|
var _c3;
|
|
2024
|
+
var AuthSessionService = class AuthSessionService2 {
|
|
2025
|
+
static {
|
|
2026
|
+
__name(this, "AuthSessionService");
|
|
2027
|
+
}
|
|
2028
|
+
tokenService;
|
|
2029
|
+
userService;
|
|
2030
|
+
cookieManager;
|
|
2031
|
+
constructor(tokenService, userService, cookieManager) {
|
|
2032
|
+
this.tokenService = tokenService;
|
|
2033
|
+
this.userService = userService;
|
|
2034
|
+
this.cookieManager = cookieManager;
|
|
2035
|
+
}
|
|
2036
|
+
async establish(user) {
|
|
2037
|
+
if (user.status !== "active") {
|
|
2038
|
+
Err7("oauth_account_inactive", 403);
|
|
2039
|
+
}
|
|
2040
|
+
await this.tokenService.deleteExpiredSessions();
|
|
2041
|
+
const generated = await this.tokenService.generateTokens(user.id);
|
|
2042
|
+
this.cookieManager.setRefreshToken(generated.refreshToken);
|
|
2043
|
+
await this.userService.updateLastLogin(user.id);
|
|
2044
|
+
const { roles, permissions, sessionVersion } = generated;
|
|
2045
|
+
this.cookieManager.setSessionCookie({
|
|
2046
|
+
user: {
|
|
2047
|
+
id: user.id,
|
|
2048
|
+
email: user.email,
|
|
2049
|
+
name: user.name,
|
|
2050
|
+
role: user.role ?? void 0,
|
|
2051
|
+
status: user.status ?? void 0
|
|
2052
|
+
},
|
|
2053
|
+
roles,
|
|
2054
|
+
permissions,
|
|
2055
|
+
sessionVersion
|
|
2056
|
+
});
|
|
2057
|
+
const { userId: _userId, tokenFamily: _tokenFamily, roles: _roles, permissions: _permissions, sessionVersion: _sessionVersion, ...tokens } = generated;
|
|
2058
|
+
return { ...tokens, user };
|
|
2059
|
+
}
|
|
2060
|
+
};
|
|
2061
|
+
AuthSessionService = __decorate11([
|
|
2062
|
+
Injectable7(),
|
|
2063
|
+
__metadata11("design:paramtypes", [typeof (_a7 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a7 : Object, typeof (_b5 = typeof UserService !== "undefined" && UserService) === "function" ? _b5 : Object, typeof (_c3 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _c3 : Object])
|
|
2064
|
+
], AuthSessionService);
|
|
2065
|
+
|
|
2066
|
+
// src/auth/AuthService.ts
|
|
2067
|
+
var __decorate12 = function(decorators, target, key, desc) {
|
|
2068
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2069
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2070
|
+
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;
|
|
2071
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2072
|
+
};
|
|
2073
|
+
var __metadata12 = function(k, v) {
|
|
2074
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2075
|
+
};
|
|
2076
|
+
var _a8;
|
|
2077
|
+
var _b6;
|
|
2078
|
+
var _c4;
|
|
1951
2079
|
var _d2;
|
|
1952
2080
|
var _e2;
|
|
1953
2081
|
var _f2;
|
|
1954
2082
|
var _g2;
|
|
2083
|
+
var _h2;
|
|
1955
2084
|
var AuthService = class AuthService2 {
|
|
1956
2085
|
static {
|
|
1957
2086
|
__name(this, "AuthService");
|
|
@@ -1963,11 +2092,12 @@ var AuthService = class AuthService2 {
|
|
|
1963
2092
|
cookieManager;
|
|
1964
2093
|
i18nService;
|
|
1965
2094
|
emailService;
|
|
2095
|
+
authSessionService;
|
|
1966
2096
|
config;
|
|
1967
2097
|
t;
|
|
1968
2098
|
logger;
|
|
1969
2099
|
dummyHash;
|
|
1970
|
-
constructor(tokenService, userService, userValidator, encryptionService, cookieManager, i18nService, emailService) {
|
|
2100
|
+
constructor(tokenService, userService, userValidator, encryptionService, cookieManager, i18nService, emailService, authSessionService) {
|
|
1971
2101
|
this.tokenService = tokenService;
|
|
1972
2102
|
this.userService = userService;
|
|
1973
2103
|
this.userValidator = userValidator;
|
|
@@ -1975,6 +2105,7 @@ var AuthService = class AuthService2 {
|
|
|
1975
2105
|
this.cookieManager = cookieManager;
|
|
1976
2106
|
this.i18nService = i18nService;
|
|
1977
2107
|
this.emailService = emailService;
|
|
2108
|
+
this.authSessionService = authSessionService;
|
|
1978
2109
|
}
|
|
1979
2110
|
isLockoutActive(lockoutUntil) {
|
|
1980
2111
|
if (!lockoutUntil)
|
|
@@ -1993,7 +2124,13 @@ var AuthService = class AuthService2 {
|
|
|
1993
2124
|
await this.getDummyHash();
|
|
1994
2125
|
}
|
|
1995
2126
|
async registerUser(body) {
|
|
1996
|
-
return await this.userService.create(
|
|
2127
|
+
return await this.userService.create({
|
|
2128
|
+
name: body.name,
|
|
2129
|
+
email: body.email,
|
|
2130
|
+
password: body.password,
|
|
2131
|
+
image: body.image,
|
|
2132
|
+
emailVerified: false
|
|
2133
|
+
});
|
|
1997
2134
|
}
|
|
1998
2135
|
/**
|
|
1999
2136
|
* Admin-initiated account creation. The user is created with a random,
|
|
@@ -2019,15 +2156,17 @@ var AuthService = class AuthService2 {
|
|
|
2019
2156
|
});
|
|
2020
2157
|
const { token } = await this.tokenService.generateInviteToken(user.id);
|
|
2021
2158
|
const inviteLink = `${this.config.frontendUrl}/reset-password?token=${token}`;
|
|
2159
|
+
let emailSent = false;
|
|
2022
2160
|
try {
|
|
2023
2161
|
await this.emailService.sendHtml(body.email, this.t("emails.accountInvite.subject"), accountInviteTemplate({
|
|
2024
2162
|
inviteLink,
|
|
2025
2163
|
userName: user.name || body.email
|
|
2026
2164
|
}));
|
|
2165
|
+
emailSent = true;
|
|
2027
2166
|
} catch (error) {
|
|
2028
2167
|
this.logger.warn("Account invite email failed", { email: body.email, error });
|
|
2029
2168
|
}
|
|
2030
|
-
return user;
|
|
2169
|
+
return { ...user, emailSent };
|
|
2031
2170
|
}
|
|
2032
2171
|
/**
|
|
2033
2172
|
* Create a login for a person record. The branch is intentional and is the
|
|
@@ -2062,7 +2201,7 @@ var AuthService = class AuthService2 {
|
|
|
2062
2201
|
user.lockoutUntil = null;
|
|
2063
2202
|
}
|
|
2064
2203
|
if (user && this.isLockoutActive(user.lockoutUntil)) {
|
|
2065
|
-
|
|
2204
|
+
Err8(this.t("errors.accountLocked"), 423);
|
|
2066
2205
|
}
|
|
2067
2206
|
const storedHash = user?.password ?? await this.getDummyHash();
|
|
2068
2207
|
const isValid = await this.userValidator.comparePassword(password, storedHash);
|
|
@@ -2071,30 +2210,23 @@ var AuthService = class AuthService2 {
|
|
|
2071
2210
|
const attempts = await this.userService.incrementFailedAttempts(user.id);
|
|
2072
2211
|
if (attempts >= this.config.lockout.maxAttempts) {
|
|
2073
2212
|
await this.userService.setLockout(user.id, this.nextLockoutUntil());
|
|
2074
|
-
|
|
2213
|
+
Err8(this.t("errors.accountLocked"), 423);
|
|
2075
2214
|
}
|
|
2076
2215
|
}
|
|
2077
|
-
|
|
2216
|
+
Err8(this.t("errors.invalidCredentials"));
|
|
2078
2217
|
}
|
|
2079
2218
|
if (user.status !== "active") {
|
|
2080
|
-
|
|
2219
|
+
Err8(this.t("errors.accountInactive"));
|
|
2220
|
+
}
|
|
2221
|
+
if (this.config.requireVerifiedEmail && !user.emailVerified) {
|
|
2222
|
+
Err8(this.t("errors.emailNotVerified"), 403);
|
|
2081
2223
|
}
|
|
2082
2224
|
if ((user.failedLoginAttempts ?? 0) > 0 || user.lockoutUntil) {
|
|
2083
2225
|
await this.userService.resetFailedAttempts(user.id);
|
|
2084
2226
|
}
|
|
2085
|
-
await this.tokenService.deleteExpiredSessions();
|
|
2086
|
-
const generated = await this.tokenService.generateTokens(user.id);
|
|
2087
|
-
this.cookieManager.setRefreshToken(generated.refreshToken);
|
|
2088
|
-
await this.userService.updateLastLogin(user.id);
|
|
2089
2227
|
const { password: _, failedLoginAttempts: __, lockoutUntil: ___, ...sanitized } = user;
|
|
2090
|
-
|
|
2091
|
-
this.
|
|
2092
|
-
user: { id: sanitized.id, email: sanitized.email, name: sanitized.name, role: sanitized.role, status: sanitized.status ?? void 0 },
|
|
2093
|
-
roles,
|
|
2094
|
-
permissions
|
|
2095
|
-
});
|
|
2096
|
-
const { userId: _userId, tokenFamily: _tokenFamily, roles: _roles, permissions: _permissions, ...tokens } = generated;
|
|
2097
|
-
return { ...tokens, user: sanitized };
|
|
2228
|
+
this.authSessionService ??= new AuthSessionService(this.tokenService, this.userService, this.cookieManager);
|
|
2229
|
+
return this.authSessionService.establish(sanitized);
|
|
2098
2230
|
}
|
|
2099
2231
|
async refreshTokens() {
|
|
2100
2232
|
const generated = await this.tokenService.refreshTokens();
|
|
@@ -2104,10 +2236,11 @@ var AuthService = class AuthService2 {
|
|
|
2104
2236
|
this.cookieManager.setSessionCookie({
|
|
2105
2237
|
user: { id: user.id, email: user.email, name: user.name, role: user.role, status: user.status ?? void 0 },
|
|
2106
2238
|
roles: generated.roles,
|
|
2107
|
-
permissions: generated.permissions
|
|
2239
|
+
permissions: generated.permissions,
|
|
2240
|
+
sessionVersion: generated.sessionVersion
|
|
2108
2241
|
});
|
|
2109
2242
|
}
|
|
2110
|
-
const { userId: _userId, tokenFamily: _tokenFamily, roles: _roles, permissions: _permissions, ...tokens } = generated;
|
|
2243
|
+
const { userId: _userId, tokenFamily: _tokenFamily, roles: _roles, permissions: _permissions, sessionVersion: _sv, ...tokens } = generated;
|
|
2111
2244
|
return tokens;
|
|
2112
2245
|
}
|
|
2113
2246
|
async logoutUser(userId, authorization) {
|
|
@@ -2153,7 +2286,7 @@ var AuthService = class AuthService2 {
|
|
|
2153
2286
|
const lang = this.i18nService.getCurrentLanguage();
|
|
2154
2287
|
result = { ...user, language: lang };
|
|
2155
2288
|
const token = this.tokenService.decodeAccessToken(authorization.replace(/^Bearer\s+/i, ""));
|
|
2156
|
-
cachePayload = { roles: token?.roles ?? [], permissions: token?.permissions ?? [] };
|
|
2289
|
+
cachePayload = { roles: token?.roles ?? [], permissions: token?.permissions ?? [], sessionVersion: token?.sessionVersion ?? 0 };
|
|
2157
2290
|
} else {
|
|
2158
2291
|
result = await this.getUserFromCookie();
|
|
2159
2292
|
}
|
|
@@ -2164,7 +2297,8 @@ var AuthService = class AuthService2 {
|
|
|
2164
2297
|
this.cookieManager.setSessionCookie({
|
|
2165
2298
|
user: { id: result.id, email: result.email, name: result.name, role: result.role, status: result.status ?? void 0 },
|
|
2166
2299
|
roles: cachePayload.roles,
|
|
2167
|
-
permissions: cachePayload.permissions
|
|
2300
|
+
permissions: cachePayload.permissions,
|
|
2301
|
+
sessionVersion: cachePayload.sessionVersion
|
|
2168
2302
|
});
|
|
2169
2303
|
}
|
|
2170
2304
|
return result;
|
|
@@ -2188,11 +2322,11 @@ var AuthService = class AuthService2 {
|
|
|
2188
2322
|
async changePassword(userId, currentPassword, newPassword) {
|
|
2189
2323
|
const user = await this.userService.getAuthRecordById(userId);
|
|
2190
2324
|
if (!user?.password) {
|
|
2191
|
-
|
|
2325
|
+
Err8(this.t("errors.invalidCredentials"));
|
|
2192
2326
|
}
|
|
2193
2327
|
const isValid = await this.userValidator.comparePassword(currentPassword, user.password);
|
|
2194
2328
|
if (!isValid) {
|
|
2195
|
-
|
|
2329
|
+
Err8(this.t("errors.invalidCredentials"));
|
|
2196
2330
|
}
|
|
2197
2331
|
this.userValidator.validatePasswordStrength(newPassword);
|
|
2198
2332
|
await this.userService.update(userId, { password: newPassword });
|
|
@@ -2213,33 +2347,33 @@ var AuthService = class AuthService2 {
|
|
|
2213
2347
|
return { message: this.t("success.passwordReset") };
|
|
2214
2348
|
}
|
|
2215
2349
|
};
|
|
2216
|
-
|
|
2350
|
+
__decorate12([
|
|
2217
2351
|
Inject8(AUTH_CONFIG),
|
|
2218
|
-
|
|
2352
|
+
__metadata12("design:type", Object)
|
|
2219
2353
|
], AuthService.prototype, "config", void 0);
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2354
|
+
__decorate12([
|
|
2355
|
+
I18n6("auth"),
|
|
2356
|
+
__metadata12("design:type", Object)
|
|
2223
2357
|
], AuthService.prototype, "t", void 0);
|
|
2224
|
-
|
|
2358
|
+
__decorate12([
|
|
2225
2359
|
Log(),
|
|
2226
|
-
|
|
2360
|
+
__metadata12("design:type", Object)
|
|
2227
2361
|
], AuthService.prototype, "logger", void 0);
|
|
2228
|
-
AuthService =
|
|
2229
|
-
|
|
2230
|
-
|
|
2362
|
+
AuthService = __decorate12([
|
|
2363
|
+
Injectable8(),
|
|
2364
|
+
__metadata12("design:paramtypes", [typeof (_a8 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a8 : Object, typeof (_b6 = typeof UserService !== "undefined" && UserService) === "function" ? _b6 : Object, typeof (_c4 = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _c4 : Object, typeof (_d2 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _d2 : Object, typeof (_e2 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _e2 : Object, typeof (_f2 = typeof I18nService2 !== "undefined" && I18nService2) === "function" ? _f2 : Object, typeof (_g2 = typeof EmailService !== "undefined" && EmailService) === "function" ? _g2 : Object, typeof (_h2 = typeof AuthSessionService !== "undefined" && AuthSessionService) === "function" ? _h2 : Object])
|
|
2231
2365
|
], AuthService);
|
|
2232
2366
|
|
|
2233
2367
|
// src/auth/AuthGuard.ts
|
|
2234
2368
|
import { Service as Service2, User } from "najm-core";
|
|
2235
2369
|
import { createGuard } from "najm-guard";
|
|
2236
|
-
var
|
|
2370
|
+
var __decorate13 = function(decorators, target, key, desc) {
|
|
2237
2371
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2238
2372
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2239
2373
|
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;
|
|
2240
2374
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2241
2375
|
};
|
|
2242
|
-
var
|
|
2376
|
+
var __metadata13 = function(k, v) {
|
|
2243
2377
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2244
2378
|
};
|
|
2245
2379
|
var __param3 = function(paramIndex, decorator) {
|
|
@@ -2255,51 +2389,28 @@ var AuthGuard = class AuthGuard2 {
|
|
|
2255
2389
|
return !!user;
|
|
2256
2390
|
}
|
|
2257
2391
|
};
|
|
2258
|
-
|
|
2392
|
+
__decorate13([
|
|
2259
2393
|
__param3(0, User()),
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2394
|
+
__metadata13("design:type", Function),
|
|
2395
|
+
__metadata13("design:paramtypes", [Object]),
|
|
2396
|
+
__metadata13("design:returntype", Boolean)
|
|
2263
2397
|
], AuthGuard.prototype, "canActivate", null);
|
|
2264
|
-
AuthGuard =
|
|
2398
|
+
AuthGuard = __decorate13([
|
|
2265
2399
|
Service2()
|
|
2266
2400
|
], AuthGuard);
|
|
2267
2401
|
var isAuth = createGuard(AuthGuard);
|
|
2268
2402
|
|
|
2269
|
-
// src/roles/index.ts
|
|
2270
|
-
var roles_exports = {};
|
|
2271
|
-
__export(roles_exports, {
|
|
2272
|
-
ROLES: () => ROLES,
|
|
2273
|
-
ROLE_GROUPS: () => ROLE_GROUPS,
|
|
2274
|
-
Role: () => Role,
|
|
2275
|
-
RoleController: () => RoleController,
|
|
2276
|
-
RoleGuard: () => RoleGuard,
|
|
2277
|
-
RoleRepository: () => RoleRepository,
|
|
2278
|
-
RoleService: () => RoleService,
|
|
2279
|
-
RoleValidator: () => RoleValidator,
|
|
2280
|
-
assignRoleDto: () => assignRoleDto,
|
|
2281
|
-
createRoleDto: () => createRoleDto,
|
|
2282
|
-
defineRoles: () => defineRoles,
|
|
2283
|
-
isAdmin: () => isAdmin,
|
|
2284
|
-
isAdministrator: () => isAdministrator,
|
|
2285
|
-
roleIdParam: () => roleIdParam,
|
|
2286
|
-
updateRoleDto: () => updateRoleDto
|
|
2287
|
-
});
|
|
2288
|
-
|
|
2289
|
-
// src/roles/defineRoles.ts
|
|
2290
|
-
import { composeGuards as composeGuards2, createGuard as createGuard3 } from "najm-guard";
|
|
2291
|
-
|
|
2292
2403
|
// src/roles/RoleGuards.ts
|
|
2293
2404
|
import { Service as Service3 } from "najm-core";
|
|
2294
2405
|
import { GuardParams, User as User2 } from "najm-core";
|
|
2295
2406
|
import { composeGuards, createGuard as createGuard2 } from "najm-guard";
|
|
2296
|
-
var
|
|
2407
|
+
var __decorate14 = function(decorators, target, key, desc) {
|
|
2297
2408
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2298
2409
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2299
2410
|
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;
|
|
2300
2411
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2301
2412
|
};
|
|
2302
|
-
var
|
|
2413
|
+
var __metadata14 = function(k, v) {
|
|
2303
2414
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2304
2415
|
};
|
|
2305
2416
|
var __param4 = function(paramIndex, decorator) {
|
|
@@ -2322,86 +2433,96 @@ var RoleGuard = class RoleGuard2 {
|
|
|
2322
2433
|
return false;
|
|
2323
2434
|
}
|
|
2324
2435
|
};
|
|
2325
|
-
|
|
2436
|
+
__decorate14([
|
|
2326
2437
|
__param4(0, GuardParams()),
|
|
2327
2438
|
__param4(1, User2("role")),
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2439
|
+
__metadata14("design:type", Function),
|
|
2440
|
+
__metadata14("design:paramtypes", [Object, String]),
|
|
2441
|
+
__metadata14("design:returntype", void 0)
|
|
2331
2442
|
], RoleGuard.prototype, "canActivate", null);
|
|
2332
|
-
RoleGuard =
|
|
2443
|
+
RoleGuard = __decorate14([
|
|
2333
2444
|
Service3()
|
|
2334
2445
|
], RoleGuard);
|
|
2335
2446
|
var Role = createGuard2(RoleGuard);
|
|
2336
2447
|
var isAdmin = composeGuards(isAuth(), Role(ROLES.ADMIN));
|
|
2337
2448
|
var isAdministrator = composeGuards(isAuth(), Role(ROLE_GROUPS.ADMINISTRATORS));
|
|
2338
2449
|
|
|
2339
|
-
// src/
|
|
2340
|
-
var Role2 = createGuard3(RoleGuard);
|
|
2341
|
-
function defineRoles(roles, options) {
|
|
2342
|
-
const ROLES2 = roles;
|
|
2343
|
-
const superRoleKeys = options?.superRoles ?? [];
|
|
2344
|
-
function resolveRoleValues(keys) {
|
|
2345
|
-
return Array.from(new Set([...keys, ...superRoleKeys].map((key) => roles[key])));
|
|
2346
|
-
}
|
|
2347
|
-
__name(resolveRoleValues, "resolveRoleValues");
|
|
2348
|
-
const guards2 = {};
|
|
2349
|
-
for (const [key, value] of Object.entries(roles)) {
|
|
2350
|
-
const name = `is${key.charAt(0).toUpperCase()}${key.slice(1).toLowerCase()}`;
|
|
2351
|
-
const allowedValues = resolveRoleValues([key]);
|
|
2352
|
-
guards2[name] = composeGuards2(isAuth(), Role2(allowedValues.length === 1 ? value : allowedValues));
|
|
2353
|
-
}
|
|
2354
|
-
function createGroupGuard(keys) {
|
|
2355
|
-
const values = resolveRoleValues(keys);
|
|
2356
|
-
return composeGuards2(isAuth(), Role2(values));
|
|
2357
|
-
}
|
|
2358
|
-
__name(createGroupGuard, "createGroupGuard");
|
|
2359
|
-
function hasRole(userRole, ...keys) {
|
|
2360
|
-
if (!userRole)
|
|
2361
|
-
return false;
|
|
2362
|
-
const normalized = userRole.toLowerCase();
|
|
2363
|
-
return resolveRoleValues(keys).some((role) => role === normalized);
|
|
2364
|
-
}
|
|
2365
|
-
__name(hasRole, "hasRole");
|
|
2366
|
-
function isInGroup(userRole, keys) {
|
|
2367
|
-
return hasRole(userRole, ...keys);
|
|
2368
|
-
}
|
|
2369
|
-
__name(isInGroup, "isInGroup");
|
|
2370
|
-
return { ROLES: ROLES2, createGroupGuard, hasRole, isInGroup, ...guards2 };
|
|
2371
|
-
}
|
|
2372
|
-
__name(defineRoles, "defineRoles");
|
|
2373
|
-
|
|
2374
|
-
// src/roles/RoleController.ts
|
|
2375
|
-
import { Controller } from "najm-core";
|
|
2376
|
-
import { Get, Post, Put, Delete, ResMsg } from "najm-core";
|
|
2377
|
-
import { Params, Body } from "najm-core";
|
|
2450
|
+
// src/auth/AuthController.ts
|
|
2378
2451
|
import { Validate } from "najm-validation";
|
|
2452
|
+
import { RateLimit } from "najm-rate";
|
|
2453
|
+
import { createHash as createHash2 } from "crypto";
|
|
2379
2454
|
|
|
2380
|
-
// src/
|
|
2455
|
+
// src/users/UserDto.ts
|
|
2381
2456
|
import { z } from "zod";
|
|
2382
|
-
var
|
|
2383
|
-
var
|
|
2384
|
-
var
|
|
2385
|
-
|
|
2386
|
-
|
|
2457
|
+
var emailField = z.string().email("Invalid email format");
|
|
2458
|
+
var passwordField = z.string().min(8, "Password must be at least 8 characters").refine((v) => new TextEncoder().encode(v).length <= 72, "Password must be at most 72 bytes").regex(/[A-Z]/, "Password must contain at least one uppercase letter").regex(/[a-z]/, "Password must contain at least one lowercase letter").regex(/\d/, "Password must contain at least one number");
|
|
2459
|
+
var optionalDateField = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").nullable().optional();
|
|
2460
|
+
var createUserDto = z.object({
|
|
2461
|
+
name: z.string().max(100).optional(),
|
|
2462
|
+
email: emailField,
|
|
2463
|
+
password: passwordField,
|
|
2464
|
+
roleId: z.string().min(1).optional(),
|
|
2465
|
+
image: z.string().nullish(),
|
|
2466
|
+
emailVerified: z.boolean().default(false),
|
|
2467
|
+
status: z.enum(["active", "inactive", "pending"]).optional()
|
|
2387
2468
|
});
|
|
2388
|
-
var
|
|
2389
|
-
var
|
|
2390
|
-
|
|
2469
|
+
var updateUserDto = createUserDto.partial();
|
|
2470
|
+
var registerDto = z.object({
|
|
2471
|
+
name: z.string().max(100).optional(),
|
|
2472
|
+
email: emailField,
|
|
2473
|
+
password: passwordField,
|
|
2474
|
+
image: z.string().nullish()
|
|
2475
|
+
});
|
|
2476
|
+
var inviteUserDto = z.object({
|
|
2477
|
+
name: z.string().max(100).optional(),
|
|
2478
|
+
email: emailField,
|
|
2479
|
+
roleId: z.string().min(1).optional(),
|
|
2480
|
+
image: z.string().nullish()
|
|
2481
|
+
});
|
|
2482
|
+
var userIdParam = z.object({
|
|
2483
|
+
id: z.string().min(1, "User ID is required")
|
|
2484
|
+
});
|
|
2485
|
+
var loginDto = z.object({
|
|
2486
|
+
email: emailField,
|
|
2487
|
+
password: passwordField
|
|
2488
|
+
});
|
|
2489
|
+
var changePasswordDto = z.object({
|
|
2490
|
+
currentPassword: passwordField,
|
|
2491
|
+
newPassword: passwordField
|
|
2492
|
+
});
|
|
2493
|
+
var resetPasswordDto = z.object({
|
|
2494
|
+
email: emailField
|
|
2495
|
+
});
|
|
2496
|
+
var confirmResetPasswordDto = z.object({
|
|
2497
|
+
token: z.string().min(10, "Invalid reset token"),
|
|
2498
|
+
newPassword: passwordField
|
|
2499
|
+
});
|
|
2500
|
+
var languageParam = z.object({
|
|
2501
|
+
language: z.string().min(2)
|
|
2502
|
+
});
|
|
2503
|
+
var emailParam = z.object({
|
|
2504
|
+
email: emailField
|
|
2505
|
+
});
|
|
2506
|
+
var userIdInParam = z.object({
|
|
2507
|
+
userId: z.string().min(1, "User ID is required")
|
|
2391
2508
|
});
|
|
2392
|
-
var
|
|
2393
|
-
userId: z.string().
|
|
2394
|
-
roleId: z.string().
|
|
2509
|
+
var assignRoleParams = z.object({
|
|
2510
|
+
userId: z.string().min(1, "User ID is required"),
|
|
2511
|
+
roleId: z.string().min(1)
|
|
2512
|
+
});
|
|
2513
|
+
var userListQuery = z.object({
|
|
2514
|
+
limit: z.coerce.number().int().min(1).max(100).default(50),
|
|
2515
|
+
offset: z.coerce.number().int().min(0).default(0)
|
|
2395
2516
|
});
|
|
2396
2517
|
|
|
2397
|
-
// src/
|
|
2398
|
-
var
|
|
2518
|
+
// src/auth/AuthController.ts
|
|
2519
|
+
var __decorate15 = function(decorators, target, key, desc) {
|
|
2399
2520
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2400
2521
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2401
2522
|
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;
|
|
2402
2523
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2403
2524
|
};
|
|
2404
|
-
var
|
|
2525
|
+
var __metadata15 = function(k, v) {
|
|
2405
2526
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2406
2527
|
};
|
|
2407
2528
|
var __param5 = function(paramIndex, decorator) {
|
|
@@ -2409,202 +2530,43 @@ var __param5 = function(paramIndex, decorator) {
|
|
|
2409
2530
|
decorator(target, key, paramIndex);
|
|
2410
2531
|
};
|
|
2411
2532
|
};
|
|
2412
|
-
var
|
|
2413
|
-
var
|
|
2414
|
-
|
|
2415
|
-
|
|
2533
|
+
var _a9;
|
|
2534
|
+
var hashKeyPart = /* @__PURE__ */ __name((value) => createHash2("sha256").update(value).digest("base64url").slice(0, 32), "hashKeyPart");
|
|
2535
|
+
var cookieFingerprint = /* @__PURE__ */ __name(() => (ctx) => {
|
|
2536
|
+
const ip = ctx.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? ctx.req.header("x-real-ip") ?? "unknown";
|
|
2537
|
+
const cookie = ctx.req.raw.headers.get("cookie") ?? "";
|
|
2538
|
+
const fingerprint = cookie ? hashKeyPart(cookie) : "none";
|
|
2539
|
+
return `${ip}:${fingerprint}`;
|
|
2540
|
+
}, "cookieFingerprint");
|
|
2541
|
+
var ipAndEmail = /* @__PURE__ */ __name(async (ctx) => {
|
|
2542
|
+
const ip = ctx.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? ctx.req.header("x-real-ip") ?? "unknown";
|
|
2543
|
+
try {
|
|
2544
|
+
const body = await ctx.req.json();
|
|
2545
|
+
if (body?.email && typeof body.email === "string") {
|
|
2546
|
+
const normalizedEmail = body.email.trim().toLowerCase();
|
|
2547
|
+
if (normalizedEmail)
|
|
2548
|
+
return `${ip}:${hashKeyPart(normalizedEmail)}`;
|
|
2549
|
+
}
|
|
2550
|
+
} catch {
|
|
2416
2551
|
}
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2552
|
+
return ip;
|
|
2553
|
+
}, "ipAndEmail");
|
|
2554
|
+
var AuthController = class AuthController2 {
|
|
2555
|
+
static {
|
|
2556
|
+
__name(this, "AuthController");
|
|
2420
2557
|
}
|
|
2421
|
-
|
|
2422
|
-
|
|
2558
|
+
authService;
|
|
2559
|
+
constructor(authService) {
|
|
2560
|
+
this.authService = authService;
|
|
2423
2561
|
}
|
|
2424
|
-
async
|
|
2425
|
-
return this.
|
|
2562
|
+
async registerUser(body) {
|
|
2563
|
+
return this.authService.registerUser(body);
|
|
2426
2564
|
}
|
|
2427
|
-
async
|
|
2428
|
-
return this.
|
|
2565
|
+
async loginUser(body) {
|
|
2566
|
+
return this.authService.loginUser(body);
|
|
2429
2567
|
}
|
|
2430
|
-
async
|
|
2431
|
-
return this.
|
|
2432
|
-
}
|
|
2433
|
-
async deleteRole(params) {
|
|
2434
|
-
return this.roleService.delete(params.id);
|
|
2435
|
-
}
|
|
2436
|
-
};
|
|
2437
|
-
__decorate14([
|
|
2438
|
-
Get(),
|
|
2439
|
-
isAdmin(),
|
|
2440
|
-
ResMsg("roles.success.retrieved"),
|
|
2441
|
-
__metadata14("design:type", Function),
|
|
2442
|
-
__metadata14("design:paramtypes", []),
|
|
2443
|
-
__metadata14("design:returntype", Promise)
|
|
2444
|
-
], RoleController.prototype, "getRoles", null);
|
|
2445
|
-
__decorate14([
|
|
2446
|
-
Get("/:id"),
|
|
2447
|
-
isAdmin(),
|
|
2448
|
-
Validate({ params: roleIdParam }),
|
|
2449
|
-
ResMsg("roles.success.retrieved"),
|
|
2450
|
-
__param5(0, Params()),
|
|
2451
|
-
__metadata14("design:type", Function),
|
|
2452
|
-
__metadata14("design:paramtypes", [Object]),
|
|
2453
|
-
__metadata14("design:returntype", Promise)
|
|
2454
|
-
], RoleController.prototype, "getRole", null);
|
|
2455
|
-
__decorate14([
|
|
2456
|
-
Post(),
|
|
2457
|
-
isAdmin(),
|
|
2458
|
-
Validate(createRoleDto),
|
|
2459
|
-
ResMsg("roles.success.created"),
|
|
2460
|
-
__param5(0, Body()),
|
|
2461
|
-
__metadata14("design:type", Function),
|
|
2462
|
-
__metadata14("design:paramtypes", [Object]),
|
|
2463
|
-
__metadata14("design:returntype", Promise)
|
|
2464
|
-
], RoleController.prototype, "createRole", null);
|
|
2465
|
-
__decorate14([
|
|
2466
|
-
Put("/:id"),
|
|
2467
|
-
isAdmin(),
|
|
2468
|
-
Validate({
|
|
2469
|
-
params: roleIdParam,
|
|
2470
|
-
body: updateRoleDto
|
|
2471
|
-
}),
|
|
2472
|
-
ResMsg("roles.success.updated"),
|
|
2473
|
-
__param5(0, Params()),
|
|
2474
|
-
__param5(1, Body()),
|
|
2475
|
-
__metadata14("design:type", Function),
|
|
2476
|
-
__metadata14("design:paramtypes", [Object, Object]),
|
|
2477
|
-
__metadata14("design:returntype", Promise)
|
|
2478
|
-
], RoleController.prototype, "updateRole", null);
|
|
2479
|
-
__decorate14([
|
|
2480
|
-
Delete("/:id"),
|
|
2481
|
-
isAdmin(),
|
|
2482
|
-
Validate({ params: roleIdParam }),
|
|
2483
|
-
ResMsg("roles.success.deleted"),
|
|
2484
|
-
__param5(0, Params()),
|
|
2485
|
-
__metadata14("design:type", Function),
|
|
2486
|
-
__metadata14("design:paramtypes", [Object]),
|
|
2487
|
-
__metadata14("design:returntype", Promise)
|
|
2488
|
-
], RoleController.prototype, "deleteRole", null);
|
|
2489
|
-
RoleController = __decorate14([
|
|
2490
|
-
Controller("/roles"),
|
|
2491
|
-
__metadata14("design:paramtypes", [typeof (_a8 = typeof RoleService !== "undefined" && RoleService) === "function" ? _a8 : Object])
|
|
2492
|
-
], RoleController);
|
|
2493
|
-
|
|
2494
|
-
// src/auth/AuthController.ts
|
|
2495
|
-
import { Validate as Validate2 } from "najm-validation";
|
|
2496
|
-
import { RateLimit } from "najm-rate";
|
|
2497
|
-
import { createHash as createHash2 } from "crypto";
|
|
2498
|
-
|
|
2499
|
-
// src/users/UserDto.ts
|
|
2500
|
-
import { z as z2 } from "zod";
|
|
2501
|
-
var emailField = z2.string().email("Invalid email format");
|
|
2502
|
-
var passwordField = z2.string().min(8, "Password must be at least 8 characters");
|
|
2503
|
-
var optionalDateField = z2.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").nullable().optional();
|
|
2504
|
-
var createUserDto = z2.object({
|
|
2505
|
-
name: z2.string().max(100).optional(),
|
|
2506
|
-
email: emailField,
|
|
2507
|
-
password: passwordField,
|
|
2508
|
-
roleId: z2.string().min(1).optional(),
|
|
2509
|
-
image: z2.string().nullish(),
|
|
2510
|
-
emailVerified: z2.boolean().default(false),
|
|
2511
|
-
status: z2.enum(["active", "inactive", "pending"]).optional()
|
|
2512
|
-
});
|
|
2513
|
-
var updateUserDto = createUserDto.partial();
|
|
2514
|
-
var inviteUserDto = z2.object({
|
|
2515
|
-
name: z2.string().max(100).optional(),
|
|
2516
|
-
email: emailField,
|
|
2517
|
-
roleId: z2.string().min(1).optional(),
|
|
2518
|
-
image: z2.string().nullish()
|
|
2519
|
-
});
|
|
2520
|
-
var userIdParam = z2.object({
|
|
2521
|
-
id: z2.string().min(1, "User ID is required")
|
|
2522
|
-
});
|
|
2523
|
-
var loginDto = z2.object({
|
|
2524
|
-
email: emailField,
|
|
2525
|
-
password: passwordField
|
|
2526
|
-
});
|
|
2527
|
-
var changePasswordDto = z2.object({
|
|
2528
|
-
currentPassword: passwordField,
|
|
2529
|
-
newPassword: passwordField
|
|
2530
|
-
});
|
|
2531
|
-
var resetPasswordDto = z2.object({
|
|
2532
|
-
email: emailField
|
|
2533
|
-
});
|
|
2534
|
-
var confirmResetPasswordDto = z2.object({
|
|
2535
|
-
token: z2.string().min(10, "Invalid reset token"),
|
|
2536
|
-
newPassword: passwordField
|
|
2537
|
-
});
|
|
2538
|
-
var languageParam = z2.object({
|
|
2539
|
-
language: z2.string().min(2)
|
|
2540
|
-
});
|
|
2541
|
-
var emailParam = z2.object({
|
|
2542
|
-
email: emailField
|
|
2543
|
-
});
|
|
2544
|
-
var userIdInParam = z2.object({
|
|
2545
|
-
userId: z2.string().min(1, "User ID is required")
|
|
2546
|
-
});
|
|
2547
|
-
var assignRoleParams = z2.object({
|
|
2548
|
-
userId: z2.string().min(1, "User ID is required"),
|
|
2549
|
-
roleId: z2.string().min(1)
|
|
2550
|
-
});
|
|
2551
|
-
var userListQuery = z2.object({
|
|
2552
|
-
limit: z2.coerce.number().int().min(1).max(100).default(50),
|
|
2553
|
-
offset: z2.coerce.number().int().min(0).default(0)
|
|
2554
|
-
});
|
|
2555
|
-
|
|
2556
|
-
// src/auth/AuthController.ts
|
|
2557
|
-
var __decorate15 = function(decorators, target, key, desc) {
|
|
2558
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2559
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2560
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2561
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2562
|
-
};
|
|
2563
|
-
var __metadata15 = function(k, v) {
|
|
2564
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2565
|
-
};
|
|
2566
|
-
var __param6 = function(paramIndex, decorator) {
|
|
2567
|
-
return function(target, key) {
|
|
2568
|
-
decorator(target, key, paramIndex);
|
|
2569
|
-
};
|
|
2570
|
-
};
|
|
2571
|
-
var _a9;
|
|
2572
|
-
var hashKeyPart = /* @__PURE__ */ __name((value) => createHash2("sha256").update(value).digest("base64url").slice(0, 32), "hashKeyPart");
|
|
2573
|
-
var cookieFingerprint = /* @__PURE__ */ __name(() => (ctx) => {
|
|
2574
|
-
const ip = ctx.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? ctx.req.header("x-real-ip") ?? "unknown";
|
|
2575
|
-
const cookie = ctx.req.raw.headers.get("cookie") ?? "";
|
|
2576
|
-
const fingerprint = cookie ? hashKeyPart(cookie) : "none";
|
|
2577
|
-
return `${ip}:${fingerprint}`;
|
|
2578
|
-
}, "cookieFingerprint");
|
|
2579
|
-
var ipAndEmail = /* @__PURE__ */ __name(async (ctx) => {
|
|
2580
|
-
const ip = ctx.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? ctx.req.header("x-real-ip") ?? "unknown";
|
|
2581
|
-
try {
|
|
2582
|
-
const body = await ctx.req.json();
|
|
2583
|
-
if (body?.email && typeof body.email === "string") {
|
|
2584
|
-
const normalizedEmail = body.email.trim().toLowerCase();
|
|
2585
|
-
if (normalizedEmail)
|
|
2586
|
-
return `${ip}:${hashKeyPart(normalizedEmail)}`;
|
|
2587
|
-
}
|
|
2588
|
-
} catch {
|
|
2589
|
-
}
|
|
2590
|
-
return ip;
|
|
2591
|
-
}, "ipAndEmail");
|
|
2592
|
-
var AuthController = class AuthController2 {
|
|
2593
|
-
static {
|
|
2594
|
-
__name(this, "AuthController");
|
|
2595
|
-
}
|
|
2596
|
-
authService;
|
|
2597
|
-
constructor(authService) {
|
|
2598
|
-
this.authService = authService;
|
|
2599
|
-
}
|
|
2600
|
-
async registerUser(body) {
|
|
2601
|
-
return this.authService.registerUser(body);
|
|
2602
|
-
}
|
|
2603
|
-
async loginUser(body) {
|
|
2604
|
-
return this.authService.loginUser(body);
|
|
2605
|
-
}
|
|
2606
|
-
async inviteUser(body) {
|
|
2607
|
-
return this.authService.inviteUser(body);
|
|
2568
|
+
async inviteUser(body) {
|
|
2569
|
+
return this.authService.inviteUser(body);
|
|
2608
2570
|
}
|
|
2609
2571
|
async refreshTokens() {
|
|
2610
2572
|
return this.authService.refreshTokens();
|
|
@@ -2626,96 +2588,96 @@ var AuthController = class AuthController2 {
|
|
|
2626
2588
|
}
|
|
2627
2589
|
};
|
|
2628
2590
|
__decorate15([
|
|
2629
|
-
|
|
2591
|
+
Post("/register"),
|
|
2630
2592
|
RateLimit({ limit: 5, window: "15m", key: ipAndEmail }),
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2593
|
+
Validate(registerDto),
|
|
2594
|
+
ResMsg("auth.success.register"),
|
|
2595
|
+
__param5(0, Body()),
|
|
2634
2596
|
__metadata15("design:type", Function),
|
|
2635
2597
|
__metadata15("design:paramtypes", [Object]),
|
|
2636
2598
|
__metadata15("design:returntype", Promise)
|
|
2637
2599
|
], AuthController.prototype, "registerUser", null);
|
|
2638
2600
|
__decorate15([
|
|
2639
|
-
|
|
2601
|
+
Post("/login"),
|
|
2640
2602
|
RateLimit({ limit: 5, window: "15m", key: ipAndEmail, message: "Too many login attempts. Please try again later." }),
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2603
|
+
Validate(loginDto),
|
|
2604
|
+
ResMsg("auth.success.login"),
|
|
2605
|
+
__param5(0, Body()),
|
|
2644
2606
|
__metadata15("design:type", Function),
|
|
2645
2607
|
__metadata15("design:paramtypes", [Object]),
|
|
2646
2608
|
__metadata15("design:returntype", Promise)
|
|
2647
2609
|
], AuthController.prototype, "loginUser", null);
|
|
2648
2610
|
__decorate15([
|
|
2649
|
-
|
|
2611
|
+
Post("/invite"),
|
|
2650
2612
|
isAdmin(),
|
|
2651
2613
|
RateLimit({ limit: 20, window: "15m", key: "user" }),
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2614
|
+
Validate(inviteUserDto),
|
|
2615
|
+
ResMsg("auth.success.accountInviteSent"),
|
|
2616
|
+
__param5(0, Body()),
|
|
2655
2617
|
__metadata15("design:type", Function),
|
|
2656
2618
|
__metadata15("design:paramtypes", [Object]),
|
|
2657
2619
|
__metadata15("design:returntype", Promise)
|
|
2658
2620
|
], AuthController.prototype, "inviteUser", null);
|
|
2659
2621
|
__decorate15([
|
|
2660
|
-
|
|
2622
|
+
Post("/refresh"),
|
|
2661
2623
|
RateLimit({ limit: 15, window: "15m", key: cookieFingerprint() }),
|
|
2662
|
-
|
|
2624
|
+
ResMsg("auth.success.tokenRefreshed"),
|
|
2663
2625
|
__metadata15("design:type", Function),
|
|
2664
2626
|
__metadata15("design:paramtypes", []),
|
|
2665
2627
|
__metadata15("design:returntype", Promise)
|
|
2666
2628
|
], AuthController.prototype, "refreshTokens", null);
|
|
2667
2629
|
__decorate15([
|
|
2668
|
-
|
|
2630
|
+
Post("/logout"),
|
|
2669
2631
|
isAuth(),
|
|
2670
2632
|
RateLimit({ limit: 10, window: "15m", key: "user" }),
|
|
2671
|
-
|
|
2672
|
-
|
|
2633
|
+
__param5(0, User3("id")),
|
|
2634
|
+
__param5(1, Headers("authorization")),
|
|
2673
2635
|
__metadata15("design:type", Function),
|
|
2674
2636
|
__metadata15("design:paramtypes", [String, String]),
|
|
2675
2637
|
__metadata15("design:returntype", Promise)
|
|
2676
2638
|
], AuthController.prototype, "logoutUser", null);
|
|
2677
2639
|
__decorate15([
|
|
2678
|
-
|
|
2640
|
+
Post("/change-password"),
|
|
2679
2641
|
isAuth(),
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2642
|
+
Validate(changePasswordDto),
|
|
2643
|
+
ResMsg("auth.success.passwordChanged"),
|
|
2644
|
+
__param5(0, User3("id")),
|
|
2645
|
+
__param5(1, Body()),
|
|
2684
2646
|
__metadata15("design:type", Function),
|
|
2685
2647
|
__metadata15("design:paramtypes", [String, Object]),
|
|
2686
2648
|
__metadata15("design:returntype", Promise)
|
|
2687
2649
|
], AuthController.prototype, "changePassword", null);
|
|
2688
2650
|
__decorate15([
|
|
2689
|
-
|
|
2651
|
+
Get("/me"),
|
|
2690
2652
|
RateLimit({ limit: 30, window: "1m", key: cookieFingerprint() }),
|
|
2691
|
-
|
|
2692
|
-
|
|
2653
|
+
ResMsg("auth.users.success.retrieved"),
|
|
2654
|
+
__param5(0, Headers("authorization")),
|
|
2693
2655
|
__metadata15("design:type", Function),
|
|
2694
2656
|
__metadata15("design:paramtypes", [String]),
|
|
2695
2657
|
__metadata15("design:returntype", Promise)
|
|
2696
2658
|
], AuthController.prototype, "userProfile", null);
|
|
2697
2659
|
__decorate15([
|
|
2698
|
-
|
|
2660
|
+
Post("/forgot-password"),
|
|
2699
2661
|
RateLimit({ limit: 3, window: "15m", key: ipAndEmail, message: "Too many password reset requests. Please try again later." }),
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2662
|
+
Validate(resetPasswordDto),
|
|
2663
|
+
ResMsg("auth.success.passwordResetSent"),
|
|
2664
|
+
__param5(0, Body()),
|
|
2703
2665
|
__metadata15("design:type", Function),
|
|
2704
2666
|
__metadata15("design:paramtypes", [Object]),
|
|
2705
2667
|
__metadata15("design:returntype", Promise)
|
|
2706
2668
|
], AuthController.prototype, "forgotPassword", null);
|
|
2707
2669
|
__decorate15([
|
|
2708
|
-
|
|
2670
|
+
Post("/reset-password"),
|
|
2709
2671
|
RateLimit({ limit: 5, window: "15m", key: "ip", message: "Too many password reset attempts. Please try again later." }),
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2672
|
+
Validate(confirmResetPasswordDto),
|
|
2673
|
+
ResMsg("auth.success.passwordReset"),
|
|
2674
|
+
__param5(0, Body()),
|
|
2713
2675
|
__metadata15("design:type", Function),
|
|
2714
2676
|
__metadata15("design:paramtypes", [Object]),
|
|
2715
2677
|
__metadata15("design:returntype", Promise)
|
|
2716
2678
|
], AuthController.prototype, "resetPassword", null);
|
|
2717
2679
|
AuthController = __decorate15([
|
|
2718
|
-
|
|
2680
|
+
Controller("/auth"),
|
|
2719
2681
|
__metadata15("design:paramtypes", [typeof (_a9 = typeof AuthService !== "undefined" && AuthService) === "function" ? _a9 : Object])
|
|
2720
2682
|
], AuthController);
|
|
2721
2683
|
|
|
@@ -2778,6 +2740,10 @@ var AuthResolver = class AuthResolver2 {
|
|
|
2778
2740
|
const session = cookieManager.getSessionCookie();
|
|
2779
2741
|
if (!session)
|
|
2780
2742
|
return false;
|
|
2743
|
+
const tokenService = await this.container.resolve(TokenService);
|
|
2744
|
+
const currentVersion = await tokenService.getSessionVersion(session.user.id);
|
|
2745
|
+
if ((session.sessionVersion ?? 0) !== currentVersion)
|
|
2746
|
+
return false;
|
|
2781
2747
|
return {
|
|
2782
2748
|
user: { ...session.user, permissions: session.permissions },
|
|
2783
2749
|
role: session.user.role ?? session.roles[0],
|
|
@@ -2886,6 +2852,7 @@ __name(runAsUser, "runAsUser");
|
|
|
2886
2852
|
// src/auth/index.ts
|
|
2887
2853
|
var AUTH_MODULE = [
|
|
2888
2854
|
AuthService,
|
|
2855
|
+
AuthSessionService,
|
|
2889
2856
|
CookieManager,
|
|
2890
2857
|
EncryptionService,
|
|
2891
2858
|
AuthGuard,
|
|
@@ -2908,6 +2875,7 @@ __export(users_exports, {
|
|
|
2908
2875
|
inviteUserDto: () => inviteUserDto,
|
|
2909
2876
|
languageParam: () => languageParam,
|
|
2910
2877
|
loginDto: () => loginDto,
|
|
2878
|
+
registerDto: () => registerDto,
|
|
2911
2879
|
resetPasswordDto: () => resetPasswordDto,
|
|
2912
2880
|
updateUserDto: () => updateUserDto,
|
|
2913
2881
|
userIdInParam: () => userIdInParam,
|
|
@@ -2919,7 +2887,87 @@ __export(users_exports, {
|
|
|
2919
2887
|
import { Controller as Controller3 } from "najm-core";
|
|
2920
2888
|
import { Get as Get3, Post as Post3, Put as Put2, Delete as Delete2, ResMsg as ResMsg3 } from "najm-core";
|
|
2921
2889
|
import { Params as Params2, Body as Body3, Query } from "najm-core";
|
|
2922
|
-
|
|
2890
|
+
|
|
2891
|
+
// src/roles/index.ts
|
|
2892
|
+
var roles_exports = {};
|
|
2893
|
+
__export(roles_exports, {
|
|
2894
|
+
ROLES: () => ROLES,
|
|
2895
|
+
ROLE_GROUPS: () => ROLE_GROUPS,
|
|
2896
|
+
Role: () => Role,
|
|
2897
|
+
RoleController: () => RoleController,
|
|
2898
|
+
RoleGuard: () => RoleGuard,
|
|
2899
|
+
RoleRepository: () => RoleRepository,
|
|
2900
|
+
RoleService: () => RoleService,
|
|
2901
|
+
RoleValidator: () => RoleValidator,
|
|
2902
|
+
assignRoleDto: () => assignRoleDto,
|
|
2903
|
+
createRoleDto: () => createRoleDto,
|
|
2904
|
+
defineRoles: () => defineRoles,
|
|
2905
|
+
isAdmin: () => isAdmin,
|
|
2906
|
+
isAdministrator: () => isAdministrator,
|
|
2907
|
+
roleIdParam: () => roleIdParam,
|
|
2908
|
+
updateRoleDto: () => updateRoleDto
|
|
2909
|
+
});
|
|
2910
|
+
|
|
2911
|
+
// src/roles/defineRoles.ts
|
|
2912
|
+
import { composeGuards as composeGuards2, createGuard as createGuard3 } from "najm-guard";
|
|
2913
|
+
var Role2 = createGuard3(RoleGuard);
|
|
2914
|
+
function defineRoles(roles, options) {
|
|
2915
|
+
const ROLES2 = roles;
|
|
2916
|
+
const superRoleKeys = options?.superRoles ?? [];
|
|
2917
|
+
function resolveRoleValues(keys) {
|
|
2918
|
+
return Array.from(new Set([...keys, ...superRoleKeys].map((key) => roles[key])));
|
|
2919
|
+
}
|
|
2920
|
+
__name(resolveRoleValues, "resolveRoleValues");
|
|
2921
|
+
const guards2 = {};
|
|
2922
|
+
for (const [key, value] of Object.entries(roles)) {
|
|
2923
|
+
const name = `is${key.charAt(0).toUpperCase()}${key.slice(1).toLowerCase()}`;
|
|
2924
|
+
const allowedValues = resolveRoleValues([key]);
|
|
2925
|
+
guards2[name] = composeGuards2(isAuth(), Role2(allowedValues.length === 1 ? value : allowedValues));
|
|
2926
|
+
}
|
|
2927
|
+
function createGroupGuard(keys) {
|
|
2928
|
+
const values = resolveRoleValues(keys);
|
|
2929
|
+
return composeGuards2(isAuth(), Role2(values));
|
|
2930
|
+
}
|
|
2931
|
+
__name(createGroupGuard, "createGroupGuard");
|
|
2932
|
+
function hasRole(userRole, ...keys) {
|
|
2933
|
+
if (!userRole)
|
|
2934
|
+
return false;
|
|
2935
|
+
const normalized = userRole.toLowerCase();
|
|
2936
|
+
return resolveRoleValues(keys).some((role) => role === normalized);
|
|
2937
|
+
}
|
|
2938
|
+
__name(hasRole, "hasRole");
|
|
2939
|
+
function isInGroup(userRole, keys) {
|
|
2940
|
+
return hasRole(userRole, ...keys);
|
|
2941
|
+
}
|
|
2942
|
+
__name(isInGroup, "isInGroup");
|
|
2943
|
+
return { ROLES: ROLES2, createGroupGuard, hasRole, isInGroup, ...guards2 };
|
|
2944
|
+
}
|
|
2945
|
+
__name(defineRoles, "defineRoles");
|
|
2946
|
+
|
|
2947
|
+
// src/roles/RoleController.ts
|
|
2948
|
+
import { Controller as Controller2 } from "najm-core";
|
|
2949
|
+
import { Get as Get2, Post as Post2, Put, Delete, ResMsg as ResMsg2 } from "najm-core";
|
|
2950
|
+
import { Params, Body as Body2 } from "najm-core";
|
|
2951
|
+
import { Validate as Validate2 } from "najm-validation";
|
|
2952
|
+
|
|
2953
|
+
// src/roles/RoleDto.ts
|
|
2954
|
+
import { z as z2 } from "zod";
|
|
2955
|
+
var nameField = z2.string().min(2, "Name must be at least 2 characters").max(50, "Name too long");
|
|
2956
|
+
var descriptionField = z2.string().max(255, "Description too long").optional();
|
|
2957
|
+
var createRoleDto = z2.object({
|
|
2958
|
+
name: nameField,
|
|
2959
|
+
description: descriptionField
|
|
2960
|
+
});
|
|
2961
|
+
var updateRoleDto = createRoleDto.partial();
|
|
2962
|
+
var roleIdParam = z2.object({
|
|
2963
|
+
id: z2.string().length(5, "Role ID must be 5 characters")
|
|
2964
|
+
});
|
|
2965
|
+
var assignRoleDto = z2.object({
|
|
2966
|
+
userId: z2.string().length(8, "User ID must be 8 characters"),
|
|
2967
|
+
roleId: z2.string().length(5, "Role ID must be 5 characters")
|
|
2968
|
+
});
|
|
2969
|
+
|
|
2970
|
+
// src/roles/RoleController.ts
|
|
2923
2971
|
var __decorate17 = function(decorators, target, key, desc) {
|
|
2924
2972
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2925
2973
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -2929,12 +2977,110 @@ var __decorate17 = function(decorators, target, key, desc) {
|
|
|
2929
2977
|
var __metadata17 = function(k, v) {
|
|
2930
2978
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2931
2979
|
};
|
|
2932
|
-
var
|
|
2980
|
+
var __param6 = function(paramIndex, decorator) {
|
|
2933
2981
|
return function(target, key) {
|
|
2934
2982
|
decorator(target, key, paramIndex);
|
|
2935
2983
|
};
|
|
2936
2984
|
};
|
|
2937
2985
|
var _a11;
|
|
2986
|
+
var RoleController = class RoleController2 {
|
|
2987
|
+
static {
|
|
2988
|
+
__name(this, "RoleController");
|
|
2989
|
+
}
|
|
2990
|
+
roleService;
|
|
2991
|
+
constructor(roleService) {
|
|
2992
|
+
this.roleService = roleService;
|
|
2993
|
+
}
|
|
2994
|
+
async getRoles() {
|
|
2995
|
+
return this.roleService.getAll();
|
|
2996
|
+
}
|
|
2997
|
+
async getRole(params) {
|
|
2998
|
+
return this.roleService.getById(params.id);
|
|
2999
|
+
}
|
|
3000
|
+
async createRole(body) {
|
|
3001
|
+
return this.roleService.create(body);
|
|
3002
|
+
}
|
|
3003
|
+
async updateRole(params, body) {
|
|
3004
|
+
return this.roleService.update(params.id, body);
|
|
3005
|
+
}
|
|
3006
|
+
async deleteRole(params) {
|
|
3007
|
+
return this.roleService.delete(params.id);
|
|
3008
|
+
}
|
|
3009
|
+
};
|
|
3010
|
+
__decorate17([
|
|
3011
|
+
Get2(),
|
|
3012
|
+
isAdmin(),
|
|
3013
|
+
ResMsg2("roles.success.retrieved"),
|
|
3014
|
+
__metadata17("design:type", Function),
|
|
3015
|
+
__metadata17("design:paramtypes", []),
|
|
3016
|
+
__metadata17("design:returntype", Promise)
|
|
3017
|
+
], RoleController.prototype, "getRoles", null);
|
|
3018
|
+
__decorate17([
|
|
3019
|
+
Get2("/:id"),
|
|
3020
|
+
isAdmin(),
|
|
3021
|
+
Validate2({ params: roleIdParam }),
|
|
3022
|
+
ResMsg2("roles.success.retrieved"),
|
|
3023
|
+
__param6(0, Params()),
|
|
3024
|
+
__metadata17("design:type", Function),
|
|
3025
|
+
__metadata17("design:paramtypes", [Object]),
|
|
3026
|
+
__metadata17("design:returntype", Promise)
|
|
3027
|
+
], RoleController.prototype, "getRole", null);
|
|
3028
|
+
__decorate17([
|
|
3029
|
+
Post2(),
|
|
3030
|
+
isAdmin(),
|
|
3031
|
+
Validate2(createRoleDto),
|
|
3032
|
+
ResMsg2("roles.success.created"),
|
|
3033
|
+
__param6(0, Body2()),
|
|
3034
|
+
__metadata17("design:type", Function),
|
|
3035
|
+
__metadata17("design:paramtypes", [Object]),
|
|
3036
|
+
__metadata17("design:returntype", Promise)
|
|
3037
|
+
], RoleController.prototype, "createRole", null);
|
|
3038
|
+
__decorate17([
|
|
3039
|
+
Put("/:id"),
|
|
3040
|
+
isAdmin(),
|
|
3041
|
+
Validate2({
|
|
3042
|
+
params: roleIdParam,
|
|
3043
|
+
body: updateRoleDto
|
|
3044
|
+
}),
|
|
3045
|
+
ResMsg2("roles.success.updated"),
|
|
3046
|
+
__param6(0, Params()),
|
|
3047
|
+
__param6(1, Body2()),
|
|
3048
|
+
__metadata17("design:type", Function),
|
|
3049
|
+
__metadata17("design:paramtypes", [Object, Object]),
|
|
3050
|
+
__metadata17("design:returntype", Promise)
|
|
3051
|
+
], RoleController.prototype, "updateRole", null);
|
|
3052
|
+
__decorate17([
|
|
3053
|
+
Delete("/:id"),
|
|
3054
|
+
isAdmin(),
|
|
3055
|
+
Validate2({ params: roleIdParam }),
|
|
3056
|
+
ResMsg2("roles.success.deleted"),
|
|
3057
|
+
__param6(0, Params()),
|
|
3058
|
+
__metadata17("design:type", Function),
|
|
3059
|
+
__metadata17("design:paramtypes", [Object]),
|
|
3060
|
+
__metadata17("design:returntype", Promise)
|
|
3061
|
+
], RoleController.prototype, "deleteRole", null);
|
|
3062
|
+
RoleController = __decorate17([
|
|
3063
|
+
Controller2("/roles"),
|
|
3064
|
+
__metadata17("design:paramtypes", [typeof (_a11 = typeof RoleService !== "undefined" && RoleService) === "function" ? _a11 : Object])
|
|
3065
|
+
], RoleController);
|
|
3066
|
+
|
|
3067
|
+
// src/users/UserController.ts
|
|
3068
|
+
import { Validate as Validate3 } from "najm-validation";
|
|
3069
|
+
var __decorate18 = function(decorators, target, key, desc) {
|
|
3070
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3071
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3072
|
+
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;
|
|
3073
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3074
|
+
};
|
|
3075
|
+
var __metadata18 = function(k, v) {
|
|
3076
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3077
|
+
};
|
|
3078
|
+
var __param7 = function(paramIndex, decorator) {
|
|
3079
|
+
return function(target, key) {
|
|
3080
|
+
decorator(target, key, paramIndex);
|
|
3081
|
+
};
|
|
3082
|
+
};
|
|
3083
|
+
var _a12;
|
|
2938
3084
|
var UserController = class UserController2 {
|
|
2939
3085
|
static {
|
|
2940
3086
|
__name(this, "UserController");
|
|
@@ -2981,75 +3127,75 @@ var UserController = class UserController2 {
|
|
|
2981
3127
|
return this.userService.removeRole(params.userId);
|
|
2982
3128
|
}
|
|
2983
3129
|
};
|
|
2984
|
-
|
|
3130
|
+
__decorate18([
|
|
2985
3131
|
Get3(),
|
|
2986
3132
|
isAdmin(),
|
|
2987
3133
|
Validate3({ query: userListQuery }),
|
|
2988
3134
|
ResMsg3("users.success.retrieved"),
|
|
2989
3135
|
__param7(0, Query()),
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
3136
|
+
__metadata18("design:type", Function),
|
|
3137
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3138
|
+
__metadata18("design:returntype", Promise)
|
|
2993
3139
|
], UserController.prototype, "getUsers", null);
|
|
2994
|
-
|
|
3140
|
+
__decorate18([
|
|
2995
3141
|
Get3("/lang"),
|
|
2996
3142
|
isAuth(),
|
|
2997
3143
|
ResMsg3("users.success.retrieved"),
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3144
|
+
__metadata18("design:type", Function),
|
|
3145
|
+
__metadata18("design:paramtypes", []),
|
|
3146
|
+
__metadata18("design:returntype", Promise)
|
|
3001
3147
|
], UserController.prototype, "getLang", null);
|
|
3002
|
-
|
|
3148
|
+
__decorate18([
|
|
3003
3149
|
Post3("/lang/:language"),
|
|
3004
3150
|
isAuth(),
|
|
3005
3151
|
Validate3({ params: languageParam }),
|
|
3006
3152
|
ResMsg3("users.success.updated"),
|
|
3007
3153
|
__param7(0, Params2()),
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3154
|
+
__metadata18("design:type", Function),
|
|
3155
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3156
|
+
__metadata18("design:returntype", Promise)
|
|
3011
3157
|
], UserController.prototype, "updateLang", null);
|
|
3012
|
-
|
|
3158
|
+
__decorate18([
|
|
3013
3159
|
Get3("/:id"),
|
|
3014
3160
|
isAdmin(),
|
|
3015
3161
|
Validate3({ params: userIdParam }),
|
|
3016
3162
|
ResMsg3("users.success.retrieved"),
|
|
3017
3163
|
__param7(0, Params2()),
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3164
|
+
__metadata18("design:type", Function),
|
|
3165
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3166
|
+
__metadata18("design:returntype", Promise)
|
|
3021
3167
|
], UserController.prototype, "getUser", null);
|
|
3022
|
-
|
|
3168
|
+
__decorate18([
|
|
3023
3169
|
Get3("/email/:email"),
|
|
3024
3170
|
isAdmin(),
|
|
3025
3171
|
Validate3({ params: emailParam }),
|
|
3026
3172
|
ResMsg3("users.success.retrieved"),
|
|
3027
3173
|
__param7(0, Params2()),
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3174
|
+
__metadata18("design:type", Function),
|
|
3175
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3176
|
+
__metadata18("design:returntype", Promise)
|
|
3031
3177
|
], UserController.prototype, "getByEmail", null);
|
|
3032
|
-
|
|
3178
|
+
__decorate18([
|
|
3033
3179
|
Get3("/role/:userId"),
|
|
3034
3180
|
isAdmin(),
|
|
3035
3181
|
Validate3({ params: userIdInParam }),
|
|
3036
3182
|
ResMsg3("users.success.retrieved"),
|
|
3037
3183
|
__param7(0, Params2()),
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3184
|
+
__metadata18("design:type", Function),
|
|
3185
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3186
|
+
__metadata18("design:returntype", Promise)
|
|
3041
3187
|
], UserController.prototype, "getRole", null);
|
|
3042
|
-
|
|
3188
|
+
__decorate18([
|
|
3043
3189
|
Post3(),
|
|
3044
3190
|
isAdmin(),
|
|
3045
3191
|
Validate3(createUserDto),
|
|
3046
3192
|
ResMsg3("users.success.created"),
|
|
3047
3193
|
__param7(0, Body3()),
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3194
|
+
__metadata18("design:type", Function),
|
|
3195
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3196
|
+
__metadata18("design:returntype", Promise)
|
|
3051
3197
|
], UserController.prototype, "create", null);
|
|
3052
|
-
|
|
3198
|
+
__decorate18([
|
|
3053
3199
|
Put2("/:id"),
|
|
3054
3200
|
isAdmin(),
|
|
3055
3201
|
Validate3({
|
|
@@ -3059,51 +3205,51 @@ __decorate17([
|
|
|
3059
3205
|
ResMsg3("users.success.updated"),
|
|
3060
3206
|
__param7(0, Params2()),
|
|
3061
3207
|
__param7(1, Body3()),
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3208
|
+
__metadata18("design:type", Function),
|
|
3209
|
+
__metadata18("design:paramtypes", [Object, Object]),
|
|
3210
|
+
__metadata18("design:returntype", Promise)
|
|
3065
3211
|
], UserController.prototype, "update", null);
|
|
3066
|
-
|
|
3212
|
+
__decorate18([
|
|
3067
3213
|
Delete2("/:id"),
|
|
3068
3214
|
isAdmin(),
|
|
3069
3215
|
Validate3({ params: userIdParam }),
|
|
3070
3216
|
ResMsg3("users.success.deleted"),
|
|
3071
3217
|
__param7(0, Params2()),
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3218
|
+
__metadata18("design:type", Function),
|
|
3219
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3220
|
+
__metadata18("design:returntype", Promise)
|
|
3075
3221
|
], UserController.prototype, "delete", null);
|
|
3076
|
-
|
|
3222
|
+
__decorate18([
|
|
3077
3223
|
Delete2(),
|
|
3078
3224
|
isAdmin(),
|
|
3079
3225
|
ResMsg3("users.success.allDeleted"),
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3226
|
+
__metadata18("design:type", Function),
|
|
3227
|
+
__metadata18("design:paramtypes", []),
|
|
3228
|
+
__metadata18("design:returntype", Promise)
|
|
3083
3229
|
], UserController.prototype, "deleteAll", null);
|
|
3084
|
-
|
|
3230
|
+
__decorate18([
|
|
3085
3231
|
Post3("/assign/:userId/:roleId"),
|
|
3086
3232
|
isAdmin(),
|
|
3087
3233
|
Validate3({ params: assignRoleParams }),
|
|
3088
3234
|
ResMsg3("users.success.updated"),
|
|
3089
3235
|
__param7(0, Params2()),
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3236
|
+
__metadata18("design:type", Function),
|
|
3237
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3238
|
+
__metadata18("design:returntype", Promise)
|
|
3093
3239
|
], UserController.prototype, "assignRole", null);
|
|
3094
|
-
|
|
3240
|
+
__decorate18([
|
|
3095
3241
|
Delete2("/remove/:userId"),
|
|
3096
3242
|
isAdmin(),
|
|
3097
3243
|
Validate3({ params: userIdInParam }),
|
|
3098
3244
|
ResMsg3("users.success.updated"),
|
|
3099
3245
|
__param7(0, Params2()),
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3246
|
+
__metadata18("design:type", Function),
|
|
3247
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3248
|
+
__metadata18("design:returntype", Promise)
|
|
3103
3249
|
], UserController.prototype, "removeRole", null);
|
|
3104
|
-
UserController =
|
|
3250
|
+
UserController = __decorate18([
|
|
3105
3251
|
Controller3("/users"),
|
|
3106
|
-
|
|
3252
|
+
__metadata18("design:paramtypes", [typeof (_a12 = typeof UserService !== "undefined" && UserService) === "function" ? _a12 : Object])
|
|
3107
3253
|
], UserController);
|
|
3108
3254
|
|
|
3109
3255
|
// src/permissions/index.ts
|
|
@@ -3126,13 +3272,13 @@ __export(permissions_exports, {
|
|
|
3126
3272
|
import { eq as eq5, and as and2 } from "drizzle-orm";
|
|
3127
3273
|
import { Repository as Repository4, Inject as Inject10 } from "najm-core";
|
|
3128
3274
|
import { DB as DB4 } from "najm-database";
|
|
3129
|
-
var
|
|
3275
|
+
var __decorate19 = function(decorators, target, key, desc) {
|
|
3130
3276
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3131
3277
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3132
3278
|
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;
|
|
3133
3279
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3134
3280
|
};
|
|
3135
|
-
var
|
|
3281
|
+
var __metadata19 = function(k, v) {
|
|
3136
3282
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3137
3283
|
};
|
|
3138
3284
|
var PermissionRepository = class PermissionRepository2 {
|
|
@@ -3210,29 +3356,29 @@ var PermissionRepository = class PermissionRepository2 {
|
|
|
3210
3356
|
return deletedPermissions;
|
|
3211
3357
|
}
|
|
3212
3358
|
};
|
|
3213
|
-
|
|
3359
|
+
__decorate19([
|
|
3214
3360
|
DB4(),
|
|
3215
|
-
|
|
3361
|
+
__metadata19("design:type", Object)
|
|
3216
3362
|
], PermissionRepository.prototype, "db", void 0);
|
|
3217
|
-
|
|
3363
|
+
__decorate19([
|
|
3218
3364
|
Inject10(AUTH_SCHEMA),
|
|
3219
|
-
|
|
3365
|
+
__metadata19("design:type", Object)
|
|
3220
3366
|
], PermissionRepository.prototype, "schema", void 0);
|
|
3221
|
-
PermissionRepository =
|
|
3367
|
+
PermissionRepository = __decorate19([
|
|
3222
3368
|
Repository4()
|
|
3223
3369
|
], PermissionRepository);
|
|
3224
3370
|
|
|
3225
3371
|
// src/permissions/PermissionGuards.ts
|
|
3226
|
-
import { Injectable as
|
|
3372
|
+
import { Injectable as Injectable9 } from "najm-core";
|
|
3227
3373
|
import { GuardParams as GuardParams2, User as User4 } from "najm-core";
|
|
3228
3374
|
import { createGuard as createGuard4, composeGuards as composeGuards3 } from "najm-guard";
|
|
3229
|
-
var
|
|
3375
|
+
var __decorate20 = function(decorators, target, key, desc) {
|
|
3230
3376
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3231
3377
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3232
3378
|
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;
|
|
3233
3379
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3234
3380
|
};
|
|
3235
|
-
var
|
|
3381
|
+
var __metadata20 = function(k, v) {
|
|
3236
3382
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3237
3383
|
};
|
|
3238
3384
|
var __param8 = function(paramIndex, decorator) {
|
|
@@ -3268,15 +3414,15 @@ var PermissionGuard = class PermissionGuard2 {
|
|
|
3268
3414
|
return false;
|
|
3269
3415
|
}
|
|
3270
3416
|
};
|
|
3271
|
-
|
|
3417
|
+
__decorate20([
|
|
3272
3418
|
__param8(0, GuardParams2()),
|
|
3273
3419
|
__param8(1, User4("permissions")),
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3420
|
+
__metadata20("design:type", Function),
|
|
3421
|
+
__metadata20("design:paramtypes", [String, Array]),
|
|
3422
|
+
__metadata20("design:returntype", Object)
|
|
3277
3423
|
], PermissionGuard.prototype, "canActivate", null);
|
|
3278
|
-
PermissionGuard =
|
|
3279
|
-
|
|
3424
|
+
PermissionGuard = __decorate20([
|
|
3425
|
+
Injectable9()
|
|
3280
3426
|
], PermissionGuard);
|
|
3281
3427
|
var Permission = createGuard4(PermissionGuard);
|
|
3282
3428
|
var Can = /* @__PURE__ */ __name((permission) => composeGuards3(isAuth(), Permission(permission))(), "Can");
|
|
@@ -3287,23 +3433,23 @@ import { Get as Get4, Post as Post4, Put as Put3, Delete as Delete3, ResMsg as R
|
|
|
3287
3433
|
import { Params as Params3, Body as Body4 } from "najm-core";
|
|
3288
3434
|
|
|
3289
3435
|
// src/permissions/PermissionService.ts
|
|
3290
|
-
import { Injectable as
|
|
3436
|
+
import { Injectable as Injectable11 } from "najm-core";
|
|
3291
3437
|
|
|
3292
3438
|
// src/permissions/PermissionValidator.ts
|
|
3293
|
-
import { Injectable as
|
|
3294
|
-
import { I18n as
|
|
3295
|
-
import { Err as
|
|
3296
|
-
var
|
|
3439
|
+
import { Injectable as Injectable10 } from "najm-core";
|
|
3440
|
+
import { I18n as I18n7 } from "najm-i18n";
|
|
3441
|
+
import { Err as Err9 } from "najm-core";
|
|
3442
|
+
var __decorate21 = function(decorators, target, key, desc) {
|
|
3297
3443
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3298
3444
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3299
3445
|
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;
|
|
3300
3446
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3301
3447
|
};
|
|
3302
|
-
var
|
|
3448
|
+
var __metadata21 = function(k, v) {
|
|
3303
3449
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3304
3450
|
};
|
|
3305
|
-
var
|
|
3306
|
-
var
|
|
3451
|
+
var _a13;
|
|
3452
|
+
var _b7;
|
|
3307
3453
|
var PermissionValidator = class PermissionValidator2 {
|
|
3308
3454
|
static {
|
|
3309
3455
|
__name(this, "PermissionValidator");
|
|
@@ -3321,7 +3467,7 @@ var PermissionValidator = class PermissionValidator2 {
|
|
|
3321
3467
|
async checkPermissionExists(id) {
|
|
3322
3468
|
const permission = await this.permissionRepository.getById(id);
|
|
3323
3469
|
if (!permission) {
|
|
3324
|
-
|
|
3470
|
+
Err9(this.t("errors.notFound"), 404);
|
|
3325
3471
|
}
|
|
3326
3472
|
return permission;
|
|
3327
3473
|
}
|
|
@@ -3331,7 +3477,7 @@ var PermissionValidator = class PermissionValidator2 {
|
|
|
3331
3477
|
async checkPermissionExistsByName(name) {
|
|
3332
3478
|
const permission = await this.permissionRepository.getByName(name);
|
|
3333
3479
|
if (!permission) {
|
|
3334
|
-
|
|
3480
|
+
Err9(this.t("errors.notFound"), 404);
|
|
3335
3481
|
}
|
|
3336
3482
|
return permission;
|
|
3337
3483
|
}
|
|
@@ -3343,7 +3489,7 @@ var PermissionValidator = class PermissionValidator2 {
|
|
|
3343
3489
|
return;
|
|
3344
3490
|
const existingPermission = await this.permissionRepository.getByName(name);
|
|
3345
3491
|
if (existingPermission && existingPermission.id !== excludeId) {
|
|
3346
|
-
|
|
3492
|
+
Err9(this.t("errors.nameExists"), 409);
|
|
3347
3493
|
}
|
|
3348
3494
|
}
|
|
3349
3495
|
/**
|
|
@@ -3366,32 +3512,32 @@ var PermissionValidator = class PermissionValidator2 {
|
|
|
3366
3512
|
await this.checkPermissionExists(permissionId);
|
|
3367
3513
|
const hasPermission = await this.permissionRepository.checkRoleHasPermission(roleId, permissionId);
|
|
3368
3514
|
if (hasPermission) {
|
|
3369
|
-
|
|
3515
|
+
Err9(this.t("errors.roleAlreadyHasPermission"), 409);
|
|
3370
3516
|
}
|
|
3371
3517
|
}
|
|
3372
3518
|
};
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3519
|
+
__decorate21([
|
|
3520
|
+
I18n7("permissions"),
|
|
3521
|
+
__metadata21("design:type", Object)
|
|
3376
3522
|
], PermissionValidator.prototype, "t", void 0);
|
|
3377
|
-
PermissionValidator =
|
|
3378
|
-
|
|
3379
|
-
|
|
3523
|
+
PermissionValidator = __decorate21([
|
|
3524
|
+
Injectable10(),
|
|
3525
|
+
__metadata21("design:paramtypes", [typeof (_a13 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a13 : Object, typeof (_b7 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _b7 : Object])
|
|
3380
3526
|
], PermissionValidator);
|
|
3381
3527
|
|
|
3382
3528
|
// src/permissions/PermissionService.ts
|
|
3383
|
-
var
|
|
3529
|
+
var __decorate22 = function(decorators, target, key, desc) {
|
|
3384
3530
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3385
3531
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3386
3532
|
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;
|
|
3387
3533
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3388
3534
|
};
|
|
3389
|
-
var
|
|
3535
|
+
var __metadata22 = function(k, v) {
|
|
3390
3536
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3391
3537
|
};
|
|
3392
|
-
var
|
|
3393
|
-
var
|
|
3394
|
-
var
|
|
3538
|
+
var _a14;
|
|
3539
|
+
var _b8;
|
|
3540
|
+
var _c5;
|
|
3395
3541
|
var PermissionService = class PermissionService2 {
|
|
3396
3542
|
static {
|
|
3397
3543
|
__name(this, "PermissionService");
|
|
@@ -3496,9 +3642,9 @@ var PermissionService = class PermissionService2 {
|
|
|
3496
3642
|
return await this.permissionRepository.deleteAll();
|
|
3497
3643
|
}
|
|
3498
3644
|
};
|
|
3499
|
-
PermissionService =
|
|
3500
|
-
|
|
3501
|
-
|
|
3645
|
+
PermissionService = __decorate22([
|
|
3646
|
+
Injectable11(),
|
|
3647
|
+
__metadata22("design:paramtypes", [typeof (_a14 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a14 : Object, typeof (_b8 = typeof PermissionValidator !== "undefined" && PermissionValidator) === "function" ? _b8 : Object, typeof (_c5 = typeof RoleService !== "undefined" && RoleService) === "function" ? _c5 : Object])
|
|
3502
3648
|
], PermissionService);
|
|
3503
3649
|
|
|
3504
3650
|
// src/permissions/PermissionController.ts
|
|
@@ -3531,13 +3677,13 @@ var checkPermissionDto = z3.object({
|
|
|
3531
3677
|
});
|
|
3532
3678
|
|
|
3533
3679
|
// src/permissions/PermissionController.ts
|
|
3534
|
-
var
|
|
3680
|
+
var __decorate23 = function(decorators, target, key, desc) {
|
|
3535
3681
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3536
3682
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3537
3683
|
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;
|
|
3538
3684
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3539
3685
|
};
|
|
3540
|
-
var
|
|
3686
|
+
var __metadata23 = function(k, v) {
|
|
3541
3687
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3542
3688
|
};
|
|
3543
3689
|
var __param9 = function(paramIndex, decorator) {
|
|
@@ -3545,7 +3691,7 @@ var __param9 = function(paramIndex, decorator) {
|
|
|
3545
3691
|
decorator(target, key, paramIndex);
|
|
3546
3692
|
};
|
|
3547
3693
|
};
|
|
3548
|
-
var
|
|
3694
|
+
var _a15;
|
|
3549
3695
|
var PermissionController = class PermissionController2 {
|
|
3550
3696
|
static {
|
|
3551
3697
|
__name(this, "PermissionController");
|
|
@@ -3591,32 +3737,32 @@ var PermissionController = class PermissionController2 {
|
|
|
3591
3737
|
return this.permissionService.deleteAll();
|
|
3592
3738
|
}
|
|
3593
3739
|
};
|
|
3594
|
-
|
|
3740
|
+
__decorate23([
|
|
3595
3741
|
Get4(),
|
|
3596
3742
|
ResMsg4("permissions.success.retrieved"),
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3743
|
+
__metadata23("design:type", Function),
|
|
3744
|
+
__metadata23("design:paramtypes", []),
|
|
3745
|
+
__metadata23("design:returntype", Promise)
|
|
3600
3746
|
], PermissionController.prototype, "getPermissions", null);
|
|
3601
|
-
|
|
3747
|
+
__decorate23([
|
|
3602
3748
|
Get4("/:id"),
|
|
3603
3749
|
Validate4({ params: permissionIdParam }),
|
|
3604
3750
|
ResMsg4("permissions.success.retrieved"),
|
|
3605
3751
|
__param9(0, Params3()),
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3752
|
+
__metadata23("design:type", Function),
|
|
3753
|
+
__metadata23("design:paramtypes", [Object]),
|
|
3754
|
+
__metadata23("design:returntype", Promise)
|
|
3609
3755
|
], PermissionController.prototype, "getPermission", null);
|
|
3610
|
-
|
|
3756
|
+
__decorate23([
|
|
3611
3757
|
Post4(),
|
|
3612
3758
|
Validate4(createPermissionDto),
|
|
3613
3759
|
ResMsg4({ message: "Permission created successfully", status: 201 }),
|
|
3614
3760
|
__param9(0, Body4()),
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3761
|
+
__metadata23("design:type", Function),
|
|
3762
|
+
__metadata23("design:paramtypes", [Object]),
|
|
3763
|
+
__metadata23("design:returntype", Promise)
|
|
3618
3764
|
], PermissionController.prototype, "create", null);
|
|
3619
|
-
|
|
3765
|
+
__decorate23([
|
|
3620
3766
|
Put3("/:id"),
|
|
3621
3767
|
Validate4({
|
|
3622
3768
|
params: permissionIdParam,
|
|
@@ -3625,67 +3771,67 @@ __decorate22([
|
|
|
3625
3771
|
ResMsg4("permissions.success.updated"),
|
|
3626
3772
|
__param9(0, Params3()),
|
|
3627
3773
|
__param9(1, Body4()),
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3774
|
+
__metadata23("design:type", Function),
|
|
3775
|
+
__metadata23("design:paramtypes", [Object, Object]),
|
|
3776
|
+
__metadata23("design:returntype", Promise)
|
|
3631
3777
|
], PermissionController.prototype, "update", null);
|
|
3632
|
-
|
|
3778
|
+
__decorate23([
|
|
3633
3779
|
Delete3("/:id"),
|
|
3634
3780
|
Validate4({ params: permissionIdParam }),
|
|
3635
3781
|
ResMsg4("permissions.success.deleted"),
|
|
3636
3782
|
__param9(0, Params3()),
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3783
|
+
__metadata23("design:type", Function),
|
|
3784
|
+
__metadata23("design:paramtypes", [Object]),
|
|
3785
|
+
__metadata23("design:returntype", Promise)
|
|
3640
3786
|
], PermissionController.prototype, "delete", null);
|
|
3641
|
-
|
|
3787
|
+
__decorate23([
|
|
3642
3788
|
Get4("/role/:id"),
|
|
3643
3789
|
Validate4({ params: roleIdParam }),
|
|
3644
3790
|
ResMsg4("permissions.success.retrieved"),
|
|
3645
3791
|
__param9(0, Params3()),
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3792
|
+
__metadata23("design:type", Function),
|
|
3793
|
+
__metadata23("design:paramtypes", [Object]),
|
|
3794
|
+
__metadata23("design:returntype", Promise)
|
|
3649
3795
|
], PermissionController.prototype, "getByRole", null);
|
|
3650
|
-
|
|
3796
|
+
__decorate23([
|
|
3651
3797
|
Get4("/roles/:id"),
|
|
3652
3798
|
Validate4({ params: permissionIdParam }),
|
|
3653
3799
|
ResMsg4("permissions.success.retrieved"),
|
|
3654
3800
|
__param9(0, Params3()),
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3801
|
+
__metadata23("design:type", Function),
|
|
3802
|
+
__metadata23("design:paramtypes", [Object]),
|
|
3803
|
+
__metadata23("design:returntype", Promise)
|
|
3658
3804
|
], PermissionController.prototype, "getRolesByPermission", null);
|
|
3659
|
-
|
|
3805
|
+
__decorate23([
|
|
3660
3806
|
Post4("/assign/:roleId/:permissionId"),
|
|
3661
3807
|
Validate4({ params: assignPermissionDto }),
|
|
3662
3808
|
ResMsg4("permissions.success.assigned"),
|
|
3663
3809
|
__param9(0, Params3()),
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3810
|
+
__metadata23("design:type", Function),
|
|
3811
|
+
__metadata23("design:paramtypes", [Object]),
|
|
3812
|
+
__metadata23("design:returntype", Promise)
|
|
3667
3813
|
], PermissionController.prototype, "assignToRole", null);
|
|
3668
|
-
|
|
3814
|
+
__decorate23([
|
|
3669
3815
|
Delete3("/remove/:roleId/:permissionId"),
|
|
3670
3816
|
Validate4({ params: assignPermissionDto }),
|
|
3671
3817
|
ResMsg4("permissions.success.removed"),
|
|
3672
3818
|
__param9(0, Params3()),
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3819
|
+
__metadata23("design:type", Function),
|
|
3820
|
+
__metadata23("design:paramtypes", [Object]),
|
|
3821
|
+
__metadata23("design:returntype", Promise)
|
|
3676
3822
|
], PermissionController.prototype, "removeFromRole", null);
|
|
3677
|
-
|
|
3823
|
+
__decorate23([
|
|
3678
3824
|
Delete3(),
|
|
3679
3825
|
isAdmin(),
|
|
3680
3826
|
ResMsg4("permissions.success.allDeleted"),
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3827
|
+
__metadata23("design:type", Function),
|
|
3828
|
+
__metadata23("design:paramtypes", []),
|
|
3829
|
+
__metadata23("design:returntype", Promise)
|
|
3684
3830
|
], PermissionController.prototype, "deleteAll", null);
|
|
3685
|
-
PermissionController =
|
|
3831
|
+
PermissionController = __decorate23([
|
|
3686
3832
|
Controller4("/permissions"),
|
|
3687
3833
|
isAdmin(),
|
|
3688
|
-
|
|
3834
|
+
__metadata23("design:paramtypes", [typeof (_a15 = typeof PermissionService !== "undefined" && PermissionService) === "function" ? _a15 : Object])
|
|
3689
3835
|
], PermissionController);
|
|
3690
3836
|
|
|
3691
3837
|
// src/tokens/index.ts
|
|
@@ -3892,15 +4038,15 @@ function own(table, opts) {
|
|
|
3892
4038
|
__name(own, "own");
|
|
3893
4039
|
|
|
3894
4040
|
// src/ownership/configureOwnership.ts
|
|
3895
|
-
import { Injectable as
|
|
4041
|
+
import { Injectable as Injectable12, Inject as Inject11, User as User5, Body as Body5, Params as Params4 } from "najm-core";
|
|
3896
4042
|
import { createGuard as createGuard5, composeGuards as composeGuards4 } from "najm-guard";
|
|
3897
|
-
var
|
|
4043
|
+
var __decorate24 = function(decorators, target, key, desc) {
|
|
3898
4044
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3899
4045
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3900
4046
|
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;
|
|
3901
4047
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3902
4048
|
};
|
|
3903
|
-
var
|
|
4049
|
+
var __metadata24 = function(k, v) {
|
|
3904
4050
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3905
4051
|
};
|
|
3906
4052
|
var __param10 = function(paramIndex, decorator) {
|
|
@@ -3920,7 +4066,7 @@ function toSingular(plural) {
|
|
|
3920
4066
|
}
|
|
3921
4067
|
__name(toSingular, "toSingular");
|
|
3922
4068
|
function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
3923
|
-
var
|
|
4069
|
+
var _a22, _b12;
|
|
3924
4070
|
const writeGuard = options?.adminGuard ?? isAdmin;
|
|
3925
4071
|
let AccessGuard = class AccessGuard {
|
|
3926
4072
|
static {
|
|
@@ -3932,19 +4078,19 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
|
3932
4078
|
return allowed ? { owner: user } : false;
|
|
3933
4079
|
}
|
|
3934
4080
|
};
|
|
3935
|
-
|
|
4081
|
+
__decorate24([
|
|
3936
4082
|
Inject11(ownershipClass),
|
|
3937
|
-
|
|
4083
|
+
__metadata24("design:type", Object)
|
|
3938
4084
|
], AccessGuard.prototype, "ownership", void 0);
|
|
3939
|
-
|
|
4085
|
+
__decorate24([
|
|
3940
4086
|
__param10(0, User5()),
|
|
3941
4087
|
__param10(1, Params4("id")),
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
4088
|
+
__metadata24("design:type", Function),
|
|
4089
|
+
__metadata24("design:paramtypes", [Object, String]),
|
|
4090
|
+
__metadata24("design:returntype", typeof (_a22 = typeof Promise !== "undefined" && Promise) === "function" ? _a22 : Object)
|
|
3945
4091
|
], AccessGuard.prototype, "canActivate", null);
|
|
3946
|
-
AccessGuard =
|
|
3947
|
-
|
|
4092
|
+
AccessGuard = __decorate24([
|
|
4093
|
+
Injectable12()
|
|
3948
4094
|
], AccessGuard);
|
|
3949
4095
|
let ListGuard = class ListGuard {
|
|
3950
4096
|
static {
|
|
@@ -3956,18 +4102,18 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
|
3956
4102
|
return { filter: ids };
|
|
3957
4103
|
}
|
|
3958
4104
|
};
|
|
3959
|
-
|
|
4105
|
+
__decorate24([
|
|
3960
4106
|
Inject11(ownershipClass),
|
|
3961
|
-
|
|
4107
|
+
__metadata24("design:type", Object)
|
|
3962
4108
|
], ListGuard.prototype, "ownership", void 0);
|
|
3963
|
-
|
|
4109
|
+
__decorate24([
|
|
3964
4110
|
__param10(0, User5()),
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
4111
|
+
__metadata24("design:type", Function),
|
|
4112
|
+
__metadata24("design:paramtypes", [Object]),
|
|
4113
|
+
__metadata24("design:returntype", typeof (_b12 = typeof Promise !== "undefined" && Promise) === "function" ? _b12 : Object)
|
|
3968
4114
|
], ListGuard.prototype, "canActivate", null);
|
|
3969
|
-
ListGuard =
|
|
3970
|
-
|
|
4115
|
+
ListGuard = __decorate24([
|
|
4116
|
+
Injectable12()
|
|
3971
4117
|
], ListGuard);
|
|
3972
4118
|
const access = createGuard5(AccessGuard);
|
|
3973
4119
|
const list = createGuard5(ListGuard);
|
|
@@ -4098,11 +4244,11 @@ function configureOwnership(config) {
|
|
|
4098
4244
|
}
|
|
4099
4245
|
}
|
|
4100
4246
|
};
|
|
4101
|
-
GeneratedOwnershipService =
|
|
4102
|
-
|
|
4247
|
+
GeneratedOwnershipService = __decorate24([
|
|
4248
|
+
Injectable12()
|
|
4103
4249
|
], GeneratedOwnershipService);
|
|
4104
4250
|
function bodyGuard(resourceType, bodyField, optional = false) {
|
|
4105
|
-
var
|
|
4251
|
+
var _a22;
|
|
4106
4252
|
let BodyAccessGuard = class BodyAccessGuard {
|
|
4107
4253
|
static {
|
|
4108
4254
|
__name(this, "BodyAccessGuard");
|
|
@@ -4115,19 +4261,19 @@ function configureOwnership(config) {
|
|
|
4115
4261
|
return this.ownership.canAccess(user, resourceType, id);
|
|
4116
4262
|
}
|
|
4117
4263
|
};
|
|
4118
|
-
|
|
4264
|
+
__decorate24([
|
|
4119
4265
|
Inject11(GeneratedOwnershipService),
|
|
4120
|
-
|
|
4266
|
+
__metadata24("design:type", GeneratedOwnershipService)
|
|
4121
4267
|
], BodyAccessGuard.prototype, "ownership", void 0);
|
|
4122
|
-
|
|
4268
|
+
__decorate24([
|
|
4123
4269
|
__param10(0, User5()),
|
|
4124
4270
|
__param10(1, Body5()),
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4271
|
+
__metadata24("design:type", Function),
|
|
4272
|
+
__metadata24("design:paramtypes", [Object, Object]),
|
|
4273
|
+
__metadata24("design:returntype", typeof (_a22 = typeof Promise !== "undefined" && Promise) === "function" ? _a22 : Object)
|
|
4128
4274
|
], BodyAccessGuard.prototype, "canActivate", null);
|
|
4129
|
-
BodyAccessGuard =
|
|
4130
|
-
|
|
4275
|
+
BodyAccessGuard = __decorate24([
|
|
4276
|
+
Injectable12()
|
|
4131
4277
|
], BodyAccessGuard);
|
|
4132
4278
|
return createGuard5(BodyAccessGuard);
|
|
4133
4279
|
}
|
|
@@ -4242,18 +4388,18 @@ __name(Policy, "Policy");
|
|
|
4242
4388
|
// src/ownership/OwnedDecorator.ts
|
|
4243
4389
|
import "reflect-metadata";
|
|
4244
4390
|
import { sql as sql5, and as and3 } from "drizzle-orm";
|
|
4245
|
-
import { Injectable as
|
|
4391
|
+
import { Injectable as Injectable13, Inject as Inject12, DI as DI2, Container as Container2, REQUEST_ID } from "najm-core";
|
|
4246
4392
|
import { USER as USER2 } from "najm-guard";
|
|
4247
|
-
var
|
|
4393
|
+
var __decorate25 = function(decorators, target, key, desc) {
|
|
4248
4394
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4249
4395
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4250
4396
|
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;
|
|
4251
4397
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4252
4398
|
};
|
|
4253
|
-
var
|
|
4399
|
+
var __metadata25 = function(k, v) {
|
|
4254
4400
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4255
4401
|
};
|
|
4256
|
-
var
|
|
4402
|
+
var _a16;
|
|
4257
4403
|
var OWNED_META = /* @__PURE__ */ Symbol.for("najm:owned");
|
|
4258
4404
|
var ScopeContext = class ScopeContext2 {
|
|
4259
4405
|
static {
|
|
@@ -4285,12 +4431,12 @@ var ScopeContext = class ScopeContext2 {
|
|
|
4285
4431
|
}
|
|
4286
4432
|
}
|
|
4287
4433
|
};
|
|
4288
|
-
|
|
4434
|
+
__decorate25([
|
|
4289
4435
|
DI2(),
|
|
4290
|
-
|
|
4436
|
+
__metadata25("design:type", typeof (_a16 = typeof Container2 !== "undefined" && Container2) === "function" ? _a16 : Object)
|
|
4291
4437
|
], ScopeContext.prototype, "container", void 0);
|
|
4292
|
-
ScopeContext =
|
|
4293
|
-
|
|
4438
|
+
ScopeContext = __decorate25([
|
|
4439
|
+
Injectable13()
|
|
4294
4440
|
], ScopeContext);
|
|
4295
4441
|
function Owned(token) {
|
|
4296
4442
|
return function(target) {
|
|
@@ -4393,7 +4539,18 @@ var en_default = {
|
|
|
4393
4539
|
unauthorized: "Unauthorized access",
|
|
4394
4540
|
sessionExpired: "Session has expired",
|
|
4395
4541
|
accountLocked: "Account is temporarily locked. Please try again later.",
|
|
4396
|
-
accountInactive: "Account is inactive. Please contact support."
|
|
4542
|
+
accountInactive: "Account is inactive. Please contact support.",
|
|
4543
|
+
emailNotVerified: "Please verify your email address before signing in.",
|
|
4544
|
+
oauthProviderDisabled: "Google sign-in is not configured.",
|
|
4545
|
+
oauthStateInvalid: "The Google sign-in attempt is invalid or expired.",
|
|
4546
|
+
oauthAccessDenied: "Google sign-in was cancelled.",
|
|
4547
|
+
oauthProviderError: "Google sign-in could not be completed.",
|
|
4548
|
+
oauthVerifiedEmailRequired: "Google must provide a verified email address.",
|
|
4549
|
+
oauthAccountLinkRequired: "Sign in with your password and link Google from your account.",
|
|
4550
|
+
oauthProviderAccountLinked: "This Google account is already linked.",
|
|
4551
|
+
oauthSignupDisabled: "Registration with Google is disabled.",
|
|
4552
|
+
oauthHostedDomainDenied: "This Google Workspace domain is not allowed.",
|
|
4553
|
+
oauthLinkSessionExpired: "Your session changed before Google could be linked. Please try again."
|
|
4397
4554
|
},
|
|
4398
4555
|
success: {
|
|
4399
4556
|
login: "Login successful",
|
|
@@ -4403,7 +4560,9 @@ var en_default = {
|
|
|
4403
4560
|
passwordResetSent: "If that email exists, a reset link has been sent",
|
|
4404
4561
|
passwordReset: "Password has been reset successfully",
|
|
4405
4562
|
accountInviteSent: "Invitation sent successfully",
|
|
4406
|
-
tokenRefreshed: "Token refreshed successfully"
|
|
4563
|
+
tokenRefreshed: "Token refreshed successfully",
|
|
4564
|
+
oauthLogin: "Google sign-in successful",
|
|
4565
|
+
oauthLinked: "Google account linked successfully"
|
|
4407
4566
|
},
|
|
4408
4567
|
emails: {
|
|
4409
4568
|
passwordReset: {
|
|
@@ -4436,7 +4595,9 @@ var en_default = {
|
|
|
4436
4595
|
notFound: "Role not found",
|
|
4437
4596
|
exists: "Role already exists",
|
|
4438
4597
|
nameRequired: "Role name is required",
|
|
4439
|
-
cannotDeleteSystem: "Cannot delete system role"
|
|
4598
|
+
cannotDeleteSystem: "Cannot delete system role",
|
|
4599
|
+
cannotRenameSystem: "Cannot rename the system admin role",
|
|
4600
|
+
roleInUse: "Cannot delete a role that is assigned to users"
|
|
4440
4601
|
},
|
|
4441
4602
|
success: {
|
|
4442
4603
|
created: "Role created successfully",
|
|
@@ -4477,6 +4638,674 @@ function getAuthLocale(lang) {
|
|
|
4477
4638
|
__name(getAuthLocale, "getAuthLocale");
|
|
4478
4639
|
var AUTH_SUPPORTED_LANGUAGES = Object.keys(AUTH_LOCALES);
|
|
4479
4640
|
|
|
4641
|
+
// src/oauth/google/GoogleOAuthProvider.ts
|
|
4642
|
+
import { Inject as Inject14, Injectable as Injectable15 } from "najm-core";
|
|
4643
|
+
|
|
4644
|
+
// src/oauth/types.ts
|
|
4645
|
+
var OAuthFlowError = class extends Error {
|
|
4646
|
+
static {
|
|
4647
|
+
__name(this, "OAuthFlowError");
|
|
4648
|
+
}
|
|
4649
|
+
oauthCode;
|
|
4650
|
+
status;
|
|
4651
|
+
constructor(oauthCode, status = 400) {
|
|
4652
|
+
super(oauthCode);
|
|
4653
|
+
this.oauthCode = oauthCode;
|
|
4654
|
+
this.status = status;
|
|
4655
|
+
this.name = "OAuthFlowError";
|
|
4656
|
+
}
|
|
4657
|
+
};
|
|
4658
|
+
|
|
4659
|
+
// src/oauth/google/GoogleTokenVerifier.ts
|
|
4660
|
+
import { Inject as Inject13, Injectable as Injectable14 } from "najm-core";
|
|
4661
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
4662
|
+
var __decorate26 = function(decorators, target, key, desc) {
|
|
4663
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4664
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4665
|
+
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;
|
|
4666
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4667
|
+
};
|
|
4668
|
+
var __metadata26 = function(k, v) {
|
|
4669
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4670
|
+
};
|
|
4671
|
+
var GOOGLE_JWKS = createRemoteJWKSet(new URL("https://www.googleapis.com/oauth2/v3/certs"));
|
|
4672
|
+
var GoogleTokenVerifier = class GoogleTokenVerifier2 {
|
|
4673
|
+
static {
|
|
4674
|
+
__name(this, "GoogleTokenVerifier");
|
|
4675
|
+
}
|
|
4676
|
+
config;
|
|
4677
|
+
jwks = GOOGLE_JWKS;
|
|
4678
|
+
async verify(idToken, nonce) {
|
|
4679
|
+
const google = this.googleConfig();
|
|
4680
|
+
try {
|
|
4681
|
+
const { payload } = await jwtVerify(idToken, this.jwks, {
|
|
4682
|
+
issuer: ["https://accounts.google.com", "accounts.google.com"],
|
|
4683
|
+
audience: google.clientId,
|
|
4684
|
+
algorithms: ["RS256"]
|
|
4685
|
+
});
|
|
4686
|
+
if (payload.nonce !== nonce)
|
|
4687
|
+
throw new OAuthFlowError("oauth_token_invalid");
|
|
4688
|
+
if (typeof payload.sub !== "string" || !payload.sub) {
|
|
4689
|
+
throw new OAuthFlowError("oauth_token_invalid");
|
|
4690
|
+
}
|
|
4691
|
+
if (typeof payload.email !== "string" || !payload.email || payload.email_verified !== true) {
|
|
4692
|
+
throw new OAuthFlowError("oauth_verified_email_required");
|
|
4693
|
+
}
|
|
4694
|
+
const hostedDomain = typeof payload.hd === "string" ? payload.hd.toLowerCase() : void 0;
|
|
4695
|
+
if (google.allowedHostedDomains.length > 0 && (!hostedDomain || !google.allowedHostedDomains.includes(hostedDomain))) {
|
|
4696
|
+
throw new OAuthFlowError("oauth_hosted_domain_denied", 403);
|
|
4697
|
+
}
|
|
4698
|
+
return {
|
|
4699
|
+
provider: "google",
|
|
4700
|
+
providerAccountId: payload.sub,
|
|
4701
|
+
email: payload.email.trim().toLowerCase(),
|
|
4702
|
+
emailVerified: true,
|
|
4703
|
+
name: typeof payload.name === "string" ? payload.name : void 0,
|
|
4704
|
+
picture: typeof payload.picture === "string" ? payload.picture : void 0,
|
|
4705
|
+
hostedDomain
|
|
4706
|
+
};
|
|
4707
|
+
} catch (error) {
|
|
4708
|
+
if (error instanceof OAuthFlowError)
|
|
4709
|
+
throw error;
|
|
4710
|
+
throw new OAuthFlowError("oauth_token_invalid");
|
|
4711
|
+
}
|
|
4712
|
+
}
|
|
4713
|
+
googleConfig() {
|
|
4714
|
+
const google = this.config.oauth?.google;
|
|
4715
|
+
if (!google)
|
|
4716
|
+
throw new OAuthFlowError("oauth_provider_disabled", 404);
|
|
4717
|
+
return google;
|
|
4718
|
+
}
|
|
4719
|
+
};
|
|
4720
|
+
__decorate26([
|
|
4721
|
+
Inject13(AUTH_CONFIG),
|
|
4722
|
+
__metadata26("design:type", Object)
|
|
4723
|
+
], GoogleTokenVerifier.prototype, "config", void 0);
|
|
4724
|
+
GoogleTokenVerifier = __decorate26([
|
|
4725
|
+
Injectable14()
|
|
4726
|
+
], GoogleTokenVerifier);
|
|
4727
|
+
|
|
4728
|
+
// src/oauth/google/GoogleOAuthProvider.ts
|
|
4729
|
+
var __decorate27 = function(decorators, target, key, desc) {
|
|
4730
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4731
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4732
|
+
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;
|
|
4733
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4734
|
+
};
|
|
4735
|
+
var __metadata27 = function(k, v) {
|
|
4736
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4737
|
+
};
|
|
4738
|
+
var _a17;
|
|
4739
|
+
var AUTHORIZATION_ENDPOINT = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
4740
|
+
var TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
|
|
4741
|
+
var GoogleOAuthProvider = class GoogleOAuthProvider2 {
|
|
4742
|
+
static {
|
|
4743
|
+
__name(this, "GoogleOAuthProvider");
|
|
4744
|
+
}
|
|
4745
|
+
verifier;
|
|
4746
|
+
config;
|
|
4747
|
+
constructor(verifier) {
|
|
4748
|
+
this.verifier = verifier;
|
|
4749
|
+
}
|
|
4750
|
+
authorizationUrl(attempt, codeChallenge) {
|
|
4751
|
+
const google = this.googleConfig();
|
|
4752
|
+
const url = new URL(AUTHORIZATION_ENDPOINT);
|
|
4753
|
+
url.search = new URLSearchParams({
|
|
4754
|
+
client_id: google.clientId,
|
|
4755
|
+
redirect_uri: google.callbackUrl,
|
|
4756
|
+
response_type: "code",
|
|
4757
|
+
scope: "openid email profile",
|
|
4758
|
+
state: attempt.state,
|
|
4759
|
+
nonce: attempt.nonce,
|
|
4760
|
+
code_challenge: codeChallenge,
|
|
4761
|
+
code_challenge_method: "S256"
|
|
4762
|
+
}).toString();
|
|
4763
|
+
return url.toString();
|
|
4764
|
+
}
|
|
4765
|
+
async exchange(code, attempt) {
|
|
4766
|
+
const google = this.googleConfig();
|
|
4767
|
+
let response;
|
|
4768
|
+
try {
|
|
4769
|
+
response = await fetch(TOKEN_ENDPOINT, {
|
|
4770
|
+
method: "POST",
|
|
4771
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
4772
|
+
body: new URLSearchParams({
|
|
4773
|
+
code,
|
|
4774
|
+
client_id: google.clientId,
|
|
4775
|
+
client_secret: google.clientSecret,
|
|
4776
|
+
redirect_uri: google.callbackUrl,
|
|
4777
|
+
grant_type: "authorization_code",
|
|
4778
|
+
code_verifier: attempt.codeVerifier
|
|
4779
|
+
}),
|
|
4780
|
+
signal: AbortSignal.timeout(15e3)
|
|
4781
|
+
});
|
|
4782
|
+
} catch {
|
|
4783
|
+
throw new OAuthFlowError("oauth_provider_error", 502);
|
|
4784
|
+
}
|
|
4785
|
+
if (!response.ok)
|
|
4786
|
+
throw new OAuthFlowError("oauth_provider_error", 502);
|
|
4787
|
+
let body;
|
|
4788
|
+
try {
|
|
4789
|
+
body = await response.json();
|
|
4790
|
+
} catch {
|
|
4791
|
+
throw new OAuthFlowError("oauth_provider_error", 502);
|
|
4792
|
+
}
|
|
4793
|
+
const idToken = body.id_token;
|
|
4794
|
+
if (typeof idToken !== "string" || !idToken) {
|
|
4795
|
+
throw new OAuthFlowError("oauth_provider_error", 502);
|
|
4796
|
+
}
|
|
4797
|
+
return this.verifier.verify(idToken, attempt.nonce);
|
|
4798
|
+
}
|
|
4799
|
+
googleConfig() {
|
|
4800
|
+
const google = this.config.oauth?.google;
|
|
4801
|
+
if (!google)
|
|
4802
|
+
throw new OAuthFlowError("oauth_provider_disabled", 404);
|
|
4803
|
+
return google;
|
|
4804
|
+
}
|
|
4805
|
+
};
|
|
4806
|
+
__decorate27([
|
|
4807
|
+
Inject14(AUTH_CONFIG),
|
|
4808
|
+
__metadata27("design:type", Object)
|
|
4809
|
+
], GoogleOAuthProvider.prototype, "config", void 0);
|
|
4810
|
+
GoogleOAuthProvider = __decorate27([
|
|
4811
|
+
Injectable15(),
|
|
4812
|
+
__metadata27("design:paramtypes", [typeof (_a17 = typeof GoogleTokenVerifier !== "undefined" && GoogleTokenVerifier) === "function" ? _a17 : Object])
|
|
4813
|
+
], GoogleOAuthProvider);
|
|
4814
|
+
|
|
4815
|
+
// src/oauth/OAuthAccountRepository.ts
|
|
4816
|
+
import { and as and4, eq as eq7 } from "drizzle-orm";
|
|
4817
|
+
import { Inject as Inject15, Repository as Repository5 } from "najm-core";
|
|
4818
|
+
import { DB as DB5 } from "najm-database";
|
|
4819
|
+
var __decorate28 = function(decorators, target, key, desc) {
|
|
4820
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4821
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4822
|
+
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;
|
|
4823
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4824
|
+
};
|
|
4825
|
+
var __metadata28 = function(k, v) {
|
|
4826
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4827
|
+
};
|
|
4828
|
+
var OAuthAccountRepository = class OAuthAccountRepository2 {
|
|
4829
|
+
static {
|
|
4830
|
+
__name(this, "OAuthAccountRepository");
|
|
4831
|
+
}
|
|
4832
|
+
db;
|
|
4833
|
+
schema;
|
|
4834
|
+
get accounts() {
|
|
4835
|
+
if (!this.schema.oauthAccounts) {
|
|
4836
|
+
throw new OAuthFlowError("oauth_schema_missing", 500);
|
|
4837
|
+
}
|
|
4838
|
+
return this.schema.oauthAccounts;
|
|
4839
|
+
}
|
|
4840
|
+
async getByProviderAccount(provider, providerAccountId) {
|
|
4841
|
+
const [account] = await this.db.select().from(this.accounts).where(and4(eq7(this.accounts.provider, provider), eq7(this.accounts.providerAccountId, providerAccountId))).limit(1);
|
|
4842
|
+
return account;
|
|
4843
|
+
}
|
|
4844
|
+
async getByUserProvider(userId, provider) {
|
|
4845
|
+
const [account] = await this.db.select().from(this.accounts).where(and4(eq7(this.accounts.userId, userId), eq7(this.accounts.provider, provider))).limit(1);
|
|
4846
|
+
return account;
|
|
4847
|
+
}
|
|
4848
|
+
async create(data) {
|
|
4849
|
+
const [account] = await this.db.insert(this.accounts).values(data).onConflictDoNothing().returning();
|
|
4850
|
+
return account;
|
|
4851
|
+
}
|
|
4852
|
+
};
|
|
4853
|
+
__decorate28([
|
|
4854
|
+
DB5(),
|
|
4855
|
+
__metadata28("design:type", Object)
|
|
4856
|
+
], OAuthAccountRepository.prototype, "db", void 0);
|
|
4857
|
+
__decorate28([
|
|
4858
|
+
Inject15(AUTH_SCHEMA),
|
|
4859
|
+
__metadata28("design:type", Object)
|
|
4860
|
+
], OAuthAccountRepository.prototype, "schema", void 0);
|
|
4861
|
+
OAuthAccountRepository = __decorate28([
|
|
4862
|
+
Repository5()
|
|
4863
|
+
], OAuthAccountRepository);
|
|
4864
|
+
|
|
4865
|
+
// src/oauth/OAuthAccountService.ts
|
|
4866
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
4867
|
+
import { Inject as Inject16, Injectable as Injectable16 } from "najm-core";
|
|
4868
|
+
import { Transaction as Transaction2 } from "najm-database";
|
|
4869
|
+
var __decorate29 = function(decorators, target, key, desc) {
|
|
4870
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4871
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4872
|
+
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;
|
|
4873
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4874
|
+
};
|
|
4875
|
+
var __metadata29 = function(k, v) {
|
|
4876
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4877
|
+
};
|
|
4878
|
+
var _a18;
|
|
4879
|
+
var _b9;
|
|
4880
|
+
var _c6;
|
|
4881
|
+
var _d3;
|
|
4882
|
+
var OAuthAccountService = class OAuthAccountService2 {
|
|
4883
|
+
static {
|
|
4884
|
+
__name(this, "OAuthAccountService");
|
|
4885
|
+
}
|
|
4886
|
+
accounts;
|
|
4887
|
+
users;
|
|
4888
|
+
config;
|
|
4889
|
+
constructor(accounts, users) {
|
|
4890
|
+
this.accounts = accounts;
|
|
4891
|
+
this.users = users;
|
|
4892
|
+
}
|
|
4893
|
+
async resolveForLogin(identity) {
|
|
4894
|
+
const linked = await this.accounts.getByProviderAccount("google", identity.providerAccountId);
|
|
4895
|
+
if (linked)
|
|
4896
|
+
return this.users.getById(linked.userId);
|
|
4897
|
+
const existingUser = await this.users.findByEmailInsensitive(identity.email);
|
|
4898
|
+
if (existingUser) {
|
|
4899
|
+
if (!this.googleConfig().autoLinkVerifiedEmail) {
|
|
4900
|
+
throw new OAuthFlowError("oauth_account_link_required", 409);
|
|
4901
|
+
}
|
|
4902
|
+
await this.createLink(existingUser.id, identity);
|
|
4903
|
+
return this.users.getById(existingUser.id);
|
|
4904
|
+
}
|
|
4905
|
+
if (!this.googleConfig().allowSignup) {
|
|
4906
|
+
throw new OAuthFlowError("oauth_signup_disabled", 403);
|
|
4907
|
+
}
|
|
4908
|
+
const password = `${randomBytes2(32).toString("base64url")}Aa1`;
|
|
4909
|
+
const user = await this.users.create({
|
|
4910
|
+
name: identity.name,
|
|
4911
|
+
email: identity.email,
|
|
4912
|
+
password,
|
|
4913
|
+
image: identity.picture,
|
|
4914
|
+
emailVerified: true
|
|
4915
|
+
});
|
|
4916
|
+
await this.createLink(user.id, identity);
|
|
4917
|
+
return this.users.getById(user.id);
|
|
4918
|
+
}
|
|
4919
|
+
async linkUser(userId, identity) {
|
|
4920
|
+
const user = await this.users.getById(userId);
|
|
4921
|
+
if (user.status !== "active")
|
|
4922
|
+
throw new OAuthFlowError("oauth_account_inactive", 403);
|
|
4923
|
+
const providerAccount = await this.accounts.getByProviderAccount("google", identity.providerAccountId);
|
|
4924
|
+
if (providerAccount && providerAccount.userId !== userId) {
|
|
4925
|
+
throw new OAuthFlowError("oauth_provider_account_linked", 409);
|
|
4926
|
+
}
|
|
4927
|
+
if (providerAccount)
|
|
4928
|
+
return user;
|
|
4929
|
+
const userProvider = await this.accounts.getByUserProvider(userId, "google");
|
|
4930
|
+
if (userProvider && userProvider.providerAccountId !== identity.providerAccountId) {
|
|
4931
|
+
throw new OAuthFlowError("oauth_user_provider_linked", 409);
|
|
4932
|
+
}
|
|
4933
|
+
if (!userProvider)
|
|
4934
|
+
await this.createLink(userId, identity);
|
|
4935
|
+
return user;
|
|
4936
|
+
}
|
|
4937
|
+
async createLink(userId, identity) {
|
|
4938
|
+
const created = await this.accounts.create({
|
|
4939
|
+
userId,
|
|
4940
|
+
provider: "google",
|
|
4941
|
+
providerAccountId: identity.providerAccountId
|
|
4942
|
+
});
|
|
4943
|
+
if (created)
|
|
4944
|
+
return;
|
|
4945
|
+
const linked = await this.accounts.getByProviderAccount("google", identity.providerAccountId);
|
|
4946
|
+
if (!linked || linked.userId !== userId) {
|
|
4947
|
+
throw new OAuthFlowError("oauth_provider_account_linked", 409);
|
|
4948
|
+
}
|
|
4949
|
+
}
|
|
4950
|
+
googleConfig() {
|
|
4951
|
+
const google = this.config.oauth?.google;
|
|
4952
|
+
if (!google)
|
|
4953
|
+
throw new OAuthFlowError("oauth_provider_disabled", 404);
|
|
4954
|
+
return google;
|
|
4955
|
+
}
|
|
4956
|
+
};
|
|
4957
|
+
__decorate29([
|
|
4958
|
+
Inject16(AUTH_CONFIG),
|
|
4959
|
+
__metadata29("design:type", Object)
|
|
4960
|
+
], OAuthAccountService.prototype, "config", void 0);
|
|
4961
|
+
__decorate29([
|
|
4962
|
+
Transaction2(),
|
|
4963
|
+
__metadata29("design:type", Function),
|
|
4964
|
+
__metadata29("design:paramtypes", [Object]),
|
|
4965
|
+
__metadata29("design:returntype", typeof (_c6 = typeof Promise !== "undefined" && Promise) === "function" ? _c6 : Object)
|
|
4966
|
+
], OAuthAccountService.prototype, "resolveForLogin", null);
|
|
4967
|
+
__decorate29([
|
|
4968
|
+
Transaction2(),
|
|
4969
|
+
__metadata29("design:type", Function),
|
|
4970
|
+
__metadata29("design:paramtypes", [String, Object]),
|
|
4971
|
+
__metadata29("design:returntype", typeof (_d3 = typeof Promise !== "undefined" && Promise) === "function" ? _d3 : Object)
|
|
4972
|
+
], OAuthAccountService.prototype, "linkUser", null);
|
|
4973
|
+
OAuthAccountService = __decorate29([
|
|
4974
|
+
Injectable16(),
|
|
4975
|
+
__metadata29("design:paramtypes", [typeof (_a18 = typeof OAuthAccountRepository !== "undefined" && OAuthAccountRepository) === "function" ? _a18 : Object, typeof (_b9 = typeof UserService !== "undefined" && UserService) === "function" ? _b9 : Object])
|
|
4976
|
+
], OAuthAccountService);
|
|
4977
|
+
|
|
4978
|
+
// src/oauth/OAuthController.ts
|
|
4979
|
+
import { createHash as createHash4 } from "crypto";
|
|
4980
|
+
import { Controller as Controller5, Ctx, Get as Get5, Post as Post5, Query as Query2, User as User6 } from "najm-core";
|
|
4981
|
+
import { RateLimit as RateLimit2 } from "najm-rate";
|
|
4982
|
+
|
|
4983
|
+
// src/oauth/OAuthService.ts
|
|
4984
|
+
import { Inject as Inject17, Injectable as Injectable18, Log as Log2 } from "najm-core";
|
|
4985
|
+
|
|
4986
|
+
// src/oauth/OAuthStateService.ts
|
|
4987
|
+
import { createHash as createHash3, randomBytes as randomBytes3, timingSafeEqual } from "crypto";
|
|
4988
|
+
import { Injectable as Injectable17 } from "najm-core";
|
|
4989
|
+
import { CookieService as CookieService2 } from "najm-cookies";
|
|
4990
|
+
var __decorate30 = function(decorators, target, key, desc) {
|
|
4991
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4992
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4993
|
+
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;
|
|
4994
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4995
|
+
};
|
|
4996
|
+
var __metadata30 = function(k, v) {
|
|
4997
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4998
|
+
};
|
|
4999
|
+
var _a19;
|
|
5000
|
+
var _b10;
|
|
5001
|
+
var ATTEMPT_TTL_MS = 10 * 60 * 1e3;
|
|
5002
|
+
var COOKIE_PREFIX = "najm.oauth.google.";
|
|
5003
|
+
var OAuthStateService = class OAuthStateService2 {
|
|
5004
|
+
static {
|
|
5005
|
+
__name(this, "OAuthStateService");
|
|
5006
|
+
}
|
|
5007
|
+
cookies;
|
|
5008
|
+
encryption;
|
|
5009
|
+
constructor(cookies2, encryption) {
|
|
5010
|
+
this.cookies = cookies2;
|
|
5011
|
+
this.encryption = encryption;
|
|
5012
|
+
}
|
|
5013
|
+
create(input) {
|
|
5014
|
+
const state = randomBytes3(32).toString("base64url");
|
|
5015
|
+
const codeVerifier = randomBytes3(48).toString("base64url");
|
|
5016
|
+
const attempt = {
|
|
5017
|
+
provider: "google",
|
|
5018
|
+
intent: input.intent,
|
|
5019
|
+
state,
|
|
5020
|
+
nonce: randomBytes3(32).toString("base64url"),
|
|
5021
|
+
codeVerifier,
|
|
5022
|
+
returnTo: this.validateReturnTo(input.returnTo),
|
|
5023
|
+
userId: input.userId,
|
|
5024
|
+
sessionVersion: input.sessionVersion,
|
|
5025
|
+
createdAt: Date.now()
|
|
5026
|
+
};
|
|
5027
|
+
this.cookies.set(this.cookieName(state), this.encryption.encrypt(JSON.stringify(attempt)), {
|
|
5028
|
+
httpOnly: true,
|
|
5029
|
+
sameSite: "Lax",
|
|
5030
|
+
path: "/",
|
|
5031
|
+
maxAge: Math.floor(ATTEMPT_TTL_MS / 1e3)
|
|
5032
|
+
});
|
|
5033
|
+
return {
|
|
5034
|
+
attempt,
|
|
5035
|
+
codeChallenge: createHash3("sha256").update(codeVerifier).digest("base64url")
|
|
5036
|
+
};
|
|
5037
|
+
}
|
|
5038
|
+
consume(state) {
|
|
5039
|
+
if (!this.isSafeState(state))
|
|
5040
|
+
throw new OAuthFlowError("oauth_state_invalid");
|
|
5041
|
+
const name = this.cookieName(state);
|
|
5042
|
+
const encrypted = this.cookies.get(name);
|
|
5043
|
+
this.cookies.delete(name, { path: "/" });
|
|
5044
|
+
if (!encrypted)
|
|
5045
|
+
throw new OAuthFlowError("oauth_state_invalid");
|
|
5046
|
+
try {
|
|
5047
|
+
const attempt = JSON.parse(this.encryption.decrypt(encrypted));
|
|
5048
|
+
const expected = Buffer.from(attempt.state);
|
|
5049
|
+
const actual = Buffer.from(state);
|
|
5050
|
+
if (expected.length !== actual.length || !timingSafeEqual(expected, actual)) {
|
|
5051
|
+
throw new OAuthFlowError("oauth_state_invalid");
|
|
5052
|
+
}
|
|
5053
|
+
if (attempt.provider !== "google" || Date.now() - attempt.createdAt > ATTEMPT_TTL_MS) {
|
|
5054
|
+
throw new OAuthFlowError("oauth_state_invalid");
|
|
5055
|
+
}
|
|
5056
|
+
attempt.returnTo = this.validateReturnTo(attempt.returnTo);
|
|
5057
|
+
return attempt;
|
|
5058
|
+
} catch (error) {
|
|
5059
|
+
if (error instanceof OAuthFlowError)
|
|
5060
|
+
throw error;
|
|
5061
|
+
throw new OAuthFlowError("oauth_state_invalid");
|
|
5062
|
+
}
|
|
5063
|
+
}
|
|
5064
|
+
validateReturnTo(value) {
|
|
5065
|
+
const candidate = value?.trim() || "/";
|
|
5066
|
+
if (!candidate.startsWith("/") || candidate.startsWith("//") || candidate.includes("\\")) {
|
|
5067
|
+
throw new OAuthFlowError("oauth_redirect_invalid");
|
|
5068
|
+
}
|
|
5069
|
+
try {
|
|
5070
|
+
const base = new URL("https://najm.invalid");
|
|
5071
|
+
const parsed = new URL(candidate, base);
|
|
5072
|
+
if (parsed.origin !== base.origin || parsed.username || parsed.password) {
|
|
5073
|
+
throw new OAuthFlowError("oauth_redirect_invalid");
|
|
5074
|
+
}
|
|
5075
|
+
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
5076
|
+
} catch (error) {
|
|
5077
|
+
if (error instanceof OAuthFlowError)
|
|
5078
|
+
throw error;
|
|
5079
|
+
throw new OAuthFlowError("oauth_redirect_invalid");
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
5082
|
+
cookieName(state) {
|
|
5083
|
+
return `${COOKIE_PREFIX}${state}`;
|
|
5084
|
+
}
|
|
5085
|
+
isSafeState(state) {
|
|
5086
|
+
return /^[A-Za-z0-9_-]{40,128}$/.test(state);
|
|
5087
|
+
}
|
|
5088
|
+
};
|
|
5089
|
+
OAuthStateService = __decorate30([
|
|
5090
|
+
Injectable17(),
|
|
5091
|
+
__metadata30("design:paramtypes", [typeof (_a19 = typeof CookieService2 !== "undefined" && CookieService2) === "function" ? _a19 : Object, typeof (_b10 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _b10 : Object])
|
|
5092
|
+
], OAuthStateService);
|
|
5093
|
+
|
|
5094
|
+
// src/oauth/OAuthService.ts
|
|
5095
|
+
var __decorate31 = function(decorators, target, key, desc) {
|
|
5096
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5097
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5098
|
+
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;
|
|
5099
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5100
|
+
};
|
|
5101
|
+
var __metadata31 = function(k, v) {
|
|
5102
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
5103
|
+
};
|
|
5104
|
+
var _a20;
|
|
5105
|
+
var _b11;
|
|
5106
|
+
var _c7;
|
|
5107
|
+
var _d4;
|
|
5108
|
+
var _e3;
|
|
5109
|
+
var _f3;
|
|
5110
|
+
var OAuthService = class OAuthService2 {
|
|
5111
|
+
static {
|
|
5112
|
+
__name(this, "OAuthService");
|
|
5113
|
+
}
|
|
5114
|
+
state;
|
|
5115
|
+
google;
|
|
5116
|
+
accounts;
|
|
5117
|
+
sessions;
|
|
5118
|
+
tokens;
|
|
5119
|
+
users;
|
|
5120
|
+
config;
|
|
5121
|
+
logger;
|
|
5122
|
+
constructor(state, google, accounts, sessions, tokens, users) {
|
|
5123
|
+
this.state = state;
|
|
5124
|
+
this.google = google;
|
|
5125
|
+
this.accounts = accounts;
|
|
5126
|
+
this.sessions = sessions;
|
|
5127
|
+
this.tokens = tokens;
|
|
5128
|
+
this.users = users;
|
|
5129
|
+
}
|
|
5130
|
+
startGoogleLogin(returnTo) {
|
|
5131
|
+
this.googleConfig();
|
|
5132
|
+
const { attempt, codeChallenge } = this.state.create({ intent: "login", returnTo });
|
|
5133
|
+
return this.google.authorizationUrl(attempt, codeChallenge);
|
|
5134
|
+
}
|
|
5135
|
+
async startGoogleLink(userId, returnTo) {
|
|
5136
|
+
this.googleConfig();
|
|
5137
|
+
const user = await this.users.getById(userId);
|
|
5138
|
+
if (user.status !== "active")
|
|
5139
|
+
throw new OAuthFlowError("oauth_account_inactive", 403);
|
|
5140
|
+
const sessionVersion = await this.tokens.getSessionVersion(userId);
|
|
5141
|
+
const { attempt, codeChallenge } = this.state.create({
|
|
5142
|
+
intent: "link",
|
|
5143
|
+
returnTo,
|
|
5144
|
+
userId,
|
|
5145
|
+
sessionVersion
|
|
5146
|
+
});
|
|
5147
|
+
return { authorizationUrl: this.google.authorizationUrl(attempt, codeChallenge) };
|
|
5148
|
+
}
|
|
5149
|
+
async finishGoogleCallback(params) {
|
|
5150
|
+
try {
|
|
5151
|
+
this.googleConfig();
|
|
5152
|
+
if (!params.state)
|
|
5153
|
+
throw new OAuthFlowError("oauth_state_invalid");
|
|
5154
|
+
const attempt = this.state.consume(params.state);
|
|
5155
|
+
if (params.error) {
|
|
5156
|
+
throw new OAuthFlowError(params.error === "access_denied" ? "oauth_access_denied" : "oauth_provider_error");
|
|
5157
|
+
}
|
|
5158
|
+
if (!params.code)
|
|
5159
|
+
throw new OAuthFlowError("oauth_provider_error");
|
|
5160
|
+
const identity = await this.google.exchange(params.code, attempt);
|
|
5161
|
+
if (attempt.intent === "link") {
|
|
5162
|
+
if (!attempt.userId || attempt.sessionVersion === void 0) {
|
|
5163
|
+
throw new OAuthFlowError("oauth_state_invalid");
|
|
5164
|
+
}
|
|
5165
|
+
const currentVersion = await this.tokens.getSessionVersion(attempt.userId);
|
|
5166
|
+
if (currentVersion !== attempt.sessionVersion) {
|
|
5167
|
+
throw new OAuthFlowError("oauth_link_session_expired", 401);
|
|
5168
|
+
}
|
|
5169
|
+
await this.accounts.linkUser(attempt.userId, identity);
|
|
5170
|
+
} else {
|
|
5171
|
+
const user = await this.accounts.resolveForLogin(identity);
|
|
5172
|
+
await this.sessions.establish(user);
|
|
5173
|
+
}
|
|
5174
|
+
return this.frontendSuccessUrl(attempt.returnTo, attempt.intent);
|
|
5175
|
+
} catch (error) {
|
|
5176
|
+
const code = this.publicErrorCode(error);
|
|
5177
|
+
this.logger.warn("Google OAuth callback failed", { provider: "google", code });
|
|
5178
|
+
return this.frontendErrorUrl(code);
|
|
5179
|
+
}
|
|
5180
|
+
}
|
|
5181
|
+
frontendSuccessUrl(returnTo, mode) {
|
|
5182
|
+
const google = this.googleConfig();
|
|
5183
|
+
const url = new URL(google.frontendCallbackPath, this.config.frontendUrl);
|
|
5184
|
+
url.searchParams.set("provider", "google");
|
|
5185
|
+
url.searchParams.set("mode", mode);
|
|
5186
|
+
url.searchParams.set("returnTo", this.state.validateReturnTo(returnTo));
|
|
5187
|
+
return url.toString();
|
|
5188
|
+
}
|
|
5189
|
+
frontendErrorUrl(code) {
|
|
5190
|
+
const path2 = this.config.oauth?.google?.errorRedirectPath ?? "/login";
|
|
5191
|
+
const url = new URL(path2, this.config.frontendUrl);
|
|
5192
|
+
url.searchParams.set("oauthError", code);
|
|
5193
|
+
return url.toString();
|
|
5194
|
+
}
|
|
5195
|
+
publicErrorCode(error) {
|
|
5196
|
+
if (error instanceof OAuthFlowError)
|
|
5197
|
+
return error.oauthCode;
|
|
5198
|
+
if (error instanceof Error && /^oauth_[a-z0-9_]+$/.test(error.message))
|
|
5199
|
+
return error.message;
|
|
5200
|
+
return "oauth_provider_error";
|
|
5201
|
+
}
|
|
5202
|
+
googleConfig() {
|
|
5203
|
+
const google = this.config.oauth?.google;
|
|
5204
|
+
if (!google)
|
|
5205
|
+
throw new OAuthFlowError("oauth_provider_disabled", 404);
|
|
5206
|
+
return google;
|
|
5207
|
+
}
|
|
5208
|
+
};
|
|
5209
|
+
__decorate31([
|
|
5210
|
+
Inject17(AUTH_CONFIG),
|
|
5211
|
+
__metadata31("design:type", Object)
|
|
5212
|
+
], OAuthService.prototype, "config", void 0);
|
|
5213
|
+
__decorate31([
|
|
5214
|
+
Log2(),
|
|
5215
|
+
__metadata31("design:type", Object)
|
|
5216
|
+
], OAuthService.prototype, "logger", void 0);
|
|
5217
|
+
OAuthService = __decorate31([
|
|
5218
|
+
Injectable18(),
|
|
5219
|
+
__metadata31("design:paramtypes", [typeof (_a20 = typeof OAuthStateService !== "undefined" && OAuthStateService) === "function" ? _a20 : Object, typeof (_b11 = typeof GoogleOAuthProvider !== "undefined" && GoogleOAuthProvider) === "function" ? _b11 : Object, typeof (_c7 = typeof OAuthAccountService !== "undefined" && OAuthAccountService) === "function" ? _c7 : Object, typeof (_d4 = typeof AuthSessionService !== "undefined" && AuthSessionService) === "function" ? _d4 : Object, typeof (_e3 = typeof TokenService !== "undefined" && TokenService) === "function" ? _e3 : Object, typeof (_f3 = typeof UserService !== "undefined" && UserService) === "function" ? _f3 : Object])
|
|
5220
|
+
], OAuthService);
|
|
5221
|
+
|
|
5222
|
+
// src/oauth/OAuthController.ts
|
|
5223
|
+
var __decorate32 = function(decorators, target, key, desc) {
|
|
5224
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5225
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5226
|
+
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;
|
|
5227
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5228
|
+
};
|
|
5229
|
+
var __metadata32 = function(k, v) {
|
|
5230
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
5231
|
+
};
|
|
5232
|
+
var __param11 = function(paramIndex, decorator) {
|
|
5233
|
+
return function(target, key) {
|
|
5234
|
+
decorator(target, key, paramIndex);
|
|
5235
|
+
};
|
|
5236
|
+
};
|
|
5237
|
+
var _a21;
|
|
5238
|
+
var callbackKey = /* @__PURE__ */ __name((ctx) => {
|
|
5239
|
+
const ip = ctx.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? ctx.req.header("x-real-ip") ?? "unknown";
|
|
5240
|
+
const state = ctx.req.query("state") ?? "none";
|
|
5241
|
+
const fingerprint = createHash4("sha256").update(state).digest("base64url").slice(0, 24);
|
|
5242
|
+
return `${ip}:${fingerprint}`;
|
|
5243
|
+
}, "callbackKey");
|
|
5244
|
+
var OAuthController = class OAuthController2 {
|
|
5245
|
+
static {
|
|
5246
|
+
__name(this, "OAuthController");
|
|
5247
|
+
}
|
|
5248
|
+
oauth;
|
|
5249
|
+
constructor(oauth) {
|
|
5250
|
+
this.oauth = oauth;
|
|
5251
|
+
}
|
|
5252
|
+
start(ctx, returnTo) {
|
|
5253
|
+
return ctx.redirect(this.oauth.startGoogleLogin(returnTo), 302);
|
|
5254
|
+
}
|
|
5255
|
+
async callback(ctx, code, state, error) {
|
|
5256
|
+
const redirect = await this.oauth.finishGoogleCallback({ code, state, error });
|
|
5257
|
+
return ctx.redirect(redirect, 302);
|
|
5258
|
+
}
|
|
5259
|
+
link(userId, returnTo) {
|
|
5260
|
+
return this.oauth.startGoogleLink(userId, returnTo);
|
|
5261
|
+
}
|
|
5262
|
+
};
|
|
5263
|
+
__decorate32([
|
|
5264
|
+
Get5("/start"),
|
|
5265
|
+
RateLimit2({ limit: 20, window: "15m", key: "ip" }),
|
|
5266
|
+
__param11(0, Ctx()),
|
|
5267
|
+
__param11(1, Query2("returnTo")),
|
|
5268
|
+
__metadata32("design:type", Function),
|
|
5269
|
+
__metadata32("design:paramtypes", [Object, String]),
|
|
5270
|
+
__metadata32("design:returntype", void 0)
|
|
5271
|
+
], OAuthController.prototype, "start", null);
|
|
5272
|
+
__decorate32([
|
|
5273
|
+
Get5("/callback"),
|
|
5274
|
+
RateLimit2({ limit: 20, window: "15m", key: callbackKey }),
|
|
5275
|
+
__param11(0, Ctx()),
|
|
5276
|
+
__param11(1, Query2("code")),
|
|
5277
|
+
__param11(2, Query2("state")),
|
|
5278
|
+
__param11(3, Query2("error")),
|
|
5279
|
+
__metadata32("design:type", Function),
|
|
5280
|
+
__metadata32("design:paramtypes", [Object, String, String, String]),
|
|
5281
|
+
__metadata32("design:returntype", Promise)
|
|
5282
|
+
], OAuthController.prototype, "callback", null);
|
|
5283
|
+
__decorate32([
|
|
5284
|
+
Post5("/link"),
|
|
5285
|
+
isAuth(),
|
|
5286
|
+
RateLimit2({ limit: 10, window: "15m", key: "user" }),
|
|
5287
|
+
__param11(0, User6("id")),
|
|
5288
|
+
__param11(1, Query2("returnTo")),
|
|
5289
|
+
__metadata32("design:type", Function),
|
|
5290
|
+
__metadata32("design:paramtypes", [String, String]),
|
|
5291
|
+
__metadata32("design:returntype", void 0)
|
|
5292
|
+
], OAuthController.prototype, "link", null);
|
|
5293
|
+
OAuthController = __decorate32([
|
|
5294
|
+
Controller5("/auth/oauth/google"),
|
|
5295
|
+
__metadata32("design:paramtypes", [typeof (_a21 = typeof OAuthService !== "undefined" && OAuthService) === "function" ? _a21 : Object])
|
|
5296
|
+
], OAuthController);
|
|
5297
|
+
|
|
5298
|
+
// src/oauth/index.ts
|
|
5299
|
+
var OAUTH_MODULE = [
|
|
5300
|
+
OAuthAccountRepository,
|
|
5301
|
+
OAuthAccountService,
|
|
5302
|
+
OAuthStateService,
|
|
5303
|
+
GoogleTokenVerifier,
|
|
5304
|
+
GoogleOAuthProvider,
|
|
5305
|
+
OAuthService,
|
|
5306
|
+
OAuthController
|
|
5307
|
+
];
|
|
5308
|
+
|
|
4480
5309
|
// src/AuthPlugin.ts
|
|
4481
5310
|
var DEFAULT_JWT = {
|
|
4482
5311
|
accessSecret: process.env.JWT_ACCESS_SECRET || "",
|
|
@@ -4484,7 +5313,47 @@ var DEFAULT_JWT = {
|
|
|
4484
5313
|
refreshSecret: process.env.JWT_REFRESH_SECRET || "",
|
|
4485
5314
|
refreshExpiresIn: process.env.REFRESH_EXPIRES_IN || "7d"
|
|
4486
5315
|
};
|
|
4487
|
-
var
|
|
5316
|
+
var validateFrontendPath = /* @__PURE__ */ __name((value, name) => {
|
|
5317
|
+
if (!value.startsWith("/") || value.startsWith("//") || value.includes("\\")) {
|
|
5318
|
+
throw new Error(`${name} must be a same-origin path starting with a single '/'`);
|
|
5319
|
+
}
|
|
5320
|
+
return value;
|
|
5321
|
+
}, "validateFrontendPath");
|
|
5322
|
+
var resolveGoogleConfig = /* @__PURE__ */ __name((config) => {
|
|
5323
|
+
const configuredGoogle = config?.oauth?.google;
|
|
5324
|
+
if (!configuredGoogle)
|
|
5325
|
+
return void 0;
|
|
5326
|
+
const google = configuredGoogle === true ? {} : configuredGoogle;
|
|
5327
|
+
const clientId = google.clientId ?? process.env.GOOGLE_CLIENT_ID ?? "";
|
|
5328
|
+
const clientSecret = google.clientSecret ?? process.env.GOOGLE_CLIENT_SECRET ?? "";
|
|
5329
|
+
if (!clientId)
|
|
5330
|
+
throw Err10.configRequired("auth.oauth.google", "GOOGLE_CLIENT_ID");
|
|
5331
|
+
if (!clientSecret)
|
|
5332
|
+
throw Err10.configRequired("auth.oauth.google", "GOOGLE_CLIENT_SECRET");
|
|
5333
|
+
const frontendUrl = config?.frontendUrl ?? process.env.FRONTEND_URL ?? "http://localhost:3000";
|
|
5334
|
+
const callbackUrl = google.callbackUrl ?? process.env.GOOGLE_CALLBACK_URL ?? `${frontendUrl.replace(/\/$/, "")}/api/auth/oauth/google/callback`;
|
|
5335
|
+
let callback;
|
|
5336
|
+
try {
|
|
5337
|
+
callback = new URL(callbackUrl);
|
|
5338
|
+
} catch {
|
|
5339
|
+
throw new Error("auth.oauth.google.callbackUrl must be an absolute URL");
|
|
5340
|
+
}
|
|
5341
|
+
const local = callback.hostname === "localhost" || callback.hostname === "127.0.0.1" || callback.hostname === "[::1]" || callback.hostname === "::1";
|
|
5342
|
+
if (callback.protocol !== "https:" && !(local && callback.protocol === "http:")) {
|
|
5343
|
+
throw new Error("auth.oauth.google.callbackUrl must use HTTPS (HTTP is allowed only for localhost)");
|
|
5344
|
+
}
|
|
5345
|
+
return {
|
|
5346
|
+
clientId,
|
|
5347
|
+
clientSecret,
|
|
5348
|
+
callbackUrl: callback.toString(),
|
|
5349
|
+
frontendCallbackPath: validateFrontendPath(google.frontendCallbackPath ?? "/auth/oauth/callback", "auth.oauth.google.frontendCallbackPath"),
|
|
5350
|
+
errorRedirectPath: validateFrontendPath(google.errorRedirectPath ?? "/login", "auth.oauth.google.errorRedirectPath"),
|
|
5351
|
+
allowSignup: google.allowSignup ?? true,
|
|
5352
|
+
autoLinkVerifiedEmail: google.autoLinkVerifiedEmail ?? false,
|
|
5353
|
+
allowedHostedDomains: [...new Set((google.allowedHostedDomains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean))]
|
|
5354
|
+
};
|
|
5355
|
+
}, "resolveGoogleConfig");
|
|
5356
|
+
var resolveAuthConfig = /* @__PURE__ */ __name((config) => {
|
|
4488
5357
|
const bcryptRounds = config?.bcryptRounds ?? 10;
|
|
4489
5358
|
if (!Number.isInteger(bcryptRounds) || bcryptRounds < 4 || bcryptRounds > 31) {
|
|
4490
5359
|
throw new Error("auth.bcryptRounds must be an integer between 4 and 31");
|
|
@@ -4500,6 +5369,8 @@ var mergeConfig = /* @__PURE__ */ __name((config) => {
|
|
|
4500
5369
|
defaultRole: config?.defaultRole ?? null,
|
|
4501
5370
|
frontendUrl: config?.frontendUrl ?? process.env.FRONTEND_URL ?? "http://localhost:3000",
|
|
4502
5371
|
registrationMode: config?.registrationMode ?? "active",
|
|
5372
|
+
requireVerifiedEmail: config?.requireVerifiedEmail ?? false,
|
|
5373
|
+
refreshCookiePath: config?.refreshCookiePath ?? "/",
|
|
4503
5374
|
lockout: {
|
|
4504
5375
|
maxAttempts: config?.lockout?.maxAttempts ?? 5,
|
|
4505
5376
|
duration: config?.lockout?.duration ?? "15m"
|
|
@@ -4510,19 +5381,26 @@ var mergeConfig = /* @__PURE__ */ __name((config) => {
|
|
|
4510
5381
|
maxAge: config?.session?.maxAge ?? 300,
|
|
4511
5382
|
secret: config?.session?.secret
|
|
4512
5383
|
// fallback to jwt.accessSecret at use site
|
|
5384
|
+
},
|
|
5385
|
+
oauth: {
|
|
5386
|
+
google: resolveGoogleConfig(config)
|
|
4513
5387
|
}
|
|
4514
5388
|
};
|
|
4515
5389
|
if (!finalConfig.jwt.accessSecret) {
|
|
4516
|
-
throw
|
|
5390
|
+
throw Err10.configRequired("auth", "JWT_ACCESS_SECRET");
|
|
4517
5391
|
}
|
|
4518
5392
|
if (!finalConfig.jwt.refreshSecret) {
|
|
4519
|
-
throw
|
|
5393
|
+
throw Err10.configRequired("auth", "JWT_REFRESH_SECRET");
|
|
4520
5394
|
}
|
|
4521
5395
|
return finalConfig;
|
|
4522
|
-
}, "
|
|
4523
|
-
var
|
|
4524
|
-
if (config?.schema)
|
|
5396
|
+
}, "resolveAuthConfig");
|
|
5397
|
+
var selectAuthSchema = /* @__PURE__ */ __name((config) => {
|
|
5398
|
+
if (config?.schema) {
|
|
5399
|
+
if (config.oauth?.google && !config.schema.oauthAccounts) {
|
|
5400
|
+
throw new Error("auth.schema.oauthAccounts is required when Google OAuth is enabled");
|
|
5401
|
+
}
|
|
4525
5402
|
return config.schema;
|
|
5403
|
+
}
|
|
4526
5404
|
const dialect = config?.dialect ?? "pg";
|
|
4527
5405
|
switch (dialect) {
|
|
4528
5406
|
case "sqlite":
|
|
@@ -4531,8 +5409,8 @@ var selectSchema = /* @__PURE__ */ __name((config) => {
|
|
|
4531
5409
|
default:
|
|
4532
5410
|
return authSchema;
|
|
4533
5411
|
}
|
|
4534
|
-
}, "
|
|
4535
|
-
var auth = /* @__PURE__ */ __name((config) => plugin("auth").version("1.0.0").depends(cache(), cookies(), i18n(), guards(), validation(config?.validation), rateLimit(config?.rateLimit), email()).requires("database").contributes(I18N_CONTRIBUTIONS, AUTH_LOCALES).services(AUTH_MODULE, users_exports, roles_exports, permissions_exports, tokens_exports, ScopeContext).config(AUTH_CONFIG,
|
|
5412
|
+
}, "selectAuthSchema");
|
|
5413
|
+
var auth = /* @__PURE__ */ __name((config) => plugin("auth").version("1.0.0").depends(cache(), cookies(), i18n(), guards(), validation(config?.validation), rateLimit(config?.rateLimit), email(config?.email)).requires("database").contributes(I18N_CONTRIBUTIONS, AUTH_LOCALES).services(AUTH_MODULE, OAUTH_MODULE, users_exports, roles_exports, permissions_exports, tokens_exports, ScopeContext).config(AUTH_CONFIG, resolveAuthConfig(config)).set(AUTH_SCHEMA, selectAuthSchema(config)).set(AUTH_ENCRYPTION_KEY, config?.encryptionKey ?? null).build(), "auth");
|
|
4536
5414
|
|
|
4537
5415
|
// src/seed.ts
|
|
4538
5416
|
var toSeedId = /* @__PURE__ */ __name((prefix, value) => {
|
|
@@ -4678,6 +5556,7 @@ export {
|
|
|
4678
5556
|
AuthQueries,
|
|
4679
5557
|
AuthResolver,
|
|
4680
5558
|
AuthService,
|
|
5559
|
+
AuthSessionService,
|
|
4681
5560
|
Can,
|
|
4682
5561
|
CanCreate,
|
|
4683
5562
|
CanDelete,
|
|
@@ -4746,12 +5625,14 @@ export {
|
|
|
4746
5625
|
join2 as join,
|
|
4747
5626
|
languageParam,
|
|
4748
5627
|
loginDto,
|
|
5628
|
+
oauthAccountsTable,
|
|
4749
5629
|
own,
|
|
4750
5630
|
parseSchema,
|
|
4751
5631
|
permissionIdParam,
|
|
4752
5632
|
permissionsTable,
|
|
4753
5633
|
pickProps,
|
|
4754
5634
|
refreshTokenDto,
|
|
5635
|
+
registerDto,
|
|
4755
5636
|
resetPasswordDto,
|
|
4756
5637
|
revokeTokenDto,
|
|
4757
5638
|
roleIdParam,
|