@modular-rest/server 1.7.0 → 1.10.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.
- package/package-lock.json +1373 -0
- package/package.json +4 -2
- package/src/application.js +58 -40
- package/src/class/collection_definition.js +1 -1
- package/src/class/database_trigger.js +2 -4
- package/src/class/directory.js +50 -51
- package/src/class/security.js +41 -18
- package/src/class/user.js +98 -83
- package/src/config.js +63 -0
- package/src/helper/data_insertion.js +12 -72
- package/src/helper/presetup_services.js +2 -14
- package/src/index.js +8 -0
- package/src/services/data_provider/router.js +490 -402
- package/src/services/data_provider/service.js +30 -13
- package/src/services/user_manager/db.js +2 -37
- package/src/services/user_manager/permissionManager.js +43 -0
- package/src/services/user_manager/service.js +9 -39
|
@@ -1,437 +1,525 @@
|
|
|
1
|
-
let { AccessTypes } = require(
|
|
2
|
-
let Router = require(
|
|
3
|
-
let validateObject = require(
|
|
4
|
-
let reply = require(
|
|
1
|
+
let { AccessTypes } = require("./../../class/security");
|
|
2
|
+
let Router = require("koa-router");
|
|
3
|
+
let validateObject = require("../../class/validator");
|
|
4
|
+
let reply = require("../../class/reply").create;
|
|
5
5
|
var nestedProperty = require("nested-property");
|
|
6
6
|
|
|
7
7
|
//let Types = require('./types.js');
|
|
8
8
|
|
|
9
|
-
let name =
|
|
9
|
+
let name = "data-provider";
|
|
10
10
|
|
|
11
|
-
let service = require(
|
|
12
|
-
let middleware = require(
|
|
11
|
+
let service = require("./service");
|
|
12
|
+
let middleware = require("./../../middlewares");
|
|
13
13
|
|
|
14
14
|
let dataProvider = new Router();
|
|
15
15
|
|
|
16
|
-
dataProvider.use(
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
dataProvider.use("/", middleware.auth, async (ctx, next) => {
|
|
17
|
+
let body = ctx.request.body;
|
|
18
|
+
let bodyValidated = validateObject(body, "database collection");
|
|
19
|
+
|
|
20
|
+
// fields validation
|
|
21
|
+
if (!bodyValidated.isValid) {
|
|
22
|
+
ctx.throw(412, JSON.stringify(reply("e", { e: bodyValidated.requires })));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// type caster
|
|
26
|
+
if (body.types && body.hasOwnProperty(body.bodyKey || ".")) {
|
|
27
|
+
let bodyKey = body.bodyKey;
|
|
28
|
+
for (const key in body.types) {
|
|
29
|
+
if (
|
|
30
|
+
body.types.hasOwnProperty(key) &&
|
|
31
|
+
typeof body.types[key] == "object"
|
|
32
|
+
) {
|
|
33
|
+
let typeDetail = body.types[key];
|
|
19
34
|
|
|
20
|
-
// fields validation
|
|
21
|
-
if (!bodyValidated.isValid) {
|
|
22
|
-
ctx.throw(412, JSON.stringify(
|
|
23
|
-
reply('e', { 'e': bodyValidated.requires })));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// type caster
|
|
27
|
-
if (body.types && body.hasOwnProperty(body.bodyKey || ".")) {
|
|
28
|
-
let bodyKey = body.bodyKey;
|
|
29
|
-
for (const key in body.types) {
|
|
30
|
-
if (
|
|
31
|
-
body.types.hasOwnProperty(key)
|
|
32
|
-
&& typeof body.types[key] == "object"
|
|
33
|
-
) {
|
|
34
|
-
let typeDetail = body.types[key];
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
let value = nestedProperty.get(body[bodyKey], typeDetail.path);
|
|
38
|
-
let newProperty = service.TypeCasters[typeDetail.type](value);
|
|
39
|
-
nestedProperty.set(body[bodyKey], typeDetail.path, newProperty);
|
|
40
|
-
console.log('newProperty', newProperty, JSON.stringify(body[bodyKey]));
|
|
41
|
-
} catch (e) {
|
|
42
|
-
console.log('type caster error', e);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
await next();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
dataProvider.post('/find', async (ctx) => {
|
|
52
|
-
let body = ctx.request.body;
|
|
53
|
-
let bodyValidate = validateObject(body, 'database collection query');
|
|
54
|
-
|
|
55
|
-
// fields validation
|
|
56
|
-
if (!bodyValidate.isValid) {
|
|
57
|
-
ctx.throw(412, JSON.stringify(
|
|
58
|
-
reply('e', { 'e': bodyValidate.requires })));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// access validation
|
|
62
|
-
let hasAccess = service.checkAccess(body.database, body.collection, AccessTypes.read, body.query, ctx.state.user);
|
|
63
|
-
if (!hasAccess) {
|
|
64
|
-
console.log(body);
|
|
65
|
-
console.log(ctx.state.user.permission);
|
|
66
|
-
ctx.throw(403, 'access denied');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// collection validation
|
|
70
|
-
let collection = service.getCollection(body.database, body.collection);
|
|
71
|
-
if (collection == null) {
|
|
72
|
-
ctx.throw(412, JSON.stringify(
|
|
73
|
-
reply('e', { 'e': 'wrong database or collection' })));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// operate on db
|
|
77
|
-
let queryRequest = collection.find(body.query, body.projection);
|
|
78
|
-
|
|
79
|
-
if (body.options) {
|
|
80
|
-
queryRequest = service.performAdditionalOptionsToQueryObject(queryRequest, body.options)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (body.populates) {
|
|
84
35
|
try {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
36
|
+
let value = nestedProperty.get(body[bodyKey], typeDetail.path);
|
|
37
|
+
let newProperty = service.TypeCasters[typeDetail.type](value);
|
|
38
|
+
nestedProperty.set(body[bodyKey], typeDetail.path, newProperty);
|
|
39
|
+
console.log(
|
|
40
|
+
"newProperty",
|
|
41
|
+
newProperty,
|
|
42
|
+
JSON.stringify(body[bodyKey])
|
|
43
|
+
);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.log("type caster error", e);
|
|
89
46
|
}
|
|
47
|
+
}
|
|
90
48
|
}
|
|
49
|
+
}
|
|
91
50
|
|
|
92
|
-
|
|
93
|
-
.then(async docs => {
|
|
94
|
-
|
|
95
|
-
// Call trigger
|
|
96
|
-
service.triggers.call('find', body.database, body.collection,
|
|
97
|
-
{ 'query': body.query, 'queryResult': docs });
|
|
98
|
-
|
|
99
|
-
ctx.body = { data: docs };
|
|
100
|
-
})
|
|
101
|
-
.catch(err => {
|
|
102
|
-
ctx.status = err.status || 500;
|
|
103
|
-
ctx.body = err.message;
|
|
104
|
-
});
|
|
51
|
+
await next();
|
|
105
52
|
});
|
|
106
53
|
|
|
107
|
-
dataProvider.post(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
54
|
+
dataProvider.post("/find", async (ctx) => {
|
|
55
|
+
let body = ctx.request.body;
|
|
56
|
+
let bodyValidate = validateObject(body, "database collection query");
|
|
57
|
+
|
|
58
|
+
// fields validation
|
|
59
|
+
if (!bodyValidate.isValid) {
|
|
60
|
+
ctx.throw(412, JSON.stringify(reply("e", { e: bodyValidate.requires })));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// access validation
|
|
64
|
+
let hasAccess = service.checkAccess(
|
|
65
|
+
body.database,
|
|
66
|
+
body.collection,
|
|
67
|
+
AccessTypes.read,
|
|
68
|
+
body.query,
|
|
69
|
+
ctx.state.user
|
|
70
|
+
);
|
|
71
|
+
if (!hasAccess) {
|
|
72
|
+
console.log(body);
|
|
73
|
+
console.log(ctx.state.user.permission);
|
|
74
|
+
ctx.throw(403, "access denied");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// collection validation
|
|
78
|
+
let collection = service.getCollection(body.database, body.collection);
|
|
79
|
+
if (collection == null) {
|
|
80
|
+
ctx.throw(
|
|
81
|
+
412,
|
|
82
|
+
JSON.stringify(reply("e", { e: "wrong database or collection" }))
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// operate on db
|
|
87
|
+
let queryRequest = collection.find(body.query, body.projection);
|
|
88
|
+
|
|
89
|
+
if (body.options) {
|
|
90
|
+
queryRequest = service.performAdditionalOptionsToQueryObject(
|
|
91
|
+
queryRequest,
|
|
92
|
+
body.options
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (body.populates) {
|
|
97
|
+
try {
|
|
98
|
+
req = service.performPopulateToQueryObject(queryRequest, body.populates);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
ctx.status = 412;
|
|
101
|
+
ctx.body = err;
|
|
142
102
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
await queryRequest
|
|
106
|
+
.exec()
|
|
107
|
+
.then(async (docs) => {
|
|
108
|
+
// Call trigger
|
|
109
|
+
service.triggers.call("find", body.database, body.collection, {
|
|
110
|
+
query: body.query,
|
|
111
|
+
queryResult: docs,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
ctx.body = { data: docs };
|
|
115
|
+
})
|
|
116
|
+
.catch((err) => {
|
|
117
|
+
ctx.status = err.status || 500;
|
|
118
|
+
ctx.body = err.message;
|
|
119
|
+
});
|
|
158
120
|
});
|
|
159
121
|
|
|
160
|
-
dataProvider.post(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
122
|
+
dataProvider.post("/find-one", async (ctx) => {
|
|
123
|
+
let body = ctx.request.body;
|
|
124
|
+
let bodyValidate = validateObject(body, "database collection query");
|
|
125
|
+
|
|
126
|
+
// fields validation
|
|
127
|
+
if (!bodyValidate.isValid) {
|
|
128
|
+
ctx.throw(JSON.stringify(reply("e", { e: bodyValidate.requires })), 412);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// access validation
|
|
132
|
+
let hasAccess = service.checkAccess(
|
|
133
|
+
body.database,
|
|
134
|
+
body.collection,
|
|
135
|
+
AccessTypes.read,
|
|
136
|
+
body.query,
|
|
137
|
+
ctx.state.user
|
|
138
|
+
);
|
|
139
|
+
if (!hasAccess) ctx.throw(403, "access denied");
|
|
140
|
+
|
|
141
|
+
// collection validation
|
|
142
|
+
let collection = service.getCollection(body.database, body.collection);
|
|
143
|
+
if (collection == null) {
|
|
144
|
+
ctx.throw(
|
|
145
|
+
JSON.stringify(reply("e", { e: "wrong database or collection" })),
|
|
146
|
+
412
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// operate on db
|
|
151
|
+
let queryRequest = collection.findOne(
|
|
152
|
+
body.query,
|
|
153
|
+
body.projection,
|
|
154
|
+
body.options
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
if (body.options) {
|
|
158
|
+
queryRequest = service.performAdditionalOptionsToQueryObject(
|
|
159
|
+
queryRequest,
|
|
160
|
+
body.options
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (body.populates) {
|
|
165
|
+
try {
|
|
166
|
+
req = service.performPopulateToQueryObject(queryRequest, body.populates);
|
|
167
|
+
} catch (err) {
|
|
168
|
+
ctx.status = 412;
|
|
169
|
+
ctx.body = err;
|
|
179
170
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// operate on db
|
|
174
|
+
await queryRequest
|
|
175
|
+
.exec()
|
|
176
|
+
.then(async (doc) => {
|
|
177
|
+
// Call trigger
|
|
178
|
+
service.triggers.call("find-one", body.database, body.collection, {
|
|
179
|
+
query: body.query,
|
|
180
|
+
queryResult: doc,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
ctx.body = { data: doc };
|
|
184
|
+
})
|
|
185
|
+
.catch((err) => {
|
|
186
|
+
ctx.status = err.status || 500;
|
|
187
|
+
ctx.body = err.message;
|
|
188
|
+
});
|
|
195
189
|
});
|
|
196
190
|
|
|
197
|
-
dataProvider.post(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
191
|
+
dataProvider.post("/count", async (ctx) => {
|
|
192
|
+
let body = ctx.request.body;
|
|
193
|
+
let bodyValidate = validateObject(body, "database collection query");
|
|
194
|
+
|
|
195
|
+
// fields validation
|
|
196
|
+
if (!bodyValidate.isValid) {
|
|
197
|
+
ctx.throw(JSON.stringify(reply("e", { e: bodyValidate.requires })), 412);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// access validation
|
|
201
|
+
let hasAccess = service.checkAccess(
|
|
202
|
+
body.database,
|
|
203
|
+
body.collection,
|
|
204
|
+
AccessTypes.read,
|
|
205
|
+
body.query,
|
|
206
|
+
ctx.state.user
|
|
207
|
+
);
|
|
208
|
+
if (!hasAccess) ctx.throw(403, "access denied");
|
|
209
|
+
|
|
210
|
+
// collection validation
|
|
211
|
+
let collection = service.getCollection(body.database, body.collection);
|
|
212
|
+
if (collection == null) {
|
|
213
|
+
ctx.throw(
|
|
214
|
+
JSON.stringify(reply("e", { e: "wrong database or collection" })),
|
|
215
|
+
412
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// operate on db
|
|
220
|
+
await collection
|
|
221
|
+
.countDocuments(body.query)
|
|
222
|
+
.exec()
|
|
223
|
+
.then((count) => {
|
|
224
|
+
// Call trigger
|
|
225
|
+
service.triggers.call("count", body.database, body.collection, {
|
|
226
|
+
query: body.query,
|
|
227
|
+
queryResult: count,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
ctx.body = { data: count };
|
|
231
|
+
})
|
|
232
|
+
.catch((err) => {
|
|
233
|
+
ctx.status = err.status || 500;
|
|
234
|
+
ctx.body = err.message;
|
|
235
|
+
});
|
|
235
236
|
});
|
|
236
237
|
|
|
237
|
-
dataProvider.post(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
238
|
+
dataProvider.post("/update-one", async (ctx) => {
|
|
239
|
+
let body = ctx.request.body;
|
|
240
|
+
let bodyValidate = validateObject(body, "database collection query update");
|
|
241
|
+
|
|
242
|
+
// fields validation
|
|
243
|
+
if (!bodyValidate.isValid) {
|
|
244
|
+
ctx.throw(JSON.stringify(reply("e", { e: bodyValidate.requires })), 412);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// access validation
|
|
248
|
+
let hasAccess = service.checkAccess(
|
|
249
|
+
body.database,
|
|
250
|
+
body.collection,
|
|
251
|
+
AccessTypes.write,
|
|
252
|
+
body.query,
|
|
253
|
+
ctx.state.user
|
|
254
|
+
);
|
|
255
|
+
if (!hasAccess) ctx.throw(403, "access denied");
|
|
256
|
+
|
|
257
|
+
// collection validation
|
|
258
|
+
let collection = service.getCollection(body.database, body.collection);
|
|
259
|
+
if (collection == null) {
|
|
260
|
+
ctx.throw(
|
|
261
|
+
JSON.stringify(reply("e", { e: "wrong database or collection" })),
|
|
262
|
+
412
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// get removing doc as output for triggers
|
|
267
|
+
let output = await collection.findOne(body.query).exec().then();
|
|
268
|
+
|
|
269
|
+
// operate on db
|
|
270
|
+
await collection
|
|
271
|
+
.updateOne(body.query, body.update, body.options)
|
|
272
|
+
.exec()
|
|
273
|
+
.then((writeOpResult) => {
|
|
274
|
+
// Call trigger
|
|
275
|
+
service.triggers.call("update-one", body.database, body.collection, {
|
|
276
|
+
query: body.query,
|
|
277
|
+
queryResult: writeOpResult,
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
ctx.body = { data: writeOpResult };
|
|
281
|
+
})
|
|
282
|
+
.catch((err) => {
|
|
283
|
+
ctx.status = err.status || 500;
|
|
284
|
+
ctx.body = err.message;
|
|
285
|
+
});
|
|
276
286
|
});
|
|
277
287
|
|
|
278
|
-
dataProvider.post(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
288
|
+
dataProvider.post("/insert-one", async (ctx) => {
|
|
289
|
+
let body = ctx.request.body;
|
|
290
|
+
let bodyValidate = validateObject(body, "database collection doc");
|
|
291
|
+
|
|
292
|
+
// fields validation
|
|
293
|
+
if (!bodyValidate.isValid) {
|
|
294
|
+
ctx.throw(JSON.stringify(reply("e", { e: bodyValidate.requires })), 412);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// access validation
|
|
298
|
+
let hasAccess = service.checkAccess(
|
|
299
|
+
body.database,
|
|
300
|
+
body.collection,
|
|
301
|
+
AccessTypes.write,
|
|
302
|
+
body.doc,
|
|
303
|
+
ctx.state.user
|
|
304
|
+
);
|
|
305
|
+
if (!hasAccess) {
|
|
306
|
+
console.log(body);
|
|
307
|
+
console.log(ctx.state.user.permission);
|
|
308
|
+
ctx.throw(403, "access denied");
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// collection validation
|
|
312
|
+
let collection = service.getCollection(body.database, body.collection);
|
|
313
|
+
if (collection == null) {
|
|
314
|
+
ctx.throw(
|
|
315
|
+
JSON.stringify(reply("e", { e: "wrong database or collection" })),
|
|
316
|
+
412
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// operate on db
|
|
321
|
+
await new collection(body.doc)
|
|
322
|
+
.save()
|
|
323
|
+
.then(async (newDoc) => {
|
|
324
|
+
// Call trigger
|
|
325
|
+
service.triggers.call("insert-one", body.database, body.collection, {
|
|
326
|
+
query: body.query,
|
|
327
|
+
queryResult: newDoc,
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
ctx.body = { data: newDoc };
|
|
331
|
+
})
|
|
332
|
+
.catch((err) => {
|
|
333
|
+
ctx.status = err.status || 500;
|
|
334
|
+
ctx.body = err.message;
|
|
335
|
+
});
|
|
316
336
|
});
|
|
317
337
|
|
|
318
|
-
dataProvider.post(
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
338
|
+
dataProvider.post("/remove-one", async (ctx) => {
|
|
339
|
+
let body = ctx.request.body;
|
|
340
|
+
let bodyValidate = validateObject(body, "database collection query");
|
|
341
|
+
|
|
342
|
+
// fields validation
|
|
343
|
+
if (!bodyValidate.isValid) {
|
|
344
|
+
ctx.throw(JSON.stringify(reply("e", { e: bodyValidate.requires })), 412);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// access validation
|
|
348
|
+
let hasAccess = service.checkAccess(
|
|
349
|
+
body.database,
|
|
350
|
+
body.collection,
|
|
351
|
+
AccessTypes.write,
|
|
352
|
+
body.query,
|
|
353
|
+
ctx.state.user
|
|
354
|
+
);
|
|
355
|
+
if (!hasAccess) ctx.throw(403, "access denied");
|
|
356
|
+
|
|
357
|
+
// collection validation
|
|
358
|
+
let collection = service.getCollection(body.database, body.collection);
|
|
359
|
+
if (collection == null) {
|
|
360
|
+
ctx.throw(
|
|
361
|
+
JSON.stringify(reply("e", { e: "wrong database or collection" })),
|
|
362
|
+
412
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// get removing doc as output for triggers
|
|
367
|
+
let output = await collection.findOne(body.query).exec().then();
|
|
368
|
+
|
|
369
|
+
// operate on db
|
|
370
|
+
await collection
|
|
371
|
+
.deleteOne(body.query)
|
|
372
|
+
.exec()
|
|
373
|
+
.then(async (result) => {
|
|
374
|
+
// Call trigger
|
|
375
|
+
service.triggers.call("remove-one", body.database, body.collection, {
|
|
376
|
+
query: body.query,
|
|
377
|
+
queryResult: result,
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
ctx.body = { data: result };
|
|
381
|
+
})
|
|
382
|
+
.catch((err) => {
|
|
383
|
+
ctx.status = err.status || 500;
|
|
384
|
+
ctx.body = err.message;
|
|
385
|
+
});
|
|
353
386
|
});
|
|
354
387
|
|
|
355
|
-
dataProvider.post(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
await next();
|
|
401
|
-
})
|
|
402
|
-
.catch(err => {
|
|
403
|
-
ctx.status = err.status || 500;
|
|
404
|
-
ctx.body = err.message;
|
|
405
|
-
});
|
|
388
|
+
dataProvider.post("/aggregate", async (ctx) => {
|
|
389
|
+
let body = ctx.request.body;
|
|
390
|
+
let bodyValidate = validateObject(body, "database collection accessQuery");
|
|
391
|
+
|
|
392
|
+
// fields validation
|
|
393
|
+
if (!bodyValidate.isValid) {
|
|
394
|
+
ctx.throw(JSON.stringify(reply("e", { e: bodyValidate.requires })), 412);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// access validation
|
|
398
|
+
let hasAccess = service.checkAccess(
|
|
399
|
+
body.database,
|
|
400
|
+
body.collection,
|
|
401
|
+
AccessTypes.read,
|
|
402
|
+
body.accessQuery,
|
|
403
|
+
ctx.state.user
|
|
404
|
+
);
|
|
405
|
+
if (!hasAccess) ctx.throw(403, "access denied");
|
|
406
|
+
|
|
407
|
+
// collection validation
|
|
408
|
+
let collection = service.getCollection(body.database, body.collection);
|
|
409
|
+
if (collection == null) {
|
|
410
|
+
ctx.throw(
|
|
411
|
+
JSON.stringify(reply("e", { e: "wrong database or collection" })),
|
|
412
|
+
412
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// operate on db
|
|
417
|
+
await collection
|
|
418
|
+
.aggregate(body.pipelines)
|
|
419
|
+
.exec()
|
|
420
|
+
.then(async (result) => {
|
|
421
|
+
// Call trigger
|
|
422
|
+
service.triggers.call("aggregate", body.database, body.collection, {
|
|
423
|
+
query: body.query,
|
|
424
|
+
queryResult: result,
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
ctx.body = { data: result };
|
|
428
|
+
})
|
|
429
|
+
.catch((err) => {
|
|
430
|
+
ctx.status = err.status || 500;
|
|
431
|
+
ctx.body = err.message;
|
|
432
|
+
});
|
|
406
433
|
});
|
|
407
434
|
|
|
408
|
-
dataProvider.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
435
|
+
dataProvider.post("/findByIds", async (ctx, next) => {
|
|
436
|
+
let body = ctx.request.body;
|
|
437
|
+
let bodyValidate = validateObject(body, "database collection ids");
|
|
438
|
+
|
|
439
|
+
// fields validation
|
|
440
|
+
if (!bodyValidate.isValid) {
|
|
441
|
+
ctx.throw(JSON.stringify(reply("e", { e: bodyValidate.requires })), 412);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// access validation
|
|
445
|
+
let hasAccess = service.checkAccess(
|
|
446
|
+
body.database,
|
|
447
|
+
body.collection,
|
|
448
|
+
AccessTypes.read,
|
|
449
|
+
body.accessQuery || {},
|
|
450
|
+
ctx.state.user
|
|
451
|
+
);
|
|
452
|
+
if (!hasAccess) ctx.throw(403, "access denied");
|
|
453
|
+
|
|
454
|
+
// collection validation
|
|
455
|
+
let collection = service.getCollection(body.database, body.collection);
|
|
456
|
+
if (collection == null) {
|
|
457
|
+
ctx.throw(
|
|
458
|
+
JSON.stringify(reply("e", { e: "wrong database or collection" })),
|
|
459
|
+
412
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
let or = [];
|
|
464
|
+
|
|
465
|
+
try {
|
|
466
|
+
body.ids.forEach((id) => {
|
|
467
|
+
let castedid = service.getAsID(id);
|
|
468
|
+
or.push({ _id: castedid });
|
|
469
|
+
});
|
|
470
|
+
} catch (e) {
|
|
471
|
+
console.log("ids.forEach", e);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
let pipelines = [
|
|
475
|
+
{
|
|
476
|
+
$match: { $or: or },
|
|
477
|
+
},
|
|
478
|
+
// {
|
|
479
|
+
// $sort: body.sort || { _id: 1 }
|
|
480
|
+
// }
|
|
481
|
+
];
|
|
482
|
+
|
|
483
|
+
// operate on db
|
|
484
|
+
await collection
|
|
485
|
+
.aggregate(pipelines)
|
|
486
|
+
.exec()
|
|
487
|
+
.then(async (result) => {
|
|
488
|
+
ctx.state = { data: result };
|
|
489
|
+
await next();
|
|
490
|
+
})
|
|
491
|
+
.catch((err) => {
|
|
492
|
+
ctx.status = err.status || 500;
|
|
493
|
+
ctx.body = err.message;
|
|
494
|
+
});
|
|
495
|
+
});
|
|
432
496
|
|
|
433
|
-
|
|
497
|
+
dataProvider.use("/", async (ctx, next) => {
|
|
498
|
+
// this event is responsible to covert whole mongoose doc to json form
|
|
499
|
+
// inclouding getters, public propertise
|
|
500
|
+
// each mongoose doc must have a "toJson" method being defined on its own Schema.
|
|
501
|
+
|
|
502
|
+
let state = ctx.state;
|
|
503
|
+
// let result;
|
|
504
|
+
|
|
505
|
+
// // array
|
|
506
|
+
// if(!isNaN(state.length)) {
|
|
507
|
+
// result = [];
|
|
508
|
+
|
|
509
|
+
// for (let index = 0; index < state.length; index++) {
|
|
510
|
+
// const element = state[index];
|
|
511
|
+
// if(element.hasOwnProperty('toJson'))
|
|
512
|
+
// result.push(element.toJson());
|
|
513
|
+
// else result.push(element);
|
|
514
|
+
// }
|
|
515
|
+
// }
|
|
516
|
+
// // object
|
|
517
|
+
// else {
|
|
518
|
+
// result = state.toJson();
|
|
519
|
+
// }
|
|
520
|
+
|
|
521
|
+
ctx.body = state;
|
|
434
522
|
});
|
|
435
523
|
|
|
436
524
|
module.exports.name = name;
|
|
437
|
-
module.exports.main = dataProvider;
|
|
525
|
+
module.exports.main = dataProvider;
|