axiodb 9.7.9 → 10.8.11

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.
Files changed (85) hide show
  1. package/README.md +22 -0
  2. package/lib/Services/Auth/AuthSeeder.service.d.ts +16 -0
  3. package/lib/Services/Auth/AuthSeeder.service.js +99 -0
  4. package/lib/Services/Auth/AuthSeeder.service.js.map +1 -0
  5. package/lib/Services/Auth/AuthService.service.d.ts +53 -0
  6. package/lib/Services/Auth/AuthService.service.js +217 -0
  7. package/lib/Services/Auth/AuthService.service.js.map +1 -0
  8. package/lib/Services/Auth/ConfigDatabase.service.d.ts +22 -0
  9. package/lib/Services/Auth/ConfigDatabase.service.js +47 -0
  10. package/lib/Services/Auth/ConfigDatabase.service.js.map +1 -0
  11. package/lib/Services/Auth/CookieCodec.helper.d.ts +10 -0
  12. package/lib/Services/Auth/CookieCodec.helper.js +30 -0
  13. package/lib/Services/Auth/CookieCodec.helper.js.map +1 -0
  14. package/lib/Services/Auth/PasswordHasher.helper.d.ts +9 -0
  15. package/lib/Services/Auth/PasswordHasher.helper.js +54 -0
  16. package/lib/Services/Auth/PasswordHasher.helper.js.map +1 -0
  17. package/lib/Services/Auth/PermissionChecker.helper.d.ts +21 -0
  18. package/lib/Services/Auth/PermissionChecker.helper.js +41 -0
  19. package/lib/Services/Auth/PermissionChecker.helper.js.map +1 -0
  20. package/lib/Services/Auth/SessionStore.service.d.ts +23 -0
  21. package/lib/Services/Auth/SessionStore.service.js +96 -0
  22. package/lib/Services/Auth/SessionStore.service.js.map +1 -0
  23. package/lib/Services/Indexation.operation.js +8 -3
  24. package/lib/Services/Indexation.operation.js.map +1 -1
  25. package/lib/config/Interfaces/Auth/auth.interface.d.ts +70 -0
  26. package/lib/config/Interfaces/Auth/auth.interface.js +4 -0
  27. package/lib/config/Interfaces/Auth/auth.interface.js.map +1 -0
  28. package/lib/config/Keys/Permissions.d.ts +51 -0
  29. package/lib/config/Keys/Permissions.js +101 -0
  30. package/lib/config/Keys/Permissions.js.map +1 -0
  31. package/lib/server/config/keys.d.ts +2 -2
  32. package/lib/server/config/keys.js +83 -1
  33. package/lib/server/config/keys.js.map +1 -1
  34. package/lib/server/config/server.js +6 -0
  35. package/lib/server/config/server.js.map +1 -1
  36. package/lib/server/controller/Auth/Auth.controller.d.ts +12 -0
  37. package/lib/server/controller/Auth/Auth.controller.js +153 -0
  38. package/lib/server/controller/Auth/Auth.controller.js.map +1 -0
  39. package/lib/server/controller/Auth/RoleManagement.controller.d.ts +9 -0
  40. package/lib/server/controller/Auth/RoleManagement.controller.js +89 -0
  41. package/lib/server/controller/Auth/RoleManagement.controller.js.map +1 -0
  42. package/lib/server/controller/Auth/UserManagement.controller.d.ts +11 -0
  43. package/lib/server/controller/Auth/UserManagement.controller.js +122 -0
  44. package/lib/server/controller/Auth/UserManagement.controller.js.map +1 -0
  45. package/lib/server/controller/Collections/Collection.controller.js +10 -0
  46. package/lib/server/controller/Collections/Collection.controller.js.map +1 -1
  47. package/lib/server/controller/Database/Databse.controller.js +17 -0
  48. package/lib/server/controller/Database/Databse.controller.js.map +1 -1
  49. package/lib/server/controller/Operation/CRUD.controller.js +31 -0
  50. package/lib/server/controller/Operation/CRUD.controller.js.map +1 -1
  51. package/lib/server/helper/responseBuilder.helper.d.ts +8 -0
  52. package/lib/server/helper/responseBuilder.helper.js +11 -1
  53. package/lib/server/helper/responseBuilder.helper.js.map +1 -1
  54. package/lib/server/middleware/auth.middleware.d.ts +14 -0
  55. package/lib/server/middleware/auth.middleware.js +64 -0
  56. package/lib/server/middleware/auth.middleware.js.map +1 -0
  57. package/lib/server/middleware/permission.middleware.d.ts +6 -0
  58. package/lib/server/middleware/permission.middleware.js +36 -0
  59. package/lib/server/middleware/permission.middleware.js.map +1 -0
  60. package/lib/server/public/AxioControl/.vite/manifest.json +2 -2
  61. package/lib/server/public/AxioControl/.vite/ssr-manifest.json +10 -0
  62. package/lib/server/public/AxioControl/assets/index-D3V1EZ2f.css +1 -0
  63. package/lib/server/public/AxioControl/assets/index-DyJg6FRw.js +75 -0
  64. package/lib/server/public/AxioControl/index.html +2 -2
  65. package/lib/server/public/AxioControl/sw.js +1 -1
  66. package/lib/server/router/Router.js +12 -1
  67. package/lib/server/router/Router.js.map +1 -1
  68. package/lib/server/router/Routers/Auth.routes.d.ts +2 -0
  69. package/lib/server/router/Routers/Auth.routes.js +27 -0
  70. package/lib/server/router/Routers/Auth.routes.js.map +1 -0
  71. package/lib/server/router/Routers/Collection.routes.js +20 -3
  72. package/lib/server/router/Routers/Collection.routes.js.map +1 -1
  73. package/lib/server/router/Routers/DB.routes.js +8 -5
  74. package/lib/server/router/Routers/DB.routes.js.map +1 -1
  75. package/lib/server/router/Routers/Operation.routes.js +31 -10
  76. package/lib/server/router/Routers/Operation.routes.js.map +1 -1
  77. package/lib/server/router/Routers/RoleManagement.routes.d.ts +2 -0
  78. package/lib/server/router/Routers/RoleManagement.routes.js +28 -0
  79. package/lib/server/router/Routers/RoleManagement.routes.js.map +1 -0
  80. package/lib/server/router/Routers/UserManagement.routes.d.ts +2 -0
  81. package/lib/server/router/Routers/UserManagement.routes.js +38 -0
  82. package/lib/server/router/Routers/UserManagement.routes.js.map +1 -0
  83. package/package.json +2 -1
  84. package/lib/server/public/AxioControl/assets/index-BRkVgnlw.js +0 -75
  85. package/lib/server/public/AxioControl/assets/index-C8TNGVxT.css +0 -1
