@nocobase/plugin-acl 0.9.1-alpha.2 → 0.9.2-alpha.2

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/lib/server.js CHANGED
@@ -4,134 +4,91 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = exports.PluginACL = exports.GrantHelper = void 0;
7
-
8
7
  function _acl() {
9
8
  const data = require("@nocobase/acl");
10
-
11
9
  _acl = function _acl() {
12
10
  return data;
13
11
  };
14
-
15
12
  return data;
16
13
  }
17
-
18
- function _actions2() {
14
+ function _actions() {
19
15
  const data = require("@nocobase/actions");
20
-
21
- _actions2 = function _actions2() {
16
+ _actions = function _actions() {
22
17
  return data;
23
18
  };
24
-
25
19
  return data;
26
20
  }
27
-
28
21
  function _database() {
29
22
  const data = require("@nocobase/database");
30
-
31
23
  _database = function _database() {
32
24
  return data;
33
25
  };
34
-
35
26
  return data;
36
27
  }
37
-
38
28
  function _server() {
39
29
  const data = require("@nocobase/server");
40
-
41
30
  _server = function _server() {
42
31
  return data;
43
32
  };
44
-
45
33
  return data;
46
34
  }
47
-
48
35
  function _lodash() {
49
36
  const data = _interopRequireDefault(require("lodash"));
50
-
51
37
  _lodash = function _lodash() {
52
38
  return data;
53
39
  };
54
-
55
40
  return data;
56
41
  }
57
-
58
42
  function _path() {
59
43
  const data = require("path");
60
-
61
44
  _path = function _path() {
62
45
  return data;
63
46
  };
64
-
65
47
  return data;
66
48
  }
67
-
68
49
  var _availableActions = require("./actions/available-actions");
69
-
70
50
  var _roleCheck = require("./actions/role-check");
71
-
72
51
  var _roleCollections = require("./actions/role-collections");
73
-
74
52
  var _userSetDefaultRole = require("./actions/user-setDefaultRole");
75
-
76
53
  var _setCurrentRole = require("./middlewares/setCurrentRole");
77
-
78
54
  var _RoleModel = require("./model/RoleModel");
79
-
80
55
  var _RoleResourceActionModel = require("./model/RoleResourceActionModel");
81
-
82
56
  var _RoleResourceModel = require("./model/RoleResourceModel");
83
-
84
57
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
85
-
86
58
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
87
-
88
59
  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."); }
89
-
90
- 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; }
91
-
60
+ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
92
61
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
93
-
94
62
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
95
-
96
63
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
97
-
98
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
99
-
64
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
65
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
66
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
100
67
  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; } } }; }
101
-
102
68
  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); }
103
-
104
69
  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; }
105
-
106
70
  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); } }
107
-
108
71
  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); }); }; }
109
-
110
72
  class GrantHelper {
111
73
  constructor() {
112
74
  this.resourceTargetActionMap = new Map();
113
75
  this.targetActionResourceMap = new Map();
114
76
  }
115
-
116
77
  }
117
-
118
78
  exports.GrantHelper = GrantHelper;
119
-
120
79
  class PluginACL extends _server().Plugin {
121
80
  constructor(...args) {
122
81
  super(...args);
82
+ // association field actions config
123
83
  this.associationFieldsActions = {};
124
84
  this.grantHelper = new GrantHelper();
125
85
  }
126
-
127
86
  get acl() {
128
87
  return this.app.acl;
129
88
  }
130
-
131
89
  registerAssociationFieldAction(associationType, value) {
132
90
  this.associationFieldsActions[associationType] = value;
133
91
  }
134
-
135
92
  registerAssociationFieldsActions() {
136
93
  // if grant create action to role, it should
137
94
  // also grant add action and association target's view action
@@ -180,10 +137,8 @@ class PluginACL extends _server().Plugin {
180
137
  }
181
138
  });
182
139
  }
