@modular-rest/server 1.6.2 → 1.6.4

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.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modular-rest/server",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
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": {
@@ -1,21 +1,31 @@
1
- const DataProvider = require('../services/data_provider/service');
1
+ const DataProvider = require("../services/data_provider/service");
2
2
 
3
3
  function createPermissions() {
4
- let model = DataProvider.getCollection('cms', 'permission');
5
-
6
- return new Promise(async (done, reject) => {
4
+ let model = DataProvider.getCollection("cms", "permission");
7
5
 
6
+ return new Promise(async (done, reject) => {
8
7
  // create customer permission
9
- let isAnonymousExisted = await model.countDocuments({ title: 'anonymous' }).exec().catch(reject);
10
- let isCoustomerExisted = await model.countDocuments({ title: 'customer' }).exec().catch(reject);
11
- let isAdministratorExisted = await model.countDocuments({ title: 'administrator' }).exec().catch(reject);
8
+ let isAnonymousExisted = await model
9
+ .countDocuments({ title: "anonymous" })
10
+ .exec()
11
+ .catch(reject);
12
+ let isCoustomerExisted = await model
13
+ .countDocuments({ title: "customer" })
14
+ .exec()
15
+ .catch(reject);
16
+ let isAdministratorExisted = await model
17
+ .countDocuments({ title: "administrator" })
18
+ .exec()
19
+ .catch(reject);
12
20
 
13
21
  if (!isAnonymousExisted) {
14
22
  await new model({
15
23
  anonymous_access: true,
16
24
  isAnonymous: true,
17
- title: 'anonymous',
18
- }).save().catch(reject);
25
+ title: "anonymous",
26
+ })
27
+ .save()
28
+ .catch(reject);
19
29
  }
20
30
 
21
31
  if (!isCoustomerExisted) {
@@ -25,8 +35,10 @@ function createPermissions() {
25
35
  upload_file_access: true,
26
36
  remove_file_access: true,
27
37
  isDefault: true,
28
- title: 'customer',
29
- }).save().catch(reject);
38
+ title: "customer",
39
+ })
40
+ .save()
41
+ .catch(reject);
30
42
  }
31
43
 
32
44
  if (!isAdministratorExisted) {
@@ -36,50 +48,61 @@ function createPermissions() {
36
48
  anonymous_access: true,
37
49
  upload_file_access: true,
38
50
  remove_file_access: true,
39
- title: 'administrator',
40
- }).save().catch(reject);
51
+ title: "administrator",
52
+ })
53
+ .save()
54
+ .catch(reject);
41
55
  }
42
56
 
43
57
  done();
44
58
  });
45
-
46
59
  }
47
60
 
48
- function createAdminUser({ email, password }) {
49
- let permissionModel = DataProvider.getCollection('cms', 'permission');
50
- let authModel = DataProvider.getCollection('cms', 'auth');
61
+ async function createAdminUser({ email, password }) {
62
+ let permissionModel = DataProvider.getCollection("cms", "permission");
63
+ let authModel = DataProvider.getCollection("cms", "auth");
51
64
 
52
- return new Promise(async (done, reject) => {
53
- let isAnonymousExisted = await authModel.countDocuments({ type: 'anonymous' }).exec().catch(reject);
54
- let isAdministratorExisted = await authModel.countDocuments({ type: 'user', email: email }).exec().catch(reject);
65
+ try {
66
+ let isAnonymousExisted = await authModel
67
+ .countDocuments({ type: "anonymous" })
68
+ .exec();
55
69
 
56
- let anonymousPermission = await permissionModel.findOne({ title: 'anonymous' }).exec().catch(reject);
57
- let administratorPermission = await permissionModel.findOne({ title: 'administrator' }).exec().catch(reject);
70
+ let isAdministratorExisted = await authModel
71
+ .countDocuments({ type: "user", email: email })
72
+ .exec();
58
73
 
59
- if (!isAnonymousExisted) {
74
+ let anonymousPermission = await permissionModel
75
+ .findOne({ title: "anonymous" })
76
+ .exec();
77
+
78
+ let administratorPermission = await permissionModel
79
+ .findOne({ title: "administrator" })
80
+ .exec();
81
+
82
+ if (isAnonymousExisted == 0) {
60
83
  await new authModel({
61
84
  permission: anonymousPermission._id,
62
- email: '',
63
- phone: '',
64
- password: '',
65
- type: 'anonymous',
66
- }).save().catch(reject);
85
+ email: "",
86
+ phone: "",
87
+ password: "",
88
+ type: "anonymous",
89
+ }).save();
67
90
  }
68
91
 
69
- if (!isAdministratorExisted) {
92
+ if (isAdministratorExisted == 0) {
70
93
  await new authModel({
71
94
  permission: administratorPermission._id,
72
95
  email: email,
73
96
  password: password,
74
- type: 'user'
75
- }).save().catch(reject);
97
+ type: "user",
98
+ }).save();
76
99
  }
77
-
78
- done();
79
- });
100
+ } catch (e) {
101
+ return Promise.reject(e);
102
+ }
80
103
  }
