@modular-rest/server 1.11.13 → 1.12.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/.nvmrc +1 -0
- package/.prettierrc.json +9 -0
- package/.releaserc.json +24 -0
- package/README.md +79 -94
- package/dist/application.d.ts +29 -0
- package/dist/application.js +217 -0
- package/dist/class/cms_trigger.d.ts +61 -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 +84 -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 +112 -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/index.js +79 -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 +187 -0
- package/dist/services/data_provider/service.d.ts +131 -0
- package/dist/services/data_provider/service.js +252 -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 +67 -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 +628 -0
- package/docs/.keep +0 -0
- package/docs/system-access-type.md +26 -0
- package/package.json +58 -45
- package/src/application.ts +206 -0
- package/src/class/cms_trigger.ts +68 -0
- package/src/class/collection_definition.ts +134 -0
- package/src/class/combinator.ts +176 -0
- package/src/class/database_trigger.ts +99 -0
- package/src/class/db_schemas.ts +44 -0
- package/src/class/{directory.js → directory.ts} +40 -18
- package/src/class/paginator.ts +51 -0
- package/src/class/reply.ts +59 -0
- package/src/class/security.ts +250 -0
- package/src/class/trigger_operator.ts +142 -0
- package/src/class/user.ts +199 -0
- package/src/class/validator.ts +123 -0
- package/src/config.ts +121 -0
- package/src/defult-permissions.ts +31 -0
- package/src/events.ts +59 -0
- package/src/helper/data_insertion.ts +94 -0
- package/src/helper/presetup_services.ts +96 -0
- package/src/index.ts +146 -0
- package/src/middlewares.ts +75 -0
- package/src/play-test.ts +8 -0
- package/src/services/data_provider/router.ts +191 -0
- package/src/services/data_provider/service.ts +305 -0
- package/src/services/data_provider/typeCasters.ts +15 -0
- package/src/services/file/db.ts +29 -0
- package/src/services/file/router.ts +88 -0
- package/src/services/file/service.ts +387 -0
- package/src/services/functions/router.ts +34 -0
- package/src/services/functions/service.ts +203 -0
- package/src/services/jwt/router.ts +73 -0
- package/src/services/jwt/service.ts +139 -0
- package/src/services/user_manager/db.ts +87 -0
- package/src/services/user_manager/permissionManager.ts +49 -0
- package/src/services/user_manager/router.ts +193 -0
- package/src/services/user_manager/service.ts +698 -0
- package/tsconfig.json +16 -9
- package/typedoc.mjs +41 -0
- package/LICENSE +0 -21
- package/package-lock.json +0 -1373
- package/src/application.js +0 -239
- package/src/class/cms_trigger.js +0 -20
- package/src/class/collection_definition.js +0 -33
- package/src/class/combinator.js +0 -133
- package/src/class/database_trigger.js +0 -20
- package/src/class/db_schemas.js +0 -18
- package/src/class/paginator.js +0 -31
- package/src/class/reply.js +0 -37
- package/src/class/security.js +0 -141
- package/src/class/trigger_operator.js +0 -39
- package/src/class/user.js +0 -112
- package/src/class/validator.js +0 -91
- package/src/config.js +0 -67
- package/src/events.js +0 -15
- package/src/helper/data_insertion.js +0 -64
- package/src/helper/presetup_services.js +0 -31
- package/src/index.js +0 -66
- package/src/middlewares.js +0 -44
- package/src/services/data_provider/router.js +0 -552
- package/src/services/data_provider/service.js +0 -262
- package/src/services/data_provider/typeCasters.js +0 -10
- package/src/services/file/db.js +0 -29
- package/src/services/file/router.js +0 -92
- package/src/services/file/service.js +0 -231
- package/src/services/functions/router.js +0 -37
- package/src/services/functions/service.js +0 -74
- package/src/services/jwt/router.js +0 -82
- package/src/services/jwt/service.js +0 -37
- package/src/services/user_manager/db.js +0 -83
- package/src/services/user_manager/permissionManager.js +0 -43
- package/src/services/user_manager/router.js +0 -176
- package/src/services/user_manager/service.js +0 -377
- package/types/application.d.ts +0 -97
- package/types/class/cms_trigger.d.ts +0 -24
- package/types/class/collection_definition.d.ts +0 -36
- package/types/class/combinator.d.ts +0 -30
- package/types/class/database_trigger.d.ts +0 -28
- package/types/class/db_schemas.d.ts +0 -2
- package/types/class/directory.d.ts +0 -2
- package/types/class/paginator.d.ts +0 -8
- package/types/class/reply.d.ts +0 -8
- package/types/class/security.d.ts +0 -109
- package/types/class/trigger_operator.d.ts +0 -19
- package/types/class/user.d.ts +0 -24
- package/types/class/validator.d.ts +0 -9
- package/types/config.d.ts +0 -101
- package/types/events.d.ts +0 -7
- package/types/helper/data_insertion.d.ts +0 -4
- package/types/helper/presetup_services.d.ts +0 -5
- package/types/index.d.ts +0 -72
- package/types/middlewares.d.ts +0 -10
- package/types/services/data_provider/router.d.ts +0 -3
- package/types/services/data_provider/service.d.ts +0 -40
- package/types/services/data_provider/typeCasters.d.ts +0 -3
- package/types/services/file/db.d.ts +0 -3
- package/types/services/file/router.d.ts +0 -3
- package/types/services/file/service.d.ts +0 -81
- package/types/services/functions/router.d.ts +0 -3
- package/types/services/functions/service.d.ts +0 -23
- package/types/services/jwt/router.d.ts +0 -3
- package/types/services/jwt/service.d.ts +0 -10
- package/types/services/user_manager/db.d.ts +0 -3
- package/types/services/user_manager/permissionManager.d.ts +0 -3
- package/types/services/user_manager/router.d.ts +0 -3
- package/types/services/user_manager/service.d.ts +0 -131
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
let name = "dataProvider";
|
|
2
|
-
const colog = require("colog");
|
|
3
|
-
let {
|
|
4
|
-
AccessTypes,
|
|
5
|
-
AccessDefinition
|
|
6
|
-
} = require("../../class/security");
|
|
7
|
-
|
|
8
|
-
const Mongoose = require("mongoose");
|
|
9
|
-
Mongoose.set("useCreateIndex", true);
|
|
10
|
-
|
|
11
|
-
let connections = {};
|
|
12
|
-
let collections = {};
|
|
13
|
-
let permissionDefinitions = {};
|
|
14
|
-
|
|
15
|
-
let triggers = require("../../class/trigger_operator");
|
|
16
|
-
let TypeCasters = require("./typeCasters");
|
|
17
|
-
const {
|
|
18
|
-
config
|
|
19
|
-
} = require("../../config");
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
* @param {string} dbName database name
|
|
24
|
-
* @param {array} CollectionDefinitionList an array of CollectionDefinition instance
|
|
25
|
-
* @param {object} mongoOption
|
|
26
|
-
* @param {string} mongoOption.dbPrefix
|
|
27
|
-
* @param {string} mongoOption.mongoBaseAddress
|
|
28
|
-
*/
|
|
29
|
-
function connectToDatabaseByCollectionDefinitionList(
|
|
30
|
-
dbName,
|
|
31
|
-
collectionDefinitionList = [],
|
|
32
|
-
mongoOption
|
|
33
|
-
) {
|
|
34
|
-
return new Promise((done, reject) => {
|
|
35
|
-
// Create db connection
|
|
36
|
-
//
|
|
37
|
-
const fullDbName = (mongoOption.dbPrefix || "") + dbName;
|
|
38
|
-
const connectionString = mongoOption.mongoBaseAddress;
|
|
39
|
-
|
|
40
|
-
colog.info(`- Connecting to database: ${fullDbName}`);
|
|
41
|
-
|
|
42
|
-
let connection = Mongoose.createConnection(connectionString, {
|
|
43
|
-
useUnifiedTopology: true,
|
|
44
|
-
useNewUrlParser: true,
|
|
45
|
-
dbName: fullDbName,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// Store connection
|
|
49
|
-
connections[dbName] = connection;
|
|
50
|
-
|
|
51
|
-
// add db models from schemas
|
|
52
|
-
collectionDefinitionList.forEach((collectionDefinition) => {
|
|
53
|
-
let collection = collectionDefinition.collection;
|
|
54
|
-
let schema = collectionDefinition.schema;
|
|
55
|
-
|
|
56
|
-
if (collections[dbName] == undefined) collections[dbName] = {};
|
|
57
|
-
|
|
58
|
-
if (permissionDefinitions[dbName] == undefined)
|
|
59
|
-
permissionDefinitions[dbName] = {};
|
|
60
|
-
|
|
61
|
-
// create model from schema
|
|
62
|
-
// and store in on global collection object
|
|
63
|
-
let model = connection.model(collection, schema);
|
|
64
|
-
collections[dbName][collection] = model;
|
|
65
|
-
|
|
66
|
-
// define Access Definition from component permissions
|
|
67
|
-
// and store it on global access definition object
|
|
68
|
-
permissionDefinitions[dbName][collection] = new AccessDefinition({
|
|
69
|
-
database: dbName,
|
|
70
|
-
collection: collection,
|
|
71
|
-
permissionList: collectionDefinition.permissions,
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
// add trigger
|
|
75
|
-
if (collectionDefinition.triggers != undefined) {
|
|
76
|
-
if (!Array.isArray(collectionDefinition.triggers)) {
|
|
77
|
-
throw "Triggers must be an array";
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
collectionDefinition.triggers.forEach((trigger) => {
|
|
81
|
-
trigger.database = collectionDefinition.database;
|
|
82
|
-
trigger.collection = collectionDefinition.collection;
|
|
83
|
-
triggers.addTrigger(trigger);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
connection.on("connected", () => {
|
|
89
|
-
colog.success(`- ${fullDbName} database has been connected`);
|
|
90
|
-
done();
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
*
|
|
97
|
-
* @param {object} option
|
|
98
|
-
* @param {array} option.list an array of CollectionDefinition instance
|
|
99
|
-
* @param {object} option.mongoOption
|
|
100
|
-
* @param {string} option.mongoOption.dbPrefix
|
|
101
|
-
* @param {string} option.mongoOption.mongoBaseAddress
|
|
102
|
-
*/
|
|
103
|
-
async function addCollectionDefinitionByList({
|
|
104
|
-
list,
|
|
105
|
-
mongoOption
|
|
106
|
-
}) {
|
|
107
|
-
let clusteredByDBName = {};
|
|
108
|
-
|
|
109
|
-
// cluster list by their database name.
|
|
110
|
-
list.forEach((collectionDefinition) => {
|
|
111
|
-
let database = collectionDefinition.database;
|
|
112
|
-
if (!clusteredByDBName[database]) clusteredByDBName[database] = [];
|
|
113
|
-
clusteredByDBName[database].push(collectionDefinition);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// connect to databases
|
|
117
|
-
for (const dbName in clusteredByDBName) {
|
|
118
|
-
if (clusteredByDBName.hasOwnProperty(dbName)) {
|
|
119
|
-
const collectionDefinitionList = clusteredByDBName[dbName];
|
|
120
|
-
await connectToDatabaseByCollectionDefinitionList(
|
|
121
|
-
dbName,
|
|
122
|
-
collectionDefinitionList,
|
|
123
|
-
mongoOption
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Get a collection from a database.
|
|
131
|
-
* @param {string} db - The database name.
|
|
132
|
-
* @param {string} collection - The collection name.
|
|
133
|
-
* @returns {import('mongoose').Model} The found collection.
|
|
134
|
-
*/
|
|
135
|
-
function getCollection(db, collection) {
|
|
136
|
-
let fountCollection;
|
|
137
|
-
|
|
138
|
-
if (collections.hasOwnProperty(db)) {
|
|
139
|
-
if (collections[db].hasOwnProperty(collection))
|
|
140
|
-
fountCollection = collections[db][collection];
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return fountCollection;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function _getPermissionList(db, collection, operationType) {
|
|
147
|
-
let permissionList = [];
|
|
148
|
-
let permissionDefinition;
|
|
149
|
-
|
|
150
|
-
if (!permissionDefinitions.hasOwnProperty(db)) return permissionList;
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
permissionDefinition = permissionDefinitions[db][collection];
|
|
154
|
-
} catch (error) {
|
|
155
|
-
return permissionList;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
permissionDefinition.permissionList.forEach((permission) => {
|
|
159
|
-
if (permission.onlyOwnData == true) {
|
|
160
|
-
permissionList.push(permission);
|
|
161
|
-
} else if (operationType == AccessTypes.read && permission.read == true) {
|
|
162
|
-
permissionList.push(permission);
|
|
163
|
-
} else if (operationType == AccessTypes.write && permission.write == true) {
|
|
164
|
-
permissionList.push(permission);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
return permissionList;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Check access to a collection.
|
|
173
|
-
* @param {string} db - The database name.
|
|
174
|
-
* @param {string} collection - The collection name.
|
|
175
|
-
* @param {string} operationType - The operation type.
|
|
176
|
-
* @param {object} queryOrDoc - The query or document.
|
|
177
|
-
* @param {import('../../class/user')} user - The user.
|
|
178
|
-
* @returns {boolean} The access result.
|
|
179
|
-
*/
|
|
180
|
-
function checkAccess(db, collection, operationType, queryOrDoc, user) {
|
|
181
|
-
let key = false;
|
|
182
|
-
|
|
183
|
-
const collectionPermissionList = _getPermissionList(
|
|
184
|
-
db,
|
|
185
|
-
collection,
|
|
186
|
-
operationType
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
collectionPermissionList.forEach((permission) => {
|
|
190
|
-
const collectionPermissionType = permission.type;
|
|
191
|
-
|
|
192
|
-
if (permission.onlyOwnData == true) {
|
|
193
|
-
const userId = user.id;
|
|
194
|
-
|
|
195
|
-
try {
|
|
196
|
-
key =
|
|
197
|
-
queryOrDoc[permission.ownerIdField].toString() === userId.toString();
|
|
198
|
-
} catch (error) {
|
|
199
|
-
key = false;
|
|
200
|
-
}
|
|
201
|
-
} else if (operationType == AccessTypes.read && permission.read) {
|
|
202
|
-
key = user.hasPermission(collectionPermissionType);
|
|
203
|
-
} else if (operationType == AccessTypes.write && permission.write) {
|
|
204
|
-
key = user.hasPermission(collectionPermissionType);
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
return key;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function getAsID(strId) {
|
|
212
|
-
let id;
|
|
213
|
-
try {
|
|
214
|
-
id = Mongoose.Types.ObjectId(strId);
|
|
215
|
-
} catch (e) {
|
|
216
|
-
console.log("strId did not cast objectId", e);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return id;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function performPopulateToQueryObject(queryObj, popArr = []) {
|
|
223
|
-
/*
|
|
224
|
-
https://mongoosejs.com/docs/populate.html
|
|
225
|
-
popArr must be contains this objects
|
|
226
|
-
{
|
|
227
|
-
path: 'fans',
|
|
228
|
-
select: 'name -_id',
|
|
229
|
-
}
|
|
230
|
-
*/
|
|
231
|
-
popArr.forEach((pop) => queryObj.populate(pop));
|
|
232
|
-
return queryObj;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function performAdditionalOptionsToQueryObject(queryObj, options) {
|
|
236
|
-
/**
|
|
237
|
-
* https://mongoosejs.com/docs/api/query.html#query_Query-sort
|
|
238
|
-
*
|
|
239
|
-
* Options must be contain a method name and an argument of above methods.
|
|
240
|
-
* {
|
|
241
|
-
* sort: '-_id',
|
|
242
|
-
* limit: 10,
|
|
243
|
-
* }
|
|
244
|
-
*/
|
|
245
|
-
Object.keys(options).forEach((method) => {
|
|
246
|
-
queryObj = queryObj[method](options[method]);
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
return queryObj;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
module.exports = {
|
|
253
|
-
name,
|
|
254
|
-
getCollection,
|
|
255
|
-
addCollectionDefinitionByList,
|
|
256
|
-
checkAccess,
|
|
257
|
-
getAsID,
|
|
258
|
-
performPopulateToQueryObject,
|
|
259
|
-
performAdditionalOptionsToQueryObject,
|
|
260
|
-
triggers,
|
|
261
|
-
TypeCasters,
|
|
262
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
const Mongoose = require('mongoose');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
'ObjectId': Mongoose.Types.ObjectId,
|
|
5
|
-
'Date': (dateValue) => {
|
|
6
|
-
const strDate = dateValue.toString();
|
|
7
|
-
const mongoDateFormateInString = new Date(strDate).toISOString().split('T')[0];
|
|
8
|
-
return new Date(mongoDateFormateInString);
|
|
9
|
-
}
|
|
10
|
-
}
|
package/src/services/file/db.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
var mongoose = require("mongoose");
|
|
2
|
-
var Schemas = require("../../class/db_schemas");
|
|
3
|
-
|
|
4
|
-
let CollectionDefinition = require("../../class/collection_definition");
|
|
5
|
-
let { Permission, PermissionTypes } = require("../../class/security");
|
|
6
|
-
const { config } = require("../../config");
|
|
7
|
-
|
|
8
|
-
module.exports = [
|
|
9
|
-
new CollectionDefinition({
|
|
10
|
-
db: "cms",
|
|
11
|
-
collection: "file",
|
|
12
|
-
schema: Schemas.file,
|
|
13
|
-
permissions: [
|
|
14
|
-
new Permission({
|
|
15
|
-
type: PermissionTypes.upload_file_access,
|
|
16
|
-
read: true,
|
|
17
|
-
write: true,
|
|
18
|
-
onlyOwnData: false,
|
|
19
|
-
}),
|
|
20
|
-
new Permission({
|
|
21
|
-
type: PermissionTypes.remove_file_access,
|
|
22
|
-
read: true,
|
|
23
|
-
write: true,
|
|
24
|
-
onlyOwnData: false,
|
|
25
|
-
}),
|
|
26
|
-
],
|
|
27
|
-
triggers: config.fileTriggers || [],
|
|
28
|
-
}),
|
|
29
|
-
];
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
let Router = require('koa-router');
|
|
2
|
-
let validateObject = require('../../class/validator');
|
|
3
|
-
let reply = require('../../class/reply').create;
|
|
4
|
-
let name = 'file';
|
|
5
|
-
|
|
6
|
-
let { AccessTypes } = require('./../../class/security');
|
|
7
|
-
|
|
8
|
-
let DataService = require('./../data_provider/service');
|
|
9
|
-
let service = require('./service');
|
|
10
|
-
let middleware = require('../../middlewares');
|
|
11
|
-
let fileRouter = new Router();
|
|
12
|
-
|
|
13
|
-
fileRouter.use('/', middleware.auth, async (ctx, next) => {
|
|
14
|
-
await next();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
fileRouter.post('/', async (ctx) => {
|
|
18
|
-
|
|
19
|
-
let body = ctx.request.body;
|
|
20
|
-
|
|
21
|
-
// validate result
|
|
22
|
-
let bodyValidate = validateObject(body, 'tag');
|
|
23
|
-
|
|
24
|
-
// fields validation
|
|
25
|
-
if (!bodyValidate.isValid) {
|
|
26
|
-
ctx.status = 412;
|
|
27
|
-
ctx.body = reply('e', { 'e': bodyValidate.requires });
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Access validation
|
|
32
|
-
let hasAccess = DataService.checkAccess('cms', 'file', AccessTypes.write, body, ctx.state.user);
|
|
33
|
-
if (!hasAccess) {
|
|
34
|
-
ctx.throw(403, 'access denied');
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let file = ctx.request.files.file;
|
|
39
|
-
let result;
|
|
40
|
-
|
|
41
|
-
if (!file) {
|
|
42
|
-
ctx.status = 412;
|
|
43
|
-
result = reply('f',
|
|
44
|
-
{ 'message': 'file field required' });
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
else {
|
|
48
|
-
await service.storeFile({
|
|
49
|
-
file: file,
|
|
50
|
-
ownerId: ctx.state.user.id,
|
|
51
|
-
tag: body.tag
|
|
52
|
-
})
|
|
53
|
-
.then((file) => {
|
|
54
|
-
result = reply('s', { file });
|
|
55
|
-
})
|
|
56
|
-
.catch((error) => {
|
|
57
|
-
ctx.status = 412;
|
|
58
|
-
result = reply('e', error);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
ctx.body = result;
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
fileRouter.delete('/', async (ctx) => {
|
|
66
|
-
let body = ctx.request.query;
|
|
67
|
-
// validate
|
|
68
|
-
let bodyValidate = validateObject(body, 'id');
|
|
69
|
-
|
|
70
|
-
let result;
|
|
71
|
-
|
|
72
|
-
if (!bodyValidate.isValid) {
|
|
73
|
-
ctx.status = 412;
|
|
74
|
-
result = reply('f', { 'message': 'some fields required.', 'error': bodyValidate.requires });
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
else {
|
|
78
|
-
await service.removeFile(body.id)
|
|
79
|
-
.then(() => {
|
|
80
|
-
result = reply('s');
|
|
81
|
-
})
|
|
82
|
-
.catch((e) => {
|
|
83
|
-
ctx.status = 412;
|
|
84
|
-
result = reply('e', { 'error': e });
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
ctx.body = result;
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
module.exports.name = name;
|
|
92
|
-
module.exports.main = fileRouter;
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
const fs = require("file-system");
|
|
2
|
-
const pathModule = require("path");
|
|
3
|
-
const DataProvider = require("./../data_provider/service");
|
|
4
|
-
const triggerService = require("./../../class/trigger_operator");
|
|
5
|
-
const { config } = require("./../../config");
|
|
6
|
-
|
|
7
|
-
class FileService {
|
|
8
|
-
constructor() {
|
|
9
|
-
this.directory = null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
setUploadDirectory(directory) {
|
|
13
|
-
this.directory = directory;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {string} fileType
|
|
19
|
-
* @param {string} tag
|
|
20
|
-
*
|
|
21
|
-
* @returns storedFile
|
|
22
|
-
* @returns storedFile.fileName
|
|
23
|
-
* @returns storedFile.directory
|
|
24
|
-
* @returns storedFile.fullPath
|
|
25
|
-
* @returns storedFile.fileFormat
|
|
26
|
-
*/
|
|
27
|
-
createStoredDetail(fileType, tag) {
|
|
28
|
-
const typeParts = fileType.split("/");
|
|
29
|
-
const fileFormat = typeParts[1] || typeParts[0] || "unknown";
|
|
30
|
-
|
|
31
|
-
const time = new Date().getTime();
|
|
32
|
-
const fileName = `${time}.${fileFormat}`;
|
|
33
|
-
|
|
34
|
-
const fullPath = pathModule.join(
|
|
35
|
-
FileService.instance.directory,
|
|
36
|
-
fileFormat,
|
|
37
|
-
tag,
|
|
38
|
-
fileName
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
return { fileName, fullPath, fileFormat };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Stores a file, removes the given temporary file, and submits file details into the database.
|
|
46
|
-
*
|
|
47
|
-
* @param {Object} options - The options for storing the file.
|
|
48
|
-
* @param {Object} options.file - The file to be stored.
|
|
49
|
-
* @param {string} options.file.path - The path of the file.
|
|
50
|
-
* @param {string} options.file.type - The type of the file.
|
|
51
|
-
* @param {string} options.file.name - The original name of the file.
|
|
52
|
-
* @param {number} options.file.size - The size of the file.
|
|
53
|
-
* @param {string} options.ownerId - The ID of the owner of the file.
|
|
54
|
-
* @param {string} options.tag - The tag associated with the file.
|
|
55
|
-
* @param {boolean} [options.removeFileAfterStore=true] - Whether to remove the file after storing it.
|
|
56
|
-
*
|
|
57
|
-
* @returns {Promise} A promise that resolves with the document of the stored file.
|
|
58
|
-
*
|
|
59
|
-
* @throws {string} If the upload directory has not been set.
|
|
60
|
-
*/
|
|
61
|
-
storeFile({ file, ownerId, tag, removeFileAfterStore = true }) {
|
|
62
|
-
if (!FileService.instance.directory)
|
|
63
|
-
throw "upload directory has not been set.";
|
|
64
|
-
|
|
65
|
-
let storedFile;
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
new Promise(async (done, reject) => /**
|
|
69
|
-
* Store file and remove temp file
|
|
70
|
-
*/ {
|
|
71
|
-
storedFile = FileService.instance.createStoredDetail(file.type, tag);
|
|
72
|
-
|
|
73
|
-
fs.copyFile(file.path, storedFile.fullPath, {
|
|
74
|
-
done: (err) => {
|
|
75
|
-
if (err) reject(err);
|
|
76
|
-
else done();
|
|
77
|
-
|
|
78
|
-
// remove temp file
|
|
79
|
-
if (removeFileAfterStore) fs.fs.unlinkSync(file.path);
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
})
|
|
83
|
-
/**
|
|
84
|
-
* Submit file detail into database
|
|
85
|
-
*/
|
|
86
|
-
.then(() => {
|
|
87
|
-
// Get collection model for access to relative collection
|
|
88
|
-
const CollectionModel = DataProvider.getCollection("cms", "file");
|
|
89
|
-
|
|
90
|
-
const data = {
|
|
91
|
-
owner: ownerId,
|
|
92
|
-
fileName: storedFile.fileName,
|
|
93
|
-
originalName: file.name,
|
|
94
|
-
format: storedFile.fileFormat,
|
|
95
|
-
tag,
|
|
96
|
-
size: file.size,
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
// Create new document
|
|
100
|
-
const doc = new CollectionModel(data);
|
|
101
|
-
|
|
102
|
-
return doc.save().then((savedDoc) => {
|
|
103
|
-
triggerService.call("insert-one", "cms", "file", {
|
|
104
|
-
query: null,
|
|
105
|
-
queryResult: savedDoc,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
return savedDoc;
|
|
109
|
-
});
|
|
110
|
-
})
|
|
111
|
-
.catch((err) => {
|
|
112
|
-
// remove stored file
|
|
113
|
-
fs.fs.unlinkSync(storedFile.fullPath);
|
|
114
|
-
|
|
115
|
-
throw err;
|
|
116
|
-
})
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Removes a file from the disk.
|
|
122
|
-
*
|
|
123
|
-
* @param {string} path - The path of the file to be removed.
|
|
124
|
-
* @returns {Promise} A promise that resolves if the file is successfully removed, and rejects if an error occurs.
|
|
125
|
-
*/
|
|
126
|
-
removeFromDisc(path) {
|
|
127
|
-
return new Promise((done, reject) => {
|
|
128
|
-
fs.fs.unlink(path, (err) => {
|
|
129
|
-
if (err) reject();
|
|
130
|
-
else done();
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Removes a file from the database and the disk.
|
|
137
|
-
*
|
|
138
|
-
* @param {string} fileId - The ID of the file to be removed.
|
|
139
|
-
* @returns {Promise} A promise that resolves if the file is successfully removed, and rejects if an error occurs.
|
|
140
|
-
* @throws Will throw an error if upload directory has not been set.
|
|
141
|
-
*/
|
|
142
|
-
removeFile(fileId) {
|
|
143
|
-
if (!FileService.instance.directory)
|
|
144
|
-
throw "upload directory has not been set.";
|
|
145
|
-
|
|
146
|
-
return new Promise(async (done, reject) => {
|
|
147
|
-
let CollectionModel = DataProvider.getCollection("cms", "file");
|
|
148
|
-
let fileDoc = await CollectionModel.findOne({ _id: fileId }).exec();
|
|
149
|
-
|
|
150
|
-
if (!fileDoc) {
|
|
151
|
-
reject("file not found");
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
await CollectionModel.deleteOne({ _id: fileId })
|
|
156
|
-
.exec()
|
|
157
|
-
.then(() => {
|
|
158
|
-
// create file path
|
|
159
|
-
const filePath = pathModule.join(
|
|
160
|
-
FileService.instance.directory,
|
|
161
|
-
fileDoc.format,
|
|
162
|
-
fileDoc.tag,
|
|
163
|
-
fileDoc.fileName
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
// Remove file from disc
|
|
167
|
-
return FileService.instance
|
|
168
|
-
.removeFromDisc(filePath)
|
|
169
|
-
.catch(async (err) => {
|
|
170
|
-
// Recreate fileDoc if removing file operation has error
|
|
171
|
-
await new CollectionModel(fileDoc).save();
|
|
172
|
-
|
|
173
|
-
throw err;
|
|
174
|
-
});
|
|
175
|
-
})
|
|
176
|
-
.then(() => {
|
|
177
|
-
triggerService.call("remove-one", "cms", "file", {
|
|
178
|
-
query: { _id: fileId },
|
|
179
|
-
queryResult: null,
|
|
180
|
-
});
|
|
181
|
-
})
|
|
182
|
-
.then(done)
|
|
183
|
-
.catch(reject);
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Retrieves a file from the database.
|
|
189
|
-
*
|
|
190
|
-
* @param {string} fileId - The ID of the file to be retrieved.
|
|
191
|
-
* @returns {Promise} A promise that resolves with the file document, or rejects if an error occurs.
|
|
192
|
-
*/
|
|
193
|
-
getFile(fileId) {
|
|
194
|
-
const CollectionModel = DataProvider.getCollection("cms", "file");
|
|
195
|
-
|
|
196
|
-
return CollectionModel.findOne({ _id: fileId }).exec();
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Retrieves the link of a file.
|
|
201
|
-
*
|
|
202
|
-
* @param {string} fileId - The ID of the file to get the link for.
|
|
203
|
-
* @returns {Promise} A promise that resolves with the file link, or rejects if an error occurs.
|
|
204
|
-
*/
|
|
205
|
-
async getFileLink(fileId) {
|
|
206
|
-
const fileDoc = await FileService.instance.getFile(fileId);
|
|
207
|
-
|
|
208
|
-
const link =
|
|
209
|
-
config.staticPath.rootPath +
|
|
210
|
-
`/${fileDoc.format}/${fileDoc.tag}/` +
|
|
211
|
-
fileDoc.fileName;
|
|
212
|
-
|
|
213
|
-
return link;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
async getFilePath(fileId) {
|
|
217
|
-
const { fileName, format, tag } = await FileService.instance.getFile(
|
|
218
|
-
fileId
|
|
219
|
-
);
|
|
220
|
-
const fullPath = pathModule.join(
|
|
221
|
-
FileService.instance.directory,
|
|
222
|
-
format,
|
|
223
|
-
tag,
|
|
224
|
-
fileName
|
|
225
|
-
);
|
|
226
|
-
return fullPath;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
FileService.instance = new FileService();
|
|
231
|
-
module.exports = FileService.instance;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
const Router = require("koa-router");
|
|
2
|
-
const service = require("./service");
|
|
3
|
-
const middleware = require("../../middlewares");
|
|
4
|
-
const validateObject = require("../../class/validator");
|
|
5
|
-
const reply = require("../../class/reply").create;
|
|
6
|
-
|
|
7
|
-
const functionRouter = new Router();
|
|
8
|
-
const name = "function";
|
|
9
|
-
|
|
10
|
-
functionRouter.use("/", middleware.auth, async (ctx, next) => {
|
|
11
|
-
const body = ctx.request.body;
|
|
12
|
-
const bodyValidated = validateObject(body, "name args");
|
|
13
|
-
|
|
14
|
-
// fields validation
|
|
15
|
-
if (!bodyValidated.isValid) {
|
|
16
|
-
ctx.throw(
|
|
17
|
-
412,
|
|
18
|
-
JSON.stringify(reply("e", { error: bodyValidated.requires }))
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
await next();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
functionRouter.post(`/run`, middleware.auth, async (ctx) => {
|
|
26
|
-
const { name, args } = ctx.request.body;
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const result = await service.runFunction(name, args, ctx.state.user);
|
|
30
|
-
ctx.body = JSON.stringify(reply("s", { data: result }));
|
|
31
|
-
} catch (e) {
|
|
32
|
-
ctx.throw(400, JSON.stringify(reply("e", { error: e.message })));
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
module.exports.name = name;
|
|
37
|
-
module.exports.main = functionRouter;
|