183
-
184
140
  writeResourceToACL(resourceModel, transaction) {
185
141
  var _this = this;
186
-
187
142
  return _asyncToGenerator(function* () {
188
143
  yield resourceModel.writeToACL({
189
144
  acl: _this.acl,
@@ -193,15 +148,11 @@ class PluginACL extends _server().Plugin {
193
148
  });
194
149
  })();
195
150
  }
196
-
197
151
  writeActionToACL(actionModel, transaction) {
198
152
  var _this2 = this;
199
-
200
153
  return _asyncToGenerator(function* () {
201
154
  const resource = actionModel.get('resource');
202
-
203
155
  const role = _this2.acl.getRole(resource.get('roleName'));
204
-
205
156
  yield actionModel.writeToACL({
206
157
  acl: _this2.acl,
207
158
  role,
@@ -211,28 +162,22 @@ class PluginACL extends _server().Plugin {
211
162
  });
212
163
  })();
213
164
  }
214
-
215
165
  writeRolesToACL() {
216
166
  var _this3 = this;
217
-
218
167
  return _asyncToGenerator(function* () {
219
168
  const roles = yield _this3.app.db.getRepository('roles').find({
220
169
  appends: ['resources', 'resources.actions']
221
170
  });
222
-
223
171
  var _iterator = _createForOfIteratorHelper(roles),
224
- _step;
225
-
172
+ _step;
226
173
  try {
227
174
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
228
175
  const role = _step.value;
229
176
  role.writeToAcl({
230
177
  acl: _this3.acl
231
178
  });
232
-
233
179
  var _iterator2 = _createForOfIteratorHelper(role.get('resources')),
234
- _step2;
235
-
180
+ _step2;
236
181
  try {
237
182
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
238
183
  const resource = _step2.value;
@@ -251,10 +196,8 @@ class PluginACL extends _server().Plugin {
251
196
  }
252
197
  })();
253
198
  }
254
-
255
199
  beforeLoad() {
256
200
  var _this4 = this;
257
-
258
201
  return _asyncToGenerator(function* () {
259
202
  _this4.db.addMigrations({
260
203
  namespace: _this4.name,
@@ -263,34 +206,26 @@ class PluginACL extends _server().Plugin {
263
206
  plugin: _this4
264
207
  }
265
208
  });
266
-
267
209
  _this4.app.db.registerModels({
268
210
  RoleResourceActionModel: _RoleResourceActionModel.RoleResourceActionModel,
269
211
  RoleResourceModel: _RoleResourceModel.RoleResourceModel,
270
212
  RoleModel: _RoleModel.RoleModel
271
213
  });
272
-
273
214
  _this4.app.acl.registerSnippet({
274
215
  name: `pm.${_this4.name}.roles`,
275
216
  actions: ['roles:*', 'roles.snippets:*', 'availableActions:list', 'roles.collections:list', 'roles.resources:*', 'uiSchemas:getProperties', 'roles.menuUiSchemas:*']
276
- }); // change resource fields to association fields
277
-
278
-
217
+ });
218
+ // change resource fields to association fields
279
219
  _this4.app.acl.beforeGrantAction(ctx => {
280
220
  const actionName = _this4.app.acl.resolveActionAlias(ctx.actionName);
281
-
282
221
  const collection = _this4.app.db.getCollection(ctx.resourceName);
283
-
284
222
  if (!collection) {
285
223
  return;
286
224
  }
287
-
288
225
  const fieldsParams = ctx.params.fields;
289
-
290
226
  if (!fieldsParams) {
291
227
  return;
292
228
  }
293
-
294
229
  if (actionName == 'view' || actionName == 'export') {
295
230
  const associationsFields = fieldsParams.filter(fieldName => {
296
231
  const field = collection.getField(fieldName);
@@ -302,30 +237,21 @@ class PluginACL extends _server().Plugin {
302
237
  });
303
238
  }
304
239
  });
305
-
306
240
  _this4.registerAssociationFieldsActions();
307
-
308
241
  _this4.app.resourcer.define(_availableActions.availableActionResource);
309
-
310
242
  _this4.app.resourcer.define(_roleCollections.roleCollectionsResource);
311
-
312
243
  _this4.app.resourcer.registerActionHandler('roles:check', _roleCheck.checkAction);
313
-
314
244
  _this4.app.resourcer.registerActionHandler(`users:setDefaultRole`, _userSetDefaultRole.setDefaultRole);
315
-
316
245
  _this4.db.on('users.afterCreateWithAssociations', /*#__PURE__*/function () {
317
246
  var _ref = _asyncToGenerator(function* (model, options) {
318
247
  const transaction = options.transaction;
319
-
320
248
  const repository = _this4.app.db.getRepository('roles');
321
-
322
249
  const defaultRole = yield repository.findOne({
323
250
  filter: {
324
251
  default: true
325
252
  },
326
253
  transaction
327
254
  });
328
-
329
255
  if (defaultRole && (yield model.countRoles({
330
256
  transaction
331
257
  })) == 0) {
@@ -334,36 +260,31 @@ class PluginACL extends _server().Plugin {
334
260
  });
335
261
  }
336
262
  });
337
-
338
263
  return function (_x, _x2) {
339
264
  return _ref.apply(this, arguments);
340
265
  };
341
266
  }());
342
-
343
267
  _this4.app.db.on('roles.afterSaveWithAssociations', /*#__PURE__*/function () {
344
268
  var _ref2 = _asyncToGenerator(function* (model, options) {
345
269
  const transaction = options.transaction;
346
270
  model.writeToAcl({
347
271
  acl: _this4.acl
348
272
  });
349
-
350
273
  var _iterator3 = _createForOfIteratorHelper(yield model.getResources({
351
- transaction
352
- })),
353
- _step3;
354
-
274
+ transaction
275
+ })),
276
+ _step3;
355
277
  try {
356
278
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
357
279
  const resource = _step3.value;
358
280
  yield _this4.writeResourceToACL(resource, transaction);
359
- } // model is default
360
-
281
+ }
282
+ // model is default
361
283
  } catch (err) {
362
284
  _iterator3.e(err);
363
285
  } finally {
364
286
  _iterator3.f();
365
287
  }
366
-
367
288
  if (model.get('default')) {
368
289
  yield _this4.app.db.getRepository('roles').update({
369
290
  values: {
@@ -377,28 +298,22 @@ class PluginACL extends _server().Plugin {
377
298
  });
378
299
  }
379
300
  });
380
-
381
301
  return function (_x3, _x4) {
382
302
  return _ref2.apply(this, arguments);
383
303
  };
384
304
  }());
385
-
386
305
  _this4.app.db.on('roles.afterDestroy', model => {
387
306
  const roleName = model.get('name');
388
-
389
307
  _this4.acl.removeRole(roleName);
390
308
  });
391
-
392
309
  _this4.app.db.on('rolesResources.afterSaveWithAssociations', /*#__PURE__*/function () {
393
310
  var _ref3 = _asyncToGenerator(function* (model, options) {
394
311
  yield _this4.writeResourceToACL(model, options.transaction);
395
312
  });
396
-
397
313
  return function (_x5, _x6) {
398
314
  return _ref3.apply(this, arguments);
399
315
  };
400
316
  }());
401
-
402
317
  _this4.app.db.on('rolesResourcesActions.afterUpdateWithAssociations', /*#__PURE__*/function () {
403
318
  var _ref4 = _asyncToGenerator(function* (model, options) {
404
319
  const transaction = options.transaction;
@@ -407,26 +322,21 @@ class PluginACL extends _server().Plugin {
407
322
  });
408
323
  yield _this4.writeResourceToACL(resource, transaction);
409
324
  });
410
-
411
325
  return function (_x7, _x8) {
412
326
  return _ref4.apply(this, arguments);
413
327
  };
414
328
  }());
415
-
416
329
  _this4.app.db.on('rolesResources.afterDestroy', /*#__PURE__*/function () {
417
330
  var _ref5 = _asyncToGenerator(function* (model, options) {
418
331
  const role = _this4.acl.getRole(model.get('roleName'));
419
-
420
332
  if (role) {
421
333
  role.revokeResource(model.get('name'));
422
334
  }
423
335
  });
424
-
425
336
  return function (_x9, _x10) {
426
337
  return _ref5.apply(this, arguments);
427
338
  };
428
339
  }());
429
-
430
340
  _this4.app.db.on('collections.afterDestroy', /*#__PURE__*/function () {
431
341
  var _ref6 = _asyncToGenerator(function* (model, options) {
432
342
  const transaction = options.transaction;
@@ -437,12 +347,10 @@ class PluginACL extends _server().Plugin {
437
347
  transaction
438
348
  });
439
349
  });
440
-
441
350
  return function (_x11, _x12) {
442
351
  return _ref6.apply(this, arguments);
443
352
  };
444
353
  }());
