@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.
@@ -11,6 +11,7 @@ let permissionDefinitions = {};
11
11
 
12
12
  let triggers = require("../../class/trigger_operator");
13
13
  let TypeCasters = require("./typeCasters");
14
+ const { config } = require("../../config");
14
15
 
15
16
  /**
16
17
  *
@@ -66,8 +67,16 @@ function connectToDatabaseByCollectionDefinitionList(
66
67
  });
67
68
 
68
69
  // add trigger
69
- if (collectionDefinition.trigger != undefined) {
70
- triggers.addTrigger(collectionDefinition.trigger);
70
+ if (collectionDefinition.triggers != undefined) {
71
+ if (!Array.isArray(collectionDefinition.triggers)) {
72
+ throw "Triggers must be an array";
73
+ }
74
+
75
+ collectionDefinition.triggers.forEach((trigger) => {
76
+ trigger.database = collectionDefinition.database;
77
+ trigger.collection = collectionDefinition.collection;
78
+ triggers.addTrigger(trigger);
79
+ });
71
80
  }
72
81
  });
73
82
 
@@ -132,7 +141,11 @@ function _getPermissionList(db, collection, operationType) {
132
141
 
133
142
  if (!permissionDefinitions.hasOwnProperty(db)) return permissionList;
134
143
 
135
- permissionDefinition = permissionDefinitions[db][collection];
144
+ try {
145
+ permissionDefinition = permissionDefinitions[db][collection];
146
+ } catch (error) {
147
+ return permissionList;
148
+ }
136
149
 
137
150
  permissionDefinition.permissionList.forEach((permission) => {
138
151
  if (permission.onlyOwnData == true) {
@@ -147,30 +160,40 @@ function _getPermissionList(db, collection, operationType) {
147
160
  return permissionList;
148
161
  }
149
162
 
163
+ /**
164
+ * Check access to a collection.
165
+ * @param {string} db - The database name.
166
+ * @param {string} collection - The collection name.
167
+ * @param {string} operationType - The operation type.
168
+ * @param {object} queryOrDoc - The query or document.
169
+ * @param {import('../../class/user')} user - The user.
170
+ * @returns {boolean} The access result.
171
+ */
150
172
  function checkAccess(db, collection, operationType, queryOrDoc, user) {
151
173
  let key = false;
152
- const permissionList = _getPermissionList(db, collection, operationType);
153
174
 
154
- permissionList.forEach((permission) => {
155
- let permissionType = permission.type;
175
+ const collectionPermissionList = _getPermissionList(
176
+ db,
177
+ collection,
178
+ operationType
179
+ );
180
+
181
+ collectionPermissionList.forEach((permission) => {
182
+ const collectionPermissionType = permission.type;
156
183
 
157
184
  if (permission.onlyOwnData == true) {
158
185
  const userId = user.id;
159
186
 
160
187
  try {
161
- if (
162
- queryOrDoc[permission.ownerIdField].toString() === userId.toString()
163
- )
164
- key = true;
188
+ key =
189
+ queryOrDoc[permission.ownerIdField].toString() === userId.toString();
165
190
  } catch (error) {
166
191
  key = false;
167
192
  }
168
- } else if (operationType == AccessTypes.read) {
169
- if (permission.read && user.permission[permissionType] == true)
170
- key = true;
171
- } else if (operationType == AccessTypes.write) {
172
- if (permission.write && user.permission[permissionType] == true)
173
- key = true;
193
+ } else if (operationType == AccessTypes.read && permission.read) {
194
+ key = user.hasPermission(collectionPermissionType);
195
+ } else if (operationType == AccessTypes.write && permission.write) {
196
+ key = user.hasPermission(collectionPermissionType);
174
197
  }
175
198
  });
176
199
 
@@ -3,37 +3,17 @@ var Schema = mongoose.Schema;
3
3
 
4
4
  let CollectionDefinition = require("../../class/collection_definition");
5
5
  let { Permission, PermissionTypes } = require("../../class/security");
6
-
7
- /**
8
- * Permission schema
9
- *
10
- * This schema is generated dynamically
11
- * by combining default & custom permissions.
12
- */
13
- let permissionSchemaConstructorOption = {
14
- title: String,
15
- isAnonymous: { type: Boolean, default: false },
16
- isDefault: { type: Boolean, default: false },
17
- };
18
- Object.keys(new PermissionTypes()).forEach((key) => {
19
- let fieldOption = { type: Boolean, default: false };
20
- permissionSchemaConstructorOption[key] = fieldOption;
21
- });
22
-
23
- let permissionSchema = new Schema(permissionSchemaConstructorOption);
24
- permissionSchema.index({ title: 1 }, { unique: true });
6
+ const { config } = require("../../config");
7
+ const triggerOperator = require("./../../class/trigger_operator");
25
8
 
26
9
  let authSchema = new Schema({
27
- permission: {
28
- type: Schema.Types.ObjectId,
29
- ref: "permission",
30
- required: false,
31
- },
10
+ permissionGroup: String,
32
11
  email: String,
33
12
  phone: String,
34
13
  password: String,
35
14
  type: { type: String, default: "user", enum: ["user", "anonymous"] },
36
15
  });
16
+
37
17
  authSchema.index({ email: 1 }, { unique: true });
38
18
  authSchema.pre(["save", "updateOne"], function (next) {
39
19
  // Encode the password before saving
@@ -43,6 +23,46 @@ authSchema.pre(["save", "updateOne"], function (next) {
43
23
  next();
44
24
  });
45
25
 
26
+ authSchema.post("save", function (doc, next) {
27
+ triggerOperator.call("insert-one", "cms", "auth", {
28
+ query: null,
29
+ queryResult: doc._doc,
30
+ });
31
+ next();
32
+ });
33
+
34
+ authSchema.post("findOneAndUpdate", function (doc, next) {
35
+ triggerOperator.call("update-one", "cms", "auth", {
36
+ query: null,
37
+ queryResult: doc._doc,
38
+ });
39
+ next();
40
+ });
41
+
42
+ authSchema.post("updateOne", function (result, next) {
43
+ triggerOperator.call("update-one", "cms", "auth", {
44
+ query: null,
45
+ queryResult: doc._doc,
46
+ });
47
+ next();
48
+ });
49
+
50
+ authSchema.post("findOneAndDelete", function (doc, next) {
51
+ triggerOperator.call("remove-one", "cms", "auth", {
52
+ query: null,
53
+ queryResult: doc._doc,
54
+ });
55
+ next();
56
+ });
57
+
58
+ authSchema.post("deleteOne", function (result, next) {
59
+ triggerOperator.call("remove-one", "cms", "auth", {
60
+ query: null,
61
+ queryResult: doc._doc,
62
+ });
63
+ next();
64
+ });
65
+
46
66
  module.exports = [
47
67
  new CollectionDefinition({
48
68
  db: "cms",
@@ -55,18 +75,6 @@ module.exports = [
55
75
  write: true,
56
76
  }),
57
77
  ],
58
- }),
59
-
60
- new CollectionDefinition({
61
- db: "cms",
62
- collection: "permission",
63
- schema: permissionSchema,
64
- permissions: [
65
- new Permission({
66
- type: PermissionTypes.advanced_settings,
67
- read: true,
68
- write: true,
69
- }),
70
- ],
78
+ triggers: config.authTriggers || [],
71
79
  }),
72
80
  ];
@@ -0,0 +1,43 @@
1
+ const { config } = require("../../config");
2
+
3
+ function getDefaultPermissionGroups() {
4
+ const defaultPermissionGroups = config.permissionGroups.find(
5
+ (group) => group.isDefault
6
+ );
7
+
8
+ if (defaultPermissionGroups == null) {
9
+ throw new Error("Default permission group not found");
10
+ }
11
+
12
+ return defaultPermissionGroups;
13
+ }
14
+
15
+ function getDefaultAnonymousPermissionGroup() {
16
+ const anonymousPermission = config.permissionGroups.find(
17
+ (group) => group.isAnonymous
18
+ );
19
+
20
+ if (anonymousPermission == null) {
21
+ throw new Error("Anonymous permission group not found");
22
+ }
23
+
24
+ return anonymousPermission;
25
+ }
26
+
27
+ function getDefaultAdministratorPermissionGroup() {
28
+ const administratorPermission = config.permissionGroups.find(
29
+ (group) => group.title.toString() == "administrator"
30
+ );
31
+
32
+ if (administratorPermission == null) {
33
+ throw new Error("Administrator permission group not found");
34
+ }
35
+
36
+ return administratorPermission;
37
+ }
38
+
39
+ module.exports = {
40
+ getDefaultPermissionGroups,
41
+ getDefaultAnonymousPermissionGroup,
42
+ getDefaultAdministratorPermissionGroup,
43
+ };
@@ -1,6 +1,12 @@
1
- let User = require("../../class/user");
1
+ const User = require("../../class/user");
2
2
  const DataProvider = require("../data_provider/service");
3
3
  const JWT = require("../jwt/service");
4
+ const { getDefaultPermissionGroups } = require("./permissionManager");
5
+
6
+ /**
7
+ * import user type
8
+ * @typedef {import('../../class/user')} User
9
+ */
4
10
 
5
11
  class UserManager {
6
12
  constructor() {
@@ -42,7 +48,6 @@ class UserManager {
42
48
  let userDoc = await userModel
43
49
  .findOne({ _id: id })
44
50
  .select({ password: 0 })
45
- .populate("permission")
46
51
  .exec()
47
52
  .catch(reject);
48
53
 
@@ -75,7 +80,6 @@ class UserManager {
75
80
  let userDoc = await userModel
76
81
  .findOne(query)
77
82
  .select({ password: 0 })
78
- .populate("permission")
79
83
  .exec()
80
84
  .catch(reject);
81
85
 
@@ -93,21 +97,10 @@ class UserManager {
93
97
  * Get a user by their token.
94
98
  * @param {string} token - The token of the user.
95
99
  * @returns {Promise<User>} A promise that resolves to the user.
96
- * @throws {string} If the user has a wrong permission.
97
100
  */
98
- getUserByToken(token) {
99
- return JWT.main.verify(token).then(async (payload) => {
100
- let user = payload;
101
- let permission = await DataProvider.getCollection("cms", "permission")
102
- .findOne({ _id: user.permission })
103
- .exec()
104
- .then();
105
-
106
- if (!permission) throw "user has a wrong permission";
107
-
108
- user.permission = permission;
109
- return user;
110
- });
101
+ async getUserByToken(token) {
102
+ const { id } = await JWT.main.verify(token);
103
+ return this.getUserById(id);
111
104
  }
112
105
 
113
106
  /**
@@ -155,11 +148,7 @@ class UserManager {
155
148
  else if (idType == "email") query["email"] = id;
156
149
 
157
150
  // Get from database
158
- const gottenFromDB = await userModel
159
- .findOne(query)
160
- .populate("permission")
161
- .exec()
162
- .catch(reject);
151
+ const gottenFromDB = await userModel.findOne(query).exec().catch(reject);
163
152
 
164
153
  if (!gottenFromDB) reject("user not found");
165
154
  // Token
@@ -193,11 +182,7 @@ class UserManager {
193
182
  const query = { email: email };
194
183
 
195
184
  // Get from database
196
- const gottenFromDB = await userModel
197
- .findOne(query)
198
- .populate("permission")
199
- .exec()
200
- .catch(reject);
185
+ const gottenFromDB = await userModel.findOne(query).exec().catch(reject);
201
186
 
202
187
  if (!gottenFromDB) reject("user not found");
203
188
 
@@ -230,7 +215,6 @@ class UserManager {
230
215
  // Get from database
231
216
  let gottenFromDB = await userModel
232
217
  .findOne(query)
233
- .populate("permission")
234
218
  .exec()
235
219
  .then()
236
220
  .catch(reject);
@@ -333,20 +317,14 @@ class UserManager {
333
317
  registerUser(detail) {
334
318
  return new Promise(async (done, reject) => {
335
319
  // get default permission
336
- let permissionId;
337
- let perM = DataProvider.getCollection("cms", "permission");
338
-
339
- let pQuery = { isDefault: true };
340
-
341
- if (detail.type == "anonymous") pQuery = { isAnonymous: true };
342
-
343
- await perM
344
- .findOne(pQuery, "_id")
345
- .exec()
346
- .then((doc) => (permissionId = doc._id))
347
- .catch(reject);
320
+ if (!detail.permissionGroup) {
321
+ detail.permissionGroup = getDefaultPermissionGroups().title;
322
+ }
348
323
 
349
- detail.permission = permissionId;
324
+ if (!detail.permissionGroup) {
325
+ reject("default permission group not found");
326
+ return;
327
+ }
350
328
 
351
329
  let authM = DataProvider.getCollection("cms", "auth");
352
330
  return User.createFromModel(authM, detail)