@nocobase/plugin-acl 0.7.0-alpha.8 → 0.7.0-alpha.80

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.
Files changed (69) hide show
  1. package/lib/actions/available-actions.js +35 -25
  2. package/lib/actions/role-check.js +85 -38
  3. package/lib/actions/role-collections.js +78 -53
  4. package/lib/collections/roles.js +70 -78
  5. package/lib/collections/rolesResources.js +27 -30
  6. package/lib/collections/rolesResourcesActions.js +26 -27
  7. package/lib/collections/rolesResourcesScopes.js +21 -22
  8. package/lib/index.js +14 -8
  9. package/lib/model/RoleModel.js +39 -15
  10. package/lib/model/RoleResourceActionModel.js +103 -66
  11. package/lib/model/RoleResourceModel.js +125 -56
  12. package/lib/server.js +609 -351
  13. package/package.json +5 -10
  14. package/src/__tests__/acl.test.ts +50 -0
  15. package/src/__tests__/own.test.ts +5 -6
  16. package/src/actions/role-collections.ts +15 -5
  17. package/src/model/RoleResourceActionModel.ts +4 -2
  18. package/src/model/RoleResourceModel.ts +12 -4
  19. package/src/server.ts +5 -0
  20. package/esm/actions/available-actions.d.ts +0 -7
  21. package/esm/actions/available-actions.js +0 -26
  22. package/esm/actions/available-actions.js.map +0 -1
  23. package/esm/actions/role-check.d.ts +0 -1
  24. package/esm/actions/role-check.js +0 -38
  25. package/esm/actions/role-check.js.map +0 -1
  26. package/esm/actions/role-collections.d.ts +0 -7
  27. package/esm/actions/role-collections.js +0 -54
  28. package/esm/actions/role-collections.js.map +0 -1
  29. package/esm/collections/roles.d.ts +0 -3
  30. package/esm/collections/roles.js +0 -78
  31. package/esm/collections/roles.js.map +0 -1
  32. package/esm/collections/rolesResources.d.ts +0 -3
  33. package/esm/collections/rolesResources.js +0 -30
  34. package/esm/collections/rolesResources.js.map +0 -1
  35. package/esm/collections/rolesResourcesActions.d.ts +0 -3
  36. package/esm/collections/rolesResourcesActions.js +0 -27
  37. package/esm/collections/rolesResourcesActions.js.map +0 -1
  38. package/esm/collections/rolesResourcesScopes.d.ts +0 -3
  39. package/esm/collections/rolesResourcesScopes.js +0 -22
  40. package/esm/collections/rolesResourcesScopes.js.map +0 -1
  41. package/esm/index.d.ts +0 -1
  42. package/esm/index.js +0 -2
  43. package/esm/index.js.map +0 -1
  44. package/esm/model/RoleModel.d.ts +0 -7
  45. package/esm/model/RoleModel.js +0 -15
  46. package/esm/model/RoleModel.js.map +0 -1
  47. package/esm/model/RoleResourceActionModel.d.ts +0 -12
  48. package/esm/model/RoleResourceActionModel.js +0 -65
  49. package/esm/model/RoleResourceActionModel.js.map +0 -1
  50. package/esm/model/RoleResourceModel.d.ts +0 -16
  51. package/esm/model/RoleResourceModel.js +0 -55
  52. package/esm/model/RoleResourceModel.js.map +0 -1
  53. package/esm/server.d.ts +0 -33
  54. package/esm/server.js +0 -366
  55. package/esm/server.js.map +0 -1
  56. package/lib/actions/available-actions.js.map +0 -1
  57. package/lib/actions/role-check.js.map +0 -1
  58. package/lib/actions/role-collections.js.map +0 -1
  59. package/lib/collections/roles.js.map +0 -1
  60. package/lib/collections/rolesResources.js.map +0 -1
  61. package/lib/collections/rolesResourcesActions.js.map +0 -1
  62. package/lib/collections/rolesResourcesScopes.js.map +0 -1
  63. package/lib/index.js.map +0 -1
  64. package/lib/model/RoleModel.js.map +0 -1
  65. package/lib/model/RoleResourceActionModel.js.map +0 -1
  66. package/lib/model/RoleResourceModel.js.map +0 -1
  67. package/lib/server.js.map +0 -1
  68. package/tsconfig.build.json +0 -9
  69. package/tsconfig.json +0 -5