445
-
446
354
  _this4.app.db.on('fields.afterCreate', /*#__PURE__*/function () {
447
355
  var _ref7 = _asyncToGenerator(function* (model, options) {
448
356
  const transaction = options.transaction;
@@ -455,10 +363,8 @@ class PluginACL extends _server().Plugin {
455
363
  transaction,
456
364
  appends: ['resource']
457
365
  });
458
-
459
366
  var _iterator4 = _createForOfIteratorHelper(resourceActions),
460
- _step4;
461
-
367
+ _step4;
462
368
  try {
463
369
  for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
464
370
  const resourceAction = _step4.value;
@@ -478,12 +384,10 @@ class PluginACL extends _server().Plugin {
478
384
  _iterator4.f();
479
385
  }
480
386
  });
481
-
482
387
  return function (_x13, _x14) {
483
388
  return _ref7.apply(this, arguments);
484
389
  };
485
390
  }());
486
-
487
391
  _this4.app.db.on('fields.afterDestroy', /*#__PURE__*/function () {
488
392
  var _ref8 = _asyncToGenerator(function* (model, options) {
489
393
  const collectionName = model.get('collectionName');
@@ -495,10 +399,8 @@ class PluginACL extends _server().Plugin {
495
399
  },
496
400
  transaction: options.transaction
497
401
  });
498
-
499
402
  var _iterator5 = _createForOfIteratorHelper(resourceActions),
500
- _step5;
501
-
403
+ _step5;
502
404
  try {
503
405
  for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
504
406
  const resourceAction = _step5.value;
@@ -518,62 +420,49 @@ class PluginACL extends _server().Plugin {
518
420
  _iterator5.f();
519
421
  }
520
422
  });
521
-
522
423
  return function (_x15, _x16) {
523
424
  return _ref8.apply(this, arguments);
524
425
  };
525
- }()); // sync database role data to acl
526
-
527
-
426
+ }());
427
+ // sync database role data to acl
528
428
  _this4.app.on('afterLoad', /*#__PURE__*/function () {
529
429
  var _ref9 = _asyncToGenerator(function* (app, options) {
530
430
  if ((options === null || options === void 0 ? void 0 : options.method) === 'install' || (options === null || options === void 0 ? void 0 : options.method) === 'upgrade') {
531
431
  return;
532
432
  }
533
-
534
433
  const exists = yield _this4.app.db.collectionExistsInDb('roles');
535
-
536
434
  if (exists) {
537
435
  yield _this4.writeRolesToACL();
538
436
  }
539
437
  });
540
-
541
438
  return function (_x17, _x18) {
542
439
  return _ref9.apply(this, arguments);
543
440
  };
544
441
  }());
