@modular-rest/server 1.6.5 → 1.7.0

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.
@@ -1,38 +1,42 @@
1
1
  class TriggerOperator {
2
- constructor() {
3
- this.triggers = [];
4
- }
2
+ constructor() {
3
+ this.triggers = [];
4
+ }
5
5
 
6
- /**
7
- * add a collection trigger
8
- * @param {object} trigger DatabaseTrigger object
9
- */
10
- addTrigger(trigger) {
11
- this.triggers.push(trigger);
12
- }
6
+ /**
7
+ * add a collection trigger
8
+ * @param {object} trigger DatabaseTrigger object
9
+ */
10
+ addTrigger(trigger) {
11
+ this.triggers.push(trigger);
12
+ }
13
13
 
14
- /**
15
- * Call a trigger
16
- * @param {string} operation operation name
17
- * @param {string} database database name
18
- * @param {string} collection collection name
19
- * @param {string} data
20
- */
21
- call(operation, database, collection, data) {
22
- let result;
14
+ /**
15
+ * Call a trigger
16
+ * @param {string} operation operation name
17
+ * @param {string} database database name
18
+ * @param {string} collection collection name
19
+ * @param {string} data
20
+ */
21
+ call(operation, database, collection, data) {
22
+ let result;
23
23
 
24
- this.triggers.forEach(trigger => {
25
- if (
26
- operation == trigger.operation &&
27
- database == trigger.database &&
28
- collection == trigger.collection
29
- )
30
- result = trigger.callback(data.input, data.output);
31
- });
24
+ this.triggers.forEach((trigger) => {
25
+ if (
26
+ operation == trigger.operation &&
27
+ database == trigger.database &&
28
+ collection == trigger.collection
29
+ )
30
+ result = trigger.callback(data.input, data.output);
31
+ });
32
32
 
33
- return result;
34
- }
33
+ return result;
34
+ }
35
+
36
+ static get instance() {
37
+ return instance;
38
+ }
35
39
  }
36
40
 
37
- TriggerOperator.instance = new TriggerOperator();
38
- module.exports = TriggerOperator.instance;
41
+ const instance = new TriggerOperator();
42
+ module.exports = TriggerOperator.instance;
package/src/index.js CHANGED
@@ -14,44 +14,21 @@ const CollectionDefinition = require("./class/collection_definition");
14
14
  const Schemas = require("./class/db_schemas");
15
15
  const DatabaseTrigger = require("./class/database_trigger");
16
16
  const SecurityClass = require("./class/security");
17
-
18
17
  const middleware = require("./middlewares");
18
+ const userManager = require("./services/user_manager/service");
19
19
 
20
20
  module.exports = {
21
21
  createRest,
22
-
23
- //
24
- // Utilities
25
- //
26
22
  reply,
27
23
  TypeCasters,
28
-
29
- /**
30
- * @type {import('./class/paginator').create}
31
- */
32
24
  paginator,
33
-
34
- /**
35
- * @type {import('./class/validator')}
36
- */
37
25
  validator,
38
-
39
- /**
40
- * @type {import('./services/data_provider/service').getCollection}
41
- * @return {import('mongoose').Model} Mongoose model https://mongoosejs.com/docs/api/model.html
42
- */
43
26
  getCollection,
44
-
45
- //
46
- // Base class
47
- //
48
27
  CollectionDefinition,
49
28
  Schemas,
50
29
  Schema,
51
30
  DatabaseTrigger,
52
-
53
31
  ...SecurityClass,
54
-
55
- // Middlewares
56
32
  middleware,
33
+ userManager: userManager.main,
57
34
  };
@@ -1,4 +1,13 @@
1
+ /**
2
+ * Validator module
3
+ * @module class/validator
4
+ */
1
5
  let validateObject = require("./class/validator");
6
+
7
+ /**
8
+ * User manager service
9
+ * @module services/user_manager/service
10
+ */
2
11
  const userManager = require("./services/user_manager/service");
3
12
 
4
13
  /**
@@ -9,7 +18,7 @@ const userManager = require("./services/user_manager/service");
9
18
  * @param {Function} next - Koa next function
10
19
  * @returns {Promise<void>}
11
20
  */
12
- module.exports.auth = async (ctx, next) => {
21
+ async function auth(ctx, next) {
13
22
  let headers = ctx.header;
14
23
  let headersValidated = validateObject(headers, "authorization");
15
24
 
@@ -27,4 +36,8 @@ module.exports.auth = async (ctx, next) => {
27
36
  console.log(err);
28
37
  ctx.throw(err.status || 412, err.message);
29
38
  });
39
+ }
40
+
41
+ module.exports = {
42
+ auth,
30
43
  };