package/README.md CHANGED
@@ -63,6 +63,7 @@ SQLite is great, but it requires native bindings that break in Electron and cros
63
63
  - **Transaction Support:** ACID-compliant transactions with savepoints, rollback, and Write-Ahead Logging (WAL)
64
64
  - **Single Instance Architecture:** Unified management for unlimited databases, collections, and documents
65
65
  - **Web-Based GUI Dashboard:** Visual database administration, query execution, and real-time monitoring at `localhost:27018`
66
+ - **Role-Based Access Control:** Built-in login for the Control Server with Super Admin/Admin/View roles and per-permission enforcement
66
67
  - **AxioDBCloud Remote Access:** TCP-based client for connecting to AxioDB from anywhere—Docker, Cloud, or local network
67
68
  - **Zero-Configuration Setup:** Serverless architecture—install and start building instantly
68
69
  - **Custom Database Path:** Flexible storage locations for better project organization
@@ -254,6 +255,27 @@ const db = new AxioDB({ GUI: true, RootName: "MyDB", CustomPath: "./custom/path"
254
255
 
255
256
  Access the GUI at `http://localhost:27018` when enabled.
256
257
 
258
+ ### Authentication & Access Control (v9.8+)
259
+
260
+ The Control Server ships with built-in login and role-based access control (RBAC). On first start with `GUI: true`, AxioDB seeds a reserved `config` database (hidden from the regular database list) containing three collections—`users`, `roles`, `permissions`—and a default account:
261
+
262
+ ```
263
+ Username: admin
264
+ Password: admin
265
+ ```
266
+
267
+ You'll be forced to change this password on first login (this applies to every account, not just the default one). Three predefined roles are seeded automatically:
268
+
269
+ | Role | Access |
270
+ |------|--------|
271
+ | **Super Admin** | Full access, including creating users/roles |
272
+ | **Admin** | Full database/collection/document access, no user or role management |
273
+ | **View** | Read-only access to databases, collections, and documents |
274
+
275
+ A Super Admin can create additional roles from the predefined permission catalogue and create new users with any role. Sessions are held only in server memory (never persisted to disk) and are tied to an httpOnly cookie, so restarting the server logs everyone out.
276
+
277
+ > **Security note:** RBAC protects the Control Server's HTTP API; it is still intended for trusted local/network access, not public internet exposure.
278
+
257
279
  ---
258
280
 
259
281
  ## ⚙️ Architecture & Internal Mechanisms
@@ -0,0 +1,16 @@
1
+ import { AxioDB } from "../Indexation.operation";
2
+ /**
3
+ * Idempotently creates the `config` database and its `users`/`roles`/`permissions`
4
+ * collections on first control-server start, then hydrates PermissionChecker's
5
+ * in-memory role->permissions cache on every boot (including subsequent restarts,
6
+ * where seeding itself is a no-op but the cache still needs rebuilding).
7
+ */
8
+ export default class AuthSeeder {
9
+ private readonly axioDBInstance;
10
+ constructor(axioDBInstance: AxioDB);
11
+ seedIfNeeded(): Promise<void>;
12
+ private seedPermissions;
13
+ private seedRoles;
14
+ private seedDefaultAdmin;
15
+ private hydratePermissionCache;
16
+ }
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const PasswordHasher_helper_1 = __importDefault(require("./PasswordHasher.helper"));
16
+ const ConfigDatabase_service_1 = __importDefault(require("./ConfigDatabase.service"));
17
+ const PermissionChecker_helper_1 = __importDefault(require("./PermissionChecker.helper"));
18
+ const Permissions_1 = require("../../config/Keys/Permissions");
19
+ /**
20
+ * Idempotently creates the `config` database and its `users`/`roles`/`permissions`
21
+ * collections on first control-server start, then hydrates PermissionChecker's
22
+ * in-memory role->permissions cache on every boot (including subsequent restarts,
23
+ * where seeding itself is a no-op but the cache still needs rebuilding).
24
+ */
25
+ class AuthSeeder {
26
+ constructor(axioDBInstance) {
27
+ this.axioDBInstance = axioDBInstance;
28
+ }
29
+ seedIfNeeded() {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ var _a;
32
+ const configDB = yield this.axioDBInstance.createDB(Permissions_1.RESERVED_DB_NAME);
33
+ const usersCollection = yield configDB.createCollection(Permissions_1.CONFIG_USERS_COLLECTION);
34
+ const rolesCollection = yield configDB.createCollection(Permissions_1.CONFIG_ROLES_COLLECTION);
35
+ const permissionsCollection = yield configDB.createCollection(Permissions_1.CONFIG_PERMISSIONS_COLLECTION);
36
+ ConfigDatabase_service_1.default.setCollections(usersCollection, rolesCollection, permissionsCollection);
37
+ // totalDocuments() counts the collection's "indexes" subfolder as an entry, so it
38
+ // reports a non-zero count even when no real document has been inserted yet - use
39
+ // an actual document query (filtered to real .axiodb files) to detect prior seeding.
40
+ const existingUsers = yield usersCollection.query({}).Limit(1).exec();
41
+ const alreadySeeded = "data" in existingUsers &&
42
+ Array.isArray((_a = existingUsers.data) === null || _a === void 0 ? void 0 : _a.documents) &&
43
+ existingUsers.data.documents.length > 0;
44
+ if (!alreadySeeded) {
45
+ yield this.seedPermissions(permissionsCollection);
46
+ yield this.seedRoles(rolesCollection);
47
+ yield this.seedDefaultAdmin(usersCollection);
48
+ }
49
+ yield this.hydratePermissionCache(rolesCollection);
50
+ });
51
+ }
52
+ seedPermissions(permissionsCollection) {
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ const documents = Permissions_1.PERMISSION_CATALOGUE.map((entry) => ({
55
+ key: entry.key,
56
+ group: entry.group,
57
+ description: entry.description,
58
+ }));
59
+ yield permissionsCollection.insertMany(documents);
60
+ });
61
+ }
62
+ seedRoles(rolesCollection) {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ const now = new Date().toISOString();
65
+ const documents = Permissions_1.PREDEFINED_ROLES.map((role) => ({
66
+ roleName: role.roleName,
67
+ permissions: role.permissions,
68
+ isSystemRole: true,
69
+ createdAt: now,
70
+ }));
71
+ yield rolesCollection.insertMany(documents);
72
+ });
73
+ }
74
+ seedDefaultAdmin(usersCollection) {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ const passwordHash = yield PasswordHasher_helper_1.default.hashPassword(Permissions_1.DEFAULT_ADMIN_PASSWORD);
77
+ const document = {
78
+ username: Permissions_1.DEFAULT_ADMIN_USERNAME,
79
+ passwordHash,
80
+ role: Permissions_1.SUPER_ADMIN_ROLE,
81
+ mustChangePassword: true,
82
+ isActive: true,
83
+ createdAt: new Date().toISOString(),
84
+ };
85
+ yield usersCollection.insert(document);
86
+ });
87
+ }
88
+ hydratePermissionCache(rolesCollection) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ const result = yield rolesCollection.query({}).Limit(1000).exec();
91
+ if ("data" in result && result.data && Array.isArray(result.data.documents)) {
92
+ const roles = result.data.documents;
93
+ PermissionChecker_helper_1.default.hydrate(roles.map((role) => ({ roleName: role.roleName, permissions: role.permissions })));
94
+ }
95
+ });
96
+ }
97
+ }
98
+ exports.default = AuthSeeder;
99
+ //# sourceMappingURL=AuthSeeder.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthSeeder.service.js","sourceRoot":"","sources":["../../../source/Services/Auth/AuthSeeder.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { UserDocument, RoleDocument } from "../../config/Interfaces/Auth/auth.interface";
2
+ export interface AuthResult {
3
+ success: boolean;
4
+ message: string;
5
+ user?: UserDocument;
6
+ }
7
+ export interface MutationResult {
8
+ success: boolean;
9
+ message: string;
10
+ /** True when the failure means "this already exists" (HTTP 409) rather than a validation failure (HTTP 400). */
11
+ conflict?: boolean;
12
+ }
13
+ export interface SafeUser {
14
+ username: string;
15
+ role: string;
16
+ mustChangePassword: boolean;
17
+ isActive: boolean;
18
+ createdAt: string;
19
+ }
20
+ /**
21
+ * Business logic for login, password management, and user/role administration.
22
+ * Backed entirely by AxioDB's own Collection API against the `config` database
23
+ * (see ConfigDatabase.service.ts) - no separate storage mechanism.
24
+ */
25
+ export default class AuthService {
26
+ login(username: string, password: string): Promise<AuthResult>;
27
+ findUserByUsername(username: string): Promise<UserDocument | null>;
28
+ listUsers(): Promise<SafeUser[]>;
29
+ createUser(username: string, password: string, role: string): Promise<MutationResult>;
30
+ changeOwnPassword(username: string, currentPassword: string, newPassword: string): Promise<{
31
+ success: boolean;
32
+ message: string;
33
+ }>;
34
+ resetUserPassword(username: string, newPassword: string): Promise<{
35
+ success: boolean;
36
+ message: string;
37
+ }>;
38
+ updateUserRole(username: string, newRole: string): Promise<{
39
+ success: boolean;
40
+ message: string;
41
+ }>;
42
+ deleteUser(username: string): Promise<{
43
+ success: boolean;
44
+ message: string;
45
+ }>;
46
+ createRole(roleName: string, permissions: string[]): Promise<MutationResult>;
47
+ listRoles(): Promise<RoleDocument[]>;
48
+ /**
49
+ * Rejects an operation that would leave zero active Super Admin users behind,
50
+ * preventing a permanent RBAC lockout.
51
+ */
52
+ private assertNotLastSuperAdmin;
53
+ }
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const PasswordHasher_helper_1 = __importDefault(require("./PasswordHasher.helper"));
16
+ const ConfigDatabase_service_1 = __importDefault(require("./ConfigDatabase.service"));
17
+ const PermissionChecker_helper_1 = __importDefault(require("./PermissionChecker.helper"));
18
+ const SessionStore_service_1 = __importDefault(require("./SessionStore.service"));
19
+ const Permissions_1 = require("../../config/Keys/Permissions");
20
+ /**
21
+ * Business logic for login, password management, and user/role administration.
22
+ * Backed entirely by AxioDB's own Collection API against the `config` database
23
+ * (see ConfigDatabase.service.ts) - no separate storage mechanism.
24
+ */
25
+ class AuthService {
26
+ login(username, password) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ const user = yield this.findUserByUsername(username);
29
+ if (!user || user.isActive === false) {
30
+ return { success: false, message: "Invalid username or password" };
31
+ }
32
+ const passwordMatches = yield PasswordHasher_helper_1.default.verifyPassword(password, user.passwordHash);
33
+ if (!passwordMatches) {
34
+ return { success: false, message: "Invalid username or password" };
35
+ }
36
+ return { success: true, message: "Login successful", user };
37
+ });
38
+ }
39
+ findUserByUsername(username) {
40
+ return __awaiter(this, void 0, void 0, function* () {
41
+ const result = yield ConfigDatabase_service_1.default.getUsersCollection()
42
+ .query({ username })
43
+ .findOne(true)
44
+ .exec();
45
+ if ("data" in result && result.data && result.data.documents) {
46
+ return result.data.documents;
47
+ }
48
+ return null;
49
+ });
50
+ }
51
+ listUsers() {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ var _a;
54
+ const result = yield ConfigDatabase_service_1.default.getUsersCollection().query({}).Limit(1000).exec();
55
+ if (!("data" in result) || !((_a = result.data) === null || _a === void 0 ? void 0 : _a.documents)) {
56
+ return [];
57
+ }
58
+ const users = result.data.documents;
59
+ return users.map((user) => ({
60
+ username: user.username,
61
+ role: user.role,
62
+ mustChangePassword: user.mustChangePassword,
63
+ isActive: user.isActive,
64
+ createdAt: user.createdAt,
65
+ }));
66
+ });
67
+ }
68
+ createUser(username, password, role) {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ if (!PermissionChecker_helper_1.default.roleExists(role)) {
71
+ return { success: false, message: `Role "${role}" does not exist` };
72
+ }
73
+ const existingUser = yield this.findUserByUsername(username);
74
+ if (existingUser) {
75
+ return { success: false, message: "Username already exists", conflict: true };
76
+ }
77
+ const passwordHash = yield PasswordHasher_helper_1.default.hashPassword(password);
78
+ const document = {
79
+ username,
80
+ passwordHash,
81
+ role,
82
+ mustChangePassword: true,
83
+ isActive: true,
84
+ createdAt: new Date().toISOString(),
85
+ };
86
+ yield ConfigDatabase_service_1.default.getUsersCollection().insert(document);
87
+ return { success: true, message: "User created successfully" };
88
+ });
89
+ }
90
+ changeOwnPassword(username, currentPassword, newPassword) {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ const user = yield this.findUserByUsername(username);
93
+ if (!user) {
94
+ return { success: false, message: "User not found" };
95
+ }
96
+ const currentPasswordMatches = yield PasswordHasher_helper_1.default.verifyPassword(currentPassword, user.passwordHash);
97
+ if (!currentPasswordMatches) {
98
+ return { success: false, message: "Current password is incorrect" };
99
+ }
100
+ const passwordHash = yield PasswordHasher_helper_1.default.hashPassword(newPassword);
101
+ yield ConfigDatabase_service_1.default.getUsersCollection()
102
+ .update({ username })
103
+ .UpdateOne({ passwordHash, mustChangePassword: false });
104
+ return { success: true, message: "Password changed successfully" };
105
+ });
106
+ }
107
+ resetUserPassword(username, newPassword) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ const user = yield this.findUserByUsername(username);
110
+ if (!user) {
111
+ return { success: false, message: "User not found" };
112
+ }
113
+ const passwordHash = yield PasswordHasher_helper_1.default.hashPassword(newPassword);
114
+ yield ConfigDatabase_service_1.default.getUsersCollection()
115
+ .update({ username })
116
+ .UpdateOne({ passwordHash, mustChangePassword: true });
117
+ SessionStore_service_1.default.revokeSessionsForUser(username);
118
+ return { success: true, message: "Password reset successfully" };
119
+ });
120
+ }
121
+ updateUserRole(username, newRole) {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ if (!PermissionChecker_helper_1.default.roleExists(newRole)) {
124
+ return { success: false, message: `Role "${newRole}" does not exist` };
125
+ }
126
+ const user = yield this.findUserByUsername(username);
127
+ if (!user) {
128
+ return { success: false, message: "User not found" };
129
+ }
130
+ if (user.role === Permissions_1.SUPER_ADMIN_ROLE && newRole !== Permissions_1.SUPER_ADMIN_ROLE) {
131
+ const lastAdminGuard = yield this.assertNotLastSuperAdmin(username);
132
+ if (!lastAdminGuard.success) {
133
+ return lastAdminGuard;
134
+ }
135
+ }
136
+ yield ConfigDatabase_service_1.default.getUsersCollection()
137
+ .update({ username })
138
+ .UpdateOne({ role: newRole });
139
+ SessionStore_service_1.default.revokeSessionsForUser(username);
140
+ return { success: true, message: "Role updated successfully" };
141
+ });
142
+ }
143
+ deleteUser(username) {
144
+ return __awaiter(this, void 0, void 0, function* () {
145
+ const user = yield this.findUserByUsername(username);
146
+ if (!user) {
147
+ return { success: false, message: "User not found" };
148
+ }
149
+ if (user.role === Permissions_1.SUPER_ADMIN_ROLE) {
150
+ const lastAdminGuard = yield this.assertNotLastSuperAdmin(username);
151
+ if (!lastAdminGuard.success) {
152
+ return lastAdminGuard;
153
+ }
154
+ }
155
+ yield ConfigDatabase_service_1.default.getUsersCollection().delete({ username }).deleteOne();
156
+ SessionStore_service_1.default.revokeSessionsForUser(username);
157
+ return { success: true, message: "User deleted successfully" };
158
+ });
159
+ }
160
+ createRole(roleName, permissions) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ if (PermissionChecker_helper_1.default.roleExists(roleName)) {
163
+ return { success: false, message: "Role already exists", conflict: true };
164
+ }
165
+ const invalidPermissions = permissions.filter((key) => !Permissions_1.ALL_PERMISSION_KEYS.includes(key));
166
+ if (invalidPermissions.length > 0) {
167
+ return {
168
+ success: false,
169
+ message: `Unknown permission key(s): ${invalidPermissions.join(", ")}`,
170
+ };
171
+ }
172
+ const document = {
173
+ roleName,
174
+ permissions,
175
+ isSystemRole: false,
176
+ createdAt: new Date().toISOString(),
177
+ };
178
+ yield ConfigDatabase_service_1.default.getRolesCollection().insert(document);
179
+ PermissionChecker_helper_1.default.setRolePermissions(roleName, permissions);
180
+ return { success: true, message: "Role created successfully" };
181
+ });
182
+ }
183
+ listRoles() {
184
+ return __awaiter(this, void 0, void 0, function* () {
185
+ var _a;
186
+ const result = yield ConfigDatabase_service_1.default.getRolesCollection().query({}).Limit(1000).exec();
187
+ if (!("data" in result) || !((_a = result.data) === null || _a === void 0 ? void 0 : _a.documents)) {
188
+ return [];
189
+ }
190
+ return result.data.documents;
191
+ });
192
+ }
193
+ /**
194
+ * Rejects an operation that would leave zero active Super Admin users behind,
195
+ * preventing a permanent RBAC lockout.
196
+ */
197
+ assertNotLastSuperAdmin(excludingUsername) {
198
+ return __awaiter(this, void 0, void 0, function* () {
199
+ var _a;
200
+ const result = yield ConfigDatabase_service_1.default.getUsersCollection()
201
+ .query({ role: Permissions_1.SUPER_ADMIN_ROLE })
202
+ .Limit(1000)
203
+ .exec();
204
+ const superAdmins = "data" in result && ((_a = result.data) === null || _a === void 0 ? void 0 : _a.documents) ? result.data.documents : [];
205
+ const remaining = superAdmins.filter((user) => user.username !== excludingUsername && user.isActive !== false);
206
+ if (remaining.length === 0) {
207
+ return {
208
+ success: false,
209
+ message: "Cannot remove the last remaining Super Admin",
210
+ };
211
+ }
212
+ return { success: true, message: "OK" };
213
+ });
214
+ }
215
+ }
216
+ exports.default = AuthService;
217
+ //# sourceMappingURL=AuthService.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthService.service.js","sourceRoot":"","sources":["../../../source/Services/Auth/AuthService.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import Collection from "../Collection/collection.operation";
2
+ /**
3
+ * Holds long-lived references to the `config` database's `users`/`roles`/`permissions`
4
+ * collections. Collection instances are reused across requests instead of being
5
+ * recreated per call, since each `Collection` eagerly loads its index cache on
6
+ * construction - recreating it per request would repeatedly reload indexes for
7
+ * no benefit.
8
+ */
9
+ declare class ConfigDatabase {
10
+ private static instance;
11
+ private usersCollection;
12
+ private rolesCollection;
13
+ private permissionsCollection;
14
+ static getInstance(): ConfigDatabase;
15
+ setCollections(usersCollection: Collection, rolesCollection: Collection, permissionsCollection: Collection): void;
16
+ isInitialized(): boolean;
17
+ getUsersCollection(): Collection;
18
+ getRolesCollection(): Collection;
19
+ getPermissionsCollection(): Collection;
20
+ }
21
+ declare const _default: ConfigDatabase;
22
+ export default _default;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Holds long-lived references to the `config` database's `users`/`roles`/`permissions`
5
+ * collections. Collection instances are reused across requests instead of being
6
+ * recreated per call, since each `Collection` eagerly loads its index cache on
7
+ * construction - recreating it per request would repeatedly reload indexes for
8
+ * no benefit.
9
+ */
10
+ class ConfigDatabase {
11
+ static getInstance() {
12
+ if (!ConfigDatabase.instance) {
13
+ ConfigDatabase.instance = new ConfigDatabase();
14
+ }
15
+ return ConfigDatabase.instance;
16
+ }
17
+ setCollections(usersCollection, rolesCollection, permissionsCollection) {
18
+ this.usersCollection = usersCollection;
19
+ this.rolesCollection = rolesCollection;
20
+ this.permissionsCollection = permissionsCollection;
21
+ }
22
+ isInitialized() {
23
+ return (this.usersCollection !== undefined &&
24
+ this.rolesCollection !== undefined &&
25
+ this.permissionsCollection !== undefined);
26
+ }
27
+ getUsersCollection() {
28
+ if (!this.usersCollection) {
29
+ throw new Error("Config database is not initialized yet");
30
+ }
31
+ return this.usersCollection;
32
+ }
33
+ getRolesCollection() {
34
+ if (!this.rolesCollection) {
35
+ throw new Error("Config database is not initialized yet");
36
+ }
37
+ return this.rolesCollection;
38
+ }
39
+ getPermissionsCollection() {
40
+ if (!this.permissionsCollection) {
41
+ throw new Error("Config database is not initialized yet");
42
+ }
43
+ return this.permissionsCollection;
44
+ }
45
+ }
46
+ exports.default = ConfigDatabase.getInstance();
47
+ //# sourceMappingURL=ConfigDatabase.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigDatabase.service.js","sourceRoot":"","sources":["../../../source/Services/Auth/ConfigDatabase.service.ts"],"names":[],"mappings":";;AAEA;;;;;;GAMG;AACH,MAAM,cAAc;IAMX,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QACjD,CAAC;QACD,OAAO,cAAc,CAAC,QAAQ,CAAC;IACjC,CAAC;IAEM,cAAc,CACnB,eAA2B,EAC3B,eAA2B,EAC3B,qBAAiC;QAEjC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;IACrD,CAAC;IAEM,aAAa;QAClB,OAAO,CACL,IAAI,CAAC,eAAe,KAAK,SAAS;YAClC,IAAI,CAAC,eAAe,KAAK,SAAS;YAClC,IAAI,CAAC,qBAAqB,KAAK,SAAS,CACzC,CAAC;IACJ,CAAC;IAEM,kBAAkB;QACvB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAEM,kBAAkB;QACvB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAEM,wBAAwB;QAC7B,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACpC,CAAC;CACF;kBAEc,cAAc,CAAC,WAAW,EAAE"}
@@ -0,0 +1,10 @@
1
+ import { CookiePayload } from "../../config/Interfaces/Auth/auth.interface";
2
+ /**
3
+ * Encodes/decodes the session cookie value. The cookie is intentionally not the
4
+ * security boundary by itself - it only carries a random `sid` used to look up the
5
+ * real session record in SessionStore's in-memory map. See SessionStore.service.ts.
6
+ */
7
+ export default class CookieCodec {
8
+ static encode(payload: CookiePayload): string;
9
+ static decode(rawCookieValue: string): CookiePayload | null;
10
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Encodes/decodes the session cookie value. The cookie is intentionally not the
5
+ * security boundary by itself - it only carries a random `sid` used to look up the
6
+ * real session record in SessionStore's in-memory map. See SessionStore.service.ts.
7
+ */
8
+ class CookieCodec {
9
+ static encode(payload) {
10
+ return Buffer.from(JSON.stringify(payload), "utf-8").toString("base64url");
11
+ }
12
+ static decode(rawCookieValue) {
13
+ try {
14
+ const json = Buffer.from(rawCookieValue, "base64url").toString("utf-8");
15
+ const parsed = JSON.parse(json);
16
+ if (typeof parsed === "object" &&
17
+ parsed !== null &&
18
+ typeof parsed.sid === "string" &&
19
+ typeof parsed.iat === "number") {
20
+ return parsed;
21
+ }
22
+ return null;
23
+ }
24
+ catch (_a) {
25
+ return null;
26
+ }
27
+ }
28
+ }
29
+ exports.default = CookieCodec;
30
+ //# sourceMappingURL=CookieCodec.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CookieCodec.helper.js","sourceRoot":"","sources":["../../../source/Services/Auth/CookieCodec.helper.ts"],"names":[],"mappings":";;AAEA;;;;GAIG;AACH;IACS,MAAM,CAAC,MAAM,CAAC,OAAsB;QACzC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC7E,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,cAAsB;QACzC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACxE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,IACE,OAAO,MAAM,KAAK,QAAQ;gBAC1B,MAAM,KAAK,IAAI;gBACf,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;gBAC9B,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,EAC9B,CAAC;gBACD,OAAO,MAAuB,CAAC;YACjC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;mBAAO,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Hashes and verifies passwords using Node's built-in scrypt KDF.
3
+ * Stored format is `${saltHex}:${hashHex}` - no external dependency required.
4
+ */
5
+ export default class PasswordHasher {
6
+ static hashPassword(plainPassword: string): Promise<string>;
7
+ static verifyPassword(plainPassword: string, storedHash: string): Promise<boolean>;
8
+ private static deriveKey;
9
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const crypto_1 = require("crypto");
13
+ const KEY_LENGTH = 64;
14
+ const SALT_LENGTH = 16;
15
+ /**
16
+ * Hashes and verifies passwords using Node's built-in scrypt KDF.
17
+ * Stored format is `${saltHex}:${hashHex}` - no external dependency required.
18
+ */
19
+ class PasswordHasher {
20
+ static hashPassword(plainPassword) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const salt = (0, crypto_1.randomBytes)(SALT_LENGTH).toString("hex");
23
+ const derivedKey = yield PasswordHasher.deriveKey(plainPassword, salt);
24
+ return `${salt}:${derivedKey.toString("hex")}`;
25
+ });
26
+ }
27
+ static verifyPassword(plainPassword, storedHash) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ const [salt, hashHex] = storedHash.split(":");
30
+ if (!salt || !hashHex) {
31
+ return false;
32
+ }
33
+ const derivedKey = yield PasswordHasher.deriveKey(plainPassword, salt);
34
+ const storedKey = Buffer.from(hashHex, "hex");
35
+ if (derivedKey.length !== storedKey.length) {
36
+ return false;
37
+ }
38
+ return (0, crypto_1.timingSafeEqual)(derivedKey, storedKey);
39
+ });
40
+ }
41
+ static deriveKey(plainPassword, salt) {
42
+ return new Promise((resolve, reject) => {
43
+ (0, crypto_1.scrypt)(plainPassword, salt, KEY_LENGTH, (error, derivedKey) => {
44
+ if (error) {
45
+ reject(error);
46
+ return;
47
+ }
48
+ resolve(derivedKey);
49
+ });
50
+ });
51
+ }
52
+ }
53
+ exports.default = PasswordHasher;
54
+ //# sourceMappingURL=PasswordHasher.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordHasher.helper.js","sourceRoot":"","sources":["../../../source/Services/Auth/PasswordHasher.helper.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,mCAA8D;AAE9D,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;;;GAGG;AACH;IACS,MAAM,CAAO,YAAY,CAAC,aAAqB;;YACpD,MAAM,IAAI,GAAG,IAAA,oBAAW,EAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACtD,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YACvE,OAAO,GAAG,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,CAAC;KAAA;IAEM,MAAM,CAAO,cAAc,CAChC,aAAqB,EACrB,UAAkB;;YAElB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,KAAK,CAAC;YACf,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YACvE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAE9C,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;gBAC3C,OAAO,KAAK,CAAC;YACf,CAAC;YAED,OAAO,IAAA,wBAAe,EAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAChD,CAAC;KAAA;IAEO,MAAM,CAAC,SAAS,CAAC,aAAqB,EAAE,IAAY;QAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAA,eAAM,EAAC,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;gBAC5D,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,CAAC,KAAK,CAAC,CAAC;oBACd,OAAO;gBACT,CAAC;gBACD,OAAO,CAAC,UAAU,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}