@modular-rest/server 1.11.13 → 1.11.15
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/.nvmrc +1 -0
- package/.prettierrc.json +9 -0
- package/.releaserc.json +24 -0
- package/README.md +79 -94
- package/dist/application.d.ts +29 -0
- package/dist/application.js +217 -0
- package/dist/class/cms_trigger.d.ts +52 -0
- package/dist/class/cms_trigger.js +47 -0
- package/dist/class/collection_definition.d.ts +112 -0
- package/dist/class/collection_definition.js +87 -0
- package/dist/class/combinator.d.ts +43 -0
- package/dist/class/combinator.js +174 -0
- package/dist/class/database_trigger.d.ts +90 -0
- package/dist/class/database_trigger.js +64 -0
- package/dist/class/db_schemas.d.ts +25 -0
- package/dist/class/db_schemas.js +28 -0
- package/dist/class/directory.d.ts +20 -0
- package/dist/class/directory.js +87 -0
- package/dist/class/paginator.d.ts +31 -0
- package/dist/class/paginator.js +43 -0
- package/dist/class/reply.d.ts +29 -0
- package/dist/class/reply.js +44 -0
- package/dist/class/security.d.ts +186 -0
- package/dist/class/security.js +178 -0
- package/dist/class/trigger_operator.d.ts +92 -0
- package/dist/class/trigger_operator.js +99 -0
- package/dist/class/user.d.ts +81 -0
- package/dist/class/user.js +151 -0
- package/dist/class/validator.d.ts +19 -0
- package/dist/class/validator.js +101 -0
- package/dist/config.d.ts +113 -0
- package/dist/config.js +26 -0
- package/dist/defult-permissions.d.ts +2 -0
- package/dist/defult-permissions.js +31 -0
- package/dist/events.d.ts +23 -0
- package/dist/events.js +47 -0
- package/dist/helper/data_insertion.d.ts +38 -0
- package/dist/helper/data_insertion.js +110 -0
- package/dist/helper/presetup_services.d.ts +60 -0
- package/dist/helper/presetup_services.js +108 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.js +79 -0
- package/dist/middlewares.d.ts +53 -0
- package/dist/middlewares.js +106 -0
- package/dist/play-test.d.ts +1 -0
- package/dist/play-test.js +9 -0
- package/dist/services/data_provider/router.d.ts +4 -0
- package/dist/services/data_provider/router.js +412 -0
- package/dist/services/data_provider/service.d.ts +132 -0
- package/dist/services/data_provider/service.js +253 -0
- package/dist/services/data_provider/typeCasters.d.ts +9 -0
- package/dist/services/data_provider/typeCasters.js +18 -0
- package/dist/services/file/db.d.ts +1 -0
- package/dist/services/file/db.js +31 -0
- package/dist/services/file/router.d.ts +4 -0
- package/dist/services/file/router.js +115 -0
- package/dist/services/file/service.d.ts +204 -0
- package/dist/services/file/service.js +341 -0
- package/dist/services/functions/router.d.ts +4 -0
- package/dist/services/functions/router.js +68 -0
- package/dist/services/functions/service.d.ts +132 -0
- package/dist/services/functions/service.js +159 -0
- package/dist/services/jwt/router.d.ts +4 -0
- package/dist/services/jwt/router.js +99 -0
- package/dist/services/jwt/service.d.ts +97 -0
- package/dist/services/jwt/service.js +135 -0
- package/dist/services/user_manager/db.d.ts +1 -0
- package/dist/services/user_manager/db.js +75 -0
- package/dist/services/user_manager/permissionManager.d.ts +19 -0
- package/dist/services/user_manager/permissionManager.js +42 -0
- package/dist/services/user_manager/router.d.ts +4 -0
- package/dist/services/user_manager/router.js +195 -0
- package/dist/services/user_manager/service.d.ts +317 -0
- package/dist/services/user_manager/service.js +632 -0
- package/docs/.keep +0 -0
- package/docs/system-access-type.md +26 -0
- package/package.json +59 -46
- package/src/application.ts +206 -0
- package/src/class/cms_trigger.ts +62 -0
- package/src/class/collection_definition.ts +134 -0
- package/src/class/combinator.ts +176 -0
- package/src/class/database_trigger.ts +105 -0
- package/src/class/db_schemas.ts +44 -0
- package/src/class/{directory.js → directory.ts} +40 -18
- package/src/class/paginator.ts +51 -0
- package/src/class/reply.ts +59 -0
- package/src/class/security.ts +250 -0
- package/src/class/trigger_operator.ts +142 -0
- package/src/class/user.ts +199 -0
- package/src/class/validator.ts +123 -0
- package/src/config.ts +122 -0
- package/src/defult-permissions.ts +31 -0
- package/src/events.ts +59 -0
- package/src/helper/data_insertion.ts +94 -0
- package/src/helper/presetup_services.ts +96 -0
- package/src/index.ts +146 -0
- package/src/middlewares.ts +75 -0
- package/src/play-test.ts +8 -0
- package/src/services/data_provider/router.ts +484 -0
- package/src/services/data_provider/service.ts +306 -0
- package/src/services/data_provider/typeCasters.ts +15 -0
- package/src/services/file/db.ts +29 -0
- package/src/services/file/router.ts +88 -0
- package/src/services/file/service.ts +387 -0
- package/src/services/functions/router.ts +35 -0
- package/src/services/functions/service.ts +203 -0
- package/src/services/jwt/router.ts +73 -0
- package/src/services/jwt/service.ts +139 -0
- package/src/services/user_manager/db.ts +87 -0
- package/src/services/user_manager/permissionManager.ts +49 -0
- package/src/services/user_manager/router.ts +193 -0
- package/src/services/user_manager/service.ts +703 -0
- package/tsconfig.json +16 -9
- package/typedoc.mjs +41 -0
- package/LICENSE +0 -21
- package/package-lock.json +0 -1373
- package/src/application.js +0 -239
- package/src/class/cms_trigger.js +0 -20
- package/src/class/collection_definition.js +0 -33
- package/src/class/combinator.js +0 -133
- package/src/class/database_trigger.js +0 -20
- package/src/class/db_schemas.js +0 -18
- package/src/class/paginator.js +0 -31
- package/src/class/reply.js +0 -37
- package/src/class/security.js +0 -141
- package/src/class/trigger_operator.js +0 -39
- package/src/class/user.js +0 -112
- package/src/class/validator.js +0 -91
- package/src/config.js +0 -67
- package/src/events.js +0 -15
- package/src/helper/data_insertion.js +0 -64
- package/src/helper/presetup_services.js +0 -31
- package/src/index.js +0 -66
- package/src/middlewares.js +0 -44
- package/src/services/data_provider/router.js +0 -552
- package/src/services/data_provider/service.js +0 -262
- package/src/services/data_provider/typeCasters.js +0 -10
- package/src/services/file/db.js +0 -29
- package/src/services/file/router.js +0 -92
- package/src/services/file/service.js +0 -231
- package/src/services/functions/router.js +0 -37
- package/src/services/functions/service.js +0 -74
- package/src/services/jwt/router.js +0 -82
- package/src/services/jwt/service.js +0 -37
- package/src/services/user_manager/db.js +0 -83
- package/src/services/user_manager/permissionManager.js +0 -43
- package/src/services/user_manager/router.js +0 -176
- package/src/services/user_manager/service.js +0 -377
- package/types/application.d.ts +0 -97
- package/types/class/cms_trigger.d.ts +0 -24
- package/types/class/collection_definition.d.ts +0 -36
- package/types/class/combinator.d.ts +0 -30
- package/types/class/database_trigger.d.ts +0 -28
- package/types/class/db_schemas.d.ts +0 -2
- package/types/class/directory.d.ts +0 -2
- package/types/class/paginator.d.ts +0 -8
- package/types/class/reply.d.ts +0 -8
- package/types/class/security.d.ts +0 -109
- package/types/class/trigger_operator.d.ts +0 -19
- package/types/class/user.d.ts +0 -24
- package/types/class/validator.d.ts +0 -9
- package/types/config.d.ts +0 -101
- package/types/events.d.ts +0 -7
- package/types/helper/data_insertion.d.ts +0 -4
- package/types/helper/presetup_services.d.ts +0 -5
- package/types/index.d.ts +0 -72
- package/types/middlewares.d.ts +0 -10
- package/types/services/data_provider/router.d.ts +0 -3
- package/types/services/data_provider/service.d.ts +0 -40
- package/types/services/data_provider/typeCasters.d.ts +0 -3
- package/types/services/file/db.d.ts +0 -3
- package/types/services/file/router.d.ts +0 -3
- package/types/services/file/service.d.ts +0 -81
- package/types/services/functions/router.d.ts +0 -3
- package/types/services/functions/service.d.ts +0 -23
- package/types/services/jwt/router.d.ts +0 -3
- package/types/services/jwt/service.d.ts +0 -10
- package/types/services/user_manager/db.d.ts +0 -3
- package/types/services/user_manager/permissionManager.d.ts +0 -3
- package/types/services/user_manager/router.d.ts +0 -3
- package/types/services/user_manager/service.d.ts +0 -131
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.main = exports.name = void 0;
|
|
37
|
+
const user_1 = require("../../class/user");
|
|
38
|
+
const DataProvider = __importStar(require("../data_provider/service"));
|
|
39
|
+
const JWT = __importStar(require("../jwt/service"));
|
|
40
|
+
const permissionManager_1 = require("./permissionManager");
|
|
41
|
+
/**
|
|
42
|
+
* Service name constant
|
|
43
|
+
* @constant {string}
|
|
44
|
+
*/
|
|
45
|
+
exports.name = 'userManager';
|
|
46
|
+
/**
|
|
47
|
+
* User manager class for handling user operations
|
|
48
|
+
|
|
49
|
+
* This service provides functionality for managing users, including:
|
|
50
|
+
* - User registration and authentication
|
|
51
|
+
* - Password management
|
|
52
|
+
* - Token generation and verification
|
|
53
|
+
* - Temporary ID handling for password reset and verification
|
|
54
|
+
*
|
|
55
|
+
*/
|
|
56
|
+
class UserManager {
|
|
57
|
+
/**
|
|
58
|
+
* @hidden
|
|
59
|
+
*/
|
|
60
|
+
constructor() {
|
|
61
|
+
/**
|
|
62
|
+
* @hidden
|
|
63
|
+
*/
|
|
64
|
+
this.tempIds = {};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sets a custom method for generating verification codes
|
|
68
|
+
* @param {Function} generatorMethod - Function that generates verification codes
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* import { userManager } from '@modular-rest/server';
|
|
72
|
+
*
|
|
73
|
+
* userManager.setCustomVerificationCodeGeneratorMethod((id, type) => {
|
|
74
|
+
* return Math.random().toString(36).substring(2, 8).toUpperCase();
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
setCustomVerificationCodeGeneratorMethod(generatorMethod) {
|
|
79
|
+
this.verificationCodeGeneratorMethod = generatorMethod;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Generates a verification code for a user
|
|
83
|
+
* @param {string} id - User ID or identifier
|
|
84
|
+
* @param {string} idType - Type of ID (email, phone)
|
|
85
|
+
* @returns {string} Verification code
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* import { userManager } from '@modular-rest/server';
|
|
89
|
+
*
|
|
90
|
+
* const code = userManager.generateVerificationCode('user@example.com', 'email');
|
|
91
|
+
* // Returns: '123' (default) or custom generated code
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
generateVerificationCode(id, idType) {
|
|
95
|
+
if (this.verificationCodeGeneratorMethod)
|
|
96
|
+
return this.verificationCodeGeneratorMethod(id, idType);
|
|
97
|
+
// this is default code
|
|
98
|
+
return '123';
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Gets a user by their ID
|
|
102
|
+
* @param {string} id - The ID of the user
|
|
103
|
+
* @returns {Promise<User>} Promise resolving to the user
|
|
104
|
+
* @throws {Error} If user model is not found or user is not found
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* import { userManager } from '@modular-rest/server';
|
|
108
|
+
*
|
|
109
|
+
* try {
|
|
110
|
+
* const user = await userManager.getUserById('user123');
|
|
111
|
+
* console.log('User details:', user);
|
|
112
|
+
* } catch (error) {
|
|
113
|
+
* console.error('Failed to get user:', error);
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
getUserById(id) {
|
|
118
|
+
return new Promise(async (done, reject) => {
|
|
119
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
120
|
+
if (!userModel) {
|
|
121
|
+
return reject(new Error('User model not found'));
|
|
122
|
+
}
|
|
123
|
+
let userDoc;
|
|
124
|
+
try {
|
|
125
|
+
userDoc = await userModel.findOne({ _id: id }).select({ password: 0 }).exec();
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
return reject(error);
|
|
129
|
+
}
|
|
130
|
+
if (!userDoc) {
|
|
131
|
+
return reject(new Error('User not found'));
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const user = await user_1.User.loadFromModel(userDoc);
|
|
135
|
+
done(user);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
reject(error);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Gets a user by their identity (email or phone)
|
|
144
|
+
* @param {string} id - The identity of the user
|
|
145
|
+
* @param {string} idType - The type of the identity (phone or email)
|
|
146
|
+
* @returns {Promise<User>} Promise resolving to the user
|
|
147
|
+
* @throws {Error} If user model is not found or user is not found
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* import { userManager } from '@modular-rest/server';
|
|
151
|
+
*
|
|
152
|
+
* // Get user by email
|
|
153
|
+
* const user = await userManager.getUserByIdentity('user@example.com', 'email');
|
|
154
|
+
*
|
|
155
|
+
* // Get user by phone
|
|
156
|
+
* const user = await userManager.getUserByIdentity('+1234567890', 'phone');
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
getUserByIdentity(id, idType) {
|
|
160
|
+
return new Promise(async (done, reject) => {
|
|
161
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
162
|
+
if (!userModel) {
|
|
163
|
+
return reject(new Error('User model not found'));
|
|
164
|
+
}
|
|
165
|
+
const query = {};
|
|
166
|
+
if (idType === 'phone')
|
|
167
|
+
query['phone'] = id;
|
|
168
|
+
else if (idType === 'email')
|
|
169
|
+
query['email'] = id;
|
|
170
|
+
let userDoc;
|
|
171
|
+
try {
|
|
172
|
+
userDoc = await userModel.findOne(query).select({ password: 0 }).exec();
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
return reject(error);
|
|
176
|
+
}
|
|
177
|
+
if (!userDoc) {
|
|
178
|
+
return reject(new Error('User not found'));
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
const user = await user_1.User.loadFromModel(userDoc);
|
|
182
|
+
done(user);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
reject(error);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Gets a user by their JWT token
|
|
191
|
+
* @param {string} token - The JWT token of the user
|
|
192
|
+
* @returns {Promise<User>} Promise resolving to the user
|
|
193
|
+
* @throws {Error} If token is invalid or user is not found
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* import { userManager } from '@modular-rest/server';
|
|
197
|
+
*
|
|
198
|
+
* try {
|
|
199
|
+
* const user = await userManager.getUserByToken('jwt.token.here');
|
|
200
|
+
* console.log('Authenticated user:', user);
|
|
201
|
+
* } catch (error) {
|
|
202
|
+
* console.error('Invalid token:', error);
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
async getUserByToken(token) {
|
|
207
|
+
const decoded = await JWT.main.verify(token);
|
|
208
|
+
return this.getUserById(decoded.id);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Checks if a verification code is valid
|
|
212
|
+
* @param {string} id - The ID of the user
|
|
213
|
+
* @param {string} code - The verification code
|
|
214
|
+
* @returns {boolean} Whether the verification code is valid
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* import { userManager } from '@modular-rest/server';
|
|
218
|
+
*
|
|
219
|
+
* const isValid = userManager.isCodeValid('user123', '123');
|
|
220
|
+
* if (isValid) {
|
|
221
|
+
* // Proceed with verification
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
isCodeValid(id, code) {
|
|
226
|
+
return this.tempIds.hasOwnProperty(id) && this.tempIds[id].code.toString() === code.toString();
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Logs in a user and returns their JWT token
|
|
230
|
+
* @param {string} [id=''] - The ID of the user (email or phone)
|
|
231
|
+
* @param {string} [idType=''] - The type of the ID (phone or email)
|
|
232
|
+
* @param {string} [password=''] - The password of the user
|
|
233
|
+
* @returns {Promise<string>} Promise resolving to the JWT token
|
|
234
|
+
* @throws {Error} If user is not found or credentials are invalid
|
|
235
|
+
* @example
|
|
236
|
+
* ```typescript
|
|
237
|
+
* import { userManager } from '@modular-rest/server';
|
|
238
|
+
*
|
|
239
|
+
* try {
|
|
240
|
+
* // Login with email
|
|
241
|
+
* const token = await userManager.loginUser('user@example.com', 'email', 'password123');
|
|
242
|
+
*
|
|
243
|
+
* // Login with phone
|
|
244
|
+
* const token = await userManager.loginUser('+1234567890', 'phone', 'password123');
|
|
245
|
+
* } catch (error) {
|
|
246
|
+
* console.error('Login failed:', error);
|
|
247
|
+
* }
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
loginUser(id = '', idType = '', password = '') {
|
|
251
|
+
return new Promise(async (done, reject) => {
|
|
252
|
+
// Get user model
|
|
253
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
254
|
+
if (!userModel) {
|
|
255
|
+
return reject(new Error('User model not found'));
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Setup query to find by phone or email
|
|
259
|
+
*/
|
|
260
|
+
const query = {
|
|
261
|
+
password: Buffer.from(password).toString('base64'),
|
|
262
|
+
type: 'user',
|
|
263
|
+
};
|
|
264
|
+
if (idType === 'phone')
|
|
265
|
+
query['phone'] = id;
|
|
266
|
+
else if (idType === 'email')
|
|
267
|
+
query['email'] = id;
|
|
268
|
+
// Get from database
|
|
269
|
+
let gottenFromDB;
|
|
270
|
+
try {
|
|
271
|
+
gottenFromDB = await userModel.findOne(query).exec();
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
return reject(error);
|
|
275
|
+
}
|
|
276
|
+
if (!gottenFromDB) {
|
|
277
|
+
return reject(new Error('User not found'));
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
// Load user
|
|
281
|
+
const user = await user_1.User.loadFromModel(gottenFromDB);
|
|
282
|
+
// Get token payload
|
|
283
|
+
// This is some information about the user.
|
|
284
|
+
const payload = user.getBrief();
|
|
285
|
+
// Generate json web token
|
|
286
|
+
const token = await JWT.main.sign(payload);
|
|
287
|
+
done(token);
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
reject(error);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Issues a JWT token for a user by email
|
|
296
|
+
* @param {string} email - The email of the user
|
|
297
|
+
* @returns {Promise<string>} Promise resolving to the JWT token
|
|
298
|
+
* @throws {Error} If user is not found
|
|
299
|
+
* @example
|
|
300
|
+
* ```typescript
|
|
301
|
+
* import { userManager } from '@modular-rest/server';
|
|
302
|
+
*
|
|
303
|
+
* try {
|
|
304
|
+
* const token = await userManager.issueTokenForUser('user@example.com');
|
|
305
|
+
* console.log('Issued token:', token);
|
|
306
|
+
* } catch (error) {
|
|
307
|
+
* console.error('Failed to issue token:', error);
|
|
308
|
+
* }
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
issueTokenForUser(email) {
|
|
312
|
+
return new Promise(async (done, reject) => {
|
|
313
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
314
|
+
if (!userModel) {
|
|
315
|
+
return reject(new Error('User model not found'));
|
|
316
|
+
}
|
|
317
|
+
const query = { email: email };
|
|
318
|
+
// Get from database
|
|
319
|
+
let gottenFromDB;
|
|
320
|
+
try {
|
|
321
|
+
gottenFromDB = await userModel.findOne(query).exec();
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
return reject(error);
|
|
325
|
+
}
|
|
326
|
+
if (!gottenFromDB) {
|
|
327
|
+
return reject(new Error('User not found'));
|
|
328
|
+
}
|
|
329
|
+
try {
|
|
330
|
+
// Load user
|
|
331
|
+
const user = await user_1.User.loadFromModel(gottenFromDB);
|
|
332
|
+
// Get token payload
|
|
333
|
+
const payload = user.getBrief();
|
|
334
|
+
// Generate json web token
|
|
335
|
+
const token = await JWT.main.sign(payload);
|
|
336
|
+
done(token);
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
reject(error);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Logs in an anonymous user and returns their JWT token
|
|
345
|
+
* @returns {Promise<string>} Promise resolving to the JWT token
|
|
346
|
+
* @example
|
|
347
|
+
* ```typescript
|
|
348
|
+
* import { userManager } from '@modular-rest/server';
|
|
349
|
+
*
|
|
350
|
+
* const token = await userManager.loginAnonymous();
|
|
351
|
+
* console.log('Anonymous token:', token);
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
loginAnonymous() {
|
|
355
|
+
return new Promise(async (done, reject) => {
|
|
356
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
357
|
+
if (!userModel) {
|
|
358
|
+
return reject(new Error('User model not found'));
|
|
359
|
+
}
|
|
360
|
+
try {
|
|
361
|
+
// Check if anonymous user already exists
|
|
362
|
+
let anonymousUser = await userModel.findOne({ type: 'anonymous' }).exec();
|
|
363
|
+
if (!anonymousUser) {
|
|
364
|
+
// Create anonymous user document
|
|
365
|
+
anonymousUser = await userModel.create({
|
|
366
|
+
type: 'anonymous',
|
|
367
|
+
permissionGroup: (0, permissionManager_1.getDefaultAnonymousPermissionGroup)().title,
|
|
368
|
+
phone: '',
|
|
369
|
+
email: 'anonymous',
|
|
370
|
+
password: '',
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
// Load user from document
|
|
374
|
+
const user = await user_1.User.loadFromModel(anonymousUser);
|
|
375
|
+
// Get token payload
|
|
376
|
+
const payload = user.getBrief();
|
|
377
|
+
// Generate json web token
|
|
378
|
+
const token = await JWT.main.sign(payload);
|
|
379
|
+
done(token);
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
reject(error);
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Registers a temporary ID for verification or password reset
|
|
388
|
+
* @param {string} id - The ID to register
|
|
389
|
+
* @param {string} type - The type of temporary ID
|
|
390
|
+
* @param {string} code - The verification code
|
|
391
|
+
* @returns {string} The registered ID
|
|
392
|
+
* @example
|
|
393
|
+
* ```typescript
|
|
394
|
+
* import { userManager } from '@modular-rest/server';
|
|
395
|
+
*
|
|
396
|
+
* const tempId = userManager.registerTemporaryID('user@example.com', 'password_reset', '123456');
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
registerTemporaryID(id, type, code) {
|
|
400
|
+
this.tempIds[id] = {
|
|
401
|
+
type,
|
|
402
|
+
code,
|
|
403
|
+
timestamp: Date.now(),
|
|
404
|
+
};
|
|
405
|
+
return id;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Submits a password for a temporary ID
|
|
409
|
+
* @param {string} id - The temporary ID
|
|
410
|
+
* @param {string} password - The new password
|
|
411
|
+
* @param {string} code - The verification code
|
|
412
|
+
* @returns {Promise<string>} Promise resolving to the JWT token
|
|
413
|
+
* @throws {Error} If verification code is invalid or user is not found
|
|
414
|
+
* @example
|
|
415
|
+
* ```typescript
|
|
416
|
+
* import { userManager } from '@modular-rest/server';
|
|
417
|
+
*
|
|
418
|
+
* try {
|
|
419
|
+
* const token = await userManager.submitPasswordForTemporaryID(
|
|
420
|
+
* 'user@example.com',
|
|
421
|
+
* 'newpassword123',
|
|
422
|
+
* '123456'
|
|
423
|
+
* );
|
|
424
|
+
* console.log('Password set successfully');
|
|
425
|
+
* } catch (error) {
|
|
426
|
+
* console.error('Failed to set password:', error);
|
|
427
|
+
* }
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
async submitPasswordForTemporaryID(id, password, code) {
|
|
431
|
+
if (!this.isCodeValid(id, code)) {
|
|
432
|
+
throw new Error('Invalid verification code');
|
|
433
|
+
}
|
|
434
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
435
|
+
if (!userModel) {
|
|
436
|
+
throw new Error('User model not found');
|
|
437
|
+
}
|
|
438
|
+
const query = { email: id };
|
|
439
|
+
// Get from database
|
|
440
|
+
let gottenFromDB;
|
|
441
|
+
try {
|
|
442
|
+
gottenFromDB = await userModel.findOne(query).exec();
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
throw error;
|
|
446
|
+
}
|
|
447
|
+
if (!gottenFromDB) {
|
|
448
|
+
throw new Error('User not found');
|
|
449
|
+
}
|
|
450
|
+
try {
|
|
451
|
+
// Load user
|
|
452
|
+
const user = await user_1.User.loadFromModel(gottenFromDB);
|
|
453
|
+
// Update password
|
|
454
|
+
user.password = password;
|
|
455
|
+
// Save to database
|
|
456
|
+
await user.save();
|
|
457
|
+
// Get token payload
|
|
458
|
+
const payload = user.getBrief();
|
|
459
|
+
// Generate json web token
|
|
460
|
+
const token = await JWT.main.sign(payload);
|
|
461
|
+
// Remove temporary ID
|
|
462
|
+
delete this.tempIds[id];
|
|
463
|
+
return token;
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
throw error;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Changes password for a temporary ID
|
|
471
|
+
* @param {string} id - The temporary ID
|
|
472
|
+
* @param {string} password - The new password
|
|
473
|
+
* @param {string} code - The verification code
|
|
474
|
+
* @returns {Promise<string>} Promise resolving to the JWT token
|
|
475
|
+
* @throws {Error} If verification code is invalid or user is not found
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* import { userManager } from '@modular-rest/server';
|
|
479
|
+
*
|
|
480
|
+
* try {
|
|
481
|
+
* const token = await userManager.changePasswordForTemporaryID(
|
|
482
|
+
* 'user@example.com',
|
|
483
|
+
* 'newpassword123',
|
|
484
|
+
* '123456'
|
|
485
|
+
* );
|
|
486
|
+
* console.log('Password changed successfully');
|
|
487
|
+
* } catch (error) {
|
|
488
|
+
* console.error('Failed to change password:', error);
|
|
489
|
+
* }
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
492
|
+
async changePasswordForTemporaryID(id, password, code) {
|
|
493
|
+
if (!this.isCodeValid(id, code)) {
|
|
494
|
+
throw new Error('Invalid verification code');
|
|
495
|
+
}
|
|
496
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
497
|
+
if (!userModel) {
|
|
498
|
+
throw new Error('User model not found');
|
|
499
|
+
}
|
|
500
|
+
const query = { email: id };
|
|
501
|
+
// Get from database
|
|
502
|
+
let gottenFromDB;
|
|
503
|
+
try {
|
|
504
|
+
gottenFromDB = await userModel.findOne(query).exec();
|
|
505
|
+
}
|
|
506
|
+
catch (error) {
|
|
507
|
+
throw error;
|
|
508
|
+
}
|
|
509
|
+
if (!gottenFromDB) {
|
|
510
|
+
throw new Error('User not found');
|
|
511
|
+
}
|
|
512
|
+
try {
|
|
513
|
+
// Load user
|
|
514
|
+
const user = await user_1.User.loadFromModel(gottenFromDB);
|
|
515
|
+
// Update password
|
|
516
|
+
user.password = password;
|
|
517
|
+
// Save to database
|
|
518
|
+
await user.save();
|
|
519
|
+
// Get token payload
|
|
520
|
+
const payload = user.getBrief();
|
|
521
|
+
// Generate json web token
|
|
522
|
+
const token = await JWT.main.sign(payload);
|
|
523
|
+
// Remove temporary ID
|
|
524
|
+
delete this.tempIds[id];
|
|
525
|
+
return token;
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
throw error;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Registers a new user
|
|
533
|
+
* @param {UserRegistrationDetail} detail - User registration details
|
|
534
|
+
* @returns {Promise<string>} Promise resolving to the JWT token
|
|
535
|
+
* @throws {Error} If user model is not found or registration fails
|
|
536
|
+
* @example
|
|
537
|
+
* ```typescript
|
|
538
|
+
* import { userManager } from '@modular-rest/server';
|
|
539
|
+
*
|
|
540
|
+
* try {
|
|
541
|
+
* const token = await userManager.registerUser({
|
|
542
|
+
* email: 'user@example.com',
|
|
543
|
+
* password: 'secure123',
|
|
544
|
+
* permissionGroup: 'user',
|
|
545
|
+
* phone: '+1234567890'
|
|
546
|
+
* });
|
|
547
|
+
* console.log('User registered successfully');
|
|
548
|
+
* } catch (error) {
|
|
549
|
+
* console.error('Registration failed:', error);
|
|
550
|
+
* }
|
|
551
|
+
* ```
|
|
552
|
+
*/
|
|
553
|
+
registerUser(detail) {
|
|
554
|
+
return new Promise(async (done, reject) => {
|
|
555
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
556
|
+
if (!userModel) {
|
|
557
|
+
return reject(new Error('User model not found'));
|
|
558
|
+
}
|
|
559
|
+
try {
|
|
560
|
+
// Create user document
|
|
561
|
+
const userDoc = await userModel.create({
|
|
562
|
+
...detail,
|
|
563
|
+
type: detail.type || 'user',
|
|
564
|
+
permissionGroup: detail.permissionGroup || (0, permissionManager_1.getDefaultPermissionGroups)().title,
|
|
565
|
+
phone: detail.phone || undefined,
|
|
566
|
+
email: detail.email || undefined,
|
|
567
|
+
password: detail.password || undefined,
|
|
568
|
+
});
|
|
569
|
+
// Load user from document
|
|
570
|
+
const user = await user_1.User.loadFromModel(userDoc);
|
|
571
|
+
// Get token payload
|
|
572
|
+
const payload = user.getBrief();
|
|
573
|
+
// Generate json web token
|
|
574
|
+
const token = await JWT.main.sign(payload);
|
|
575
|
+
done(token);
|
|
576
|
+
}
|
|
577
|
+
catch (error) {
|
|
578
|
+
reject(error);
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Changes a user's password
|
|
584
|
+
* @param {Record<string, any>} query - Query to find the user
|
|
585
|
+
* @param {string} newPass - The new password
|
|
586
|
+
* @returns {Promise<void>} Promise resolving when password is changed
|
|
587
|
+
* @throws {Error} If user is not found or password change fails
|
|
588
|
+
* @example
|
|
589
|
+
* ```typescript
|
|
590
|
+
* import { userManager } from '@modular-rest/server';
|
|
591
|
+
*
|
|
592
|
+
* try {
|
|
593
|
+
* await userManager.changePassword(
|
|
594
|
+
* { email: 'user@example.com' },
|
|
595
|
+
* 'newpassword123'
|
|
596
|
+
* );
|
|
597
|
+
* console.log('Password changed successfully');
|
|
598
|
+
* } catch (error) {
|
|
599
|
+
* console.error('Failed to change password:', error);
|
|
600
|
+
* }
|
|
601
|
+
* ```
|
|
602
|
+
*/
|
|
603
|
+
async changePassword(query, newPass) {
|
|
604
|
+
const userModel = DataProvider.getCollection('cms', 'auth');
|
|
605
|
+
if (!userModel) {
|
|
606
|
+
throw new Error('User model not found');
|
|
607
|
+
}
|
|
608
|
+
const userDoc = await userModel.findOne(query).exec();
|
|
609
|
+
if (!userDoc) {
|
|
610
|
+
throw new Error('User not found');
|
|
611
|
+
}
|
|
612
|
+
const user = await user_1.User.loadFromModel(userDoc);
|
|
613
|
+
user.password = newPass;
|
|
614
|
+
await user.save();
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Gets the singleton instance of UserManager
|
|
618
|
+
* @returns {UserManager} The UserManager instance
|
|
619
|
+
* @hidden
|
|
620
|
+
*/
|
|
621
|
+
static get instance() {
|
|
622
|
+
if (!this._instance) {
|
|
623
|
+
this._instance = new UserManager();
|
|
624
|
+
}
|
|
625
|
+
return this._instance;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Main user manager instance
|
|
630
|
+
* @constant {UserManager}
|
|
631
|
+
*/
|
|
632
|
+
exports.main = UserManager.instance;
|
package/docs/.keep
ADDED
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
### System Access Types
|
|
2
|
+
|
|
3
|
+
The permission system works by matching the user's assigned permission types (stored in their permission group) against the required permissions defined on collections and functions. This allows for flexible and granular access control.
|
|
4
|
+
|
|
5
|
+
For example, a collection could be configured to:
|
|
6
|
+
|
|
7
|
+
- Allow read access for users with 'user_access' permission
|
|
8
|
+
- Restrict write operations to users with 'advanced_settings' permission
|
|
9
|
+
- Only let users who has the 'upload_file_access' access type in their permission group to upload new files
|
|
10
|
+
|
|
11
|
+
**Built-in Permission Types**
|
|
12
|
+
|
|
13
|
+
The system comes with the following pre-defined permission types:
|
|
14
|
+
|
|
15
|
+
| Permission Type | Description |
|
|
16
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| `god_access` | Grants unrestricted super admin access. Users with this permission can perform any operation and access all collections and functions. |
|
|
18
|
+
| `user_access` | Basic user-level access for authenticated users. Typically grants read access to most collections and basic functionality. |
|
|
19
|
+
| `upload_file_access` | Required specifically for file upload operations. Users need this permission to upload files to the system. |
|
|
20
|
+
| `remove_file_access` | Required for file deletion operations. Users need this permission to remove files from the system. |
|
|
21
|
+
| `anonymous_access` | Used for unauthenticated access. Defines what operations are available to users who are not logged in. |
|
|
22
|
+
| `advanced_settings` | Grants access to advanced system configuration and administrative features. More privileged than basic user access. |
|
|
23
|
+
|
|
24
|
+
These permission types can be combined in permission groups to create different access levels. For example, an admin user might have both `advanced_settings` and `user_access`, while a basic user would only have `user_access`.
|
|
25
|
+
|
|
26
|
+
You can also define custom permission types for specific needs in your application. The permission system is flexible enough to accommodate any additional access types you require.
|