@@ -1,196 +1,193 @@
1
- let name = 'dataProvider';
2
- const colog = require('colog');
3
- let {
4
- AccessTypes,
5
- AccessDefinition
6
- } = require('../../class/security');
1
+ let name = "dataProvider";
2
+ const colog = require("colog");
3
+ let { AccessTypes, AccessDefinition } = require("../../class/security");
7
4
 
8
- const Mongoose = require('mongoose');
9
- Mongoose.set('useCreateIndex', true);
5
+ const Mongoose = require("mongoose");
6
+ Mongoose.set("useCreateIndex", true);
10
7
 
11
8
  let connections = {};
12
9
  let collections = {};
13
10
  let permissionDefinitions = {};
14
11
 
15
- let triggers = require('../../class/trigger_operator');
16
- let TypeCasters = require('./typeCasters');
12
+ let triggers = require("../../class/trigger_operator");
13
+ let TypeCasters = require("./typeCasters");
17
14
 
18
15
  /**
19
- *
16
+ *
20
17
  * @param {string} dbName database name
21
18
  * @param {array} CollectionDefinitionList an array of CollectionDefinition instance
22
19
  * @param {object} mongoOption
23
20
  * @param {string} mongoOption.dbPrefix
24
21
  * @param {string} mongoOption.mongoBaseAddress
25
22
  */
