@modular-rest/server 1.11.14 → 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/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/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/package.json +3 -3
- package/src/application.ts +1 -1
- package/src/class/cms_trigger.ts +8 -14
- package/src/class/database_trigger.ts +10 -4
- package/src/class/user.ts +1 -1
- package/src/services/data_provider/router.ts +293 -0
- package/src/services/data_provider/service.ts +2 -1
- package/src/services/functions/router.ts +3 -2
- package/src/services/user_manager/db.ts +5 -5
- package/src/services/user_manager/service.ts +20 -15
|
@@ -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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modular-rest/server",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.15",
|
|
4
4
|
"description": "TypeScript version of a nodejs module based on KOAJS for developing Rest-APIs in a modular solution.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"bugs": {
|
|
28
28
|
"url": "https://github.com/modular-rest/modular-rest/issues"
|
|
29
29
|
},
|
|
30
|
-
"homepage": "https://
|
|
30
|
+
"homepage": "https://modular-rest.github.io/modular-rest",
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@koa/cors": "^3.1.0",
|
|
33
33
|
"colog": "^1.0.4",
|
|
@@ -57,4 +57,4 @@
|
|
|
57
57
|
"typedoc-plugin-missing-exports": "^4.0.0",
|
|
58
58
|
"typescript": "^5.3.3"
|
|
59
59
|
}
|
|
60
|
-
}
|
|
60
|
+
}
|
package/src/application.ts
CHANGED
|
@@ -78,7 +78,7 @@ export async function createRest(options: RestOptions): Promise<{ app: Koa; serv
|
|
|
78
78
|
const defaultStaticPath = config.staticPath.actualPath || '';
|
|
79
79
|
const defaultStaticRootPath = config.staticPath.path || '/assets';
|
|
80
80
|
|
|
81
|
-
const staticOptions: Partial<StaticPathOptions> = { ...config.staticPath };
|
|
81
|
+
const staticOptions: Partial<StaticPathOptions> = { ...config.staticPath, defer: true };
|
|
82
82
|
|
|
83
83
|
delete staticOptions.actualPath;
|
|
84
84
|
delete staticOptions.path;
|