@modular-rest/server 1.8.0 → 1.10.1
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/package-lock.json +1373 -0
- package/package.json +4 -2
- package/src/application.js +60 -40
- package/src/class/collection_definition.js +3 -3
- package/src/class/database_trigger.js +4 -3
- package/src/class/directory.js +50 -51
- package/src/class/security.js +32 -17
- package/src/class/trigger_operator.js +4 -7
- package/src/class/user.js +98 -83
- package/src/config.js +65 -0
- package/src/events.js +15 -0
- package/src/helper/data_insertion.js +31 -75
- package/src/helper/presetup_services.js +2 -14
- package/src/services/data_provider/router.js +490 -402
- package/src/services/data_provider/service.js +39 -16
- package/src/services/user_manager/db.js +45 -37
- package/src/services/user_manager/permissionManager.js +43 -0
- package/src/services/user_manager/service.js +19 -41
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modular-rest/server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "a nodejs module based on KOAJS for developing Rest-APIs in a modular solution.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"nested-property": "^4.0.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
+
"@types/bson": "4.2.0",
|
|
41
42
|
"@types/koa": "^2.14.0",
|
|
43
|
+
"@types/koa__cors": "^5.0.0",
|
|
42
44
|
"typescript": "^5.3.3"
|
|
43
45
|
}
|
|
44
|
-
}
|
|
46
|
+
}
|
package/src/application.js
CHANGED
|
@@ -7,15 +7,22 @@ const Combination = require("./class/combinator");
|
|
|
7
7
|
const DataProvider = require("./services/data_provider/service");
|
|
8
8
|
const UserService = require("./services/user_manager/service");
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const defaultServiceRoot = __dirname + "/services";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @typedef {import('koa')} Koa
|
|
14
|
+
* @typedef {import('http').Server} server
|
|
15
|
+
* @typedef {import('@koa/cors').Options} Cors
|
|
16
|
+
* @typedef {import('./class/security').PermissionGroup} PermissionGroup
|
|
17
|
+
* @typedef {import('./class/database_trigger.js')} DatabaseTrigger
|
|
14
18
|
*/
|
|
15
19
|
|
|
20
|
+
const { config, setConfig } = require("./config");
|
|
21
|
+
|
|
16
22
|
/**
|
|
23
|
+
* Create a modular REST instance with Koa and MongoDB support.
|
|
17
24
|
* @param {{
|
|
18
|
-
* cors?:
|
|
25
|
+
* cors?: Cors; // CORS options.
|
|
19
26
|
* modulesPath?: string; // Root directory of your router.js/db.js files.
|
|
20
27
|
* staticPath?: {
|
|
21
28
|
* rootDir?: string; // Root directory of your static files.
|
|
@@ -48,10 +55,13 @@ let defaultServiceRoot = __dirname + "/services";
|
|
|
48
55
|
* };
|
|
49
56
|
* verificationCodeGeneratorMethod: () => string; // A method to return a verification code when registering a new user.
|
|
50
57
|
* collectionDefinitions?: CollectionDefinition[]; // An array of additional collection definitions.
|
|
58
|
+
* permissionGroups?: PermissionGroup[]; // An array of additional permission groups.
|
|
59
|
+
* authTriggers?: DatabaseTrigger[]; // An array of additional database triggers for the auth collection.
|
|
51
60
|
* }} options
|
|
61
|
+
* @returns {Promise<{app: Koa, server: Server}>}
|
|
52
62
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
async function createRest(options) {
|
|
64
|
+
setConfig({
|
|
55
65
|
port: 3000,
|
|
56
66
|
dontListen: false,
|
|
57
67
|
mongo: {
|
|
@@ -65,19 +75,19 @@ module.exports = async function createRest(options) {
|
|
|
65
75
|
},
|
|
66
76
|
|
|
67
77
|
...options,
|
|
68
|
-
};
|
|
78
|
+
});
|
|
69
79
|
|
|
70
|
-
|
|
80
|
+
const app = new koa();
|
|
71
81
|
|
|
72
82
|
/**
|
|
73
83
|
* Plug in Cors
|
|
74
84
|
*/
|
|
75
|
-
app.use(cors(
|
|
85
|
+
app.use(cors(config.cors || {}));
|
|
76
86
|
|
|
77
87
|
/**
|
|
78
88
|
* Plug in BodyParser
|
|
79
89
|
*/
|
|
80
|
-
|
|
90
|
+
const bodyParserOptions = {
|
|
81
91
|
multipart: true,
|
|
82
92
|
};
|
|
83
93
|
app.use(koaBody(bodyParserOptions));
|
|
@@ -85,14 +95,14 @@ module.exports = async function createRest(options) {
|
|
|
85
95
|
/**
|
|
86
96
|
* Plug In KoaStatic
|
|
87
97
|
*/
|
|
88
|
-
if (
|
|
89
|
-
app.use(koaStatic(
|
|
98
|
+
if (config.staticPath) {
|
|
99
|
+
app.use(koaStatic(config.staticPath));
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
/**
|
|
93
103
|
* Run before hook
|
|
94
104
|
*/
|
|
95
|
-
if (
|
|
105
|
+
if (config.onBeforeInit) config.onBeforeInit(app);
|
|
96
106
|
|
|
97
107
|
/**
|
|
98
108
|
* Setup default services
|
|
@@ -118,25 +128,29 @@ module.exports = async function createRest(options) {
|
|
|
118
128
|
// Plug in default databaseDefinitions
|
|
119
129
|
await DataProvider.addCollectionDefinitionByList({
|
|
120
130
|
list: defaultDatabaseDefinitionList,
|
|
121
|
-
mongoOption:
|
|
131
|
+
mongoOption: config.mongo,
|
|
122
132
|
});
|
|
123
133
|
|
|
124
134
|
// Setting up default services
|
|
125
|
-
|
|
135
|
+
try {
|
|
136
|
+
await require("./helper/presetup_services").setup(options);
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return Promise.reject(e);
|
|
139
|
+
}
|
|
126
140
|
|
|
127
141
|
/**
|
|
128
142
|
* User Services
|
|
129
143
|
*
|
|
130
144
|
* Plug in routes and database
|
|
131
145
|
*/
|
|
132
|
-
if (
|
|
146
|
+
if (config.modulesPath) {
|
|
133
147
|
// Plug in user routes
|
|
134
|
-
await Combination.combineRoutesByFilePath(
|
|
148
|
+
await Combination.combineRoutesByFilePath(config.modulesPath, app);
|
|
135
149
|
|
|
136
150
|
// Collect user CollectionDefinitions (db.js files)
|
|
137
151
|
let userDatabaseDetail = [];
|
|
138
152
|
userDatabaseDetail = await Combination.combineModulesByFilePath({
|
|
139
|
-
rootDirectory:
|
|
153
|
+
rootDirectory: config.modulesPath,
|
|
140
154
|
filename: {
|
|
141
155
|
name: "db",
|
|
142
156
|
extension: ".js",
|
|
@@ -144,21 +158,21 @@ module.exports = async function createRest(options) {
|
|
|
144
158
|
combineWithRoot: true,
|
|
145
159
|
});
|
|
146
160
|
|
|
147
|
-
//
|
|
148
|
-
if (
|
|
149
|
-
userDatabaseDetail.concat(
|
|
161
|
+
// Combine additional CollectionDefinitions
|
|
162
|
+
if (config.collectionDefinitions) {
|
|
163
|
+
userDatabaseDetail.concat(config.collectionDefinitions);
|
|
150
164
|
}
|
|
151
165
|
|
|
152
166
|
// Plug in user CollectionDefinitions
|
|
153
167
|
await DataProvider.addCollectionDefinitionByList({
|
|
154
168
|
list: userDatabaseDetail || [],
|
|
155
|
-
mongoOption:
|
|
169
|
+
mongoOption: config.mongo,
|
|
156
170
|
});
|
|
157
171
|
|
|
158
172
|
// Plug in Verification method
|
|
159
|
-
if (typeof
|
|
173
|
+
if (typeof config.verificationCodeGeneratorMethod == "function") {
|
|
160
174
|
UserService.main.setCustomVerificationCodeGeneratorMethod(
|
|
161
|
-
|
|
175
|
+
config.verificationCodeGeneratorMethod
|
|
162
176
|
);
|
|
163
177
|
}
|
|
164
178
|
}
|
|
@@ -169,23 +183,29 @@ module.exports = async function createRest(options) {
|
|
|
169
183
|
* return KOA app object
|
|
170
184
|
*/
|
|
171
185
|
return new Promise((done, reject) => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
186
|
+
try {
|
|
187
|
+
let server;
|
|
188
|
+
|
|
189
|
+
if (!config.dontListen) {
|
|
190
|
+
server = app.listen(config.port);
|
|
191
|
+
|
|
192
|
+
console.log(
|
|
193
|
+
"\x1b[35m",
|
|
194
|
+
`KOAS has been launched on: localhost:${config.port}`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// on after init
|
|
199
|
+
if (config.onAfterInit) config.onAfterInit(app);
|
|
200
|
+
|
|
201
|
+
done({
|
|
202
|
+
app,
|
|
203
|
+
server,
|
|
204
|
+
});
|
|
205
|
+
} catch (err) {
|
|
206
|
+
reject(err);
|
|
180
207
|
}
|
|
181
|
-
|
|
182
|
-
// on after init
|
|
183
|
-
if (options.onAfterInit) options.onAfterInit(app);
|
|
184
|
-
|
|
185
|
-
//done
|
|
186
|
-
done({
|
|
187
|
-
app,
|
|
188
|
-
server,
|
|
189
|
-
});
|
|
190
208
|
});
|
|
191
|
-
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
module.exports = createRest;
|
|
@@ -14,9 +14,9 @@ class CollectionDefinition {
|
|
|
14
14
|
* @param {string} option.collection - Collection name
|
|
15
15
|
* @param {Object} option.schema - Mongoose schema
|
|
16
16
|
* @param {Array<Permission>} option.permissions - A list of permissions for this collection
|
|
17
|
-
* @param {Array<DatabaseTrigger>=} option.
|
|
17
|
+
* @param {Array<DatabaseTrigger>=} option.triggers - A database trigger
|
|
18
18
|
*/
|
|
19
|
-
constructor({ db, collection, schema, permissions,
|
|
19
|
+
constructor({ db, collection, schema, permissions, triggers }) {
|
|
20
20
|
// string
|
|
21
21
|
this.database = db;
|
|
22
22
|
// string
|
|
@@ -26,7 +26,7 @@ class CollectionDefinition {
|
|
|
26
26
|
// a list of Permission for this collection
|
|
27
27
|
this.permissions = permissions;
|
|
28
28
|
|
|
29
|
-
this.
|
|
29
|
+
this.triggers = triggers;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -7,10 +7,11 @@ class DatabaseTrigger {
|
|
|
7
7
|
/**
|
|
8
8
|
* Creates a new instance of `DatabaseTrigger`.
|
|
9
9
|
*
|
|
10
|
-
* @param {'find' | 'find-one' | 'count' | 'update-one' | 'insert-one' | 'remove-one' | 'aggregate'} operation - The operation to be triggered. Supported operations are:
|
|
11
|
-
* @param {function(query, queryResult)} callback - The callback to be called when the operation is executed.
|
|
10
|
+
* @param {'find' | 'find-one' | 'count' | 'update-one' | 'insert-one' | 'remove-one' | 'aggregate'} operation - The operation to be triggered. Supported operations are: 'find', 'find-one', 'count', 'update-one', 'insert-one', 'remove-one', 'aggregate'.
|
|
11
|
+
* @param {function({query: any, queryResult: any}): void} [callback=(context) => {}] - The callback to be called when the operation is executed. The callback function takes an object as parameter with two properties: 'query' and 'queryResult'.
|
|
12
|
+
* @constructor
|
|
12
13
|
*/
|
|
13
|
-
constructor(operation, callback = (
|
|
14
|
+
constructor(operation, callback = (context) => {}) {
|
|
14
15
|
this.operation = operation;
|
|
15
16
|
this.callback = callback;
|
|
16
17
|
}
|
package/src/class/directory.js
CHANGED
|
@@ -1,66 +1,65 @@
|
|
|
1
|
-
const fs = require(
|
|
2
|
-
const path = require(
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
3
|
|
|
4
|
-
function walk(dir, settings, done)
|
|
5
|
-
|
|
6
|
-
let results = [];
|
|
4
|
+
function walk(dir, settings, done) {
|
|
5
|
+
let results = [];
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
// Read director file and folders
|
|
8
|
+
fs.readdir(dir, function (err, list) {
|
|
9
|
+
if (err) return done(err, results);
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
var pending = list.length;
|
|
12
|
+
if (!pending) return done(null, results);
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
var fileNameKey = true;
|
|
14
|
+
list.forEach(function (file) {
|
|
15
|
+
file = path.join(dir, file);
|
|
16
|
+
fs.stat(file, function (err, stat) {
|
|
17
|
+
// If directory, execute a recursive call
|
|
18
|
+
if (stat && stat.isDirectory()) {
|
|
19
|
+
// Add directory to array [comment if you need to remove the directories from the array]
|
|
20
|
+
// results.push(file);
|
|
21
|
+
walk(file, settings, function (err, res) {
|
|
22
|
+
results = results.concat(res);
|
|
23
|
+
if (!--pending) done(null, results);
|
|
24
|
+
});
|
|
25
|
+
} else {
|
|
26
|
+
// file filter
|
|
27
|
+
var extension = path.extname(file);
|
|
28
|
+
var fileName = path.basename(file).split(".")[0];
|
|
29
|
+
var fileNameKey = true;
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
// name filter
|
|
32
|
+
if (settings.name && settings.name === fileName) fileNameKey = true;
|
|
33
|
+
else fileNameKey = false;
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
// extension filter
|
|
36
|
+
if (settings.filter && fileNameKey) {
|
|
37
|
+
settings.filter.forEach(function (element) {
|
|
38
|
+
if (element.toLowerCase() === extension.toLowerCase())
|
|
39
|
+
results.push(file);
|
|
40
|
+
}, this);
|
|
41
|
+
}
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
// push any file if no option
|
|
44
|
+
else if (fileNameKey) results.push(file);
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
});
|
|
46
|
+
if (!--pending) done(null, results);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
52
49
|
});
|
|
53
|
-
};
|
|
50
|
+
});
|
|
51
|
+
}
|
|
54
52
|
|
|
55
53
|
function find(dir, settings) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
54
|
+
return new Promise((don, reject) => {
|
|
55
|
+
walk(dir, settings, (err, result) => {
|
|
56
|
+
if (err) reject(err);
|
|
57
|
+
else don(result);
|
|
61
58
|
});
|
|
59
|
+
});
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
module.exports = {
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
walk,
|
|
64
|
+
find,
|
|
65
|
+
};
|
package/src/class/security.js
CHANGED
|
@@ -17,7 +17,7 @@ class AccessDefinition {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* @typedef {('
|
|
20
|
+
* @typedef {('user_access'|'upload_file_access'|'remove_file_access'|'anonymous_access'|'advanced_settings')} PermissionType
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -53,18 +53,6 @@ class Permission {
|
|
|
53
53
|
* Each static getter returns a string that represents a specific type of permission.
|
|
54
54
|
*/
|
|
55
55
|
class PermissionTypes {
|
|
56
|
-
/**
|
|
57
|
-
* Create permission types.
|
|
58
|
-
* Each property represents a specific type of permission.
|
|
59
|
-
*/
|
|
60
|
-
constructor() {
|
|
61
|
-
this.god_access = "god_access"; // Represents god access permission type
|
|
62
|
-
this.user_access = "user_access"; // Represents user access permission type
|
|
63
|
-
this.upload_file_access = "upload_file_access"; // Represents upload file access permission type
|
|
64
|
-
this.remove_file_access = "remove_file_access"; // Represents remove file access permission type
|
|
65
|
-
this.anonymous_access = "anonymous_access"; // Represents anonymous access permission type
|
|
66
|
-
}
|
|
67
|
-
|
|
68
56
|
/**
|
|
69
57
|
* Get the string representing god access permission type.
|
|
70
58
|
* @return {string} The god access permission type.
|
|
@@ -73,6 +61,14 @@ class PermissionTypes {
|
|
|
73
61
|
return "god_access";
|
|
74
62
|
}
|
|
75
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Get the string representing advanced settings permission type.
|
|
66
|
+
* @return {string} The advanced settings permission type.
|
|
67
|
+
*/
|
|
68
|
+
static get advanced_settings() {
|
|
69
|
+
return "advanced_settings";
|
|
70
|
+
}
|
|
71
|
+
|
|
76
72
|
/**
|
|
77
73
|
* Get the string representing user access permission type.
|
|
78
74
|
* @return {string} The user access permission type.
|
|
@@ -96,13 +92,31 @@ class PermissionTypes {
|
|
|
96
92
|
static get remove_file_access() {
|
|
97
93
|
return "remove_file_access";
|
|
98
94
|
}
|
|
95
|
+
}
|
|
99
96
|
|
|
97
|
+
class PermissionGroup {
|
|
100
98
|
/**
|
|
101
|
-
*
|
|
102
|
-
* @
|
|
99
|
+
* Create a permission group.
|
|
100
|
+
* @param {Object} options - The options for the permission group.
|
|
101
|
+
* @param {string} options.title - The title of the permission group.
|
|
102
|
+
* @param {boolean} [options.isDefault=false] - If true, the permission group is the default permission group.
|
|
103
|
+
* @param {boolean} [options.isAnonymous=false] - If true, the permission group is the anonymous permission group.
|
|
104
|
+
* @param {Array.<PermissionType>} [options.validPermissionTypes=[]] - The valid permission types of the permission group.
|
|
105
|
+
* @return {PermissionGroup} The created permission group.
|
|
103
106
|
*/
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
constructor({
|
|
108
|
+
title,
|
|
109
|
+
isDefault = false,
|
|
110
|
+
isAnonymous = false,
|
|
111
|
+
validPermissionTypes = [],
|
|
112
|
+
}) {
|
|
113
|
+
//
|
|
114
|
+
this.title = title;
|
|
115
|
+
|
|
116
|
+
this.isDefault = isDefault;
|
|
117
|
+
this.isAnonymous = isAnonymous;
|
|
118
|
+
|
|
119
|
+
this.validPermissionTypes = validPermissionTypes;
|
|
106
120
|
}
|
|
107
121
|
}
|
|
108
122
|
|
|
@@ -122,5 +136,6 @@ module.exports = {
|
|
|
122
136
|
AccessDefinition,
|
|
123
137
|
Permission,
|
|
124
138
|
PermissionTypes,
|
|
139
|
+
PermissionGroup,
|
|
125
140
|
AccessTypes,
|
|
126
141
|
};
|
|
@@ -13,24 +13,21 @@ class TriggerOperator {
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Call a trigger
|
|
16
|
-
* @param {
|
|
16
|
+
* @param {'find' | 'find-one' | 'count' | 'update-one' | 'insert-one' | 'remove-one' | 'aggregate'} operation operation name
|
|
17
17
|
* @param {string} database database name
|
|
18
18
|
* @param {string} collection collection name
|
|
19
19
|
* @param {string} data
|
|
20
20
|
*/
|
|
21
21
|
call(operation, database, collection, data) {
|
|
22
|
-
let result;
|
|
23
|
-
|
|
24
22
|
this.triggers.forEach((trigger) => {
|
|
25
23
|
if (
|
|
26
24
|
operation == trigger.operation &&
|
|
27
25
|
database == trigger.database &&
|
|
28
|
-
collection == trigger.collection
|
|
26
|
+
collection == trigger.collection &&
|
|
27
|
+
trigger.callback
|
|
29
28
|
)
|
|
30
|
-
|
|
29
|
+
trigger.callback(data);
|
|
31
30
|
});
|
|
32
|
-
|
|
33
|
-
return result;
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
static get instance() {
|
package/src/class/user.js
CHANGED
|
@@ -1,97 +1,112 @@
|
|
|
1
|
-
|
|
1
|
+
const { config } = require("../config");
|
|
2
|
+
let validateObject = require("./validator");
|
|
2
3
|
|
|
3
4
|
module.exports = class User {
|
|
5
|
+
constructor(id, permissionGroup, phone, email, password, type, model) {
|
|
6
|
+
this.id = id;
|
|
7
|
+
this.permissionGroup = permissionGroup;
|
|
8
|
+
this.email = email;
|
|
9
|
+
this.phone = phone;
|
|
10
|
+
this.password = password;
|
|
11
|
+
this.type = type;
|
|
12
|
+
this.dbModel = model;
|
|
13
|
+
}
|
|
4
14
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.email = email;
|
|
10
|
-
this.phone = phone;
|
|
11
|
-
this.password = password;
|
|
12
|
-
this.type = type;
|
|
13
|
-
this.dbModel = model;
|
|
14
|
-
}
|
|
15
|
+
getBrief() {
|
|
16
|
+
const permissionGroup = config.permissionGroups.find(
|
|
17
|
+
(group) => group.title == this.permissionGroup
|
|
18
|
+
);
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
type : this.type,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return brief;
|
|
27
|
-
}
|
|
20
|
+
const brief = {
|
|
21
|
+
id: this.id,
|
|
22
|
+
permissionGroup: permissionGroup,
|
|
23
|
+
phone: this.phone,
|
|
24
|
+
email: this.email,
|
|
25
|
+
type: this.type,
|
|
26
|
+
};
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if(detail.phone) this.phone = detail.phone;
|
|
32
|
-
if(detail.email) this.email = detail.email;
|
|
33
|
-
if(detail.password) this.password = detail.password;
|
|
34
|
-
}
|
|
28
|
+
return brief;
|
|
29
|
+
}
|
|
35
30
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
setNewDetail(detail) {
|
|
32
|
+
if (detail.phone) this.phone = detail.phone;
|
|
33
|
+
if (detail.email) this.email = detail.email;
|
|
34
|
+
if (detail.password) this.password = detail.password;
|
|
35
|
+
}
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
hasPermission(permissionField) {
|
|
38
|
+
const permissionGroup = config.permissionGroups.find(
|
|
39
|
+
(group) => group.title == this.permissionGroup
|
|
40
|
+
);
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
return key;
|
|
45
|
-
}
|
|
42
|
+
if (permissionGroup == null) return false;
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
this.mode['permission'] = this.permission;
|
|
50
|
-
this.mode['phone'] = this.phone;
|
|
51
|
-
this.mode['email'] = this.email;
|
|
52
|
-
this.mode['password'] = this.password;
|
|
44
|
+
let key = false;
|
|
53
45
|
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
for (let i = 0; i < permissionGroup.validPermissionTypes.length; i++) {
|
|
47
|
+
const userPermissionType = permissionGroup.validPermissionTypes[i];
|
|
56
48
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// check required fields
|
|
62
|
-
let isValidData = validateObject(model, 'fullname email password permission');
|
|
63
|
-
if(!isValidData)
|
|
64
|
-
reject(User.notValid(detail));
|
|
65
|
-
|
|
66
|
-
let id = model.id;
|
|
67
|
-
let permission = model.permission;
|
|
68
|
-
let phone = model.phone;
|
|
69
|
-
let email = model.email;
|
|
70
|
-
let password = model.password;
|
|
71
|
-
let type = model.type;
|
|
72
|
-
|
|
73
|
-
//create user
|
|
74
|
-
let newUser = new User(id, permission, phone, email, password, type, model);
|
|
75
|
-
done(newUser);
|
|
76
|
-
});
|
|
49
|
+
if (userPermissionType == permissionField) {
|
|
50
|
+
key = true;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
77
53
|
}
|
|
78
54
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return new Promise( async (done, reject) =>
|
|
82
|
-
{
|
|
83
|
-
//create user
|
|
84
|
-
await new model(detail).save()
|
|
85
|
-
.then(newUser =>
|
|
86
|
-
done(User.loadFromModel(newUser)))
|
|
87
|
-
.catch(reject);
|
|
88
|
-
});
|
|
89
|
-
}
|
|
55
|
+
return key;
|
|
56
|
+
}
|
|
90
57
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
58
|
+
async save() {
|
|
59
|
+
this.mode["permissionGroup"] = this.permissionGroup;
|
|
60
|
+
this.mode["phone"] = this.phone;
|
|
61
|
+
this.mode["email"] = this.email;
|
|
62
|
+
this.mode["password"] = this.password;
|
|
63
|
+
|
|
64
|
+
await mode.save();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static loadFromModel(model) {
|
|
68
|
+
return new Promise((done, reject) => {
|
|
69
|
+
// check required fields
|
|
70
|
+
let isValidData = validateObject(
|
|
71
|
+
model,
|
|
72
|
+
"fullname email password permission"
|
|
73
|
+
);
|
|
74
|
+
if (!isValidData) reject(User.notValid(detail));
|
|
75
|
+
|
|
76
|
+
let id = model.id;
|
|
77
|
+
let permissionGroup = model.permissionGroup;
|
|
78
|
+
let phone = model.phone;
|
|
79
|
+
let email = model.email;
|
|
80
|
+
let password = model.password;
|
|
81
|
+
let type = model.type;
|
|
82
|
+
|
|
83
|
+
//create user
|
|
84
|
+
let newUser = new User(
|
|
85
|
+
id,
|
|
86
|
+
permissionGroup,
|
|
87
|
+
phone,
|
|
88
|
+
email,
|
|
89
|
+
password,
|
|
90
|
+
type,
|
|
91
|
+
model
|
|
92
|
+
);
|
|
93
|
+
done(newUser);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static createFromModel(model, detail) {
|
|
98
|
+
return new Promise(async (done, reject) => {
|
|
99
|
+
//create user
|
|
100
|
+
await new model(detail)
|
|
101
|
+
.save()
|
|
102
|
+
.then((newUser) => done(User.loadFromModel(newUser)))
|
|
103
|
+
.catch(reject);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static notValid(object) {
|
|
108
|
+
let error = `user detail are not valid ${object}`;
|
|
109
|
+
console.error(error);
|
|
110
|
+
return error;
|
|
111
|
+
}
|
|
112
|
+
};
|