26
- function connectToDatabaseByCollectionDefinitionList(dbName, collectionDefinitionList = [], mongoOption) {
27
-
28
- return new Promise((done, reject) => {
29
- // Create db connection
30
- //
31
- const fullDbName = (mongoOption.dbPrefix || '') + dbName
32
- const connectionString = mongoOption.mongoBaseAddress + '/' + fullDbName;
33
-
34
- colog.info(`- Connecting to database ${connectionString}`)
35
-
36
- let connection = Mongoose.createConnection(connectionString, {
37
- ...mongoOption,
38
- useUnifiedTopology: true,
39
- useNewUrlParser: true,
40
- });
41
-
42
- // Store connection
43
- connections[dbName] = connection;
44
-
45
- // add db models from schemas
46
- collectionDefinitionList.forEach(collectionDefinition => {
47
-
48
- let collection = collectionDefinition.collection;
49
- let schema = collectionDefinition.schema;
50
-
51
- if (collections[dbName] == undefined)
52
- collections[dbName] = {};
53
-
54
- if (permissionDefinitions[dbName] == undefined)
55
- permissionDefinitions[dbName] = {};
56
-
57
- // create model from schema
58
- // and store in on global collection object
59
- let model = connection.model(collection, schema);
60
- collections[dbName][collection] = model
61
-
62
- // define Access Definition from component permissions
63
- // and store it on global access definition object
64
- permissionDefinitions[dbName][collection] = new AccessDefinition({
65
- database: dbName,
66
- collection: collection,
67
- permissionList: collectionDefinition.permissions
68
- });
69
-
70
- // add trigger
71
- if (collectionDefinition.trigger != undefined) {
72
- triggers.addTrigger(collectionDefinition.trigger);
73
- }
74
-
75
- })
76
-
77
- connection.on('connected', () => {
78
- colog.success(`- ${fullDbName} database has been connected`)
79
- done()
80
- });
81
- })
23
+ function connectToDatabaseByCollectionDefinitionList(
24
+ dbName,
25
+ collectionDefinitionList = [],
26
+ mongoOption
27
+ ) {
28
+ return new Promise((done, reject) => {
29
+ // Create db connection
30
+ //
31
+ const fullDbName = (mongoOption.dbPrefix || "") + dbName;
32
+ const connectionString = mongoOption.mongoBaseAddress + "/" + fullDbName;
33
+
34
+ colog.info(`- Connecting to database ${connectionString}`);
35
+
36
+ let connection = Mongoose.createConnection(connectionString, {
37
+ ...mongoOption,
38
+ useUnifiedTopology: true,
39
+ useNewUrlParser: true,
40
+ });
41
+
42
+ // Store connection
43
+ connections[dbName] = connection;
44
+
45
+ // add db models from schemas
46
+ collectionDefinitionList.forEach((collectionDefinition) => {
47
+ let collection = collectionDefinition.collection;
48
+ let schema = collectionDefinition.schema;
49
+
50
+ if (collections[dbName] == undefined) collections[dbName] = {};
51
+
52
+ if (permissionDefinitions[dbName] == undefined)
53
+ permissionDefinitions[dbName] = {};
54
+
55
+ // create model from schema
56
+ // and store in on global collection object
57
+ let model = connection.model(collection, schema);
58
+ collections[dbName][collection] = model;
59
+
60
+ // define Access Definition from component permissions
61
+ // and store it on global access definition object
62
+ permissionDefinitions[dbName][collection] = new AccessDefinition({
63
+ database: dbName,
64
+ collection: collection,
65
+ permissionList: collectionDefinition.permissions,
66
+ });
67
+
68
+ // add trigger
69
+ if (collectionDefinition.trigger != undefined) {
70
+ triggers.addTrigger(collectionDefinition.trigger);
71
+ }
72
+ });
73
+
74
+ connection.on("connected", () => {
75
+ colog.success(`- ${fullDbName} database has been connected`);
76
+ done();
77
+ });
78
+ });
82
79
  }
83
80
 
84
81
  /**
85
- *
82
+ *
86
83
  * @param {object} option
87
84
  * @param {array} option.list an array of CollectionDefinition instance
88
85
  * @param {object} option.mongoOption
89
86
  * @param {string} option.mongoOption.dbPrefix
90
87
  * @param {string} option.mongoOption.mongoBaseAddress
91
88
  */
92
- async function addCollectionDefinitionByList({
93
- list,
94
- mongoOption
95
- }) {
96
- let clusteredByDBName = {};
97
-
98
- // cluster list by their database name.
99
- list.forEach(collectionDefinition => {
100
- let database = collectionDefinition.database;
101
- if (!clusteredByDBName[database]) clusteredByDBName[database] = [];
102
- clusteredByDBName[database].push(collectionDefinition);
103
- })
104
-
105
- // connect to databases
106
- for (const dbName in clusteredByDBName) {
107
- if (clusteredByDBName.hasOwnProperty(dbName)) {
108
- const collectionDefinitionList = clusteredByDBName[dbName];
109
- await connectToDatabaseByCollectionDefinitionList(dbName, collectionDefinitionList, mongoOption);
110
- }
89
+ async function addCollectionDefinitionByList({ list, mongoOption }) {
90
+ let clusteredByDBName = {};
91
+
92
+ // cluster list by their database name.
93
+ list.forEach((collectionDefinition) => {
94
+ let database = collectionDefinition.database;
95
+ if (!clusteredByDBName[database]) clusteredByDBName[database] = [];
96
+ clusteredByDBName[database].push(collectionDefinition);
97
+ });
98
+
99
+ // connect to databases
100
+ for (const dbName in clusteredByDBName) {
101
+ if (clusteredByDBName.hasOwnProperty(dbName)) {
102
+ const collectionDefinitionList = clusteredByDBName[dbName];
103
+ await connectToDatabaseByCollectionDefinitionList(
104
+ dbName,
105
+ collectionDefinitionList,
106
+ mongoOption
107
+ );
111
108
  }
109
+ }
112
110
  }
113
111
 
112
+ /**
113
+ * Get a collection from a database.
114
+ * @param {string} db - The database name.
115
+ * @param {string} collection - The collection name.
116
+ * @returns {import('mongoose').Model} The found collection.
117
+ */
114
118
  function getCollection(db, collection) {
115
- let fountCollection;
119
+ let fountCollection;
116
120
 
117
- if (collections.hasOwnProperty(db)) {
118
- if (collections[db].hasOwnProperty(collection))
119
- fountCollection = collections[db][collection];
120
- }
121
+ if (collections.hasOwnProperty(db)) {
122
+ if (collections[db].hasOwnProperty(collection))
123
+ fountCollection = collections[db][collection];
124
+ }
121
125
 
122
- return fountCollection;
126
+ return fountCollection;
123
127
  }
124
128
 
125
129
  function _getPermissionList(db, collection, operationType) {
126
- let permissionList = [];
127
- let permissionDefinition;
128
-
129
- if (!permissionDefinitions.hasOwnProperty(db))
130
- return permissionList;
131
-
132
- permissionDefinition = permissionDefinitions[db][collection];
133
-
134
- permissionDefinition.permissionList.forEach(permission => {
135
- if (permission.onlyOwnData == true) {
136
- permissionList.push(permission);
137
- } else if (operationType == AccessTypes.read &&
138
- permission.read == true) {
139
- permissionList.push(permission);
140
- } else if (operationType == AccessTypes.write &&
141
- permission.write == true) {
142
- permissionList.push(permission);
143
- }
144
- });
130
+ let permissionList = [];
131
+ let permissionDefinition;
132
+
133
+ if (!permissionDefinitions.hasOwnProperty(db)) return permissionList;
145
134
 
146
- return permissionList;
135
+ permissionDefinition = permissionDefinitions[db][collection];
136
+
137
+ permissionDefinition.permissionList.forEach((permission) => {
138
+ if (permission.onlyOwnData == true) {
139
+ permissionList.push(permission);
140
+ } else if (operationType == AccessTypes.read && permission.read == true) {
141
+ permissionList.push(permission);
142
+ } else if (operationType == AccessTypes.write && permission.write == true) {
143
+ permissionList.push(permission);
144
+ }
145
+ });
146
+
147
+ return permissionList;
147
148
  }
148
149
 
149
150
  function checkAccess(db, collection, operationType, queryOrDoc, user) {
150
- let key = false;
151
- let permissionList = _getPermissionList(db, collection, operationType);
152
-
153
- permissionList.forEach(permission => {
154
- let permissionType = permission.type;
155
-
156
- if (permission.onlyOwnData == true) {
157
- let owner = queryOrDoc.owner;
158
- let userId = user.id;
159
-
160
- try {
161
- if (owner.toString() == userId.toString())
162
- key = true;
163
- } catch (error) {
164
- key = false;
165
- }
166
- } else if (operationType == AccessTypes.read) {
167
- if (permission.read &&
168
- user.permission[permissionType] == true)
169
- key = true;
170
- } else if (operationType == AccessTypes.write) {
171
-
172
- if (permission.write &&
173
- user.permission[permissionType] == true)
174
- key = true;
175
- }
176
- });
151
+ let key = false;
152
+ let permissionList = _getPermissionList(db, collection, operationType);
177
153
 
178
- return key;
179
- }
154
+ permissionList.forEach((permission) => {
155
+ let permissionType = permission.type;
180
156
 
181
- function getAsID(strId) {
182
- let id;
183
- try {
184
- id = Mongoose.Types.ObjectId(strId);
185
- } catch (e) {
186
- console.log('strId did not cast objectId', e);
157
+ if (permission.onlyOwnData == true) {
158
+ let owner = queryOrDoc.owner;
159
+ let userId = user.id;
160
+
161
+ try {
162
+ if (owner.toString() == userId.toString()) key = true;
163
+ } catch (error) {
164
+ key = false;
165
+ }
166
+ } else if (operationType == AccessTypes.read) {
167
+ if (permission.read && user.permission[permissionType] == true)
168
+ key = true;
169
+ } else if (operationType == AccessTypes.write) {
170
+ if (permission.write && user.permission[permissionType] == true)
171
+ key = true;
187
172
  }
173
+ });
188
174
 
189
- return id;
175
+ return key;
176
+ }
177
+
178
+ function getAsID(strId) {
179
+ let id;
180
+ try {
181
+ id = Mongoose.Types.ObjectId(strId);
182
+ } catch (e) {
183
+ console.log("strId did not cast objectId", e);
184
+ }
185
+
186
+ return id;
190
187
  }
191
188
 
192
189
  function performPopulateToQueryObject(queryObj, popArr = []) {
193
- /*
190
+ /*
194
191
  https://mongoosejs.com/docs/populate.html
195
192
  popArr must be contains this objects
196
193
  {
@@ -198,36 +195,35 @@ function performPopulateToQueryObject(queryObj, popArr = []) {
198
195
  select: 'name -_id',
199
196
  }
200
197
  */
201
- popArr.forEach(pop => queryObj.populate(pop));
202
- return queryObj;
198
+ popArr.forEach((pop) => queryObj.populate(pop));
199
+ return queryObj;
203
200
  }
204
201
 
205
202
  function performAdditionalOptionsToQueryObject(queryObj, options) {
206
- /**
207
- * https://mongoosejs.com/docs/api/query.html#query_Query-sort
208
- *
209
- * Options must be contain a method name and an argument of above methods.
210
- * {
211
- * sort: '-_id',
212
- * limit: 10,
213
- * }
214
- */
215
- Object.keys(options).forEach(method => {
216
- queryObj = queryObj[method](options[method]);
217
- })
218
-
219
- return queryObj;
203
+ /**
204
+ * https://mongoosejs.com/docs/api/query.html#query_Query-sort
205
+ *
206
+ * Options must be contain a method name and an argument of above methods.
207
+ * {
208
+ * sort: '-_id',
209
+ * limit: 10,
210
+ * }
211
+ */
212
+ Object.keys(options).forEach((method) => {
213
+ queryObj = queryObj[method](options[method]);
214
+ });
215
+
216
+ return queryObj;
220
217
  }
221
218
 
222
-
223
219
  module.exports = {
224
- name,
225
- getCollection,
226
- addCollectionDefinitionByList,
227
- checkAccess,
228
- getAsID,
229
- performPopulateToQueryObject,
230
- performAdditionalOptionsToQueryObject,
231
- triggers,
232
- TypeCasters,
233
- }
220
+ name,
221
+ getCollection,
222
+ addCollectionDefinitionByList,
223
+ checkAccess,
224
+ getAsID,
225
+ performPopulateToQueryObject,
226
+ performAdditionalOptionsToQueryObject,
227
+ triggers,
228
+ TypeCasters,
229
+ };