package/lib/server.js CHANGED
@@ -1,371 +1,629 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.PluginACL = exports.GrantHelper = void 0;
13
- const server_1 = require("@nocobase/server");
14
- const path_1 = require("path");
15
- const available_actions_1 = require("./actions/available-actions");
16
- const role_check_1 = require("./actions/role-check");
17
- const role_collections_1 = require("./actions/role-collections");
18
- const RoleModel_1 = require("./model/RoleModel");
19
- const RoleResourceActionModel_1 = require("./model/RoleResourceActionModel");
20
- const RoleResourceModel_1 = require("./model/RoleResourceModel");
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.PluginACL = exports.GrantHelper = void 0;
7
+
8
+ function _server() {
9
+ const data = require("@nocobase/server");
10
+
11
+ _server = function _server() {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ function _path() {
19
+ const data = require("path");
20
+
21
+ _path = function _path() {
22
+ return data;
23
+ };
24
+
25
+ return data;
26
+ }
27
+
28
+ var _availableActions = require("./actions/available-actions");
29
+
30
+ var _roleCheck = require("./actions/role-check");
31
+
32
+ var _roleCollections = require("./actions/role-collections");
33
+
34
+ var _RoleModel = require("./model/RoleModel");
35
+
36
+ var _RoleResourceActionModel = require("./model/RoleResourceActionModel");
37
+
38
+ var _RoleResourceModel = require("./model/RoleResourceModel");
39
+
40
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
41
+
42
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
43
+
44
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
45
+
46
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
47
+
48
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
49
+
50
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
51
+
52
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
53
+
54
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
55
+
56
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
57
+
21
58
  class GrantHelper {
22
- constructor() {
23
- this.resourceTargetActionMap = new Map();
24
- this.targetActionResourceMap = new Map();
25
- }
59
+ constructor() {
60
+ this.resourceTargetActionMap = new Map();
61
+ this.targetActionResourceMap = new Map();
62
+ }
63
+
26
64
  }
65
+
27
66
  exports.GrantHelper = GrantHelper;
28
- class PluginACL extends server_1.Plugin {
29
- constructor() {
30
- super(...arguments);
31
- this.associationFieldsActions = {};
32
- this.grantHelper = new GrantHelper();
33
- }
34
- get acl() {
35
- return this.app.acl;
36
- }
37
- registerAssociationFieldAction(associationType, value) {
38
- this.associationFieldsActions[associationType] = value;
39
- }
40
- registerAssociationFieldsActions() {
41
- this.registerAssociationFieldAction('linkTo', {
42
- view: {
43
- associationActions: ['list', 'get'],
44
- },
45
- create: {
46
- associationActions: ['add'],
47
- targetActions: ['view'],
48
- },
49
- update: {
50
- associationActions: ['add', 'remove', 'toggle'],
51
- targetActions: ['view'],
52
- },
67
+
68
+ class PluginACL extends _server().Plugin {
69
+ constructor(...args) {
70
+ super(...args);
71
+ this.associationFieldsActions = {};
72
+ this.grantHelper = new GrantHelper();
73
+ }
74
+
75
+ get acl() {
76
+ return this.app.acl;
77
+ }
78
+
79
+ registerAssociationFieldAction(associationType, value) {
80
+ this.associationFieldsActions[associationType] = value;
81
+ }
82
+
83
+ registerAssociationFieldsActions() {
84
+ // if grant create action to role, it should
85
+ // also grant add action and association target's view action
86
+ this.registerAssociationFieldAction('linkTo', {
87
+ view: {
88
+ associationActions: ['list', 'get']
89
+ },
90
+ create: {
91
+ associationActions: ['add'],
92
+ targetActions: ['view']
93
+ },
94
+ update: {
95
+ associationActions: ['add', 'remove', 'toggle'],
96
+ targetActions: ['view']
97
+ }
98
+ });
99
+ this.registerAssociationFieldAction('attachments', {
100
+ view: {
101
+ associationActions: ['list', 'get']
102
+ },
103
+ add: {
104
+ associationActions: ['upload', 'add']
105
+ },
106
+ update: {
107
+ associationActions: ['update', 'add', 'remove', 'toggle']
108
+ }
109
+ });
110
+ this.registerAssociationFieldAction('subTable', {
111
+ view: {
112
+ associationActions: ['list', 'get']
113
+ },
114
+ create: {
115
+ associationActions: ['create']
116
+ },
117
+ update: {
118
+ associationActions: ['update', 'destroy']
119
+ }
120
+ });
121
+ }
122
+
123
+ writeResourceToACL(resourceModel, transaction) {
124
+ var _this = this;
125
+
126
+ return _asyncToGenerator(function* () {
127
+ yield resourceModel.writeToACL({
128
+ acl: _this.acl,
129
+ associationFieldsActions: _this.associationFieldsActions,
130
+ transaction: transaction,
131
+ grantHelper: _this.grantHelper
132
+ });
133
+ })();
134
+ }
135
+
136
+ writeActionToACL(actionModel, transaction) {
137
+ var _this2 = this;
138
+
139
+ return _asyncToGenerator(function* () {
140
+ const resource = actionModel.get('resource');
141
+
142
+ const role = _this2.acl.getRole(resource.get('roleName'));
143
+
144
+ yield actionModel.writeToACL({
145
+ acl: _this2.acl,
146
+ role,
147
+ resourceName: resource.get('name'),
148
+ associationFieldsActions: _this2.associationFieldsActions,
149
+ grantHelper: _this2.grantHelper
150
+ });
151
+ })();
152
+ }
153
+
154
+ writeRolesToACL() {
155
+ var _this3 = this;
156
+
157
+ return _asyncToGenerator(function* () {
158
+ const roles = yield _this3.app.db.getRepository('roles').find({
159
+ appends: ['resources', 'resources.actions']
160
+ });
161
+
162
+ var _iterator = _createForOfIteratorHelper(roles),
163
+ _step;
164
+
165
+ try {
166
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
167
+ const role = _step.value;
168
+ role.writeToAcl({
169
+ acl: _this3.acl
170
+ });
171
+
172
+ var _iterator2 = _createForOfIteratorHelper(role.get('resources')),
173
+ _step2;
174
+
175
+ try {
176
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
177
+ const resource = _step2.value;
178
+ yield _this3.writeResourceToACL(resource, null);
179
+ }
180
+ } catch (err) {
181
+ _iterator2.e(err);
182
+ } finally {
183
+ _iterator2.f();
184
+ }
185
+ }
186
+ } catch (err) {
187
+ _iterator.e(err);
188
+ } finally {
189
+ _iterator.f();
190
+ }
191
+ })();
192
+ }
193
+
194
+ beforeLoad() {
195
+ var _this4 = this;
196
+
197
+ return _asyncToGenerator(function* () {
198
+ _this4.app.db.registerModels({
199
+ RoleResourceActionModel: _RoleResourceActionModel.RoleResourceActionModel,
200
+ RoleResourceModel: _RoleResourceModel.RoleResourceModel,
201
+ RoleModel: _RoleModel.RoleModel
202
+ });
203
+
204
+ _this4.registerAssociationFieldsActions();
205
+
206
+ _this4.app.resourcer.define(_availableActions.availableActionResource);
207
+
208
+ _this4.app.resourcer.define(_roleCollections.roleCollectionsResource);
209
+
210
+ _this4.app.resourcer.registerActionHandler('roles:check', _roleCheck.checkAction);
211
+
212
+ _this4.app.db.on('roles.afterSaveWithAssociations', /*#__PURE__*/function () {
213
+ var _ref = _asyncToGenerator(function* (model, options) {
214
+ const transaction = options.transaction;
215
+ model.writeToAcl({
216
+ acl: _this4.acl
217
+ });
218
+
219
+ var _iterator3 = _createForOfIteratorHelper(yield model.getResources({
220
+ transaction
221
+ })),
222
+ _step3;
223
+
224
+ try {
225
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
226
+ const resource = _step3.value;
227
+ yield _this4.writeResourceToACL(resource, transaction);
228
+ } // model is default
229
+
230
+ } catch (err) {
231
+ _iterator3.e(err);
232
+ } finally {
233
+ _iterator3.f();
234
+ }
235
+
236
+ if (model.get('default')) {
237
+ yield _this4.app.db.getRepository('roles').update({
238
+ values: {
239
+ default: false
240
+ },
241
+ filter: {
242
+ 'name.$ne': model.get('name')
243
+ },
244
+ hooks: false,
245
+ transaction
246
+ });
247
+ }
53
248
  });
54
- this.registerAssociationFieldAction('attachments', {
55
- view: {
56
- associationActions: ['list', 'get'],
57
- },
58
- add: {
59
- associationActions: ['upload', 'add'],
60
- },
61
- update: {
62
- associationActions: ['update', 'add', 'remove', 'toggle'],
63
- },
249
+
250
+ return function (_x, _x2) {
251
+ return _ref.apply(this, arguments);
252
+ };
253
+ }());
254
+
255
+ _this4.app.db.on('roles.afterDestroy', model => {
256
+ const roleName = model.get('name');
257
+
258
+ _this4.acl.removeRole(roleName);
259
+ });
260
+
261
+ _this4.app.db.on('rolesResources.afterSaveWithAssociations', /*#__PURE__*/function () {
262
+ var _ref2 = _asyncToGenerator(function* (model, options) {
263
+ yield _this4.writeResourceToACL(model, options.transaction);
64
264
  });
65
- this.registerAssociationFieldAction('subTable', {
66
- view: {
67
- associationActions: ['list', 'get'],
68
- },
69
- create: {
70
- associationActions: ['create'],
265
+
266
+ return function (_x3, _x4) {
267
+ return _ref2.apply(this, arguments);
268
+ };
269
+ }());
270
+
271
+ _this4.app.db.on('rolesResourcesActions.afterUpdateWithAssociations', /*#__PURE__*/function () {
272
+ var _ref3 = _asyncToGenerator(function* (model, options) {
273
+ const transaction = options.transaction;
274
+ const resource = yield model.getResource({
275
+ transaction
276
+ });
277
+ yield _this4.writeResourceToACL(resource, transaction);
278
+ });
279
+
280
+ return function (_x5, _x6) {
281
+ return _ref3.apply(this, arguments);
282
+ };
283
+ }());
284
+
285
+ _this4.app.db.on('rolesResources.afterDestroy', /*#__PURE__*/function () {
286
+ var _ref4 = _asyncToGenerator(function* (model, options) {
287
+ const role = _this4.acl.getRole(model.get('roleName'));
288
+
289
+ role.revokeResource(model.get('name'));
290
+ });
291
+
292
+ return function (_x7, _x8) {
293
+ return _ref4.apply(this, arguments);
294
+ };
295
+ }());
296
+
297
+ _this4.app.db.on('collections.afterDestroy', /*#__PURE__*/function () {
298
+ var _ref5 = _asyncToGenerator(function* (model, options) {
299
+ const transaction = options.transaction;
300
+ yield _this4.app.db.getRepository('rolesResources').destroy({
301
+ filter: {
302
+ name: model.get('name')
71
303
  },
72
- update: {
73
- associationActions: ['update', 'destroy'],
304
+ transaction
305
+ });
306
+ });
307
+
308
+ return function (_x9, _x10) {
309
+ return _ref5.apply(this, arguments);
310
+ };
311
+ }());
312
+
313
+ _this4.app.db.on('fields.afterCreate', /*#__PURE__*/function () {
314
+ var _ref6 = _asyncToGenerator(function* (model, options) {
315
+ const transaction = options.transaction;
316
+ const collectionName = model.get('collectionName');
317
+ const fieldName = model.get('name');
318
+ const resourceActions = yield _this4.app.db.getRepository('rolesResourcesActions').find({
319
+ filter: {
320
+ 'resource.name': collectionName
74
321
  },
322
+ transaction,
323
+ appends: ['resource']
324
+ });
325
+
326
+ var _iterator4 = _createForOfIteratorHelper(resourceActions),
327
+ _step4;
328
+
329
+ try {
330
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
331
+ const resourceAction = _step4.value;
332
+ const fields = resourceAction.get('fields');
333
+ const newFields = [...fields, fieldName];
334
+ yield _this4.app.db.getRepository('rolesResourcesActions').update({
335
+ filterByTk: resourceAction.get('id'),
336
+ values: {
337
+ fields: newFields
338
+ },
339
+ transaction
340
+ });
341
+ }
342
+ } catch (err) {
343
+ _iterator4.e(err);
344
+ } finally {
345
+ _iterator4.f();
346
+ }
75
347
  });
76
- }
77
- writeResourceToACL(resourceModel, transaction) {
78
- return __awaiter(this, void 0, void 0, function* () {
79
- yield resourceModel.writeToACL({
80
- acl: this.acl,
81
- associationFieldsActions: this.associationFieldsActions,
82
- transaction: transaction,
83
- grantHelper: this.grantHelper,
84
- });
348
+
349
+ return function (_x11, _x12) {
350
+ return _ref6.apply(this, arguments);
351
+ };
352
+ }());
353
+
354
+ _this4.app.db.on('fields.afterDestroy', /*#__PURE__*/function () {
355
+ var _ref7 = _asyncToGenerator(function* (model, options) {
356
+ const collectionName = model.get('collectionName');
357
+ const fieldName = model.get('name');
358
+ const resourceActions = yield _this4.app.db.getRepository('rolesResourcesActions').find({
359
+ filter: {
360
+ 'resource.name': collectionName,
361
+ 'fields.$anyOf': [fieldName]
362
+ },
363
+ transaction: options.transaction
364
+ });
365
+
366
+ var _iterator5 = _createForOfIteratorHelper(resourceActions),
367
+ _step5;
368
+
369
+ try {
370
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
371
+ const resourceAction = _step5.value;
372
+ const fields = resourceAction.get('fields');
373
+ const newFields = fields.filter(field => field != fieldName);
374
+ yield _this4.app.db.getRepository('rolesResourcesActions').update({
375
+ filterByTk: resourceAction.get('id'),
376
+ values: {
377
+ fields: newFields
378
+ },
379
+ transaction: options.transaction
380
+ });
381
+ }
382
+ } catch (err) {
383
+ _iterator5.e(err);
384
+ } finally {
385
+ _iterator5.f();
386
+ }
85
387
  });
86
- }
87
- writeActionToACL(actionModel, transaction) {
88
- return __awaiter(this, void 0, void 0, function* () {
89
- const resource = actionModel.get('resource');
90
- const role = this.acl.getRole(resource.get('roleName'));
91
- yield actionModel.writeToACL({
92
- acl: this.acl,
93
- role,
94
- resourceName: resource.get('name'),
95
- associationFieldsActions: this.associationFieldsActions,
96
- grantHelper: this.grantHelper,
97
- });
388
+
389
+ return function (_x13, _x14) {
390
+ return _ref7.apply(this, arguments);
391
+ };
392
+ }()); // sync database role data to acl
393
+
394
+
395
+ _this4.app.on('beforeStart', /*#__PURE__*/_asyncToGenerator(function* () {
396
+ yield _this4.writeRolesToACL();
397
+ }));
398
+
399
+ _this4.app.on('beforeInstallPlugin', /*#__PURE__*/function () {
400
+ var _ref9 = _asyncToGenerator(function* (plugin) {
401
+ if (plugin.constructor.name !== 'UsersPlugin') {
402
+ return;
403
+ }
404
+
405
+ const roles = _this4.app.db.getRepository('roles');
406
+
407
+ yield roles.createMany({
408
+ records: [{
409
+ name: 'root',
410
+ title: '{{t("Root")}}',
411
+ hidden: true
412
+ }, {
413
+ name: 'admin',
414
+ title: '{{t("Admin")}}',
415
+ allowConfigure: true,
416
+ allowNewMenu: true,
417
+ strategy: {
418
+ actions: ['create', 'export', 'view', 'update', 'destroy']
419
+ }
420
+ }, {
421
+ name: 'member',
422
+ title: '{{t("Member")}}',
423
+ allowNewMenu: true,
424
+ strategy: {
425
+ actions: ['view', 'update:own', 'destroy:own', 'create']
426
+ },
427
+ default: true
428
+ }]
429
+ });
430
+
431
+ const rolesResourcesScopes = _this4.app.db.getRepository('rolesResourcesScopes');
432
+
433
+ yield rolesResourcesScopes.createMany({
434
+ records: [{
435
+ key: 'all',
436
+ name: '{{t("All records")}}',
437
+ scope: {}
438
+ }, {
439
+ key: 'own',
440
+ name: '{{t("Own records")}}',
441
+ scope: {
442
+ createdById: '{{ ctx.state.currentUser.id }}'
443
+ }
444
+ }]
445
+ });
98
446
  });
99
- }
100
- writeRolesToACL() {
101
- return __awaiter(this, void 0, void 0, function* () {
102
- const roles = (yield this.app.db.getRepository('roles').find({
103
- appends: ['resources', 'resources.actions'],
104
- }));
105
- for (const role of roles) {
106
- role.writeToAcl({ acl: this.acl });
107
- for (const resource of role.get('resources')) {
108
- yield this.writeResourceToACL(resource, null);
447
+
448
+ return function (_x15) {
449
+ return _ref9.apply(this, arguments);
450
+ };
451
+ }());
452
+
453
+ _this4.app.acl.allow('roles', 'check', 'loggedIn');
454
+
455
+ _this4.app.acl.allow('roles', ['create', 'update', 'destroy'], 'allowConfigure');
456
+
457
+ _this4.app.acl.allow('roles.menuUiSchemas', ['set', 'toggle', 'list'], 'allowConfigure');
458
+
459
+ _this4.app.acl.allow('*', '*', ctx => {
460
+ return ctx.state.currentRole === 'root';
461
+ });
462
+
463
+ _this4.app.resourcer.use( /*#__PURE__*/function () {
464
+ var _ref10 = _asyncToGenerator(function* (ctx, next) {
465
+ const _ctx$action = ctx.action,
466
+ actionName = _ctx$action.actionName,
467
+ resourceName = _ctx$action.resourceName,
468
+ params = _ctx$action.params;
469
+
470
+ const _ref11 = params || {},
471
+ showAnonymous = _ref11.showAnonymous;
472
+
473
+ if (actionName === 'list' && resourceName === 'roles') {
474
+ if (!showAnonymous) {
475
+ ctx.action.mergeParams({
476
+ filter: {
477
+ 'name.$ne': 'anonymous'
109
478
  }
479
+ });
110
480
  }
481
+ }
482
+
483
+ yield next();
111
484
  });
112
- }
113
- beforeLoad() {
114
- return __awaiter(this, void 0, void 0, function* () {
115
- this.app.db.registerModels({
116
- RoleResourceActionModel: RoleResourceActionModel_1.RoleResourceActionModel,
117
- RoleResourceModel: RoleResourceModel_1.RoleResourceModel,
118
- RoleModel: RoleModel_1.RoleModel,
119
- });
120
- this.registerAssociationFieldsActions();
121
- this.app.resourcer.define(available_actions_1.availableActionResource);
122
- this.app.resourcer.define(role_collections_1.roleCollectionsResource);
123
- this.app.resourcer.registerActionHandler('roles:check', role_check_1.checkAction);
124
- this.app.db.on('roles.afterSaveWithAssociations', (model, options) => __awaiter(this, void 0, void 0, function* () {
125
- const { transaction } = options;
126
- model.writeToAcl({
127
- acl: this.acl,
128
- });
129
- for (const resource of (yield model.getResources({ transaction }))) {
130
- yield this.writeResourceToACL(resource, transaction);
131
- }
132
- // model is default
133
- if (model.get('default')) {
134
- yield this.app.db.getRepository('roles').update({
135
- values: {
136
- default: false,
137
- },
138
- filter: {
139
- 'name.$ne': model.get('name'),
140
- },
141
- hooks: false,
142
- transaction,
143
- });
144
- }
145
- }));
146
- this.app.db.on('roles.afterDestroy', (model) => {
147
- const roleName = model.get('name');
148
- this.acl.removeRole(roleName);
149
- });
150
- this.app.db.on('rolesResources.afterSaveWithAssociations', (model, options) => __awaiter(this, void 0, void 0, function* () {
151
- yield this.writeResourceToACL(model, options.transaction);
152
- }));
153
- this.app.db.on('rolesResourcesActions.afterUpdateWithAssociations', (model, options) => __awaiter(this, void 0, void 0, function* () {
154
- const { transaction } = options;
155
- const resource = yield model.getResource({
156
- transaction,
157
- });
158
- yield this.writeResourceToACL(resource, transaction);
159
- }));
160
- this.app.db.on('rolesResources.afterDestroy', (model, options) => __awaiter(this, void 0, void 0, function* () {
161
- const role = this.acl.getRole(model.get('roleName'));
162
- role.revokeResource(model.get('name'));
163
- }));
164
- this.app.db.on('collections.afterDestroy', (model, options) => __awaiter(this, void 0, void 0, function* () {
165
- const { transaction } = options;
166
- yield this.app.db.getRepository('rolesResources').destroy({
167
- filter: {
168
- name: model.get('name'),
169
- },
170
- transaction,
171
- });
172
- }));
173
- this.app.db.on('fields.afterCreate', (model, options) => __awaiter(this, void 0, void 0, function* () {
174
- const { transaction } = options;
175
- const collectionName = model.get('collectionName');
176
- const fieldName = model.get('name');
177
- const resourceActions = (yield this.app.db.getRepository('rolesResourcesActions').find({
178
- filter: {
179
- 'resource.name': collectionName,
180
- },
181
- transaction,
182
- appends: ['resource'],
183
- }));
184
- for (const resourceAction of resourceActions) {
185
- const fields = resourceAction.get('fields');
186
- const newFields = [...fields, fieldName];
187
- yield this.app.db.getRepository('rolesResourcesActions').update({
188
- filterByTk: resourceAction.get('id'),
189
- values: {
190
- fields: newFields,
191
- },
192
- transaction,
193
- });
194
- }
195
- }));
196
- this.app.db.on('fields.afterDestroy', (model, options) => __awaiter(this, void 0, void 0, function* () {
197
- const collectionName = model.get('collectionName');
198
- const fieldName = model.get('name');
199
- const resourceActions = yield this.app.db.getRepository('rolesResourcesActions').find({
200
- filter: {
201
- 'resource.name': collectionName,
202
- 'fields.$anyOf': [fieldName],
203
- },
204
- transaction: options.transaction,
205
- });
206
- for (const resourceAction of resourceActions) {
207
- const fields = resourceAction.get('fields');
208
- const newFields = fields.filter((field) => field != fieldName);
209
- yield this.app.db.getRepository('rolesResourcesActions').update({
210
- filterByTk: resourceAction.get('id'),
211
- values: {
212
- fields: newFields,
213
- },
214
- transaction: options.transaction,
215
- });
216
- }
217
- }));
218
- // sync database role data to acl
219
- this.app.on('beforeStart', () => __awaiter(this, void 0, void 0, function* () {
220
- yield this.writeRolesToACL();
221
- }));
222
- this.app.on('beforeInstallPlugin', (plugin) => __awaiter(this, void 0, void 0, function* () {
223
- if (plugin.constructor.name !== 'UsersPlugin') {
224
- return;
225
- }
226
- const roles = this.app.db.getRepository('roles');
227
- yield roles.createMany({
228
- records: [
229
- {
230
- name: 'root',
231
- title: '{{t("Root")}}',
232
- hidden: true,
233
- },
234
- {
235
- name: 'admin',
236
- title: '{{t("Admin")}}',
237
- allowConfigure: true,
238
- allowNewMenu: true,
239
- strategy: { actions: ['create', 'export', 'view', 'update', 'destroy'] },
240
- },
241
- {
242
- name: 'member',
243
- title: '{{t("Member")}}',
244
- allowNewMenu: true,
245
- strategy: { actions: ['view', 'update:own', 'destroy:own', 'create'] },
246
- default: true,
247
- },
248
- ],
249
- });
250
- const rolesResourcesScopes = this.app.db.getRepository('rolesResourcesScopes');
251
- yield rolesResourcesScopes.createMany({
252
- records: [
253
- {
254
- key: 'all',
255
- name: '{{t("All records")}}',
256
- scope: {},
257
- },
258
- {
259
- key: 'own',
260
- name: '{{t("Own records")}}',
261
- scope: {
262
- createdById: '{{ ctx.state.currentUser.id }}',
263
- },
264
- },
265
- ],
266
- });
267
- }));
268
- this.app.acl.allow('roles', 'check', 'loggedIn');
269
- this.app.acl.allow('roles', ['create', 'update', 'destroy'], 'allowConfigure');
270
- this.app.acl.allow('roles.menuUiSchemas', ['set', 'toggle', 'list'], 'allowConfigure');
271
- this.app.acl.allow('*', '*', (ctx) => {
272
- return ctx.state.currentRole === 'root';
273
- });
274
- this.app.resourcer.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
275
- const { actionName, resourceName, params } = ctx.action;
276
- const { showAnonymous } = params || {};
277
- if (actionName === 'list' && resourceName === 'roles') {
278
- if (!showAnonymous) {
279
- ctx.action.mergeParams({
280
- filter: {
281
- 'name.$ne': 'anonymous',
282
- },
283
- });
284
- }
285
- }
286
- yield next();
287
- }));
288
- this.app.acl.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
289
- var _a, _b, _c, _d, _e;
290
- const { actionName, resourceName } = ctx.action;
291
- if (actionName === 'get' || actionName === 'list') {
292
- if (!Array.isArray((_c = (_b = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.permission) === null || _a === void 0 ? void 0 : _a.can) === null || _b === void 0 ? void 0 : _b.params) === null || _c === void 0 ? void 0 : _c.fields)) {
293
- return next();
294
- }
295
- let collection;
296
- if (resourceName.includes('.')) {
297
- const [collectionName, associationName] = resourceName.split('.');
298
- const field = (_e = (_d = ctx.db.getCollection(collectionName)) === null || _d === void 0 ? void 0 : _d.getField) === null || _e === void 0 ? void 0 : _e.call(_d, associationName);
299
- if (field.target) {
300
- collection = ctx.db.getCollection(field.target);
301
- }
302
- }
303
- else {
304
- collection = ctx.db.getCollection(resourceName);
305
- }
306
- if (collection && collection.hasField('createdById')) {
307
- ctx.permission.can.params.fields.push('createdById');
308
- }
309
- }
310
- return next();
311
- }));
312
- const parseJsonTemplate = this.app.acl.parseJsonTemplate;
313
- this.app.acl.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
314
- var _f, _g, _h, _j;
315
- const { actionName, resourceName, resourceOf } = ctx.action;
316
- if (resourceName.includes('.') && resourceOf) {
317
- if (!((_g = (_f = ctx === null || ctx === void 0 ? void 0 : ctx.permission) === null || _f === void 0 ? void 0 : _f.can) === null || _g === void 0 ? void 0 : _g.params)) {
318
- return next();
319
- }
320
- // 关联数据去掉 filter
321
- delete ctx.permission.can.params.filter;
322
- // 关联数据能不能处理取决于 source 是否有权限
323
- const [collectionName] = resourceName.split('.');
324
- const action = ctx.can({ resource: collectionName, action: actionName });
325
- const availableAction = this.app.acl.getAvailableAction(actionName);
326
- if ((_h = availableAction === null || availableAction === void 0 ? void 0 : availableAction.options) === null || _h === void 0 ? void 0 : _h.onNewRecord) {
327
- if (action) {
328
- ctx.permission.skip = true;
329
- }
330
- else {
331
- ctx.permission.can = false;
332
- }
333
- }
334
- else {
335
- const filter = parseJsonTemplate(((_j = action === null || action === void 0 ? void 0 : action.params) === null || _j === void 0 ? void 0 : _j.filter) || {}, ctx);
336
- const sourceInstance = yield ctx.db.getRepository(collectionName).findOne({
337
- filterByTk: resourceOf,
338
- filter,
339
- });
340
- if (!sourceInstance) {
341
- ctx.permission.can = false;
342
- }
343
- }
344
- }
345
- yield next();
346
- }));
347
- });
348
- }
349
- install() {
350
- return __awaiter(this, void 0, void 0, function* () {
351
- const repo = this.db.getRepository('collections');
352
- if (repo) {
353
- yield repo.db2cm('roles');
485
+
486
+ return function (_x16, _x17) {
487
+ return _ref10.apply(this, arguments);
488
+ };
489
+ }());
490
+
491
+ _this4.app.acl.use( /*#__PURE__*/function () {
492
+ var _ref12 = _asyncToGenerator(function* (ctx, next) {
493
+ const _ctx$action2 = ctx.action,
494
+ actionName = _ctx$action2.actionName,
495
+ resourceName = _ctx$action2.resourceName;
496
+
497
+ if (actionName === 'get' || actionName === 'list') {
498
+ var _ctx$permission, _ctx$permission$can, _ctx$permission$can$p;
499
+
500
+ if (!Array.isArray(ctx === null || ctx === void 0 ? void 0 : (_ctx$permission = ctx.permission) === null || _ctx$permission === void 0 ? void 0 : (_ctx$permission$can = _ctx$permission.can) === null || _ctx$permission$can === void 0 ? void 0 : (_ctx$permission$can$p = _ctx$permission$can.params) === null || _ctx$permission$can$p === void 0 ? void 0 : _ctx$permission$can$p.fields)) {
501
+ return next();
502
+ }
503
+
504
+ let collection;
505
+
506
+ if (resourceName.includes('.')) {
507
+ var _ctx$db$getCollection, _ctx$db$getCollection2;
508
+
509
+ const _resourceName$split = resourceName.split('.'),
510
+ _resourceName$split2 = _slicedToArray(_resourceName$split, 2),
511
+ collectionName = _resourceName$split2[0],
512
+ associationName = _resourceName$split2[1];
513
+
514
+ const field = (_ctx$db$getCollection = ctx.db.getCollection(collectionName)) === null || _ctx$db$getCollection === void 0 ? void 0 : (_ctx$db$getCollection2 = _ctx$db$getCollection.getField) === null || _ctx$db$getCollection2 === void 0 ? void 0 : _ctx$db$getCollection2.call(_ctx$db$getCollection, associationName);
515
+
516
+ if (field.target) {
517
+ collection = ctx.db.getCollection(field.target);
518
+ }
519
+ } else {
520
+ collection = ctx.db.getCollection(resourceName);
354
521
  }
522
+
523
+ if (collection && collection.hasField('createdById')) {
524
+ ctx.permission.can.params.fields.push('createdById');
525
+ }
526
+ }
527
+
528
+ return next();
355
529
  });
356
- }
357
- load() {
358
- return __awaiter(this, void 0, void 0, function* () {
359
- yield this.app.db.import({
360
- directory: (0, path_1.resolve)(__dirname, 'collections'),
530
+
531
+ return function (_x18, _x19) {
532
+ return _ref12.apply(this, arguments);
533
+ };
534
+ }());
535
+
536
+ const parseJsonTemplate = _this4.app.acl.parseJsonTemplate;
537
+
538
+ _this4.app.acl.use( /*#__PURE__*/function () {
539
+ var _ref13 = _asyncToGenerator(function* (ctx, next) {
540
+ const _ctx$action3 = ctx.action,
541
+ actionName = _ctx$action3.actionName,
542
+ resourceName = _ctx$action3.resourceName,
543
+ resourceOf = _ctx$action3.resourceOf;
544
+
545
+ if (resourceName.includes('.') && resourceOf) {
546
+ var _ctx$permission2, _ctx$permission2$can, _availableAction$opti;
547
+
548
+ if (!(ctx === null || ctx === void 0 ? void 0 : (_ctx$permission2 = ctx.permission) === null || _ctx$permission2 === void 0 ? void 0 : (_ctx$permission2$can = _ctx$permission2.can) === null || _ctx$permission2$can === void 0 ? void 0 : _ctx$permission2$can.params)) {
549
+ return next();
550
+ } // 关联数据去掉 filter
551
+
552
+
553
+ delete ctx.permission.can.params.filter; // 关联数据能不能处理取决于 source 是否有权限
554
+
555
+ const _resourceName$split3 = resourceName.split('.'),
556
+ _resourceName$split4 = _slicedToArray(_resourceName$split3, 1),
557
+ collectionName = _resourceName$split4[0];
558
+
559
+ const action = ctx.can({
560
+ resource: collectionName,
561
+ action: actionName
361
562
  });
362
- this.app.resourcer.use(this.acl.middleware());
563
+
564
+ const availableAction = _this4.app.acl.getAvailableAction(actionName);
565
+
566
+ if (availableAction === null || availableAction === void 0 ? void 0 : (_availableAction$opti = availableAction.options) === null || _availableAction$opti === void 0 ? void 0 : _availableAction$opti.onNewRecord) {
567
+ if (action) {
568
+ ctx.permission.skip = true;
569
+ } else {
570
+ ctx.permission.can = false;
571
+ }
572
+ } else {
573
+ var _action$params;
574
+
575
+ const filter = parseJsonTemplate((action === null || action === void 0 ? void 0 : (_action$params = action.params) === null || _action$params === void 0 ? void 0 : _action$params.filter) || {}, ctx);
576
+ const sourceInstance = yield ctx.db.getRepository(collectionName).findOne({
577
+ filterByTk: resourceOf,
578
+ filter
579
+ });
580
+
581
+ if (!sourceInstance) {
582
+ ctx.permission.can = false;
583
+ }
584
+ }
585
+ }
586
+
587
+ yield next();
363
588
  });
364
- }
365
- getName() {
366
- return this.getPackageName(__dirname);
367
- }
589
+
590
+ return function (_x20, _x21) {
591
+ return _ref13.apply(this, arguments);
592
+ };
593
+ }());
594
+ })();
595
+ }
596
+
597
+ install() {
598
+ var _this5 = this;
599
+
600
+ return _asyncToGenerator(function* () {
601
+ const repo = _this5.db.getRepository('collections');
602
+
603
+ if (repo) {
604
+ yield repo.db2cm('roles');
605
+ }
606
+ })();
607
+ }
608
+
609
+ load() {
610
+ var _this6 = this;
611
+
612
+ return _asyncToGenerator(function* () {
613
+ yield _this6.app.db.import({
614
+ directory: (0, _path().resolve)(__dirname, 'collections')
615
+ });
616
+
617
+ _this6.app.resourcer.use(_this6.acl.middleware());
618
+ })();
619
+ }
620
+
621
+ getName() {
622
+ return this.getPackageName(__dirname);
623
+ }
624
+
368
625
  }
626
+
369
627
  exports.PluginACL = PluginACL;
370
- exports.default = PluginACL;
371
- //# sourceMappingURL=server.js.map
628
+ var _default = PluginACL;
629
+ exports.default = _default;