545
-
546
442
  _this4.app.on('afterInstall', /*#__PURE__*/function () {
547
443
  var _ref10 = _asyncToGenerator(function* (app, options) {
548
444
  const exists = yield _this4.app.db.collectionExistsInDb('roles');
549
-
550
445
  if (exists) {
551
446
  yield _this4.writeRolesToACL();
552
447
  }
553
448
  });
554
-
555
449
  return function (_x19, _x20) {
556
450
  return _ref10.apply(this, arguments);
557
451
  };
558
452
  }());
559
-
560
453
  _this4.app.on('afterInstallPlugin', /*#__PURE__*/function () {
561
454
  var _ref11 = _asyncToGenerator(function* (plugin) {
562
455
  if (plugin.getName() !== 'users') {
563
456
  return;
564
457
  }
565
-
566
458
  const User = _this4.db.getCollection('users');
567
-
568
459
  yield User.repository.update({
569
460
  values: {
570
461
  roles: ['root', 'admin', 'member']
571
462
  },
572
463
  forceUpdate: true
573
464
  });
574
-
575
465
  const RolesUsers = _this4.db.getCollection('rolesUsers');
576
-
577
466
  yield RolesUsers.repository.update({
578
467
  filter: {
579
468
  userId: 1,
@@ -584,20 +473,16 @@ class PluginACL extends _server().Plugin {
584
473
  }
585
474
  });
586
475
  });
587
-
588
476
  return function (_x21) {
589
477
  return _ref11.apply(this, arguments);
590
478
  };
591
479
  }());
592
-
593
480
  _this4.app.on('beforeInstallPlugin', /*#__PURE__*/function () {
594
481
  var _ref12 = _asyncToGenerator(function* (plugin) {
595
482
  if (plugin.getName() !== 'users') {
596
483
  return;
597
484
  }
598
-
599
485
  const roles = _this4.app.db.getRepository('roles');
600
-
601
486
  yield roles.createMany({
602
487
  records: [{
603
488
  name: 'root',
@@ -624,9 +509,7 @@ class PluginACL extends _server().Plugin {
624
509
  snippets: ['!ui.*', '!pm', '!pm.*']
625
510
  }]
626
511
  });
627
-
628
512
  const rolesResourcesScopes = _this4.app.db.getRepository('rolesResourcesScopes');
629
-
630
513
  yield rolesResourcesScopes.createMany({
631
514
  records: [{
632
515
  key: 'all',
@@ -641,26 +524,20 @@ class PluginACL extends _server().Plugin {
641
524
  }]
642
525
  });
643
526
  });
644
-
645
527
  return function (_x22) {
646
528
  return _ref12.apply(this, arguments);
647
529
  };
648
530
  }());
649
-
650
531
  _this4.app.resourcer.use(_setCurrentRole.setCurrentRole, {
651
532
  tag: 'setCurrentRole',
652
533
  before: 'acl',
653
534
  after: 'parseToken'
654
535
  });
655
-
656
536
  _this4.app.acl.allow('users', 'setDefaultRole', 'loggedIn');
657
-
658
537
  _this4.app.acl.allow('roles', 'check', 'loggedIn');
659
-
660
538
  _this4.app.acl.allow('*', '*', ctx => {
661
539
  return ctx.state.currentRole === 'root';
662
540
  });
663
-
664
541
  _this4.app.acl.addFixedParams('collections', 'destroy', () => {
665
542
  return {
666
543
  filter: {
@@ -672,7 +549,6 @@ class PluginACL extends _server().Plugin {
672
549
  }
673
550
  };
674
551
  });
675
-
676
552
  _this4.app.acl.addFixedParams('rolesResourcesScopes', 'destroy', () => {
677
553
  return {
678
554
  filter: {
@@ -684,7 +560,6 @@ class PluginACL extends _server().Plugin {
684
560
  }
685
561
  };
686
562
  });
687
-
688
563
  _this4.app.acl.addFixedParams('rolesResourcesScopes', 'update', () => {
689
564
  return {
690
565
  filter: {
@@ -696,7 +571,6 @@ class PluginACL extends _server().Plugin {
696
571
  }
697
572
  };
698
573
  });
699
-
700
574
  _this4.app.acl.addFixedParams('roles', 'destroy', () => {
701
575
  return {
702
576
  filter: {
@@ -710,17 +584,14 @@ class PluginACL extends _server().Plugin {
710
584
  }
711
585
  };
712
586
  });
713
-
714
587
  _this4.app.resourcer.use( /*#__PURE__*/function () {
715
588
  var _ref13 = _asyncToGenerator(function* (ctx, next) {
716
589
  const _ctx$action = ctx.action,
717
- actionName = _ctx$action.actionName,
718
- resourceName = _ctx$action.resourceName,
719
- params = _ctx$action.params;
720
-
590
+ actionName = _ctx$action.actionName,
591
+ resourceName = _ctx$action.resourceName,
592
+ params = _ctx$action.params;
721
593
  const _ref14 = params || {},
722
- showAnonymous = _ref14.showAnonymous;
723
-
594
+ showAnonymous = _ref14.showAnonymous;
724
595
  if (actionName === 'list' && resourceName === 'roles') {
725
596
  if (!showAnonymous) {
726
597
  ctx.action.mergeParams({
@@ -730,96 +601,75 @@ class PluginACL extends _server().Plugin {
730
601
  });
731
602
  }
732
603
  }
733
-
734
604
  if (actionName === 'update' && resourceName === 'roles.resources') {
735
605
  ctx.action.mergeParams({
736
606
  updateAssociationValues: ['actions']
737
607
  });
738
608
  }
739
-
740
609
  yield next();
741
610
  });
742
-
743
611
  return function (_x23, _x24) {
744
612
  return _ref13.apply(this, arguments);
745
613
  };
746
614
  }());
747
-
748
615
  _this4.app.acl.use( /*#__PURE__*/function () {
749
616
  var _ref15 = _asyncToGenerator(function* (ctx, next) {
750
617
  const _ctx$action2 = ctx.action,
751
- actionName = _ctx$action2.actionName,
752
- resourceName = _ctx$action2.resourceName;
753
-
618
+ actionName = _ctx$action2.actionName,
619
+ resourceName = _ctx$action2.resourceName;
754
620
  if (actionName === 'get' || actionName === 'list') {
755
621
  var _ctx$permission, _ctx$permission$can, _ctx$permission$can$p;
756
-
757
622
  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)) {
758
623
  return next();
759
624
  }
760
-
761
625
  let collection;
762
-
763
626
  if (resourceName.includes('.')) {
764
627
  var _ctx$db$getCollection, _ctx$db$getCollection2;
765
-
766
628
  const _resourceName$split = resourceName.split('.'),
767
- _resourceName$split2 = _slicedToArray(_resourceName$split, 2),
768
- collectionName = _resourceName$split2[0],
769
- associationName = _resourceName$split2[1];
770
-
629
+ _resourceName$split2 = _slicedToArray(_resourceName$split, 2),
630
+ collectionName = _resourceName$split2[0],
631
+ associationName = _resourceName$split2[1];
771
632
  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);
772
-
773
633
  if (field.target) {
774
634
  collection = ctx.db.getCollection(field.target);
775
635
  }
776
636
  } else {
777
637
  collection = ctx.db.getCollection(resourceName);
778
638
  }
779
-
780
639
  if (collection && collection.hasField('createdById')) {
781
640
  ctx.permission.can.params.fields.push('createdById');
782
641
  }
783
642
  }
784
-
785
643
  return next();
786
644
  });
787
-
788
645
  return function (_x25, _x26) {
789
646
  return _ref15.apply(this, arguments);
790
647
  };
791
648
  }());
792
-
793
649
  const parseJsonTemplate = _this4.app.acl.parseJsonTemplate;
794
-
795
650
  _this4.app.acl.use( /*#__PURE__*/function () {
796
651
  var _ref16 = _asyncToGenerator(function* (ctx, next) {
797
652
  const _ctx$action3 = ctx.action,
798
- actionName = _ctx$action3.actionName,
799
- resourceName = _ctx$action3.resourceName,
800
- resourceOf = _ctx$action3.resourceOf; // is association request
801
-
653
+ actionName = _ctx$action3.actionName,
654
+ resourceName = _ctx$action3.resourceName,
655
+ resourceOf = _ctx$action3.resourceOf;
656
+ // is association request
802
657
  if (resourceName.includes('.') && resourceOf) {
803
658
  var _ctx$permission2, _ctx$permission2$can, _availableAction$opti;
804
-
805
659
  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)) {
806
660
  return next();
807
- } // 关联数据去掉 filter
808
-
809
-
810
- delete ctx.permission.can.params.filter; // 关联数据能不能处理取决于 source 是否有权限
811
-
661
+ }
662
+ // 关联数据去掉 filter
663
+ delete ctx.permission.can.params.filter;
664
+ // 关联数据能不能处理取决于 source 是否有权限
812
665
  const _resourceName$split3 = resourceName.split('.'),
813
- _resourceName$split4 = _slicedToArray(_resourceName$split3, 1),
814
- collectionName = _resourceName$split4[0];
815
-
666
+ _resourceName$split4 = _slicedToArray(_resourceName$split3, 1),
667
+ collectionName = _resourceName$split4[0];
816
668
  const action = ctx.can({
817
669
  resource: collectionName,
818
670
  action: actionName
819
671
  });
820
-
821
672
  const availableAction = _this4.app.acl.getAvailableAction(actionName);
822
-
823
673
  if (availableAction === null || availableAction === void 0 ? void 0 : (_availableAction$opti = availableAction.options) === null || _availableAction$opti === void 0 ? void 0 : _availableAction$opti.onNewRecord) {
824
674
  if (action) {
825
675
  ctx.permission.skip = true;
@@ -828,53 +678,42 @@ class PluginACL extends _server().Plugin {
828
678
  }
829
679
  } else {
830
680
  var _action$params;
831
-
832
681
  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);
833
682
  const sourceInstance = yield ctx.db.getRepository(collectionName).findOne({
834
683
  filterByTk: resourceOf,
835
684
  filter
836
685
  });
837
-
838
686
  if (!sourceInstance) {
839
687
  ctx.permission.can = false;
840
688
  }
841
689
  }
842
690
  }
843
-
844
691
  yield next();
845
692
  });
846
-
847
693
  return function (_x27, _x28) {
848
694
  return _ref16.apply(this, arguments);
849
695
  };
850
696
  }(), {
851
697
  before: 'core'
852
- }); // throw error when user has no fixed params permissions
853
-
854
-
698
+ });
699
+ // throw error when user has no fixed params permissions
855
700
  _this4.app.acl.use( /*#__PURE__*/function () {
856
701
  var _ref17 = _asyncToGenerator(function* (ctx, next) {
857
702
  var _ctx$permission3, _ctx$permission3$can;
858
-
859
703
  const action = (_ctx$permission3 = ctx.permission) === null || _ctx$permission3 === void 0 ? void 0 : (_ctx$permission3$can = _ctx$permission3.can) === null || _ctx$permission3$can === void 0 ? void 0 : _ctx$permission3$can.action;
860
-
861
704
  if (action == 'destroy' && !ctx.action.resourceName.includes('.')) {
862
- const repository = _actions2().utils.getRepositoryFromParams(ctx); // params after merge with fixed params
863
-
864
-
865
- const filteredCount = yield repository.count(ctx.permission.mergedParams); // params user requested
866
-
705
+ const repository = _actions().utils.getRepositoryFromParams(ctx);
706
+ // params after merge with fixed params
707
+ const filteredCount = yield repository.count(ctx.permission.mergedParams);
708
+ // params user requested
867
709
  const queryCount = yield repository.count(ctx.permission.rawParams);
868
-
869
710
  if (queryCount > filteredCount) {
870
711
  ctx.throw(403, 'No permissions');
871
712
  return;
872
713
  }
873
714
  }
874
-
875
715
  yield next();
876
716
  });
877
-
878
717
  return function (_x29, _x30) {
879
718
  return _ref17.apply(this, arguments);
880
719
  };
@@ -882,56 +721,35 @@ class PluginACL extends _server().Plugin {
882
721
  after: 'core',
883
722
  group: 'after'
884
723
  });
885
-
886
724
  const withACLMeta = /*#__PURE__*/function () {
887
725
  var _ref18 = _asyncToGenerator(function* (ctx, next) {
888
726
  var _ctx$body;
889
-
890
727
  yield next();
891
-
892
- if (!ctx.action) {
728
+ if (!ctx.action || !ctx.get('X-With-ACL-Meta') || ctx.status !== 200) {
893
729
  return;
894
730
  }
895
-
896
731
  const _ctx$action4 = ctx.action,
897
- resourceName = _ctx$action4.resourceName,
898
- actionName = _ctx$action4.actionName;
899
-
900
- if (!ctx.get('X-With-ACL-Meta')) {
901
- return;
902
- }
903
-
904
- if (ctx.status !== 200) {
905
- return;
906
- }
907
-
732
+ resourceName = _ctx$action4.resourceName,
733
+ actionName = _ctx$action4.actionName;
908
734
  if (!['list', 'get'].includes(actionName)) {
909
735
  return;
910
736
  }
911
-
912
737
  const collection = ctx.db.getCollection(resourceName);
913
-
914
738
  if (!collection) {
915
739
  return;
916
740
  }
917
-
918
741
  const Model = collection.model;
919
742
  const primaryKeyField = Model.primaryKeyField || Model.primaryKeyAttribute;
920
743
  const dataPath = ((_ctx$body = ctx.body) === null || _ctx$body === void 0 ? void 0 : _ctx$body.rows) ? 'body.rows' : 'body';
921
-
922
744
  let listData = _lodash().default.get(ctx, dataPath);
923
-
924
745
  if (actionName == 'get') {
925
746
  listData = _lodash().default.castArray(listData);
926
747
  }
927
-
928
- const actions = ['view', 'update', 'destroy'];
748
+ const inspectActions = ['view', 'update', 'destroy'];
929
749
  const actionsParams = [];
930
-
931
- for (var _i2 = 0, _actions = actions; _i2 < _actions.length; _i2++) {
750
+ for (var _i2 = 0, _inspectActions = inspectActions; _i2 < _inspectActions.length; _i2++) {
932
751
  var _actionCtx$permission, _actionCtx$permission2;
933
-
934
- const action = _actions[_i2];
752
+ const action = _inspectActions[_i2];
935
753
  const actionCtx = {
936
754
  db: ctx.db,
937
755
  action: {
@@ -940,9 +758,7 @@ class PluginACL extends _server().Plugin {
940
758
  params: {},
941
759
  resourceName: ctx.action.resourceName,
942
760
  resourceOf: ctx.action.resourceOf,
943
-
944
761
  mergeParams() {}
945
-
946
762
  },
947
763
  state: {
948
764
  currentRole: ctx.state.currentRole,
@@ -950,101 +766,96 @@ class PluginACL extends _server().Plugin {
950
766
  if (!ctx.state.currentUser) {
951
767
  return null;
952
768
  }
953
-
954
769
  if (ctx.state.currentUser.toJSON) {
955
770
  var _ctx$state$currentUse;
956
-
957
771
  return (_ctx$state$currentUse = ctx.state.currentUser) === null || _ctx$state$currentUse === void 0 ? void 0 : _ctx$state$currentUse.toJSON();
958
772
  }
959
-
960
773
  return ctx.state.currentUser;
961
774
  })()
962
775
  },
963
776
  permission: {},
964
-
965
777
  throw(...args) {
966
778
  throw new (_acl().NoPermissionError)(...args);
967
779
  }
968
-
969
780
  };
970
-
971
781
  try {
972
782
  yield _this4.app.acl.getActionParams(actionCtx);
973
783
  } catch (e) {
974
784
  if (e instanceof _acl().NoPermissionError) {
975
785
  continue;
976
786
  }
977
-
978
787
  throw e;
979
788
  }
980
-
981
789
  actionsParams.push([action, ((_actionCtx$permission = actionCtx.permission) === null || _actionCtx$permission === void 0 ? void 0 : _actionCtx$permission.can) === null && !actionCtx.permission.skip ? null : ((_actionCtx$permission2 = actionCtx.permission) === null || _actionCtx$permission2 === void 0 ? void 0 : _actionCtx$permission2.parsedParams) || {}, actionCtx]);
982
790
  }
983
-
984
- const ids = listData.map(item => item[primaryKeyField]);
791
+ const ids = (() => {
792
+ if (collection.options.tree) {
793
+ if (listData.length == 0) return [];
794
+ const getAllNodeIds = data => [data[primaryKeyField], ...(data.children || []).flatMap(getAllNodeIds)];
795
+ return listData.map(tree => getAllNodeIds(tree.toJSON())).flat();
796
+ }
797
+ return listData.map(item => item[primaryKeyField]);
798
+ })();
985
799
  const conditions = [];
986
800
  const allAllowed = [];
987
-
988
801
  for (var _i3 = 0, _actionsParams = actionsParams; _i3 < _actionsParams.length; _i3++) {
989
802
  const _actionsParams$_i = _slicedToArray(_actionsParams[_i3], 3),
990
- action = _actionsParams$_i[0],
991
- params = _actionsParams$_i[1],
992
- actionCtx = _actionsParams$_i[2];
993
-
803
+ action = _actionsParams$_i[0],
804
+ params = _actionsParams$_i[1],
805
+ actionCtx = _actionsParams$_i[2];
994
806
  if (!params) {
995
807
  continue;
996
808
  }
997
-
998
809
  if (_lodash().default.isEmpty(params) || _lodash().default.isEmpty(params.filter)) {
999
810
  allAllowed.push(action);
1000
811
  continue;
1001
812
  }
1002
-
1003
813
  const queryParams = collection.repository.buildQueryOptions(_objectSpread(_objectSpread({}, params), {}, {
1004
814
  context: actionCtx
1005
815
  }));
1006
816
  const actionSql = ctx.db.sequelize.queryInterface.queryGenerator.selectQuery(Model.getTableName(), {
1007
817
  where: (() => {
1008
818
  const filterObj = queryParams.where;
1009
-
1010
819
  if (!_this4.db.options.underscored) {
1011
820
  return filterObj;
1012
821
  }
1013
-
822
+ const isAssociationKey = key => {
823
+ return key.startsWith('$') && key.endsWith('$');
824
+ };
825
+ // change camelCase to snake_case
1014
826
  const iterate = (rootObj, path = []) => {
1015
827
  const obj = path.length == 0 ? rootObj : _lodash().default.get(rootObj, path);
1016
-
1017
828
  if (Array.isArray(obj)) {
1018
829
  for (let i = 0; i < obj.length; i++) {
1019
830
  if (obj[i] === null) {
1020
831
  continue;
1021
832
  }
1022
-
1023
833
  if (typeof obj[i] === 'object') {
1024
834
  iterate(rootObj, [...path, i]);
1025
835
  }
1026
836
  }
1027
-
1028
837
  return;
1029
838
  }
1030
-
1031
839
  Reflect.ownKeys(obj).forEach(key => {
1032
840
  if (Array.isArray(obj) && key == 'length') {
1033
841
  return;
1034
842
  }
1035
-
1036
843
  if (typeof obj[key] === 'object' && obj[key] !== null || typeof obj[key] === 'symbol') {
1037
844
  iterate(rootObj, [...path, key]);
1038
845
  }
1039
-
1040
846
  if (typeof key === 'string' && key !== (0, _database().snakeCase)(key)) {
1041
- _lodash().default.set(rootObj, [...path, (0, _database().snakeCase)(key)], _lodash().default.cloneDeep(obj[key]));
1042
-
847
+ const setKey = isAssociationKey(key) ? (() => {
848
+ const parts = key.split('.');
849
+ parts[parts.length - 1] = _lodash().default.snakeCase(parts[parts.length - 1]);
850
+ const result = parts.join('.');
851
+ return result.endsWith('$') ? result : `${result}$`;
852
+ })() : (0, _database().snakeCase)(key);
853
+ const setValue = _lodash().default.cloneDeep(obj[key]);
1043
854
  _lodash().default.unset(rootObj, [...path, key]);
855
+ _lodash().default.set(rootObj, [...path, setKey], setValue);
1044
856
  }
1045
857
  });
1046
858
  };
1047
-
1048
859
  iterate(filterObj);
1049
860
  return filterObj;
1050
861
  })(),
@@ -1058,7 +869,6 @@ class PluginACL extends _server().Plugin {
1058
869
  include: queryParams.include
1059
870
  });
1060
871
  }
1061
-
1062
872
  const results = yield collection.model.findAll({
1063
873
  where: {
1064
874
  [primaryKeyField]: ids
@@ -1068,34 +878,29 @@ class PluginACL extends _server().Plugin {
1068
878
  })],
1069
879
  include: conditions.map(condition => condition.include).flat()
1070
880
  });
1071
- const allowedActions = actions.map(action => {
881
+ const allowedActions = inspectActions.map(action => {
1072
882
  if (allAllowed.includes(action)) {
1073
883
  return [action, ids];
1074
884
  }
1075
-
1076
885
  return [action, results.filter(item => Boolean(item.get(action))).map(item => item.get(primaryKeyField))];
1077
886
  }).reduce((acc, [action, ids]) => {
1078
887
  acc[action] = ids;
1079
888
  return acc;
1080
889
  }, {});
1081
-
1082
890
  if (actionName == 'get') {
1083
891
  ctx.bodyMeta = _objectSpread(_objectSpread({}, ctx.bodyMeta || {}), {}, {
1084
892
  allowedActions: allowedActions
1085
893
  });
1086
894
  }
1087
-
1088
895
  if (actionName == 'list') {
1089
896
  ctx.body.allowedActions = allowedActions;
1090
897
  }
1091
898
  });
1092
-
1093
899
  return function withACLMeta(_x31, _x32) {
1094
900
  return _ref18.apply(this, arguments);
1095
901
  };
1096
- }(); // append allowedActions to list & get response
1097
-
1098
-
902
+ }();
903
+ // append allowedActions to list & get response
1099
904
  _this4.app.use( /*#__PURE__*/function () {
1100
905
  var _ref19 = _asyncToGenerator(function* (ctx, next) {
1101
906
  try {
@@ -1104,7 +909,6 @@ class PluginACL extends _server().Plugin {
1104
909
  ctx.logger.error(error);
1105
910
  }
1106
911
  });
1107
-
1108
912
  return function (_x33, _x34) {
1109
913
  return _ref19.apply(this, arguments);
1110
914
  };
@@ -1114,35 +918,27 @@ class PluginACL extends _server().Plugin {
1114
918
  });
1115
919
  })();
1116
920
  }
1117
-
1118
921
  install() {
1119
922
  var _this5 = this;
1120
-
1121
923
  return _asyncToGenerator(function* () {
1122
924
  const repo = _this5.db.getRepository('collections');
1123
-
1124
925
  if (repo) {
1125
926
  yield repo.db2cm('roles');
1126
927
  }
1127
928
  })();
1128
929
  }
1129
-
1130
930
  load() {
1131
931
  var _this6 = this;
1132
-
1133
932
  return _asyncToGenerator(function* () {
1134
933
  yield _this6.importCollections((0, _path().resolve)(__dirname, 'collections'));
1135
-
1136
934
  _this6.db.extendCollection({
1137
935
  name: 'rolesUischemas',
1138
- namespace: 'acl',
936
+ namespace: 'acl.acl',
1139
937
  duplicator: 'required'
1140
938
  });
1141
939
  })();
1142
940
  }
1143
-
1144
941
  }
1145
-
1146
942
  exports.PluginACL = PluginACL;
1147
943
  var _default = PluginACL;
1148
944
  exports.default = _default;