81
104
 
82
105
  module.exports = {
83
106
  createPermissions,
84
107
  createAdminUser,
85
- };
108
+ };
@@ -35,38 +35,14 @@ let authSchema = new Schema({
35
35
  type: { type: String, default: "user", enum: ["user", "anonymous"] },
36
36
  });
37
37
  authSchema.index({ email: 1 }, { unique: true });
38
-
39
- authSchema
40
- .virtual("base64Password")
41
- .get(function () {
42
- return Buffer.from(this.password, "base64").toString("utf-8");
43
- })
44
- .set(function (value) {
45
- this.password = Buffer.from(value).toString("base64");
46
- });
47
-
48
- // Middleware for encoding password on save and init
49
- authSchema.pre("save", function (next) {
38
+ authSchema.pre(["save", "updateOne"], function (next) {
50
39
  // Encode the password before saving
51
40
  if (this.isModified("password")) {
52
- this.base64Password = this.password;
41
+ this.password = Buffer.from(this.password).toString("base64");
53
42
  }
54
43
  next();
55
44
  });
56
45
 
57
- authSchema.pre("init", function (next) {
58
- // Decode the password on init
59
- this.password = this.base64Password;
60
- next();
61
- });
62
-
63
- // Middleware for decoding password on findOne
64
- authSchema.post("findOne", function (doc) {
65
- if (this._conditions.password) {
66
- this._conditions.password = Buffer.from(value).toString("base64");
67
- }
68
- });
69
-
70
46
  module.exports = [
71
47
  new CollectionDefinition({
72
48
  db: "cms",
@@ -1,271 +1,275 @@
1
- let User = require('../../class/user');
2
- const DataProvider = require('../data_provider/service')
3
- const JWT = require('../jwt/service')
1
+ let User = require("../../class/user");
2
+ const DataProvider = require("../data_provider/service");
3
+ const JWT = require("../jwt/service");
4
4
 
5
5
  class UserManager {
6
-
7
- constructor() {
8
- this.tempIds = {};
9
- }
10
-
11
- /**
12
- *
13
- * @param {function} method a method that return random verification code
14
- */
15
- setCustomVerificationCodeGeneratorMethod(method) {
16
- this.verificationCodeGeneratorMethod = method
17
- }
18
-
19
- generateVerificationCode(id, idType) {
20
-
21
- if (this.verificationCodeGeneratorMethod)
22
- return this.verificationCodeGeneratorMethod(id, idType)
23
-
24
- // this is default code
25
- return '123'
26
- }
27
-
28
-
29
- /**
30
- * Get a user by its Id.
31
- *
32
- * @param {string} id userid
33
- */
34
- getUserById(id) {
35
- return new Promise(async (done, reject) => {
36
- let userModel = DataProvider.getCollection('cms', 'auth');
37
-
38
- let userDoc = await userModel.findOne({ '_id': id }).select({ password: 0 })
39
- .populate('permission').exec().catch(reject);
40
-
41
- if (!userDoc) reject('user not found');
42
-
43
- let user = User.loadFromModel(userDoc);
44
- done(user);
45
- })
46
- }
47
-
48
- /**
49
- * Get user by token.
50
- *
51
- * @param {string} token auth token
52
- */
53
- getUserByToken(token) {
54
- return JWT.main.verify(token)
55
- .then(async payload => {
56
- let user = payload;
57
- let permission = await DataProvider.getCollection('cms', 'permission')
58
- .findOne({ _id: user.permission }).exec().then();
59
-
60
- if (!permission) throw ('user has a wrong permission');
61
-
62
- user.permission = permission;
63
- return user;
64
- });
65
- }
66
-
67
- /**
68
- * Define whether or not verification code is valid.
69
- *
70
- * @param {string} id auth id phone|email
71
- * @param {string} code verification code
72
- */
73
- isCodeValid(id, code) {
74
- let key = false;
75
-
76
- if (this.tempIds.hasOwnProperty(id) && this.tempIds[id].code.toString() === code.toString())
77
- key = true;
78
-
79
- return key;
80
- }
81
-
82
- /**
83
- * Login and return user token.
84
- *
85
- * @param {string} id auth id phone|email
86
- * @param {string} idType auth type phone|email
87
- * @param {string} password
88
- */
89
- loginUser(id = '', idType = '', password = '') {
90
- let token;
91
-
92
- return new Promise(async (done, reject) => {
93
-
94
- // Get user model
95
- let userModel = DataProvider.getCollection('cms', 'auth');
96
-
97
- /**
98
- * Setup query to find by phone or email
99
- */
100
- let query = { 'password': password, type: "user" };
101
-
102
- if (idType == 'phone') query['phone'] = id;
103
- else if (idType == 'email') query['email'] = id;
104
-
105
- // Get from database
106
- let gottenFromDB = await userModel
107
- .findOne(query).populate('permission')
108
- .exec().catch(reject);
109
-
110
- if (!gottenFromDB) reject('user not found');
111
-
112
- // Token
113
- else {
114
-
115
- // Load user
116
- let user = await User.loadFromModel(gottenFromDB)
117
- .then().catch(reject);
118
-
119
- // Get token payload
120
- // This is some information about the user.
121
- let payload = user.getBrief();
122
-
123
- // Generate json web token
124
- token = await JWT.main.sign(payload)
125
- .then().catch(reject);
126
-
127
- done(token);
128
- }
129
- });
130
- }
131
-
132
- /**
133
- * Login as anonymous user
134
- */
135
- loginAnonymous() {
136
- let token;
137
-
138
- return new Promise(async (done, reject) => {
139
-
140
- // Get user model
141
- let userModel = DataProvider.getCollection('cms', 'auth');
142
-
143
- // Setup query
144
- let query = { 'type': 'anonymous' };
145
-
146
- // Get from database
147
- let gottenFromDB = await userModel
148
- .findOne(query).populate('permission')
149
- .exec().then().catch(reject);
150
-
151
- // Create a new anonymous user if it doesn't exist.
152
- // There are only one anonymous user in the database
153
- // and every guest token being generated from it.
154
- if (!gottenFromDB) {
155
- let newUserId = await this.registerUser({ 'type': 'anonymous' }).catch(reject);
156
- gottenFromDB = await this.getUserById(newUserId).catch(reject);
157
- }
158
-
159
- // load User
160
- let user = await User.loadFromModel(gottenFromDB)
161
- .then().catch(reject);
162
-
163
- // Get token payload
164
- // This is some information about the user.
165
- let payload = user.getBrief();
166
-
167
- // Generate json web token
168
- token = await JWT.main.sign(payload)
169
- .then().catch(reject);
170
-
171
- done(token);
172
- });
173
- }
174
-
175
- /**
176
- * Store user email|phone temporarily in memory.
177
- *
178
- * @param {string} id id is username or phone number
179
- * @param {string} type type is the type of id
180
- * @param {string} code code is a string being sent to user and he/she must return it back.
181
- */
182
- registerTemporaryID(id, type, code) {
183
- this.tempIds[id] = { 'id': id, 'type': type, 'code': code };
184
- }
185
-
186
- async submitPasswordForTemporaryID(id, password, code) {
187
- let key = false;
188
-
189
- // If user email|phone has already stored
190
- // a new user being created
191
- if (
192
- this.tempIds.hasOwnProperty(id) &&
193
- this.tempIds[id].code.toString() == code.toString()
194
- ) {
195
-
196
- let authDetail = { 'password': password };
197
-
198
- if (this.tempIds[id].type == 'phone')
199
- authDetail['phone'] = id;
200
- else if (this.tempIds[id].type == 'email')
201
- authDetail['email'] = id;
202
-
203
- await this.registerUser(authDetail)
204
- .then(() => key = true)
205
- .catch((e) => console.log(e));
206
- }
207
-
208
- delete this.tempIds[id];
209
- return key;
6
+ constructor() {
7
+ this.tempIds = {};
8
+ }
9
+
10
+ /**
11
+ *
12
+ * @param {function} method a method that return random verification code
13
+ */
14
+ setCustomVerificationCodeGeneratorMethod(method) {
15
+ this.verificationCodeGeneratorMethod = method;
16
+ }
17
+
18
+ generateVerificationCode(id, idType) {
19
+ if (this.verificationCodeGeneratorMethod)
20
+ return this.verificationCodeGeneratorMethod(id, idType);
21
+
22
+ // this is default code
23
+ return "123";
24
+ }
25
+
26
+ /**
27
+ * Get a user by its Id.
28
+ *
29
+ * @param {string} id userid
30
+ */
31
+ getUserById(id) {
32
+ return new Promise(async (done, reject) => {
33
+ let userModel = DataProvider.getCollection("cms", "auth");
34
+
35
+ let userDoc = await userModel
36
+ .findOne({ _id: id })
37
+ .select({ password: 0 })
38
+ .populate("permission")
39
+ .exec()
40
+ .catch(reject);
41
+
42
+ if (!userDoc) reject("user not found");
43
+
44
+ let user = User.loadFromModel(userDoc);
45
+ done(user);
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Get user by token.
51
+ *
52
+ * @param {string} token auth token
53
+ */
54
+ getUserByToken(token) {
55
+ return JWT.main.verify(token).then(async (payload) => {
56
+ let user = payload;
57
+ let permission = await DataProvider.getCollection("cms", "permission")
58
+ .findOne({ _id: user.permission })
59
+ .exec()
60
+ .then();
61
+
62
+ if (!permission) throw "user has a wrong permission";
63
+
64
+ user.permission = permission;
65
+ return user;
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Define whether or not verification code is valid.
71
+ *
72
+ * @param {string} id auth id phone|email
73
+ * @param {string} code verification code
74
+ */
75
+ isCodeValid(id, code) {
76
+ let key = false;
77
+
78
+ if (
79
+ this.tempIds.hasOwnProperty(id) &&
80
+ this.tempIds[id].code.toString() === code.toString()
81
+ )
82
+ key = true;
83
+
84
+ return key;
85
+ }
86
+
87
+ /**
88
+ * Login and return user token.
89
+ *
90
+ * @param {string} id auth id phone|email
91
+ * @param {string} idType auth type phone|email
92
+ * @param {string} password
93
+ */
94
+ loginUser(id = "", idType = "", password = "") {
95
+ let token;
96
+
97
+ return new Promise(async (done, reject) => {
98
+ // Get user model
99
+ let userModel = DataProvider.getCollection("cms", "auth");
100
+
101
+ /**
102
+ * Setup query to find by phone or email
103
+ */
104
+ let query = {
105
+ password: Buffer.from(password).toString("base64"),
106
+ type: "user",
107
+ };
108
+
109
+ if (idType == "phone") query["phone"] = id;
110
+ else if (idType == "email") query["email"] = id;
111
+
112
+ // Get from database
113
+ let gottenFromDB = await userModel
114
+ .findOne(query)
115
+ .populate("permission")
116
+ .exec()
117
+ .catch(reject);
118
+
119
+ if (!gottenFromDB) reject("user not found");
120
+ // Token
121
+ else {
122
+ // Load user
123
+ let user = await User.loadFromModel(gottenFromDB).then().catch(reject);
124
+
125
+ // Get token payload
126
+ // This is some information about the user.
127
+ let payload = user.getBrief();
128
+
129
+ // Generate json web token
130
+ token = await JWT.main.sign(payload).then().catch(reject);
131
+
132
+ done(token);
133
+ }
134
+ });
135
+ }
136
+
137
+ /**
138
+ * Login as anonymous user
139
+ */
140
+ loginAnonymous() {
141
+ let token;
142
+
143
+ return new Promise(async (done, reject) => {
144
+ // Get user model
145
+ let userModel = DataProvider.getCollection("cms", "auth");
146
+
147
+ // Setup query
148
+ let query = { type: "anonymous" };
149
+
150
+ // Get from database
151
+ let gottenFromDB = await userModel
152
+ .findOne(query)
153
+ .populate("permission")
154
+ .exec()
155
+ .then()
156
+ .catch(reject);
157
+
158
+ // Create a new anonymous user if it doesn't exist.
159
+ // There are only one anonymous user in the database
160
+ // and every guest token being generated from it.
161
+ if (!gottenFromDB) {
162
+ let newUserId = await this.registerUser({ type: "anonymous" }).catch(
163
+ reject
164
+ );
165
+ gottenFromDB = await this.getUserById(newUserId).catch(reject);
166
+ }
167
+
168
+ // load User
169
+ let user = await User.loadFromModel(gottenFromDB).then().catch(reject);
170
+
171
+ // Get token payload
172
+ // This is some information about the user.
173
+ let payload = user.getBrief();
174
+
175
+ // Generate json web token
176
+ token = await JWT.main.sign(payload).then().catch(reject);
177
+
178
+ done(token);
179
+ });
180
+ }
181
+
182
+ /**
183
+ * Store user email|phone temporarily in memory.
184
+ *
185
+ * @param {string} id id is username or phone number
186
+ * @param {string} type type is the type of id
187
+ * @param {string} code code is a string being sent to user and he/she must return it back.
188
+ */
189
+ registerTemporaryID(id, type, code) {
190
+ this.tempIds[id] = { id: id, type: type, code: code };
191
+ }
192
+
193
+ async submitPasswordForTemporaryID(id, password, code) {
194
+ let key = false;
195
+
196
+ // If user email|phone has already stored
197
+ // a new user being created
198
+ if (
199
+ this.tempIds.hasOwnProperty(id) &&
200
+ this.tempIds[id].code.toString() == code.toString()
201
+ ) {
202
+ let authDetail = { password: password };
203
+
204
+ if (this.tempIds[id].type == "phone") authDetail["phone"] = id;
205
+ else if (this.tempIds[id].type == "email") authDetail["email"] = id;
206
+
207
+ await this.registerUser(authDetail)
208
+ .then(() => (key = true))
209
+ .catch((e) => console.log(e));
210
210
  }
211
211
 
212
- async changePasswordForTemporaryID(id, password, code) {
213
- let key = false;
212
+ delete this.tempIds[id];
213
+ return key;
214
+ }
214
215
 
215
- if (this.tempIds.hasOwnProperty(id)
216
- && this.tempIds[id].code == code) {
217
- let query = {};
216
+ async changePasswordForTemporaryID(id, password, code) {
217
+ let key = false;
218
218
 
219
- if (this.tempIds[id].type == 'phone')
220
- query['phone'] = id;
221
- else if (this.tempIds[id].type == 'email')
222
- query['email'] = id;
219
+ if (this.tempIds.hasOwnProperty(id) && this.tempIds[id].code == code) {
220
+ let query = {};
223
221
 
224
- await this.changePassword(query, password)
225
- .then(() => key = true)
226
- .catch((e) => console.log(e));
227
- }
222
+ if (this.tempIds[id].type == "phone") query["phone"] = id;
223
+ else if (this.tempIds[id].type == "email") query["email"] = id;
228
224
 
229
- delete this.tempIds[id];
230
- return key;
225
+ await this.changePassword(query, password)
226
+ .then(() => (key = true))
227
+ .catch((e) => console.log(e));
231
228
  }
232
229
 
233
- registerUser(detail) {
234
- return new Promise(async (done, reject) => {
235
- // get default permission
236
- let permissionId;
237
- let perM = DataProvider.getCollection('cms', 'permission');
230
+ delete this.tempIds[id];
231
+ return key;
232
+ }
238
233
 
239
- let pQuery = { isDefault: true };
234
+ registerUser(detail) {
235
+ return new Promise(async (done, reject) => {
236
+ // get default permission
237
+ let permissionId;
238
+ let perM = DataProvider.getCollection("cms", "permission");
240
239
 
241
- if (detail.type == 'anonymous')
242
- pQuery = { isAnonymous: true };
240
+ let pQuery = { isDefault: true };
243
241
 
244
- await perM.findOne(pQuery, '_id').exec()
245
- .then((doc) => permissionId = doc._id)
246
- .catch(reject);
242
+ if (detail.type == "anonymous") pQuery = { isAnonymous: true };
247
243
 
248
- detail.permission = permissionId;
244
+ await perM
245
+ .findOne(pQuery, "_id")
246
+ .exec()
247
+ .then((doc) => (permissionId = doc._id))
248
+ .catch(reject);
249
249
 
250
- let authM = DataProvider.getCollection('cms', 'auth');
251
- return User.createFromModel(authM, detail)
252
- .then(newUser => {
253
- DataProvider.triggers
254
- .call('insertOne', 'cms', 'auth', { 'input': detail, 'output': newUser.dbModel });
250
+ detail.permission = permissionId;
255
251
 
256
- done(newUser.id);
257
- })
258
- .catch(reject);
259
- });
260
- }
252
+ let authM = DataProvider.getCollection("cms", "auth");
253
+ return User.createFromModel(authM, detail)
254
+ .then((newUser) => {
255
+ DataProvider.triggers.call("insertOne", "cms", "auth", {
256
+ input: detail,
257
+ output: newUser.dbModel,
258
+ });
261
259
 
262
- changePassword(query, newPass) {
263
- let update = { '$set': { 'password': newPass } };
264
- let authM = DataProvider.getCollection('cms', 'auth');
265
- return authM.updateOne(query, update).exec().then();
266
- }
260
+ done(newUser.id);
261
+ })
262
+ .catch(reject);
263
+ });
264
+ }
265
+
266
+ changePassword(query, newPass) {
267
+ let update = { $set: { password: newPass } };
268
+ let authM = DataProvider.getCollection("cms", "auth");
269
+ return authM.updateOne(query, update).exec().then();
270
+ }
267
271
  }
268
272
 
269
- UserManager.instance = new UserManager()
270
- module.exports.name = 'userManager';
271
- module.exports.main = UserManager.instance;
273
+ UserManager.instance = new UserManager();
274
+ module.exports.name = "userManager";
275
+ module.exports.main = UserManager.instance;