oak-domain 3.0.0 → 3.0.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.
Files changed (226) hide show
  1. package/lib/actions/action.d.ts +16 -16
  2. package/lib/actions/action.js +17 -17
  3. package/lib/actions/relation.d.ts +5 -5
  4. package/lib/actions/relation.js +38 -38
  5. package/lib/base-app-domain/ActionAuth/Schema.d.ts +160 -160
  6. package/lib/base-app-domain/ActionAuth/Schema.js +2 -2
  7. package/lib/base-app-domain/ActionAuth/Storage.d.ts +3 -3
  8. package/lib/base-app-domain/ActionAuth/Storage.js +42 -42
  9. package/lib/base-app-domain/ActionDefDict.d.ts +9 -9
  10. package/lib/base-app-domain/ActionDefDict.js +11 -11
  11. package/lib/base-app-domain/EntityDict.d.ts +24 -24
  12. package/lib/base-app-domain/EntityDict.js +2 -2
  13. package/lib/base-app-domain/I18n/Schema.d.ts +129 -129
  14. package/lib/base-app-domain/I18n/Schema.js +2 -2
  15. package/lib/base-app-domain/I18n/Storage.d.ts +3 -3
  16. package/lib/base-app-domain/I18n/Storage.js +59 -59
  17. package/lib/base-app-domain/Modi/Action.d.ts +10 -10
  18. package/lib/base-app-domain/Modi/Action.js +14 -14
  19. package/lib/base-app-domain/Modi/Schema.d.ts +136 -136
  20. package/lib/base-app-domain/Modi/Schema.js +2 -2
  21. package/lib/base-app-domain/Modi/Storage.d.ts +3 -3
  22. package/lib/base-app-domain/Modi/Storage.js +63 -63
  23. package/lib/base-app-domain/ModiEntity/Schema.d.ts +311 -311
  24. package/lib/base-app-domain/ModiEntity/Schema.js +2 -2
  25. package/lib/base-app-domain/ModiEntity/Storage.d.ts +3 -3
  26. package/lib/base-app-domain/ModiEntity/Storage.js +30 -30
  27. package/lib/base-app-domain/Oper/Schema.d.ts +152 -152
  28. package/lib/base-app-domain/Oper/Schema.js +2 -2
  29. package/lib/base-app-domain/Oper/Storage.d.ts +3 -3
  30. package/lib/base-app-domain/Oper/Storage.js +38 -38
  31. package/lib/base-app-domain/OperEntity/Schema.d.ts +300 -300
  32. package/lib/base-app-domain/OperEntity/Schema.js +2 -2
  33. package/lib/base-app-domain/OperEntity/Storage.d.ts +3 -3
  34. package/lib/base-app-domain/OperEntity/Storage.js +30 -30
  35. package/lib/base-app-domain/Relation/Schema.d.ts +188 -188
  36. package/lib/base-app-domain/Relation/Schema.js +2 -2
  37. package/lib/base-app-domain/Relation/Storage.d.ts +3 -3
  38. package/lib/base-app-domain/Relation/Storage.js +54 -54
  39. package/lib/base-app-domain/Relation.d.ts +10 -10
  40. package/lib/base-app-domain/Relation.js +10 -10
  41. package/lib/base-app-domain/RelationAuth/Schema.d.ts +180 -180
  42. package/lib/base-app-domain/RelationAuth/Schema.js +2 -2
  43. package/lib/base-app-domain/RelationAuth/Storage.d.ts +3 -3
  44. package/lib/base-app-domain/RelationAuth/Storage.js +46 -46
  45. package/lib/base-app-domain/Storage.d.ts +3 -3
  46. package/lib/base-app-domain/Storage.js +27 -27
  47. package/lib/base-app-domain/User/Action.d.ts +10 -10
  48. package/lib/base-app-domain/User/Action.js +12 -12
  49. package/lib/base-app-domain/User/Schema.d.ts +197 -197
  50. package/lib/base-app-domain/User/Schema.js +2 -2
  51. package/lib/base-app-domain/User/Storage.d.ts +3 -3
  52. package/lib/base-app-domain/User/Storage.js +33 -33
  53. package/lib/base-app-domain/UserEntityGrant/Action.d.ts +5 -5
  54. package/lib/base-app-domain/UserEntityGrant/Action.js +5 -5
  55. package/lib/base-app-domain/UserEntityGrant/Schema.d.ts +157 -157
  56. package/lib/base-app-domain/UserEntityGrant/Schema.js +2 -2
  57. package/lib/base-app-domain/UserEntityGrant/Storage.d.ts +3 -3
  58. package/lib/base-app-domain/UserEntityGrant/Storage.js +29 -29
  59. package/lib/base-app-domain/UserRelation/Schema.d.ts +194 -194
  60. package/lib/base-app-domain/UserRelation/Schema.js +2 -2
  61. package/lib/base-app-domain/UserRelation/Storage.d.ts +3 -3
  62. package/lib/base-app-domain/UserRelation/Storage.js +56 -56
  63. package/lib/base-app-domain/_SubQuery.d.ts +112 -112
  64. package/lib/base-app-domain/_SubQuery.js +2 -2
  65. package/lib/base-app-domain/index.d.ts +4 -4
  66. package/lib/base-app-domain/index.js +7 -7
  67. package/lib/checkers/index.d.ts +5 -5
  68. package/lib/checkers/index.js +14 -14
  69. package/lib/compiler/env.d.ts +14 -14
  70. package/lib/compiler/env.js +50 -50
  71. package/lib/compiler/localeBuilder.d.ts +22 -22
  72. package/lib/compiler/localeBuilder.js +169 -169
  73. package/lib/compiler/schemalBuilder.d.ts +11 -11
  74. package/lib/compiler/schemalBuilder.js +3787 -3787
  75. package/lib/compiler/uiBuilder.d.ts +1 -1
  76. package/lib/compiler/uiBuilder.js +3 -3
  77. package/lib/entities/ActionAuth.d.ts +12 -12
  78. package/lib/entities/ActionAuth.js +29 -29
  79. package/lib/entities/I18n.d.ts +9 -9
  80. package/lib/entities/I18n.js +37 -37
  81. package/lib/entities/Modi.d.ts +11 -11
  82. package/lib/entities/Modi.js +49 -49
  83. package/lib/entities/ModiEntity.d.ts +8 -8
  84. package/lib/entities/ModiEntity.js +18 -18
  85. package/lib/entities/Oper.d.ts +11 -11
  86. package/lib/entities/Oper.js +21 -21
  87. package/lib/entities/OperEntity.d.ts +8 -8
  88. package/lib/entities/OperEntity.js +18 -18
  89. package/lib/entities/Relation.d.ts +8 -8
  90. package/lib/entities/Relation.js +35 -35
  91. package/lib/entities/RelationAuth.d.ts +8 -8
  92. package/lib/entities/RelationAuth.js +34 -34
  93. package/lib/entities/User.d.ts +8 -8
  94. package/lib/entities/User.js +31 -31
  95. package/lib/entities/UserEntityGrant.d.ts +8 -8
  96. package/lib/entities/UserEntityGrant.js +18 -18
  97. package/lib/entities/UserRelation.d.ts +10 -10
  98. package/lib/entities/UserRelation.js +38 -38
  99. package/lib/store/AsyncRowStore.d.ts +58 -58
  100. package/lib/store/AsyncRowStore.js +190 -190
  101. package/lib/store/CascadeStore.d.ts +103 -103
  102. package/lib/store/CascadeStore.js +2035 -2031
  103. package/lib/store/RelationAuth.d.ts +103 -96
  104. package/lib/store/RelationAuth.js +1492 -1307
  105. package/lib/store/SyncRowStore.d.ts +29 -29
  106. package/lib/store/SyncRowStore.js +49 -48
  107. package/lib/store/TriggerExecutor.d.ts +31 -31
  108. package/lib/store/TriggerExecutor.js +532 -532
  109. package/lib/store/actionAuth.d.ts +4 -4
  110. package/lib/store/actionAuth.js +40 -40
  111. package/lib/store/actionDef.d.ts +10 -10
  112. package/lib/store/actionDef.js +351 -351
  113. package/lib/store/checker.d.ts +26 -26
  114. package/lib/store/checker.js +623 -623
  115. package/lib/store/filter.d.ts +123 -123
  116. package/lib/store/filter.js +1761 -1739
  117. package/lib/store/modi.d.ts +13 -13
  118. package/lib/store/modi.js +315 -315
  119. package/lib/store/relation.d.ts +12 -12
  120. package/lib/store/relation.js +67 -67
  121. package/lib/timers/oper.d.ts +18 -18
  122. package/lib/timers/oper.js +60 -60
  123. package/lib/timers/vaccum.d.ts +20 -20
  124. package/lib/timers/vaccum.js +176 -176
  125. package/lib/triggers/index.d.ts +5 -5
  126. package/lib/triggers/index.js +8 -8
  127. package/lib/types/Action.d.ts +20 -20
  128. package/lib/types/Action.js +2 -2
  129. package/lib/types/AppLoader.d.ts +11 -11
  130. package/lib/types/AppLoader.js +10 -10
  131. package/lib/types/Aspect.d.ts +13 -13
  132. package/lib/types/Aspect.js +4 -4
  133. package/lib/types/Auth.d.ts +74 -74
  134. package/lib/types/Auth.js +2 -2
  135. package/lib/types/Connector.d.ts +33 -33
  136. package/lib/types/Connector.js +9 -9
  137. package/lib/types/Context.d.ts +7 -7
  138. package/lib/types/Context.js +3 -3
  139. package/lib/types/DataType.d.ts +24 -24
  140. package/lib/types/DataType.js +6 -6
  141. package/lib/types/Demand.d.ts +88 -88
  142. package/lib/types/Demand.js +10 -10
  143. package/lib/types/Endpoint.d.ts +11 -11
  144. package/lib/types/Endpoint.js +3 -3
  145. package/lib/types/Entity.d.ts +193 -192
  146. package/lib/types/Entity.js +14 -14
  147. package/lib/types/EntityDesc.d.ts +8 -8
  148. package/lib/types/EntityDesc.js +2 -2
  149. package/lib/types/Environment.d.ts +57 -57
  150. package/lib/types/Environment.js +2 -2
  151. package/lib/types/Exception.d.ts +115 -115
  152. package/lib/types/Exception.js +389 -389
  153. package/lib/types/Expression.d.ts +163 -163
  154. package/lib/types/Expression.js +427 -427
  155. package/lib/types/Geo.d.ts +18 -18
  156. package/lib/types/Geo.js +2 -2
  157. package/lib/types/Locale.d.ts +25 -25
  158. package/lib/types/Locale.js +2 -2
  159. package/lib/types/Logger.d.ts +6 -6
  160. package/lib/types/Logger.js +3 -3
  161. package/lib/types/Polyfill.d.ts +24 -24
  162. package/lib/types/Polyfill.js +2 -2
  163. package/lib/types/Port.d.ts +18 -18
  164. package/lib/types/Port.js +2 -2
  165. package/lib/types/RowStore.d.ts +18 -18
  166. package/lib/types/RowStore.js +34 -34
  167. package/lib/types/Storage.d.ts +57 -57
  168. package/lib/types/Storage.js +2 -2
  169. package/lib/types/Style.d.ts +11 -11
  170. package/lib/types/Style.js +2 -2
  171. package/lib/types/Timer.d.ts +14 -14
  172. package/lib/types/Timer.js +2 -2
  173. package/lib/types/Trigger.d.ts +108 -108
  174. package/lib/types/Trigger.js +54 -54
  175. package/lib/types/Txn.d.ts +2 -2
  176. package/lib/types/Txn.js +3 -3
  177. package/lib/types/Watcher.d.ts +19 -19
  178. package/lib/types/Watcher.js +4 -4
  179. package/lib/types/index.d.ts +24 -24
  180. package/lib/types/index.js +27 -27
  181. package/lib/types/schema/DataTypes.d.ts +34 -34
  182. package/lib/types/schema/DataTypes.js +3 -3
  183. package/lib/utils/SimpleConnector.d.ts +48 -48
  184. package/lib/utils/SimpleConnector.js +180 -180
  185. package/lib/utils/assert.d.ts +5 -5
  186. package/lib/utils/assert.js +9 -9
  187. package/lib/utils/concurrent.d.ts +15 -15
  188. package/lib/utils/concurrent.js +89 -89
  189. package/lib/utils/date.d.ts +1 -1
  190. package/lib/utils/date.js +18 -18
  191. package/lib/utils/geo.d.ts +4 -4
  192. package/lib/utils/geo.js +24 -24
  193. package/lib/utils/lodash.d.ts +20 -20
  194. package/lib/utils/lodash.js +55 -55
  195. package/lib/utils/mask.d.ts +5 -5
  196. package/lib/utils/mask.js +35 -35
  197. package/lib/utils/money.d.ts +6 -6
  198. package/lib/utils/money.js +40 -40
  199. package/lib/utils/random/random.d.ts +1 -1
  200. package/lib/utils/random/random.js +24 -24
  201. package/lib/utils/random/random.mp.d.ts +1 -1
  202. package/lib/utils/random/random.mp.js +25 -25
  203. package/lib/utils/random/random.web.d.ts +1 -1
  204. package/lib/utils/random/random.web.js +17 -17
  205. package/lib/utils/string.d.ts +28 -28
  206. package/lib/utils/string.js +82 -82
  207. package/lib/utils/url.d.ts +1 -1
  208. package/lib/utils/url.js +12 -12
  209. package/lib/utils/uuid.d.ts +17 -17
  210. package/lib/utils/uuid.js +257 -257
  211. package/lib/utils/validator.d.ts +25 -25
  212. package/lib/utils/validator.js +128 -128
  213. package/lib/utils/version.d.ts +7 -7
  214. package/lib/utils/version.js +21 -21
  215. package/package.json +49 -49
  216. package/src/entities/ActionAuth.ts +41 -41
  217. package/src/entities/I18n.ts +46 -46
  218. package/src/entities/Modi.ts +69 -69
  219. package/src/entities/ModiEntity.ts +26 -26
  220. package/src/entities/Oper.ts +32 -32
  221. package/src/entities/OperEntity.ts +27 -27
  222. package/src/entities/Relation.ts +43 -43
  223. package/src/entities/RelationAuth.ts +43 -43
  224. package/src/entities/User.ts +48 -48
  225. package/src/entities/UserEntityGrant.ts +27 -27
  226. package/src/entities/UserRelation.ts +50 -50
@@ -1,1307 +1,1492 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getUserRelationsByActions = exports.RelationAuth = void 0;
4
- var tslib_1 = require("tslib");
5
- var assert_1 = tslib_1.__importDefault(require("assert"));
6
- var types_1 = require("../types");
7
- var AsyncRowStore_1 = require("./AsyncRowStore");
8
- var filter_1 = require("./filter");
9
- var relation_1 = require("./relation");
10
- var SyncRowStore_1 = require("./SyncRowStore");
11
- var action_1 = require("../actions/action");
12
- var lodash_1 = require("../utils/lodash");
13
- var env_1 = require("../compiler/env");
14
- var RelationAuth = /** @class */ (function () {
15
- function RelationAuth(schema, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities) {
16
- this.actionCascadePathGraph = actionCascadePathGraph;
17
- this.relationCascadePathGraph = relationCascadePathGraph;
18
- this.schema = schema;
19
- this.selectFreeEntities = selectFreeEntities || [];
20
- this.createFreeEntities = createFreeEntities || [];
21
- this.updateFreeEntities = updateFreeEntities || [];
22
- this.authDeduceRelationMap = Object.assign({}, authDeduceRelationMap, {
23
- modi: 'entity',
24
- });
25
- }
26
- // 前台检查filter是否满足relation约束
27
- RelationAuth.prototype.checkRelationSync = function (entity, operation, context) {
28
- if (context.isRoot()) {
29
- return;
30
- }
31
- this.checkActions2(entity, operation, context);
32
- };
33
- /**
34
- * 查询当前用户在对应entity上可以操作的relationIds
35
- * @param entity
36
- * @param entityId
37
- * @param context
38
- * @returns
39
- */
40
- RelationAuth.prototype.getGrantedRelationIds = function (entity, entityId, context) {
41
- var result = context.select('relationAuth', {
42
- data: {
43
- id: 1,
44
- destRelationId: 1,
45
- destRelation: {
46
- id: 1,
47
- name: 1,
48
- entity: 1,
49
- entityId: 1,
50
- display: 1,
51
- },
52
- },
53
- filter: {
54
- sourceRelation: {
55
- userRelation$relation: {
56
- userId: context.getCurrentUserId(),
57
- }
58
- },
59
- destRelation: {
60
- entity: entity,
61
- $or: [
62
- {
63
- entityId: entityId,
64
- },
65
- {
66
- entityId: {
67
- $exists: false,
68
- },
69
- }
70
- ],
71
- },
72
- },
73
- }, {});
74
- if (result instanceof Promise) {
75
- return result.then(function (r2) { return r2.map(function (ele) { return ele.destRelation; }); });
76
- }
77
- return result.map(function (ele) { return ele.destRelation; });
78
- };
79
- // 后台检查filter是否满足relation约束
80
- RelationAuth.prototype.checkRelationAsync = function (entity, operation, context) {
81
- return tslib_1.__awaiter(this, void 0, void 0, function () {
82
- return tslib_1.__generator(this, function (_a) {
83
- switch (_a.label) {
84
- case 0:
85
- if (context.isRoot()) {
86
- return [2 /*return*/];
87
- }
88
- return [4 /*yield*/, this.checkActions2(entity, operation, context)];
89
- case 1:
90
- _a.sent();
91
- return [2 /*return*/];
92
- }
93
- });
94
- });
95
- };
96
- RelationAuth.prototype.checkOperateSpecialEntities2 = function (entity2, action, filter, context) {
97
- switch (entity2) {
98
- case 'userRelation': {
99
- (0, assert_1.default)(!(filter instanceof Array));
100
- (0, assert_1.default)(['create', 'remove'].includes(action));
101
- if (action === 'create') {
102
- (0, assert_1.default)(!(filter instanceof Array));
103
- var _a = filter, entity = _a.entity, entityId = _a.entityId, relationId_1 = _a.relationId;
104
- // 创建userRelation如果是领取动作,先暂使用root身份通过
105
- var destRelations = this.getGrantedRelationIds(entity, entityId, context);
106
- if (destRelations instanceof Promise) {
107
- return destRelations.then(function (r2) {
108
- if (relationId_1 && !r2.find(function (ele) { return ele.id === relationId_1; }) || r2.length === 0) {
109
- return false;
110
- }
111
- return true;
112
- });
113
- }
114
- // 若指定了要create的relation,则必须有该relationId存在,否则只要有任意可授权的relation即可
115
- if (relationId_1 && !destRelations.find(function (ele) { return ele.id === relationId_1; }) || destRelations.length === 0) {
116
- return false;
117
- }
118
- return true;
119
- }
120
- else {
121
- (0, assert_1.default)(action === 'remove');
122
- var userId = context.getCurrentUserId();
123
- (0, assert_1.default)(filter);
124
- var contained = {
125
- relation: {
126
- relationAuth$destRelation: {
127
- sourceRelation: {
128
- userRelation$relation: {
129
- userId: userId,
130
- },
131
- },
132
- },
133
- },
134
- };
135
- return (0, filter_1.checkFilterContains)(entity2, context, contained, filter, true);
136
- }
137
- }
138
- case 'user': {
139
- // 对用户的操作由应用自己去管理权限,这里只检查grant/revoke
140
- if (['grant', 'revoke'].includes(action)) {
141
- // assert(filter && Object.keys(filter).length === 1, 'grant/revoke只能操作userRelation$user');
142
- // assert(filter!.hasOwnProperty('userRelation$user'), 'grant/revoke只能操作userRelation$user');
143
- return true;
144
- }
145
- else {
146
- // 应用允许用户操作其它用户的逻辑请通过编写类型为relation的checker去控制,在这里不能加以限制
147
- return true;
148
- }
149
- }
150
- case 'modi': {
151
- // modi的操作权限都是由触发器触发,不用再检测了
152
- return true;
153
- }
154
- case 'relation': {
155
- // 创建relation目前不支持,以后再说
156
- return false;
157
- }
158
- case 'userEntityGrant': {
159
- // userEntityGrant的创建相当于授权,领取相当于赋权
160
- if (['create', 'update', 'remove'].includes(action)) {
161
- if (action === 'create') {
162
- return this.checkOperateSpecialEntities2('userRelation', 'create', filter, context);
163
- }
164
- return this.checkOperateSpecialEntities2('userRelation', 'action', {
165
- relation: {
166
- userEntityGrant$relation: filter,
167
- },
168
- }, context);
169
- }
170
- // 领取和读取动作公开
171
- return true;
172
- }
173
- default: {
174
- (0, assert_1.default)(false, "\u5BF9\u8C61".concat(entity2, "\u7684\u6743\u9650\u63A7\u5236\u6CA1\u6709\u52A0\u4EE5\u63A7\u5236"));
175
- }
176
- }
177
- };
178
- RelationAuth.prototype.getDeducedEntityFilters = function (entity, filter, actions, context) {
179
- var e_1, _a;
180
- var _this = this;
181
- var entityFilters = [
182
- {
183
- entity: entity,
184
- filter: filter,
185
- actions: actions,
186
- }
187
- ];
188
- if (this.authDeduceRelationMap[entity]) {
189
- (0, assert_1.default)(this.authDeduceRelationMap[entity] === 'entity');
190
- var _b = filter, deduceEntity = _b.entity, deduceEntityId_1 = _b.entityId;
191
- var deduceFilter = {};
192
- if (deduceEntity && deduceEntityId_1) {
193
- deduceFilter = { id: deduceEntityId_1 };
194
- }
195
- else {
196
- // 也可能是用cascade方式进行查找,这里有时候filter上会带有两个不同的entity目标,尚未处理(todo!)
197
- var ref = this.schema[entity].attributes.entity.ref;
198
- (0, assert_1.default)(ref instanceof Array);
199
- try {
200
- for (var ref_1 = tslib_1.__values(ref), ref_1_1 = ref_1.next(); !ref_1_1.done; ref_1_1 = ref_1.next()) {
201
- var refEntity = ref_1_1.value;
202
- if (filter[refEntity]) {
203
- deduceEntity = refEntity;
204
- deduceFilter = filter[refEntity];
205
- break;
206
- }
207
- }
208
- }
209
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
210
- finally {
211
- try {
212
- if (ref_1_1 && !ref_1_1.done && (_a = ref_1.return)) _a.call(ref_1);
213
- }
214
- finally { if (e_1) throw e_1.error; }
215
- }
216
- }
217
- var getRecursiveDeducedFilters_1 = function (deduceEntity, deduceFilter) {
218
- var excludeActions = action_1.readOnlyActions.concat([ /* 'create', 'remove' */]);
219
- var updateActions = _this.schema[deduceEntity].actions.filter(function (a) { return !excludeActions.includes(a); });
220
- if (!RelationAuth.SPECIAL_ENTITIES.includes(deduceEntity)) {
221
- return _this.getDeducedEntityFilters(deduceEntity, deduceFilter, actions[0] === 'select' ? actions : updateActions, context);
222
- }
223
- return [];
224
- };
225
- if (deduceEntity && deduceFilter) {
226
- var deducedSelections = getRecursiveDeducedFilters_1(deduceEntity, deduceFilter);
227
- if (deducedSelections instanceof Promise) {
228
- return deducedSelections.then(function (ds) {
229
- entityFilters.push.apply(entityFilters, tslib_1.__spreadArray([], tslib_1.__read(ds), false));
230
- return entityFilters;
231
- });
232
- }
233
- entityFilters.push.apply(entityFilters, tslib_1.__spreadArray([], tslib_1.__read(deducedSelections), false));
234
- return entityFilters;
235
- }
236
- else {
237
- /**
238
- * 这种情况说明从filter中无法确定相应的deduceFilter,需要查找该实体对应的entity/entityId来进行推导。
239
- * 这种情况一般发生在entity1 -> entity2上,此时entity2应该是一个固定id查询的filter
240
- * 在这里先假设如果碰到了list类型的filter,直接不使用deduce路径上的对象来推导
241
- */
242
- var rows2 = context.select(entity, {
243
- data: {
244
- id: 1,
245
- entity: 1,
246
- entityId: 1,
247
- },
248
- filter: filter,
249
- indexFrom: 0,
250
- count: 10,
251
- }, { dontCollect: true, blockTrigger: true });
252
- var dealWithData_1 = function (rows) {
253
- // 这里如果entity指向不同的实体,一般出现这样的查询,则其权限应当不由这条deduce路径处理
254
- // 同上,如果找到的行数大于1行,说明deduce路径上的对象不确定,也暂不处理 by Xc 20230725
255
- if (rows.length > 1 || rows.length === 0) {
256
- if (process.env.NODE_ENV === 'development') {
257
- console.warn("\u8FDB\u884Cdeduce\u63A8\u5BFC\u65F6\u627E\u5230\u4E86".concat(rows.length, "\u884C").concat(entity, "\u6570\u636E"));
258
- }
259
- return entityFilters;
260
- }
261
- var _a = rows[0], deducedEntity = _a.entity, deducedEntityId = _a.entityId;
262
- if (!deducedEntity || !deducedEntityId) {
263
- // 这种情况会出现在前台缓存里
264
- return entityFilters;
265
- }
266
- var result = getRecursiveDeducedFilters_1(deducedEntity, {
267
- id: deduceEntityId_1,
268
- });
269
- if (result instanceof Promise) {
270
- return result.then(function (r2) {
271
- entityFilters.push.apply(entityFilters, tslib_1.__spreadArray([], tslib_1.__read(r2), false));
272
- return entityFilters;
273
- });
274
- }
275
- entityFilters.push.apply(entityFilters, tslib_1.__spreadArray([], tslib_1.__read(result), false));
276
- return entityFilters;
277
- };
278
- if (rows2 instanceof Promise) {
279
- return rows2.then(function (r2) { return dealWithData_1(r2); });
280
- }
281
- return dealWithData_1(rows2);
282
- }
283
- }
284
- return entityFilters;
285
- };
286
- /**
287
- * 对于selection,解构出最底层的对象,如果最底层的对象可以被访问,则父对象一定可以
288
- * 但对于deduce的子对象,不必再向底层查看(假设deduce对象一般都位于树的最底层附近)
289
- * @param entity
290
- * @param operation
291
- */
292
- RelationAuth.prototype.destructSelection = function (entity, selection) {
293
- var _this = this;
294
- var leafSelections = [];
295
- var destructInner = function (entity2, selection2) {
296
- var _a, _b;
297
- var data = selection2.data, filter = selection2.filter;
298
- var hasOneToMany = false;
299
- for (var attr in data) {
300
- var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
301
- if (rel instanceof Array) {
302
- var _c = tslib_1.__read(rel, 2), e = _c[0], foreignKey = _c[1];
303
- if (foreignKey) {
304
- (0, assert_1.default)(!_this.authDeduceRelationMap[e]);
305
- hasOneToMany = true;
306
- destructInner(e, {
307
- data: data[attr].data,
308
- filter: (0, filter_1.combineFilters)(e, _this.schema, [(_a = {},
309
- _a[foreignKey.slice(0, foreignKey.length - 2)] = filter,
310
- _a), data[attr].filter || {}]),
311
- });
312
- }
313
- else {
314
- if (!_this.authDeduceRelationMap[e]) {
315
- hasOneToMany = true;
316
- destructInner(e, {
317
- data: data[attr].data,
318
- filter: (0, filter_1.combineFilters)(e, _this.schema, [(_b = {},
319
- _b[entity2] = filter,
320
- _b), data[attr].filter || {}]),
321
- });
322
- }
323
- else {
324
- (0, assert_1.default)(_this.authDeduceRelationMap[e] === 'entity');
325
- }
326
- }
327
- }
328
- }
329
- if (!hasOneToMany) {
330
- leafSelections.push({
331
- entity: entity2,
332
- filter: filter,
333
- });
334
- }
335
- };
336
- destructInner(entity, (0, lodash_1.cloneDeep)(selection));
337
- return leafSelections;
338
- };
339
- /**
340
- * 对于operation,解构出一个树形结构,以方便自顶向下的进行访问
341
- * 但对于deduce的子对象,不必再向底层查看
342
- * @param entity
343
- * @param selection
344
- */
345
- RelationAuth.prototype.destructOperation = function (entity2, operation2, userId) {
346
- var _this = this;
347
- /**
348
- * 对create动作,把data中的cascade部分剔除后作为filter参与后续的检验
349
- * @param operation
350
- * @returns
351
- */
352
- var makeCreateFilter = function (entity, operation) {
353
- var _a;
354
- var data = operation.data, filter = operation.filter;
355
- (0, assert_1.default)(!(data instanceof Array));
356
- if (data) {
357
- var data2 = {};
358
- for (var attr in data) {
359
- var rel = (0, relation_1.judgeRelation)(_this.schema, entity, attr);
360
- if (rel === 1) {
361
- // 只需要记住id和各种外键属性,不这样处理有些古怪的属性比如coordinate,其作为createdata和作为filter并不同构
362
- if ((['id', 'entity', 'entityId'].includes(attr) || ((_a = _this.schema[entity].attributes[attr]) === null || _a === void 0 ? void 0 : _a.type) === 'ref') && typeof data[attr] === 'string') {
363
- data2[attr] = data[attr];
364
- }
365
- }
366
- }
367
- return data2;
368
- }
369
- return filter;
370
- };
371
- var addChild = function (node, path, child) {
372
- var _a;
373
- // 在这里要把可以被node deduce出来的child处理掉
374
- var paths = path.split('$');
375
- (0, assert_1.default)(paths.length >= 2);
376
- if (_this.authDeduceRelationMap[child.entity] === paths[1]) {
377
- (0, assert_1.default)(paths[1] === 'entity', '当前只支持entity外键上的deduce');
378
- return false;
379
- }
380
- if (node.children[path]) {
381
- if (node.children[path] instanceof Array) {
382
- node.children[path].push(child);
383
- }
384
- else {
385
- node.children[path] = [node.children[path], child];
386
- }
387
- }
388
- else {
389
- Object.assign(node.children, (_a = {},
390
- _a[path] = child,
391
- _a));
392
- }
393
- return true;
394
- };
395
- var destructInner = function (entity, operation,
396
- // extraFilter?: ED[T2]['Selection']['filter'],
397
- path, child, hasParent) {
398
- var action = operation.action, data = operation.data, filter = operation.filter;
399
- var filter2 = action === 'create' ? makeCreateFilter(entity, operation) : filter;
400
- (0, assert_1.default)(filter2);
401
- // const filter3 = extraFilter ? combineFilters(entity, schema, [filter2, extraFilter]) : filter2;
402
- var me = {
403
- entity: entity,
404
- filter: filter2,
405
- children: {},
406
- action: action,
407
- };
408
- var root = me;
409
- // 如果当前对象是一个toModi的,意味着它的cascadeUpdate会全部被变为modi去缓存,因此不需要再向下检查了
410
- // modi被apply时,这些modi产生的更新才会被实际检查
411
- var isModiUpdate = _this.schema[entity].toModi && action !== 'remove';
412
- if (child) {
413
- (0, assert_1.default)(path);
414
- addChild(me, path, child);
415
- }
416
- var _loop_1 = function (attr) {
417
- var rel = (0, relation_1.judgeRelation)(_this.schema, entity, attr);
418
- if (rel === 2 && !isModiUpdate) {
419
- (0, assert_1.default)(root === me && !hasParent, 'cascadeUpdate必须是树结构,避免森林');
420
- root = destructInner(attr, data[attr], "".concat(entity, "$entity"), me);
421
- }
422
- else if (typeof rel === 'string' && !isModiUpdate) {
423
- (0, assert_1.default)(root === me && !hasParent, 'cascadeUpdate必须是树结构,避免森林');
424
- root = destructInner(rel, data[attr], "".concat(entity, "$").concat(attr), me);
425
- }
426
- else if (rel instanceof Array && !isModiUpdate) {
427
- var _a = tslib_1.__read(rel, 2), e_2 = _a[0], f = _a[1];
428
- var otmOperations = data[attr];
429
- if (e_2 === 'userRelation' && entity !== 'user') {
430
- me.userRelations = [];
431
- var dealWithUserRelation_1 = function (userRelation) {
432
- var _a;
433
- var action = userRelation.action, data = userRelation.data;
434
- (0, assert_1.default)(action === 'create', 'cascade更新中只允许创建userRelation');
435
- var attrs = Object.keys(data);
436
- (0, assert_1.default)((0, lodash_1.difference)(attrs, Object.keys(_this.schema.userRelation.attributes).concat('id')).length === 0);
437
- if (data.userId === userId) {
438
- (_a = me.userRelations) === null || _a === void 0 ? void 0 : _a.push(data);
439
- }
440
- };
441
- if (otmOperations instanceof Array) {
442
- otmOperations.forEach(function (otmOperation) { return dealWithUserRelation_1(otmOperation); });
443
- }
444
- else {
445
- dealWithUserRelation_1(otmOperations);
446
- }
447
- }
448
- else {
449
- if (otmOperations instanceof Array) {
450
- otmOperations.forEach(function (otmOperation) {
451
- var son = destructInner(e_2, otmOperation, undefined, undefined, true);
452
- addChild(me, attr, son);
453
- });
454
- }
455
- else {
456
- var son = destructInner(e_2, otmOperations, undefined, undefined, true);
457
- addChild(me, attr, son);
458
- }
459
- }
460
- }
461
- };
462
- for (var attr in data) {
463
- _loop_1(attr);
464
- }
465
- return root;
466
- };
467
- return destructInner(entity2, (0, lodash_1.cloneDeep)(operation2));
468
- };
469
- /**
470
- * 定位到了当前用户所有可能的actionAuth,对单条actionAuth加以判断,找到可以满足当前操作的actionAuth
471
- * @param entity
472
- * @param filter
473
- * @param actionAuths
474
- * @param context
475
- * @return string代表用户获得授权的relationId,空字符串代表通过userId赋权,false代表失败
476
- */
477
- RelationAuth.prototype.filterActionAuths = function (entity, filter, actionAuths, context, actions) {
478
- return actionAuths.map(function (ele) {
479
- var paths = ele.paths, relation = ele.relation, relationId = ele.relationId;
480
- // 在cache中,可能出现relation外键指向的对象为null的情况,要容错
481
- if (relationId) {
482
- if (relation) {
483
- var userRelations = relation.userRelation$relation;
484
- if (userRelations.length > 0) {
485
- var entityIds = (0, lodash_1.uniq)(userRelations.map(function (ele) { return ele.entityId; }));
486
- var idFilter_1 = entityIds.length > 1 ? {
487
- $in: entityIds,
488
- } : entityIds[0];
489
- (0, assert_1.default)(idFilter_1);
490
- var pathFilters_1 = paths.map(function (path) {
491
- if (path) {
492
- return (0, lodash_1.set)({}, path, {
493
- id: idFilter_1,
494
- });
495
- }
496
- return {
497
- id: idFilter_1,
498
- };
499
- });
500
- // 这里是或关系,只要对象落在任意一条路径上就可以
501
- var contained_1 = (0, filter_1.combineFilters)(entity, context.getSchema(), pathFilters_1, true);
502
- var contains_1 = (0, filter_1.checkFilterContains)(entity, context, contained_1, filter, true);
503
- if (contains_1 instanceof Promise) {
504
- return contains_1.then(function (c) {
505
- if (c) {
506
- return ele;
507
- }
508
- return;
509
- });
510
- }
511
- if (contains_1) {
512
- return ele;
513
- }
514
- return;
515
- }
516
- }
517
- return;
518
- }
519
- // 说明是通过userId关联
520
- var pathFilters = paths.map(function (path) { return (0, lodash_1.set)({}, "".concat(path, ".id"), context.getCurrentUserId()); });
521
- var contained = (0, filter_1.combineFilters)(entity, context.getSchema(), pathFilters, true);
522
- var contains = (0, filter_1.checkFilterContains)(entity, context, contained, filter, true);
523
- if (contains instanceof Promise) {
524
- return contains.then(function (c) {
525
- if (c) {
526
- return ele;
527
- }
528
- return;
529
- });
530
- }
531
- if (contains) {
532
- return ele;
533
- }
534
- });
535
- };
536
- /**
537
- * 对于有些特殊的查询(带很多$or的查询,多发生在系统级别),单个actionAuth无法满足,需要共同加以判定
538
- * @param entity
539
- * @param filter
540
- * @param actionAuths
541
- * @param context
542
- * @param actions
543
- */
544
- RelationAuth.prototype.checkActionAuthInGroup = function (entity, filter, actionAuths, context) {
545
- var filters = actionAuths.filter(function (ele) { return ele.destEntity === entity; }).map(function (ele) {
546
- var paths = ele.paths, relation = ele.relation, relationId = ele.relationId;
547
- if (relationId) {
548
- (0, assert_1.default)(relation);
549
- var userRelations = relation.userRelation$relation;
550
- (0, assert_1.default)(userRelations.length > 0);
551
- var entityIds = (0, lodash_1.uniq)(userRelations.map(function (ele) { return ele.entityId; }));
552
- var idFilter_2 = entityIds.length > 1 ? {
553
- $in: entityIds,
554
- } : entityIds[0];
555
- (0, assert_1.default)(idFilter_2);
556
- var pathFilters = paths.map(function (path) {
557
- if (path) {
558
- return (0, lodash_1.set)({}, path, {
559
- id: idFilter_2,
560
- });
561
- }
562
- return {
563
- id: idFilter_2
564
- };
565
- });
566
- return pathFilters;
567
- }
568
- // 说明是通过userId关联
569
- return paths.map(function (path) { return (0, lodash_1.set)({}, "".concat(path, ".id"), context.getCurrentUserId()); });
570
- });
571
- var groupFilter = (0, filter_1.combineFilters)(entity, this.schema, filters.flat(), true);
572
- if (groupFilter) {
573
- return (0, filter_1.checkFilterContains)(entity, context, groupFilter, filter, true);
574
- }
575
- return false;
576
- };
577
- RelationAuth.prototype.checkSelection = function (entity, selection, context) {
578
- var _this = this;
579
- var leafSelections = this.destructSelection(entity, selection);
580
- var deducedLeafSelections = leafSelections.map(function (_a) {
581
- var entity = _a.entity, filter = _a.filter;
582
- return _this.getDeducedEntityFilters(entity, filter, ['select'], context);
583
- });
584
- var checkDeducedLeafSelections = function (dlSelections2) {
585
- var dlSelections = dlSelections2.filter(function (ele) {
586
- var entities = ele.map(function (ele2) { return ele2.entity; });
587
- // 同一个leaf的deducedSelections中只要有一个能通过就足够了
588
- if ((0, lodash_1.intersection)(_this.selectFreeEntities, entities).length > 0) {
589
- return false;
590
- }
591
- if ((0, lodash_1.intersection)(RelationAuth.SPECIAL_ENTITIES, entities).length > 0) {
592
- // todo
593
- return false;
594
- }
595
- return true;
596
- });
597
- if (dlSelections.length === 0) {
598
- return true;
599
- }
600
- if (!context.getCurrentUserId()) {
601
- throw new types_1.OakUnloggedInException();
602
- }
603
- var allEntities = [];
604
- dlSelections.forEach(function (ele) { return ele.forEach(function (_a) {
605
- var entity = _a.entity;
606
- allEntities.push(entity);
607
- }); });
608
- var actionAuths = context.select('actionAuth', {
609
- data: {
610
- id: 1,
611
- paths: 1,
612
- destEntity: 1,
613
- deActions: 1,
614
- relation: {
615
- id: 1,
616
- userRelation$relation: {
617
- $entity: 'userRelation',
618
- data: {
619
- id: 1,
620
- entity: 1,
621
- entityId: 1,
622
- },
623
- filter: {
624
- userId: context.getCurrentUserId(),
625
- },
626
- },
627
- },
628
- },
629
- filter: {
630
- deActions: {
631
- $contains: 'select',
632
- },
633
- destEntity: {
634
- $in: allEntities,
635
- },
636
- $or: [
637
- {
638
- relation: {
639
- userRelation$relation: {
640
- userId: context.getCurrentUserId(),
641
- },
642
- }
643
- },
644
- {
645
- relationId: {
646
- $exists: false,
647
- },
648
- }
649
- ]
650
- }
651
- }, { dontCollect: true });
652
- /**
653
- * 返回的结果中,第一层为leafNode,必须全通过,第二层为单个leafNode上的deduce,通过一个就可以
654
- * @param result
655
- * @returns
656
- */
657
- var checkResult = function (result) {
658
- var e_3, _a;
659
- var idx = 0;
660
- try {
661
- for (var result_1 = tslib_1.__values(result), result_1_1 = result_1.next(); !result_1_1.done; result_1_1 = result_1.next()) {
662
- var r1 = result_1_1.value;
663
- var r2 = r1.find(function (ele) { return ele === true; });
664
- if (!r2) {
665
- if (process.env.NODE_ENV === 'development') {
666
- console.warn('对象的select权限被否决,请检查', dlSelections[idx]);
667
- }
668
- return false;
669
- }
670
- }
671
- }
672
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
673
- finally {
674
- try {
675
- if (result_1_1 && !result_1_1.done && (_a = result_1.return)) _a.call(result_1);
676
- }
677
- finally { if (e_3) throw e_3.error; }
678
- }
679
- return true;
680
- };
681
- if (actionAuths instanceof Promise) {
682
- (0, assert_1.default)(context instanceof AsyncRowStore_1.AsyncContext);
683
- return actionAuths.then(function (aas) { return Promise.all(dlSelections.map(function (ele) { return Promise.all(ele.map(function (ele2) { return _this.checkActionAuthInGroup(ele2.entity, ele2.filter, aas, context); })); })).then(function (result) { return checkResult(result); }); });
684
- }
685
- return checkResult(dlSelections.map(function (ele) { return ele.map(function (ele2) { return _this.checkActionAuthInGroup(ele2.entity, ele2.filter, actionAuths, context); }); }));
686
- };
687
- if (deducedLeafSelections[0] instanceof Promise) {
688
- return Promise.all(deducedLeafSelections)
689
- .then(function (dls) { return checkDeducedLeafSelections(dls); });
690
- }
691
- return checkDeducedLeafSelections(deducedLeafSelections);
692
- };
693
- RelationAuth.prototype.findActionAuthsOnNode = function (node, context) {
694
- var _this = this;
695
- var entity = node.entity, filter = node.filter, action = node.action, userRelations = node.userRelations;
696
- if (RelationAuth.SPECIAL_ENTITIES.includes(entity)) {
697
- // 特殊对象不用查询
698
- return [];
699
- }
700
- var deducedEntityFilters2 = this.getDeducedEntityFilters(entity, filter, [action], context);
701
- var dealWithDeducedEntityFilters = function (deducedEntityFilters) {
702
- var allEntities = deducedEntityFilters.map(function (ele) { return ele.entity; });
703
- var allActions = (0, lodash_1.uniq)(deducedEntityFilters.map(function (ele) { return ele.actions; }).flat());
704
- var actionAuths = context.select('actionAuth', {
705
- data: {
706
- id: 1,
707
- paths: 1,
708
- destEntity: 1,
709
- deActions: 1,
710
- relation: {
711
- id: 1,
712
- userRelation$relation: {
713
- $entity: 'userRelation',
714
- data: {
715
- id: 1,
716
- entity: 1,
717
- entityId: 1,
718
- },
719
- filter: {
720
- userId: context.getCurrentUserId(),
721
- },
722
- },
723
- },
724
- },
725
- filter: {
726
- destEntity: {
727
- $in: allEntities,
728
- },
729
- deActions: {
730
- $overlaps: allActions,
731
- },
732
- }
733
- }, { dontCollect: true });
734
- var getActionAuths = function (result) {
735
- var aas = [];
736
- result.forEach(function (ele) { return ele.forEach(function (ele2) {
737
- if (!!ele2) {
738
- aas.push(ele2);
739
- }
740
- }); });
741
- return aas;
742
- };
743
- /**
744
- * 搜索判定是否允许自建对象,自建的条件是 path = '',destEntity === entity
745
- * @param actionAuths
746
- * @returns
747
- */
748
- var findOwnCreateUserRelation = function (actionAuths) {
749
- if (userRelations) {
750
- (0, assert_1.default)(action === 'create');
751
- var ars = actionAuths.filter(function (ar) { return !!userRelations.find(function (ur) { return ur.relationId === ar.relationId; }) && ar.paths.includes('') && ar.destEntity === entity; });
752
- if (ars.length > 0) {
753
- return ars;
754
- }
755
- }
756
- };
757
- if (actionAuths instanceof Promise) {
758
- return actionAuths.then(function (ars) {
759
- var created = findOwnCreateUserRelation(ars);
760
- if (created) {
761
- return created;
762
- }
763
- return Promise.all(deducedEntityFilters.map(function (ele) {
764
- var ars2 = ars.filter(function (ele2) { return ele2.destEntity === ele.entity && (0, lodash_1.intersection)(ele2.deActions, ele.actions).length > 0; } // 这里只要overlap就可以了
765
- );
766
- return Promise.all(_this.filterActionAuths(ele.entity, ele.filter, ars2, context, ele.actions));
767
- })).then(function (result) { return getActionAuths(result); });
768
- });
769
- }
770
- (0, assert_1.default)(context instanceof SyncRowStore_1.SyncContext);
771
- var created = findOwnCreateUserRelation(actionAuths);
772
- if (created) {
773
- return created;
774
- }
775
- return getActionAuths(deducedEntityFilters.map(function (ele) {
776
- var ars2 = actionAuths.filter(function (ele2) { return ele2.destEntity === ele.entity && (0, lodash_1.intersection)(ele2.deActions, ele.actions).length > 0; } // 这里只要overlap就可以了
777
- );
778
- return _this.filterActionAuths(ele.entity, ele.filter, ars2, context, ele.actions);
779
- }));
780
- };
781
- if (deducedEntityFilters2 instanceof Promise) {
782
- return deducedEntityFilters2.then(function (def2) { return dealWithDeducedEntityFilters(def2); });
783
- }
784
- return dealWithDeducedEntityFilters(deducedEntityFilters2);
785
- };
786
- RelationAuth.prototype.checkOperationTree = function (tree, context) {
787
- var _this = this;
788
- var actionAuths2 = this.findActionAuthsOnNode(tree, context);
789
- var checkChildNode = function (actionAuths, node) {
790
- var checkChildNodeInner = function (legalAuths) {
791
- // 因为如果children是数组的话,会把数组中所有的action并起来查询,所以在这里还要再确认一次
792
- var realLegalPaths = legalAuths.filter(function (ele) {
793
- if (ele.destEntity === node.entity && ele.deActions.includes(node.action)) {
794
- return true;
795
- }
796
- // 有一种例外情况,是在tree的根结点findActionAuthsOnNode时,deduce出了另外一个对象的权限,此时肯定可以通过,但不能再使用这条路径对children进行进一步判断了
797
- if (node === tree) {
798
- return true;
799
- }
800
- return false;
801
- });
802
- var checkChildren = function () {
803
- var children = node.children;
804
- var childPath = Object.keys(children);
805
- if (childPath.length === 0) {
806
- return true;
807
- }
808
- var selfLegalPaths = realLegalPaths.filter(function (ele) {
809
- if (ele.destEntity === node.entity && ele.deActions.includes(node.action)) {
810
- return true;
811
- }
812
- return false;
813
- });
814
- // assert(selfLegalPaths.length > 0, `对象${node.entity as string}的权限检查是用deduce的对象通过的,无法再进一步对子对象加以判断`);
815
- var childResult = childPath.map(function (childPath) {
816
- var child = children[childPath];
817
- var childEntity = child instanceof Array ? child[0].entity : child.entity;
818
- // 这里如果该子结点能deduce到父,则直接通过
819
- if (_this.authDeduceRelationMap[childEntity]) {
820
- (0, assert_1.default)(_this.authDeduceRelationMap[childEntity] === 'entity');
821
- var rel = (0, relation_1.judgeRelation)(_this.schema, childEntity, childPath);
822
- if (rel === 2) {
823
- return true;
824
- }
825
- }
826
- var pathToParent = childPath.endsWith('$entity') ? node.entity : childPath.split('$')[1];
827
- if (child instanceof Array) {
828
- var childActions_1 = child.map(function (ele) { return ele.action; });
829
- var childLegalAuths_1 = selfLegalPaths.map(function (ele) {
830
- var paths = ele.paths, relationId = ele.relationId;
831
- var paths2 = paths.map(function (path) { return path ? "".concat(pathToParent, ".").concat(path) : pathToParent; });
832
- return context.select('actionAuth', {
833
- data: {
834
- id: 1,
835
- },
836
- filter: {
837
- paths: {
838
- $overlaps: paths2,
839
- },
840
- destEntity: childEntity,
841
- deActions: {
842
- $overlaps: childActions_1,
843
- },
844
- relationId: relationId || {
845
- $exists: false,
846
- },
847
- }
848
- }, { dontCollect: true });
849
- }).flat();
850
- if (childLegalAuths_1[0] instanceof Promise) {
851
- return Promise.all(childLegalAuths_1).then(function (clas) { return child.map(function (c) { return checkChildNode(clas, c); }); });
852
- }
853
- return child.map(function (c) { return checkChildNode(childLegalAuths_1, c); });
854
- }
855
- var childLegalAuths = realLegalPaths.map(function (ele) {
856
- var paths = ele.paths, relationId = ele.relationId;
857
- var paths2 = paths.map(function (path) { return path ? "".concat(pathToParent, ".").concat(path) : pathToParent; });
858
- return context.select('actionAuth', {
859
- data: {
860
- id: 1,
861
- },
862
- filter: {
863
- paths: {
864
- $overlaps: paths2,
865
- },
866
- destEntity: childEntity,
867
- deActions: {
868
- $overlaps: child.action,
869
- },
870
- relationId: relationId || {
871
- $exists: false,
872
- },
873
- }
874
- }, { dontCollect: true });
875
- }).flat();
876
- if (childLegalAuths[0] instanceof Promise) {
877
- return Promise.all(childLegalAuths).then(function (clas) { return checkChildNode(clas.flat(), child); });
878
- }
879
- return checkChildNode(childLegalAuths, child);
880
- }).flat();
881
- if (childResult[0] instanceof Promise) {
882
- return Promise.all(childResult).then(function (r) { return !r.includes(false); });
883
- }
884
- return !childResult.includes(false);
885
- };
886
- if (RelationAuth.SPECIAL_ENTITIES.includes(node.entity)) {
887
- // 特殊entity走特别的路径判断
888
- var result = _this.checkOperateSpecialEntities2(node.entity, node.action, node.filter, context);
889
- if (result instanceof Promise) {
890
- return result.then(function (r) {
891
- if (r) {
892
- return checkChildren();
893
- }
894
- return false;
895
- });
896
- }
897
- if (result) {
898
- if (node.entity === 'user') {
899
- // 如果当前是对user对象操作,需要加上一个指向它自身的actionAuth,否则剩下的子对象会判定不过
900
- // user的操作权限由应用自己决定,如果user的操作最终过不去,这里放过也没关系
901
- (0, assert_1.default)(node === tree && realLegalPaths.length === 0); // user不可能是非根结点
902
- realLegalPaths.push({
903
- id: 'temp',
904
- paths: [''],
905
- $$createAt$$: 1,
906
- $$updateAt$$: 1,
907
- $$seq$$: 'temp',
908
- destEntity: 'user',
909
- deActions: [node.action],
910
- });
911
- }
912
- return checkChildren();
913
- }
914
- if (process.env.NODE_ENV === 'development') {
915
- console.warn('对象operate权限检查不通过', node);
916
- }
917
- return false;
918
- }
919
- if (realLegalPaths.length === 0) {
920
- if (node === tree) {
921
- if (process.env.NODE_ENV === 'development') {
922
- console.warn('对象operate权限检查不通过', node);
923
- }
924
- return false;
925
- }
926
- // 如果不是tree的根结点,相对路径上的actionAuth找不到,还可以尝试从自身的filter去重试其它路径
927
- return _this.checkOperationTree(node, context);
928
- }
929
- return checkChildren();
930
- };
931
- if (actionAuths instanceof Promise) {
932
- return actionAuths.then(function (aars) { return checkChildNodeInner(aars); });
933
- }
934
- return checkChildNodeInner(actionAuths);
935
- };
936
- return checkChildNode(actionAuths2, tree);
937
- };
938
- RelationAuth.prototype.checkOperation = function (entity, operation, context) {
939
- var action = operation.action, filter = operation.filter, data = operation.data;
940
- if (action === 'create' && this.createFreeEntities.includes(entity)) {
941
- return true;
942
- }
943
- else if (action === 'update' && this.updateFreeEntities.includes(entity)) {
944
- return true;
945
- }
946
- var userId = context.getCurrentUserId();
947
- if (!userId) {
948
- throw new types_1.OakUnloggedInException();
949
- }
950
- if (!filter && (!data || action !== 'create')) {
951
- if (process.env.NODE_ENV === 'development') {
952
- console.warn('operation不能没有限制条件', operation);
953
- }
954
- return false;
955
- }
956
- var updateTree = this.destructOperation(entity, operation, userId);
957
- return this.checkOperationTree(updateTree, context);
958
- };
959
- /**
960
- * 检查一个operation是否能被通过权限测试
961
- * 一个cascadeOperation是一棵树形结构:
962
- * * 对于select,只要叶子通过其父结点必然通过;
963
- * * 对于update,自顶向下进行检查,若父亲被权限S通过,则只需要检查子对于S有没有相对路径上的actionAuth
964
- * 另外在update中,还需要考虑自建userRelation的case(例如在电子商务网站上购买商品,创建订单同时创建用户和订单的关系)
965
- * @param entity
966
- * @param operation
967
- * @param context
968
- * @param actions
969
- * @returns
970
- */
971
- RelationAuth.prototype.checkActions2 = function (entity, operation, context, actions) {
972
- var action = operation.action;
973
- if (!action || action_1.readOnlyActions.includes(action)) {
974
- var result = this.checkSelection(entity, operation, context);
975
- if (result instanceof Promise) {
976
- return result.then(function (r) {
977
- if (!r) {
978
- throw new types_1.OakUserUnpermittedException();
979
- }
980
- });
981
- }
982
- if (!result) {
983
- throw new types_1.OakUserUnpermittedException();
984
- }
985
- }
986
- else {
987
- var result = this.checkOperation(entity, operation, context);
988
- if (result instanceof Promise) {
989
- return result.then(function (r) {
990
- if (!r) {
991
- throw new types_1.OakUserUnpermittedException();
992
- }
993
- });
994
- }
995
- if (!result) {
996
- throw new types_1.OakUserUnpermittedException();
997
- }
998
- }
999
- };
1000
- RelationAuth.SPECIAL_ENTITIES = env_1.SYSTEM_RESERVE_ENTITIES;
1001
- return RelationAuth;
1002
- }());
1003
- exports.RelationAuth = RelationAuth;
1004
- ;
1005
- /**
1006
- * 获取有对entity进行actions操作权限的userRelation关系
1007
- * @param params
1008
- * @param context
1009
- * todo paths改成复数以后这里还未充分测试过
1010
- */
1011
- function getUserRelationsByActions(params, context) {
1012
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1013
- var entity, filter, actions, overlap, actionAuthfilter, actionAuths, getUserRelations, getDirectUserEntities, urAuths2, directAuths2, _a, userRelations, userEntities;
1014
- var _this = this;
1015
- return tslib_1.__generator(this, function (_b) {
1016
- switch (_b.label) {
1017
- case 0:
1018
- entity = params.entity, filter = params.filter, actions = params.actions, overlap = params.overlap;
1019
- actionAuthfilter = {
1020
- destEntity: entity,
1021
- };
1022
- if (overlap) {
1023
- Object.assign(actionAuthfilter, {
1024
- deActions: {
1025
- $overlaps: actions,
1026
- },
1027
- });
1028
- }
1029
- else {
1030
- Object.assign(actionAuthfilter, {
1031
- deActions: {
1032
- $contains: actions,
1033
- },
1034
- });
1035
- }
1036
- return [4 /*yield*/, context.select('actionAuth', {
1037
- data: {
1038
- id: 1,
1039
- paths: 1,
1040
- relationId: 1,
1041
- relation: {
1042
- id: 1,
1043
- entity: 1,
1044
- },
1045
- },
1046
- filter: actionAuthfilter,
1047
- }, { dontCollect: true })];
1048
- case 1:
1049
- actionAuths = _b.sent();
1050
- getUserRelations = function (urAuths) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1051
- var makeRelationIterator, urAuthDict2, userRelations;
1052
- var _this = this;
1053
- return tslib_1.__generator(this, function (_a) {
1054
- switch (_a.label) {
1055
- case 0:
1056
- makeRelationIterator = function (path, relationIds) {
1057
- var paths = path.split('.');
1058
- var makeIter = function (e, idx) {
1059
- var _a, _b, _c;
1060
- if (idx === paths.length) {
1061
- return {
1062
- projection: {
1063
- id: 1,
1064
- userRelation$entity: {
1065
- $entity: 'userRelation',
1066
- data: {
1067
- id: 1,
1068
- relationId: 1,
1069
- relation: {
1070
- id: 1,
1071
- name: 1,
1072
- },
1073
- entity: 1,
1074
- entityId: 1,
1075
- userId: 1,
1076
- },
1077
- filter: {
1078
- relationId: {
1079
- $in: relationIds,
1080
- },
1081
- },
1082
- }
1083
- },
1084
- getData: function (d) {
1085
- return d.userRelation$entity;
1086
- },
1087
- };
1088
- }
1089
- var attr = paths[idx];
1090
- var rel = (0, relation_1.judgeRelation)(context.getSchema(), e, attr);
1091
- if (rel === 2) {
1092
- var _d = makeIter(attr, idx + 1), projection = _d.projection, getData_1 = _d.getData;
1093
- return {
1094
- projection: (_a = {
1095
- id: 1
1096
- },
1097
- _a[attr] = projection,
1098
- _a),
1099
- getData: function (d) { return d[attr] && getData_1(d[attr]); },
1100
- };
1101
- }
1102
- else if (typeof rel === 'string') {
1103
- var _e = makeIter(rel, idx + 1), projection = _e.projection, getData_2 = _e.getData;
1104
- return {
1105
- projection: (_b = {
1106
- id: 1
1107
- },
1108
- _b[attr] = projection,
1109
- _b),
1110
- getData: function (d) { return d[attr] && getData_2(d[attr]); },
1111
- };
1112
- }
1113
- else {
1114
- (0, assert_1.default)(rel instanceof Array);
1115
- var _f = tslib_1.__read(rel, 2), e2 = _f[0], fk = _f[1];
1116
- var _g = makeIter(e2, idx + 1), projection = _g.projection, getData_3 = _g.getData;
1117
- return {
1118
- projection: (_c = {
1119
- id: 1
1120
- },
1121
- _c[attr] = {
1122
- $entity: e2,
1123
- data: projection,
1124
- },
1125
- _c),
1126
- getData: function (d) { return d[attr] && d[attr].map(function (ele) { return getData_3(ele); }); },
1127
- };
1128
- }
1129
- };
1130
- return makeIter(entity, 0);
1131
- };
1132
- urAuthDict2 = {};
1133
- urAuths.forEach(function (auth) {
1134
- var paths = auth.paths, relationId = auth.relationId;
1135
- paths.forEach(function (path) {
1136
- if (!urAuthDict2[path]) {
1137
- urAuthDict2[path] = [relationId];
1138
- }
1139
- else if (!urAuthDict2[path].includes(relationId)) {
1140
- urAuthDict2[path].push(relationId);
1141
- }
1142
- });
1143
- });
1144
- return [4 /*yield*/, Promise.all(Object.keys(urAuthDict2).map(function (path) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1145
- var relationIds, _a, projection, getData, rows, urs;
1146
- return tslib_1.__generator(this, function (_b) {
1147
- switch (_b.label) {
1148
- case 0:
1149
- relationIds = urAuthDict2[path];
1150
- _a = makeRelationIterator(path, relationIds), projection = _a.projection, getData = _a.getData;
1151
- return [4 /*yield*/, context.select(entity, {
1152
- data: projection,
1153
- filter: filter,
1154
- }, { dontCollect: true })];
1155
- case 1:
1156
- rows = _b.sent();
1157
- urs = rows.map(function (ele) { return getData(ele); }).flat().filter(function (ele) { return !!ele; });
1158
- return [2 /*return*/, urs];
1159
- }
1160
- });
1161
- }); }))];
1162
- case 1:
1163
- userRelations = _a.sent();
1164
- return [2 /*return*/, userRelations.flat()];
1165
- }
1166
- });
1167
- }); };
1168
- getDirectUserEntities = function (directAuths) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1169
- var makeRelationIterator, userEntities;
1170
- var _this = this;
1171
- return tslib_1.__generator(this, function (_a) {
1172
- switch (_a.label) {
1173
- case 0:
1174
- makeRelationIterator = function (path) {
1175
- var paths = path.split('.');
1176
- var makeIter = function (e, idx) {
1177
- var _a, _b, _c, _d;
1178
- var attr = paths[idx];
1179
- var rel = (0, relation_1.judgeRelation)(context.getSchema(), e, attr);
1180
- if (idx === paths.length - 1) {
1181
- if (rel === 2) {
1182
- (0, assert_1.default)(attr === 'user');
1183
- return {
1184
- projection: {
1185
- id: 1,
1186
- entity: 1,
1187
- entityId: 1,
1188
- },
1189
- getData: function (d) {
1190
- if (d) {
1191
- return {
1192
- entity: e,
1193
- entityId: d.id,
1194
- userId: d.entityId,
1195
- };
1196
- }
1197
- },
1198
- };
1199
- }
1200
- else {
1201
- (0, assert_1.default)(rel === 'user');
1202
- return {
1203
- projection: (_a = {
1204
- id: 1
1205
- },
1206
- _a["".concat(attr, "Id")] = 1,
1207
- _a),
1208
- getData: function (d) {
1209
- if (d) {
1210
- return {
1211
- entity: e,
1212
- entityId: d.id,
1213
- userId: d["".concat(attr, "Id")]
1214
- };
1215
- }
1216
- },
1217
- };
1218
- }
1219
- }
1220
- if (rel === 2) {
1221
- var _e = makeIter(attr, idx + 1), projection = _e.projection, getData_4 = _e.getData;
1222
- return {
1223
- projection: (_b = {
1224
- id: 1
1225
- },
1226
- _b[attr] = projection,
1227
- _b),
1228
- getData: function (d) { return d[attr] && getData_4(d[attr]); },
1229
- };
1230
- }
1231
- else if (typeof rel === 'string') {
1232
- var _f = makeIter(rel, idx + 1), projection = _f.projection, getData_5 = _f.getData;
1233
- return {
1234
- projection: (_c = {
1235
- id: 1
1236
- },
1237
- _c[attr] = projection,
1238
- _c),
1239
- getData: function (d) { return d[attr] && getData_5(d[attr]); },
1240
- };
1241
- }
1242
- else {
1243
- (0, assert_1.default)(rel instanceof Array);
1244
- var _g = tslib_1.__read(rel, 2), e2 = _g[0], fk = _g[1];
1245
- var _h = makeIter(e2, idx + 1), projection = _h.projection, getData_6 = _h.getData;
1246
- return {
1247
- projection: (_d = {
1248
- id: 1
1249
- },
1250
- _d[attr] = {
1251
- $entity: e2,
1252
- data: projection,
1253
- },
1254
- _d),
1255
- getData: function (d) { return d[attr] && d[attr].map(function (ele) { return getData_6(ele); }); },
1256
- };
1257
- }
1258
- };
1259
- return makeIter(entity, 0);
1260
- };
1261
- return [4 /*yield*/, Promise.all(directAuths.map(function (_a) {
1262
- var paths = _a.paths;
1263
- return tslib_1.__awaiter(_this, void 0, void 0, function () {
1264
- var _this = this;
1265
- return tslib_1.__generator(this, function (_b) {
1266
- return [2 /*return*/, paths.map(function (path) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1267
- var _a, getData, projection, rows, userEntities;
1268
- return tslib_1.__generator(this, function (_b) {
1269
- switch (_b.label) {
1270
- case 0:
1271
- _a = makeRelationIterator(path), getData = _a.getData, projection = _a.projection;
1272
- return [4 /*yield*/, context.select(entity, {
1273
- data: projection,
1274
- filter: filter,
1275
- }, { dontCollect: true })];
1276
- case 1:
1277
- rows = _b.sent();
1278
- userEntities = rows.map(function (ele) { return getData(ele); }).flat().filter(function (ele) { return !!ele; });
1279
- return [2 /*return*/, userEntities];
1280
- }
1281
- });
1282
- }); })];
1283
- });
1284
- });
1285
- }))];
1286
- case 1:
1287
- userEntities = _a.sent();
1288
- return [2 /*return*/, userEntities.flat()];
1289
- }
1290
- });
1291
- }); };
1292
- urAuths2 = actionAuths.filter(function (ele) { return !!ele.relationId; } // 有relation说明通过userRelation关联
1293
- );
1294
- directAuths2 = actionAuths.filter(function (ele) { return !ele.relationId; } // 没relation说明通过user关联
1295
- );
1296
- return [4 /*yield*/, Promise.all([getUserRelations(urAuths2), getDirectUserEntities(directAuths2)])];
1297
- case 2:
1298
- _a = tslib_1.__read.apply(void 0, [_b.sent(), 2]), userRelations = _a[0], userEntities = _a[1];
1299
- return [2 /*return*/, {
1300
- userRelations: userRelations,
1301
- userEntities: userEntities,
1302
- }];
1303
- }
1304
- });
1305
- });
1306
- }
1307
- exports.getUserRelationsByActions = getUserRelationsByActions;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUserRelationsByActions = exports.RelationAuth = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var assert_1 = tslib_1.__importDefault(require("assert"));
6
+ var types_1 = require("../types");
7
+ var AsyncRowStore_1 = require("./AsyncRowStore");
8
+ var filter_1 = require("./filter");
9
+ var relation_1 = require("./relation");
10
+ var action_1 = require("../actions/action");
11
+ var lodash_1 = require("../utils/lodash");
12
+ var env_1 = require("../compiler/env");
13
+ var RelationAuth = /** @class */ (function () {
14
+ function RelationAuth(schema, actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, selectFreeEntities, createFreeEntities, updateFreeEntities) {
15
+ this.actionCascadePathGraph = actionCascadePathGraph;
16
+ this.relationCascadePathGraph = relationCascadePathGraph;
17
+ this.schema = schema;
18
+ this.selectFreeEntities = selectFreeEntities || [];
19
+ this.createFreeEntities = createFreeEntities || [];
20
+ this.updateFreeEntities = updateFreeEntities || [];
21
+ this.authDeduceRelationMap = Object.assign({}, authDeduceRelationMap, {
22
+ modi: 'entity',
23
+ });
24
+ }
25
+ // 前台检查filter是否满足relation约束
26
+ RelationAuth.prototype.checkRelationSync = function (entity, operation, context) {
27
+ if (context.isRoot()) {
28
+ return;
29
+ }
30
+ this.checkActions2(entity, operation, context);
31
+ };
32
+ /**
33
+ * 查询当前用户在对应entity上可以操作的relationIds
34
+ * @param entity
35
+ * @param entityId
36
+ * @param context
37
+ * @returns
38
+ */
39
+ RelationAuth.prototype.getGrantedRelationIds = function (entity, entityId, context) {
40
+ var result = context.select('relationAuth', {
41
+ data: {
42
+ id: 1,
43
+ destRelationId: 1,
44
+ destRelation: {
45
+ id: 1,
46
+ name: 1,
47
+ entity: 1,
48
+ entityId: 1,
49
+ display: 1,
50
+ },
51
+ },
52
+ filter: {
53
+ sourceRelation: {
54
+ userRelation$relation: {
55
+ userId: context.getCurrentUserId(),
56
+ }
57
+ },
58
+ destRelation: {
59
+ entity: entity,
60
+ $or: [
61
+ {
62
+ entityId: entityId,
63
+ },
64
+ {
65
+ entityId: {
66
+ $exists: false,
67
+ },
68
+ }
69
+ ],
70
+ },
71
+ },
72
+ }, {});
73
+ if (result instanceof Promise) {
74
+ return result.then(function (r2) { return r2.map(function (ele) { return ele.destRelation; }); });
75
+ }
76
+ return result.map(function (ele) { return ele.destRelation; });
77
+ };
78
+ // 后台检查filter是否满足relation约束
79
+ RelationAuth.prototype.checkRelationAsync = function (entity, operation, context) {
80
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
81
+ return tslib_1.__generator(this, function (_a) {
82
+ switch (_a.label) {
83
+ case 0:
84
+ if (context.isRoot()) {
85
+ return [2 /*return*/];
86
+ }
87
+ return [4 /*yield*/, this.checkActions2(entity, operation, context)];
88
+ case 1:
89
+ _a.sent();
90
+ return [2 /*return*/];
91
+ }
92
+ });
93
+ });
94
+ };
95
+ RelationAuth.prototype.checkOperateSpecialEntities2 = function (entity2, action, filter, context) {
96
+ switch (entity2) {
97
+ case 'userRelation': {
98
+ (0, assert_1.default)(!(filter instanceof Array));
99
+ (0, assert_1.default)(['create', 'remove'].includes(action));
100
+ if (action === 'create') {
101
+ (0, assert_1.default)(!(filter instanceof Array));
102
+ var _a = filter, entity = _a.entity, entityId = _a.entityId, relationId_1 = _a.relationId;
103
+ // 创建userRelation如果是领取动作,先暂使用root身份通过
104
+ var destRelations = this.getGrantedRelationIds(entity, entityId, context);
105
+ if (destRelations instanceof Promise) {
106
+ return destRelations.then(function (r2) {
107
+ if (relationId_1 && !r2.find(function (ele) { return ele.id === relationId_1; }) || r2.length === 0) {
108
+ return false;
109
+ }
110
+ return true;
111
+ });
112
+ }
113
+ // 若指定了要create的relation,则必须有该relationId存在,否则只要有任意可授权的relation即可
114
+ if (relationId_1 && !destRelations.find(function (ele) { return ele.id === relationId_1; }) || destRelations.length === 0) {
115
+ return false;
116
+ }
117
+ return true;
118
+ }
119
+ else {
120
+ (0, assert_1.default)(action === 'remove');
121
+ var userId = context.getCurrentUserId();
122
+ (0, assert_1.default)(filter);
123
+ var contained = {
124
+ relation: {
125
+ relationAuth$destRelation: {
126
+ sourceRelation: {
127
+ userRelation$relation: {
128
+ userId: userId,
129
+ },
130
+ },
131
+ },
132
+ },
133
+ };
134
+ return (0, filter_1.checkFilterContains)(entity2, context, contained, filter, true);
135
+ }
136
+ }
137
+ case 'user': {
138
+ // 对用户的操作由应用自己去管理权限,这里只检查grant/revoke
139
+ if (['grant', 'revoke'].includes(action)) {
140
+ // assert(filter && Object.keys(filter).length === 1, 'grant/revoke只能操作userRelation$user');
141
+ // assert(filter!.hasOwnProperty('userRelation$user'), 'grant/revoke只能操作userRelation$user');
142
+ return true;
143
+ }
144
+ else {
145
+ // 应用允许用户操作其它用户的逻辑请通过编写类型为relation的checker去控制,在这里不能加以限制
146
+ return true;
147
+ }
148
+ }
149
+ case 'modi': {
150
+ // modi的操作权限都是由触发器触发,不用再检测了
151
+ return true;
152
+ }
153
+ case 'relation': {
154
+ // 创建relation目前不支持,以后再说
155
+ return false;
156
+ }
157
+ case 'userEntityGrant': {
158
+ // userEntityGrant的创建相当于授权,领取相当于赋权
159
+ if (['create', 'update', 'remove'].includes(action)) {
160
+ if (action === 'create') {
161
+ return this.checkOperateSpecialEntities2('userRelation', 'create', filter, context);
162
+ }
163
+ return this.checkOperateSpecialEntities2('userRelation', 'action', {
164
+ relation: {
165
+ userEntityGrant$relation: filter,
166
+ },
167
+ }, context);
168
+ }
169
+ // 领取和读取动作公开
170
+ return true;
171
+ }
172
+ default: {
173
+ (0, assert_1.default)(false, "\u5BF9\u8C61".concat(entity2, "\u7684\u6743\u9650\u63A7\u5236\u6CA1\u6709\u52A0\u4EE5\u63A7\u5236"));
174
+ }
175
+ }
176
+ };
177
+ RelationAuth.prototype.getDeducedEntityFilters = function (entity, filter, actions, context) {
178
+ var e_1, _a;
179
+ var _this = this;
180
+ var entityFilters = [
181
+ {
182
+ entity: entity,
183
+ filter: filter,
184
+ actions: actions,
185
+ }
186
+ ];
187
+ if (this.authDeduceRelationMap[entity]) {
188
+ (0, assert_1.default)(this.authDeduceRelationMap[entity] === 'entity');
189
+ var _b = filter, deduceEntity = _b.entity, deduceEntityId_1 = _b.entityId;
190
+ var deduceFilter = {};
191
+ if (deduceEntity && deduceEntityId_1) {
192
+ deduceFilter = { id: deduceEntityId_1 };
193
+ }
194
+ else {
195
+ // 也可能是用cascade方式进行查找,这里有时候filter上会带有两个不同的entity目标,尚未处理(todo!)
196
+ var ref = this.schema[entity].attributes.entity.ref;
197
+ (0, assert_1.default)(ref instanceof Array);
198
+ try {
199
+ for (var ref_1 = tslib_1.__values(ref), ref_1_1 = ref_1.next(); !ref_1_1.done; ref_1_1 = ref_1.next()) {
200
+ var refEntity = ref_1_1.value;
201
+ if (filter[refEntity]) {
202
+ deduceEntity = refEntity;
203
+ deduceFilter = filter[refEntity];
204
+ break;
205
+ }
206
+ }
207
+ }
208
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
209
+ finally {
210
+ try {
211
+ if (ref_1_1 && !ref_1_1.done && (_a = ref_1.return)) _a.call(ref_1);
212
+ }
213
+ finally { if (e_1) throw e_1.error; }
214
+ }
215
+ }
216
+ var getRecursiveDeducedFilters_1 = function (deduceEntity, deduceFilter) {
217
+ var excludeActions = action_1.readOnlyActions.concat([ /* 'create', 'remove' */]);
218
+ var updateActions = _this.schema[deduceEntity].actions.filter(function (a) { return !excludeActions.includes(a); });
219
+ /* if (!RelationAuth.SPECIAL_ENTITIES.includes(deduceEntity as string)) {
220
+ return this.getDeducedEntityFilters(deduceEntity, deduceFilter, actions[0] === 'select' ? actions : updateActions, context);
221
+ }
222
+ return []; */
223
+ return _this.getDeducedEntityFilters(deduceEntity, deduceFilter, actions[0] === 'select' ? actions : updateActions, context);
224
+ };
225
+ if (deduceEntity && deduceFilter) {
226
+ var deducedSelections = getRecursiveDeducedFilters_1(deduceEntity, deduceFilter);
227
+ if (deducedSelections instanceof Promise) {
228
+ return deducedSelections.then(function (ds) {
229
+ entityFilters.push.apply(entityFilters, tslib_1.__spreadArray([], tslib_1.__read(ds), false));
230
+ return entityFilters;
231
+ });
232
+ }
233
+ entityFilters.push.apply(entityFilters, tslib_1.__spreadArray([], tslib_1.__read(deducedSelections), false));
234
+ return entityFilters;
235
+ }
236
+ else {
237
+ /**
238
+ * 这种情况说明从filter中无法确定相应的deduceFilter,需要查找该实体对应的entity/entityId来进行推导。
239
+ * 这种情况一般发生在entity1 -> entity2上,此时entity2应该是一个固定id查询的filter
240
+ * 在这里先假设如果碰到了list类型的filter,直接不使用deduce路径上的对象来推导
241
+ */
242
+ var rows2 = context.select(entity, {
243
+ data: {
244
+ id: 1,
245
+ entity: 1,
246
+ entityId: 1,
247
+ },
248
+ filter: filter,
249
+ indexFrom: 0,
250
+ count: 10,
251
+ }, { dontCollect: true, blockTrigger: true });
252
+ var dealWithData_1 = function (rows) {
253
+ // 这里如果entity指向不同的实体,一般出现这样的查询,则其权限应当不由这条deduce路径处理
254
+ // 同上,如果找到的行数大于1行,说明deduce路径上的对象不确定,也暂不处理 by Xc 20230725
255
+ if (rows.length > 1 || rows.length === 0) {
256
+ if (process.env.NODE_ENV === 'development') {
257
+ console.warn("\u8FDB\u884Cdeduce\u63A8\u5BFC\u65F6\u627E\u5230\u4E86".concat(rows.length, "\u884C").concat(entity, "\u6570\u636E"));
258
+ }
259
+ return entityFilters;
260
+ }
261
+ var _a = rows[0], deducedEntity = _a.entity, deducedEntityId = _a.entityId;
262
+ if (!deducedEntity || !deducedEntityId) {
263
+ // 这种情况会出现在前台缓存里
264
+ return entityFilters;
265
+ }
266
+ var result = getRecursiveDeducedFilters_1(deducedEntity, {
267
+ id: deduceEntityId_1,
268
+ });
269
+ if (result instanceof Promise) {
270
+ return result.then(function (r2) {
271
+ entityFilters.push.apply(entityFilters, tslib_1.__spreadArray([], tslib_1.__read(r2), false));
272
+ return entityFilters;
273
+ });
274
+ }
275
+ entityFilters.push.apply(entityFilters, tslib_1.__spreadArray([], tslib_1.__read(result), false));
276
+ return entityFilters;
277
+ };
278
+ if (rows2 instanceof Promise) {
279
+ return rows2.then(function (r2) { return dealWithData_1(r2); });
280
+ }
281
+ return dealWithData_1(rows2);
282
+ }
283
+ }
284
+ return entityFilters;
285
+ };
286
+ /**
287
+ * 对于selection,解构出最底层的对象,如果最底层的对象可以被访问,则父对象一定可以
288
+ * 但对于deduce的子对象,不必再向底层查看(假设deduce对象一般都位于树的最底层附近)
289
+ * @param entity
290
+ * @param operation
291
+ */
292
+ RelationAuth.prototype.destructSelection = function (entity, selection) {
293
+ var _this = this;
294
+ var leafSelections = [];
295
+ var destructInner = function (entity2, selection2) {
296
+ var _a, _b;
297
+ var data = selection2.data, filter = selection2.filter;
298
+ var hasOneToMany = false;
299
+ for (var attr in data) {
300
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
301
+ if (rel instanceof Array) {
302
+ var _c = tslib_1.__read(rel, 2), e = _c[0], foreignKey = _c[1];
303
+ if (foreignKey) {
304
+ (0, assert_1.default)(!_this.authDeduceRelationMap[e]);
305
+ hasOneToMany = true;
306
+ destructInner(e, {
307
+ data: data[attr].data,
308
+ filter: (0, filter_1.combineFilters)(e, _this.schema, [(_a = {},
309
+ _a[foreignKey.slice(0, foreignKey.length - 2)] = filter,
310
+ _a), data[attr].filter || {}]),
311
+ });
312
+ }
313
+ else {
314
+ if (!_this.authDeduceRelationMap[e]) {
315
+ hasOneToMany = true;
316
+ destructInner(e, {
317
+ data: data[attr].data,
318
+ filter: (0, filter_1.combineFilters)(e, _this.schema, [(_b = {},
319
+ _b[entity2] = filter,
320
+ _b), data[attr].filter || {}]),
321
+ });
322
+ }
323
+ else {
324
+ (0, assert_1.default)(_this.authDeduceRelationMap[e] === 'entity');
325
+ }
326
+ }
327
+ }
328
+ }
329
+ if (!hasOneToMany) {
330
+ leafSelections.push({
331
+ entity: entity2,
332
+ filter: filter,
333
+ });
334
+ }
335
+ };
336
+ destructInner(entity, (0, lodash_1.cloneDeep)(selection));
337
+ return leafSelections;
338
+ };
339
+ /**
340
+ * 对于operation,解构出一个树形结构,以方便自顶向下的进行访问
341
+ * 但对于deduce的子对象,不必再向底层查看
342
+ * @param entity
343
+ * @param selection
344
+ */
345
+ RelationAuth.prototype.destructOperation = function (entity2, operation2, userId) {
346
+ var _this = this;
347
+ /**
348
+ * 对create动作,把data中的cascade部分剔除后作为filter参与后续的检验
349
+ * @param operation
350
+ * @returns
351
+ */
352
+ var makeCreateFilter = function (entity, operation) {
353
+ var _a;
354
+ var data = operation.data, filter = operation.filter;
355
+ (0, assert_1.default)(!(data instanceof Array));
356
+ if (data) {
357
+ var data2 = {};
358
+ for (var attr in data) {
359
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entity, attr);
360
+ if (rel === 1) {
361
+ // 只需要记住id和各种外键属性,不这样处理有些古怪的属性比如coordinate,其作为createdata和作为filter并不同构
362
+ if ((['id', 'entity', 'entityId'].includes(attr) || ((_a = _this.schema[entity].attributes[attr]) === null || _a === void 0 ? void 0 : _a.type) === 'ref') && typeof data[attr] === 'string') {
363
+ data2[attr] = data[attr];
364
+ }
365
+ }
366
+ }
367
+ return data2;
368
+ }
369
+ return filter;
370
+ };
371
+ var addChild = function (node, path, child) {
372
+ var _a;
373
+ // 在这里要把可以被node deduce出来的child处理掉
374
+ var paths = path.split('$');
375
+ (0, assert_1.default)(paths.length >= 2);
376
+ if (_this.authDeduceRelationMap[child.entity] === paths[1]) {
377
+ (0, assert_1.default)(paths[1] === 'entity', '当前只支持entity外键上的deduce');
378
+ return false;
379
+ }
380
+ if (node.children[path]) {
381
+ if (node.children[path] instanceof Array) {
382
+ node.children[path].push(child);
383
+ }
384
+ else {
385
+ node.children[path] = [node.children[path], child];
386
+ }
387
+ }
388
+ else {
389
+ Object.assign(node.children, (_a = {},
390
+ _a[path] = child,
391
+ _a));
392
+ }
393
+ return true;
394
+ };
395
+ var destructInner = function (entity, operation,
396
+ // extraFilter?: ED[T2]['Selection']['filter'],
397
+ path, child, hasParent) {
398
+ var action = operation.action, data = operation.data, filter = operation.filter;
399
+ var filter2 = action === 'create' ? makeCreateFilter(entity, operation) : filter;
400
+ (0, assert_1.default)(filter2);
401
+ // const filter3 = extraFilter ? combineFilters(entity, schema, [filter2, extraFilter]) : filter2;
402
+ var me = {
403
+ entity: entity,
404
+ filter: filter2,
405
+ children: {},
406
+ action: action,
407
+ };
408
+ var root = me;
409
+ // 如果当前对象是一个toModi的,意味着它的cascadeUpdate会全部被变为modi去缓存,因此不需要再向下检查了
410
+ // modi被apply时,这些modi产生的更新才会被实际检查
411
+ var isModiUpdate = _this.schema[entity].toModi && action !== 'remove';
412
+ if (child) {
413
+ (0, assert_1.default)(path);
414
+ addChild(me, path, child);
415
+ }
416
+ var _loop_1 = function (attr) {
417
+ var rel = (0, relation_1.judgeRelation)(_this.schema, entity, attr);
418
+ if (rel === 2 && !isModiUpdate) {
419
+ (0, assert_1.default)(root === me && !hasParent, 'cascadeUpdate必须是树结构,避免森林');
420
+ root = destructInner(attr, data[attr], "".concat(entity, "$entity"), me);
421
+ }
422
+ else if (typeof rel === 'string' && !isModiUpdate) {
423
+ (0, assert_1.default)(root === me && !hasParent, 'cascadeUpdate必须是树结构,避免森林');
424
+ root = destructInner(rel, data[attr], "".concat(entity, "$").concat(attr), me);
425
+ }
426
+ else if (rel instanceof Array && !isModiUpdate) {
427
+ var _a = tslib_1.__read(rel, 2), e_2 = _a[0], f = _a[1];
428
+ var otmOperations = data[attr];
429
+ if (e_2 === 'userRelation' && entity !== 'user') {
430
+ me.userRelations = [];
431
+ var dealWithUserRelation_1 = function (userRelation) {
432
+ var _a;
433
+ var action = userRelation.action, data = userRelation.data;
434
+ (0, assert_1.default)(action === 'create', 'cascade更新中只允许创建userRelation');
435
+ var attrs = Object.keys(data);
436
+ (0, assert_1.default)((0, lodash_1.difference)(attrs, Object.keys(_this.schema.userRelation.attributes).concat('id')).length === 0);
437
+ if (data.userId === userId) {
438
+ (_a = me.userRelations) === null || _a === void 0 ? void 0 : _a.push(data);
439
+ }
440
+ };
441
+ if (otmOperations instanceof Array) {
442
+ otmOperations.forEach(function (otmOperation) { return dealWithUserRelation_1(otmOperation); });
443
+ }
444
+ else {
445
+ dealWithUserRelation_1(otmOperations);
446
+ }
447
+ }
448
+ else {
449
+ if (otmOperations instanceof Array) {
450
+ otmOperations.forEach(function (otmOperation) {
451
+ var son = destructInner(e_2, otmOperation, undefined, undefined, true);
452
+ addChild(me, attr, son);
453
+ });
454
+ }
455
+ else {
456
+ var son = destructInner(e_2, otmOperations, undefined, undefined, true);
457
+ addChild(me, attr, son);
458
+ }
459
+ }
460
+ }
461
+ };
462
+ for (var attr in data) {
463
+ _loop_1(attr);
464
+ }
465
+ return root;
466
+ };
467
+ return destructInner(entity2, (0, lodash_1.cloneDeep)(operation2));
468
+ };
469
+ /**
470
+ * 对所有满足操作要求的actionAuth加以判断,找到可以满足当前用户身份的actionAuth
471
+ * @param entity
472
+ * @param filter
473
+ * @param actionAuths
474
+ * @param context
475
+ * @return
476
+ */
477
+ RelationAuth.prototype.filterActionAuths = function (entity, filter, actionAuths, context) {
478
+ var result = actionAuths.map(function (ele) {
479
+ var paths = ele.paths, relation = ele.relation, relationId = ele.relationId;
480
+ // 在cache中,可能出现relation外键指向的对象为null的情况,要容错
481
+ if (relationId) {
482
+ if (relation) {
483
+ var userRelations = relation.userRelation$relation;
484
+ if (userRelations.length > 0) {
485
+ var entityIds = (0, lodash_1.uniq)(userRelations.map(function (ele) { return ele.entityId; }));
486
+ var idFilter_1 = entityIds.length > 1 ? {
487
+ $in: entityIds,
488
+ } : entityIds[0];
489
+ (0, assert_1.default)(idFilter_1);
490
+ var pathFilters_1 = paths.map(function (path) {
491
+ if (path) {
492
+ return (0, lodash_1.set)({}, path, {
493
+ id: idFilter_1,
494
+ });
495
+ }
496
+ return {
497
+ id: idFilter_1,
498
+ };
499
+ });
500
+ // 这里是或关系,只要对象落在任意一条路径上就可以
501
+ var contained_1 = (0, filter_1.combineFilters)(entity, context.getSchema(), pathFilters_1, true);
502
+ var contains_1 = (0, filter_1.checkFilterContains)(entity, context, contained_1, filter, true);
503
+ if (contains_1 instanceof Promise) {
504
+ return contains_1.then(function (c) {
505
+ if (c) {
506
+ return ele;
507
+ }
508
+ return;
509
+ });
510
+ }
511
+ if (contains_1) {
512
+ return ele;
513
+ }
514
+ return;
515
+ }
516
+ }
517
+ return;
518
+ }
519
+ // 说明是通过userId关联
520
+ var pathFilters = paths.map(function (path) { return (0, lodash_1.set)({}, "".concat(path, ".id"), context.getCurrentUserId()); });
521
+ var contained = (0, filter_1.combineFilters)(entity, context.getSchema(), pathFilters, true);
522
+ var contains = (0, filter_1.checkFilterContains)(entity, context, contained, filter, true);
523
+ if (contains instanceof Promise) {
524
+ return contains.then(function (c) {
525
+ if (c) {
526
+ return ele;
527
+ }
528
+ return;
529
+ });
530
+ }
531
+ if (contains) {
532
+ return ele;
533
+ }
534
+ });
535
+ if (result.find(function (ele) { return ele instanceof Promise; })) {
536
+ return Promise.all(result).then(function (r2) { return r2.filter(function (ele) { return !!ele; }); });
537
+ }
538
+ return result.filter(function (ele) { return !!ele; });
539
+ };
540
+ /**
541
+ * 对于有些特殊的查询(带很多$or的查询,多发生在系统级别),单个actionAuth无法满足,需要共同加以判定
542
+ * @param entity
543
+ * @param filter
544
+ * @param actionAuths
545
+ * @param context
546
+ * @param actions
547
+ */
548
+ RelationAuth.prototype.checkActionAuthInGroup = function (entity, filter, actionAuths, context) {
549
+ var filters = actionAuths.filter(function (ele) { return ele.destEntity === entity; }).map(function (ele) {
550
+ var paths = ele.paths, relation = ele.relation, relationId = ele.relationId;
551
+ if (relationId) {
552
+ (0, assert_1.default)(relation);
553
+ var userRelations = relation.userRelation$relation;
554
+ (0, assert_1.default)(userRelations.length > 0);
555
+ var entityIds = (0, lodash_1.uniq)(userRelations.map(function (ele) { return ele.entityId; }));
556
+ var idFilter_2 = entityIds.length > 1 ? {
557
+ $in: entityIds,
558
+ } : entityIds[0];
559
+ (0, assert_1.default)(idFilter_2);
560
+ var pathFilters = paths.map(function (path) {
561
+ if (path) {
562
+ return (0, lodash_1.set)({}, path, {
563
+ id: idFilter_2,
564
+ });
565
+ }
566
+ return {
567
+ id: idFilter_2
568
+ };
569
+ });
570
+ return pathFilters;
571
+ }
572
+ // 说明是通过userId关联
573
+ return paths.map(function (path) { return (0, lodash_1.set)({}, "".concat(path, ".id"), context.getCurrentUserId()); });
574
+ });
575
+ var groupFilter = (0, filter_1.combineFilters)(entity, this.schema, filters.flat(), true);
576
+ if (groupFilter) {
577
+ return (0, filter_1.checkFilterContains)(entity, context, groupFilter, filter, true);
578
+ }
579
+ return false;
580
+ };
581
+ RelationAuth.prototype.checkSelection = function (entity, selection, context) {
582
+ var _this = this;
583
+ var leafSelections = this.destructSelection(entity, selection);
584
+ var deducedLeafSelections = leafSelections.map(function (_a) {
585
+ var entity = _a.entity, filter = _a.filter;
586
+ return _this.getDeducedEntityFilters(entity, filter, ['select'], context);
587
+ });
588
+ var checkDeducedLeafSelections = function (dlSelections2) {
589
+ var dlSelections = dlSelections2.filter(function (ele) {
590
+ var entities = ele.map(function (ele2) { return ele2.entity; });
591
+ // 同一个leaf的deducedSelections中只要有一个能通过就足够了
592
+ if ((0, lodash_1.intersection)(_this.selectFreeEntities, entities).length > 0) {
593
+ return false;
594
+ }
595
+ if ((0, lodash_1.intersection)(RelationAuth.SPECIAL_ENTITIES, entities).length > 0) {
596
+ // todo
597
+ return false;
598
+ }
599
+ return true;
600
+ });
601
+ if (dlSelections.length === 0) {
602
+ return true;
603
+ }
604
+ if (!context.getCurrentUserId()) {
605
+ throw new types_1.OakUnloggedInException();
606
+ }
607
+ var allEntities = [];
608
+ dlSelections.forEach(function (ele) { return ele.forEach(function (_a) {
609
+ var entity = _a.entity;
610
+ allEntities.push(entity);
611
+ }); });
612
+ var actionAuths = context.select('actionAuth', {
613
+ data: {
614
+ id: 1,
615
+ paths: 1,
616
+ destEntity: 1,
617
+ deActions: 1,
618
+ relation: {
619
+ id: 1,
620
+ userRelation$relation: {
621
+ $entity: 'userRelation',
622
+ data: {
623
+ id: 1,
624
+ entity: 1,
625
+ entityId: 1,
626
+ },
627
+ filter: {
628
+ userId: context.getCurrentUserId(),
629
+ },
630
+ },
631
+ },
632
+ },
633
+ filter: {
634
+ deActions: {
635
+ $contains: 'select',
636
+ },
637
+ destEntity: {
638
+ $in: allEntities,
639
+ },
640
+ $or: [
641
+ {
642
+ relation: {
643
+ userRelation$relation: {
644
+ userId: context.getCurrentUserId(),
645
+ },
646
+ }
647
+ },
648
+ {
649
+ relationId: {
650
+ $exists: false,
651
+ },
652
+ }
653
+ ]
654
+ }
655
+ }, { dontCollect: true, ignoreForeignKeyMiss: true });
656
+ /**
657
+ * 返回的结果中,第一层为leafNode,必须全通过,第二层为单个leafNode上的deduce,通过一个就可以
658
+ * @param result
659
+ * @returns
660
+ */
661
+ var checkResult = function (result) {
662
+ var e_3, _a;
663
+ var idx = 0;
664
+ try {
665
+ for (var result_1 = tslib_1.__values(result), result_1_1 = result_1.next(); !result_1_1.done; result_1_1 = result_1.next()) {
666
+ var r1 = result_1_1.value;
667
+ var r2 = r1.find(function (ele) { return ele === true; });
668
+ if (!r2) {
669
+ if (process.env.NODE_ENV === 'development') {
670
+ console.warn('对象的select权限被否决,请检查', dlSelections[idx]);
671
+ }
672
+ return false;
673
+ }
674
+ }
675
+ }
676
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
677
+ finally {
678
+ try {
679
+ if (result_1_1 && !result_1_1.done && (_a = result_1.return)) _a.call(result_1);
680
+ }
681
+ finally { if (e_3) throw e_3.error; }
682
+ }
683
+ return true;
684
+ };
685
+ if (actionAuths instanceof Promise) {
686
+ (0, assert_1.default)(context instanceof AsyncRowStore_1.AsyncContext);
687
+ return actionAuths.then(function (aas) { return Promise.all(dlSelections.map(function (ele) { return Promise.all(ele.map(function (ele2) { return _this.checkActionAuthInGroup(ele2.entity, ele2.filter, aas, context); })); })).then(function (result) { return checkResult(result); }); });
688
+ }
689
+ return checkResult(dlSelections.map(function (ele) { return ele.map(function (ele2) { return _this.checkActionAuthInGroup(ele2.entity, ele2.filter, actionAuths, context); }); }));
690
+ };
691
+ if (deducedLeafSelections[0] instanceof Promise) {
692
+ return Promise.all(deducedLeafSelections)
693
+ .then(function (dls) { return checkDeducedLeafSelections(dls); });
694
+ }
695
+ return checkDeducedLeafSelections(deducedLeafSelections);
696
+ };
697
+ /**
698
+ * 此函数判定一个结点是否能通过权限检测,同时寻找该结点本身对象上成立的actionAuth,用于本结点子孙结点的快速检测
699
+ * 如果结点因其deduce的对象通过了检测,其被推断对象的actionAuth无法用于更低对象的权限检测
700
+ * @param node
701
+ * @param context
702
+ * @returns
703
+ */
704
+ RelationAuth.prototype.findActionAuthsOnNode = function (node, context) {
705
+ var _this = this;
706
+ var entity = node.entity, filter = node.filter, action = node.action, userRelations = node.userRelations;
707
+ var deducedEntityFilters2 = this.getDeducedEntityFilters(entity, filter, [action], context);
708
+ /**
709
+ * 搜索判定是否允许自建对象,自建的条件是 path = '',destEntity === entity
710
+ * @param actionAuths
711
+ * @returns
712
+ */
713
+ var findOwnCreateUserRelation = function (actionAuths) {
714
+ if (userRelations && userRelations.length > 0) {
715
+ (0, assert_1.default)(action === 'create');
716
+ var ars = actionAuths.filter(function (ar) { return !!userRelations.find(function (ur) { return ur.relationId === ar.relationId; }) && ar.paths.includes('') && ar.destEntity === entity; });
717
+ if (ars.length > 0) {
718
+ return ars;
719
+ }
720
+ }
721
+ };
722
+ var actionAuthOnEntities = [];
723
+ var dealWithDeducedEntityFilters = function (deducedEntityFilters) {
724
+ var specialEntities = deducedEntityFilters.filter(function (ele) { return RelationAuth.SPECIAL_ENTITIES.includes(ele.entity); });
725
+ var unspecicalEntities = deducedEntityFilters.filter(function (ele) { return !RelationAuth.SPECIAL_ENTITIES.includes(ele.entity); });
726
+ var result = [];
727
+ if (specialEntities.length > 0) {
728
+ // 对于deduce出来的special对象,直接判定create应该问题不大,否则写起来太烦琐(具体情况遇到了再调试)
729
+ result.push.apply(result, tslib_1.__spreadArray([], tslib_1.__read(specialEntities.map(function (ele) { return _this.checkOperateSpecialEntities2(ele.entity, ele.entity === entity ? node.action : 'create', ele.filter, context); })), false));
730
+ }
731
+ if (unspecicalEntities.length > 0) {
732
+ var allEntities = unspecicalEntities.map(function (ele) { return ele.entity; });
733
+ var allActions = (0, lodash_1.uniq)(unspecicalEntities.map(function (ele) { return ele.actions; }).flat());
734
+ var actionAuths2 = context.select('actionAuth', {
735
+ data: {
736
+ id: 1,
737
+ paths: 1,
738
+ destEntity: 1,
739
+ deActions: 1,
740
+ relation: {
741
+ id: 1,
742
+ userRelation$relation: {
743
+ $entity: 'userRelation',
744
+ data: {
745
+ id: 1,
746
+ entity: 1,
747
+ entityId: 1,
748
+ },
749
+ filter: {
750
+ userId: context.getCurrentUserId(),
751
+ },
752
+ },
753
+ },
754
+ },
755
+ filter: {
756
+ destEntity: {
757
+ $in: allEntities,
758
+ },
759
+ deActions: {
760
+ $overlaps: allActions,
761
+ },
762
+ }
763
+ }, { dontCollect: true, ignoreForeignKeyMiss: true });
764
+ var checkActionAuths_1 = function (actionAuths) {
765
+ var created = findOwnCreateUserRelation(actionAuths);
766
+ if (created) {
767
+ actionAuthOnEntities.push.apply(actionAuthOnEntities, tslib_1.__spreadArray([], tslib_1.__read(created), false));
768
+ return true;
769
+ }
770
+ var result = deducedEntityFilters.map(function (ele) {
771
+ var ars2 = actionAuths.filter(function (ele2) { return ele2.destEntity === ele.entity && (0, lodash_1.intersection)(ele2.deActions, ele.actions).length > 0; } // 这里只要overlap就可以了
772
+ );
773
+ var ars3 = _this.filterActionAuths(ele.entity, ele.filter, ars2, context);
774
+ var checkFilteredArs = function (actionAuths2) {
775
+ if (actionAuths2.length > 0) {
776
+ if (ele.entity === entity) {
777
+ actionAuthOnEntities.push.apply(actionAuthOnEntities, tslib_1.__spreadArray([], tslib_1.__read(actionAuths2), false));
778
+ }
779
+ return true;
780
+ }
781
+ return false;
782
+ };
783
+ if (ars3 instanceof Promise) {
784
+ return ars3.then(function (ars4) { return checkFilteredArs(ars4); });
785
+ }
786
+ return checkFilteredArs(ars3);
787
+ });
788
+ if (result.find(function (ele) { return ele instanceof Promise; })) {
789
+ return Promise.all(result).then(function (r2) { return r2.includes(true); });
790
+ }
791
+ return result.includes(true);
792
+ };
793
+ if (actionAuths2 instanceof Promise) {
794
+ result.push(actionAuths2.then(function (ars2) { return checkActionAuths_1(ars2); }));
795
+ }
796
+ else {
797
+ result.push(checkActionAuths_1(actionAuths2));
798
+ }
799
+ }
800
+ if (result.find(function (ele) { return ele instanceof Promise; })) {
801
+ return Promise.all(result).then(function (r2) {
802
+ // r2中只有一个通过就能通过
803
+ if (r2.includes(true)) {
804
+ return actionAuthOnEntities;
805
+ }
806
+ return false;
807
+ });
808
+ }
809
+ if (result.includes(true)) {
810
+ return actionAuthOnEntities;
811
+ }
812
+ return false;
813
+ };
814
+ if (deducedEntityFilters2 instanceof Promise) {
815
+ return deducedEntityFilters2.then(function (def2) { return dealWithDeducedEntityFilters(def2); });
816
+ }
817
+ return dealWithDeducedEntityFilters(deducedEntityFilters2);
818
+ };
819
+ RelationAuth.prototype.checkOperationTree2 = function (tree, context) {
820
+ var _this = this;
821
+ var checkNode = function (node, actionAuths) {
822
+ var checkChildren = function (legalPaths) {
823
+ var children = node.children;
824
+ var childPath = Object.keys(children);
825
+ if (childPath.length === 0) {
826
+ return true;
827
+ }
828
+ var childResult = childPath.map(function (childPath) {
829
+ var child = children[childPath];
830
+ var childEntity = child instanceof Array ? child[0].entity : child.entity;
831
+ // 这里如果该子结点能deduce到父,则直接通过
832
+ if (_this.authDeduceRelationMap[childEntity]) {
833
+ (0, assert_1.default)(_this.authDeduceRelationMap[childEntity] === 'entity');
834
+ var rel = (0, relation_1.judgeRelation)(_this.schema, childEntity, childPath);
835
+ if (rel === 2) {
836
+ return true;
837
+ }
838
+ }
839
+ var pathToParent = childPath.endsWith('$entity') ? node.entity : childPath.split('$')[1];
840
+ if (child instanceof Array) {
841
+ var childActions_1 = child.map(function (ele) { return ele.action; });
842
+ var childLegalAuths_1 = legalPaths.map(function (ele) {
843
+ var paths = ele.paths, relationId = ele.relationId;
844
+ var paths2 = paths.map(function (path) { return path ? "".concat(pathToParent, ".").concat(path) : pathToParent; });
845
+ return context.select('actionAuth', {
846
+ data: {
847
+ id: 1,
848
+ },
849
+ filter: {
850
+ paths: {
851
+ $overlaps: paths2,
852
+ },
853
+ destEntity: childEntity,
854
+ deActions: {
855
+ $overlaps: childActions_1,
856
+ },
857
+ relationId: relationId || {
858
+ $exists: false,
859
+ },
860
+ }
861
+ }, { dontCollect: true });
862
+ }).flat();
863
+ if (childLegalAuths_1[0] instanceof Promise) {
864
+ return Promise.all(childLegalAuths_1).then(function (clas) { return child.map(function (c) { return checkNode(c, clas); }); });
865
+ }
866
+ return child.map(function (c) { return checkNode(c, childLegalAuths_1); });
867
+ }
868
+ var childLegalAuths = legalPaths.map(function (ele) {
869
+ var paths = ele.paths, relationId = ele.relationId;
870
+ var paths2 = paths.map(function (path) { return path ? "".concat(pathToParent, ".").concat(path) : pathToParent; });
871
+ return context.select('actionAuth', {
872
+ data: {
873
+ id: 1,
874
+ },
875
+ filter: {
876
+ paths: {
877
+ $overlaps: paths2,
878
+ },
879
+ destEntity: childEntity,
880
+ deActions: {
881
+ $overlaps: child.action,
882
+ },
883
+ relationId: relationId || {
884
+ $exists: false,
885
+ },
886
+ }
887
+ }, { dontCollect: true });
888
+ }).flat();
889
+ if (childLegalAuths[0] instanceof Promise) {
890
+ return Promise.all(childLegalAuths).then(function (clas) { return checkNode(child, clas.flat()); });
891
+ }
892
+ return checkNode(child, childLegalAuths);
893
+ }).flat();
894
+ if (childResult[0] instanceof Promise) {
895
+ return Promise.all(childResult).then(function (r) { return !r.includes(false); });
896
+ }
897
+ return !childResult.includes(false);
898
+ };
899
+ // 先根据parent传下来的合法auths来搜寻,只需要查找actionAuth,降低开销
900
+ // 这里有可能父结点根据actionAuths能通过,但子结点需要重新搜索父结点上的新actionAuths才能通过吗?应该不存在这种情况。 by Xc 20230824
901
+ if (actionAuths && actionAuths.length > 0) {
902
+ return checkChildren(actionAuths);
903
+ }
904
+ // 没有能根据父亲传下来的actionAuth判定,只能自己找
905
+ var result = _this.findActionAuthsOnNode(node, context);
906
+ var checkResult = function (result2) {
907
+ if (result2 === false) {
908
+ return false;
909
+ }
910
+ // 如果是对user对象操作通过,需要增添一条虚假的的actionAuth
911
+ if (node.entity === 'user') {
912
+ result2.push({
913
+ id: 'temp',
914
+ paths: [''],
915
+ $$createAt$$: 1,
916
+ $$updateAt$$: 1,
917
+ $$seq$$: 'temp',
918
+ destEntity: 'user',
919
+ deActions: [node.action],
920
+ });
921
+ }
922
+ return checkChildren(result2);
923
+ };
924
+ if (result instanceof Promise) {
925
+ return result.then(function (r2) { return checkResult(r2); });
926
+ }
927
+ return checkResult(result);
928
+ };
929
+ return checkNode(tree);
930
+ };
931
+ /* private checkOperationTree<Cxt extends AsyncContext<ED> | SyncContext<ED>>(tree: OperationTree<ED>, context: Cxt) {
932
+ const actionAuths2 = this.findActionAuthsOnNode(tree, context);
933
+
934
+ const checkChildNode = (actionAuths: ED['actionAuth']['Schema'][] | Promise<ED['actionAuth']['Schema'][]>, node: OperationTree<ED>): boolean | Promise<boolean> => {
935
+ const checkChildNodeInner = (legalAuths: ED['actionAuth']['Schema'][]) => {
936
+ // 因为如果children是数组的话,会把数组中所有的action并起来查询,所以在这里还要再确认一次
937
+
938
+ const realLegalPaths = legalAuths.filter(
939
+ (ele) => {
940
+ if (ele.destEntity === node.entity && ele.deActions.includes(node.action)) {
941
+ return true;
942
+ }
943
+ // 有一种例外情况,是在tree的根结点findActionAuthsOnNode时,deduce出了另外一个对象的权限,此时肯定可以通过,但不能再使用这条路径对children进行进一步判断了
944
+ if (node === tree) {
945
+ return true;
946
+ }
947
+ return false;
948
+ }
949
+ );
950
+ const checkChildren = () => {
951
+ const { children } = node;
952
+ const childPath = Object.keys(children);
953
+ if (childPath.length === 0) {
954
+ return true;
955
+ }
956
+
957
+ const selfLegalPaths = realLegalPaths.filter(
958
+ (ele) => {
959
+ if (ele.destEntity === node.entity && ele.deActions.includes(node.action)) {
960
+ return true;
961
+ }
962
+ return false;
963
+ }
964
+ );
965
+ // assert(selfLegalPaths.length > 0, `对象${node.entity as string}的权限检查是用deduce的对象通过的,无法再进一步对子对象加以判断`);
966
+ const childResult = childPath.map(
967
+ (childPath) => {
968
+ const child = children[childPath];
969
+ const childEntity = child instanceof Array ? child[0].entity : child.entity;
970
+ // 这里如果该子结点能deduce到父,则直接通过
971
+ if (this.authDeduceRelationMap[childEntity]) {
972
+ assert(this.authDeduceRelationMap[childEntity] === 'entity');
973
+ const rel = judgeRelation(this.schema, childEntity, childPath);
974
+ if (rel === 2) {
975
+ return true;
976
+ }
977
+ }
978
+
979
+ const pathToParent = childPath.endsWith('$entity') ? node.entity as string : childPath.split('$')[1];
980
+ if (child instanceof Array) {
981
+ const childActions = child.map(ele => ele.action);
982
+ const childLegalAuths = selfLegalPaths.map(
983
+ (ele) => {
984
+ const { paths, relationId } = ele;
985
+ const paths2 = paths.map(
986
+ (path) => path ? `${pathToParent}.${path}` : pathToParent
987
+ );
988
+ return context.select('actionAuth', {
989
+ data: {
990
+ id: 1,
991
+ },
992
+ filter: {
993
+ paths: {
994
+ $overlaps: paths2,
995
+ },
996
+ destEntity: childEntity as string,
997
+ deActions: {
998
+ $overlaps: childActions,
999
+ },
1000
+ relationId: relationId || {
1001
+ $exists: false,
1002
+ },
1003
+ }
1004
+ }, { dontCollect: true })
1005
+ }
1006
+ ).flat() as ED['actionAuth']['Schema'][] | Promise<ED['actionAuth']['Schema']>[];
1007
+ if (childLegalAuths[0] instanceof Promise) {
1008
+ return Promise.all(childLegalAuths).then(
1009
+ (clas) => child.map(
1010
+ (c) => checkChildNode(clas, c)
1011
+ )
1012
+ )
1013
+ }
1014
+ return child.map(
1015
+ (c) => checkChildNode(childLegalAuths as ED['actionAuth']['Schema'][], c)
1016
+ );
1017
+ }
1018
+
1019
+ const childLegalAuths = realLegalPaths.map(
1020
+ (ele) => {
1021
+ const { paths, relationId } = ele;
1022
+ const paths2 = paths.map(
1023
+ (path) => path ? `${pathToParent}.${path}` : pathToParent
1024
+ );
1025
+ return context.select('actionAuth', {
1026
+ data: {
1027
+ id: 1,
1028
+ },
1029
+ filter: {
1030
+ paths: {
1031
+ $overlaps: paths2,
1032
+ },
1033
+ destEntity: childEntity as string,
1034
+ deActions: {
1035
+ $overlaps: child.action,
1036
+ },
1037
+ relationId: relationId || {
1038
+ $exists: false,
1039
+ },
1040
+ }
1041
+ }, { dontCollect: true })
1042
+ }
1043
+ ).flat() as ED['actionAuth']['Schema'][] | Promise<ED['actionAuth']['Schema']>[];
1044
+
1045
+ if (childLegalAuths[0] instanceof Promise) {
1046
+ return Promise.all(childLegalAuths).then(
1047
+ (clas) => checkChildNode(clas.flat(), child)
1048
+ );
1049
+ }
1050
+ return checkChildNode(childLegalAuths as ED['actionAuth']['Schema'][], child);
1051
+ }
1052
+ ).flat();
1053
+
1054
+ if (childResult[0] instanceof Promise) {
1055
+ return Promise.all(childResult).then(
1056
+ (r) => !r.includes(false)
1057
+ );
1058
+ }
1059
+ return !childResult.includes(false);
1060
+ };
1061
+
1062
+ if (RelationAuth.SPECIAL_ENTITIES.includes(node.entity as string)) {
1063
+ // 特殊entity走特别的路径判断
1064
+ const result = this.checkOperateSpecialEntities2(node.entity, node.action, node.filter, context);
1065
+
1066
+ if (result instanceof Promise) {
1067
+ return result.then(
1068
+ (r) => {
1069
+ if (r) {
1070
+ return checkChildren();
1071
+ }
1072
+ return false;
1073
+ }
1074
+ );
1075
+ }
1076
+ if (result) {
1077
+ if (node.entity === 'user') {
1078
+ // 如果当前是对user对象操作,需要加上一个指向它自身的actionAuth,否则剩下的子对象会判定不过
1079
+ // user的操作权限由应用自己决定,如果user的操作最终过不去,这里放过也没关系
1080
+ assert(node === tree && realLegalPaths.length === 0); // user不可能是非根结点
1081
+ realLegalPaths.push({
1082
+ id: 'temp',
1083
+ paths: [''],
1084
+ $$createAt$$: 1,
1085
+ $$updateAt$$: 1,
1086
+ $$seq$$: 'temp',
1087
+ destEntity: 'user',
1088
+ deActions: [node.action],
1089
+ });
1090
+ }
1091
+ return checkChildren();
1092
+ }
1093
+ if (process.env.NODE_ENV === 'development') {
1094
+ console.warn('对象operate权限检查不通过', node);
1095
+ }
1096
+ return false;
1097
+ }
1098
+
1099
+ if (realLegalPaths.length === 0) {
1100
+ if (node === tree) {
1101
+ if (process.env.NODE_ENV === 'development') {
1102
+ console.warn('对象operate权限检查不通过', node);
1103
+ }
1104
+ return false;
1105
+ }
1106
+ // 如果不是tree的根结点,相对路径上的actionAuth找不到,还可以尝试从自身的filter去重试其它路径
1107
+ return this.checkOperationTree(node, context);
1108
+ }
1109
+
1110
+ return checkChildren();
1111
+ };
1112
+
1113
+ if (actionAuths instanceof Promise) {
1114
+ return actionAuths.then(
1115
+ (aars) => checkChildNodeInner(aars)
1116
+ );
1117
+ }
1118
+ return checkChildNodeInner(actionAuths);
1119
+ };
1120
+
1121
+ return checkChildNode(actionAuths2, tree);
1122
+ } */
1123
+ RelationAuth.prototype.checkOperation = function (entity, operation, context) {
1124
+ var action = operation.action, filter = operation.filter, data = operation.data;
1125
+ if (action === 'create' && this.createFreeEntities.includes(entity)) {
1126
+ return true;
1127
+ }
1128
+ else if (action === 'update' && this.updateFreeEntities.includes(entity)) {
1129
+ return true;
1130
+ }
1131
+ var userId = context.getCurrentUserId();
1132
+ if (!userId) {
1133
+ throw new types_1.OakUnloggedInException();
1134
+ }
1135
+ if (!filter && (!data || action !== 'create')) {
1136
+ if (process.env.NODE_ENV === 'development') {
1137
+ console.warn('operation不能没有限制条件', operation);
1138
+ }
1139
+ return false;
1140
+ }
1141
+ var updateTree = this.destructOperation(entity, operation, userId);
1142
+ return this.checkOperationTree2(updateTree, context);
1143
+ };
1144
+ /**
1145
+ * 检查一个operation是否能被通过权限测试
1146
+ * 一个cascadeOperation是一棵树形结构:
1147
+ * * 对于select,只要叶子通过其父结点必然通过;
1148
+ * * 对于update,自顶向下进行检查,若父亲被权限S通过,则只需要检查子对于S有没有相对路径上的actionAuth
1149
+ * 另外在update中,还需要考虑自建userRelation的case(例如在电子商务网站上购买商品,创建订单同时创建用户和订单的关系)
1150
+ * @param entity
1151
+ * @param operation
1152
+ * @param context
1153
+ * @param actions
1154
+ * @returns
1155
+ */
1156
+ RelationAuth.prototype.checkActions2 = function (entity, operation, context, actions) {
1157
+ var action = operation.action;
1158
+ if (!action || action_1.readOnlyActions.includes(action)) {
1159
+ var result = this.checkSelection(entity, operation, context);
1160
+ if (result instanceof Promise) {
1161
+ return result.then(function (r) {
1162
+ if (!r) {
1163
+ throw new types_1.OakUserUnpermittedException();
1164
+ }
1165
+ });
1166
+ }
1167
+ if (!result) {
1168
+ throw new types_1.OakUserUnpermittedException();
1169
+ }
1170
+ }
1171
+ else {
1172
+ var result = this.checkOperation(entity, operation, context);
1173
+ if (result instanceof Promise) {
1174
+ return result.then(function (r) {
1175
+ if (!r) {
1176
+ throw new types_1.OakUserUnpermittedException();
1177
+ }
1178
+ });
1179
+ }
1180
+ if (!result) {
1181
+ throw new types_1.OakUserUnpermittedException();
1182
+ }
1183
+ }
1184
+ };
1185
+ RelationAuth.SPECIAL_ENTITIES = env_1.SYSTEM_RESERVE_ENTITIES;
1186
+ return RelationAuth;
1187
+ }());
1188
+ exports.RelationAuth = RelationAuth;
1189
+ ;
1190
+ /**
1191
+ * 获取有对entity进行actions操作权限的userRelation关系
1192
+ * @param params
1193
+ * @param context
1194
+ * todo paths改成复数以后这里还未充分测试过
1195
+ */
1196
+ function getUserRelationsByActions(params, context) {
1197
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
1198
+ var entity, filter, actions, overlap, actionAuthfilter, actionAuths, getUserRelations, getDirectUserEntities, urAuths2, directAuths2, _a, userRelations, userEntities;
1199
+ var _this = this;
1200
+ return tslib_1.__generator(this, function (_b) {
1201
+ switch (_b.label) {
1202
+ case 0:
1203
+ entity = params.entity, filter = params.filter, actions = params.actions, overlap = params.overlap;
1204
+ actionAuthfilter = {
1205
+ destEntity: entity,
1206
+ };
1207
+ if (overlap) {
1208
+ Object.assign(actionAuthfilter, {
1209
+ deActions: {
1210
+ $overlaps: actions,
1211
+ },
1212
+ });
1213
+ }
1214
+ else {
1215
+ Object.assign(actionAuthfilter, {
1216
+ deActions: {
1217
+ $contains: actions,
1218
+ },
1219
+ });
1220
+ }
1221
+ return [4 /*yield*/, context.select('actionAuth', {
1222
+ data: {
1223
+ id: 1,
1224
+ paths: 1,
1225
+ relationId: 1,
1226
+ relation: {
1227
+ id: 1,
1228
+ entity: 1,
1229
+ },
1230
+ },
1231
+ filter: actionAuthfilter,
1232
+ }, { dontCollect: true })];
1233
+ case 1:
1234
+ actionAuths = _b.sent();
1235
+ getUserRelations = function (urAuths) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1236
+ var makeRelationIterator, urAuthDict2, userRelations;
1237
+ var _this = this;
1238
+ return tslib_1.__generator(this, function (_a) {
1239
+ switch (_a.label) {
1240
+ case 0:
1241
+ makeRelationIterator = function (path, relationIds) {
1242
+ var paths = path.split('.');
1243
+ var makeIter = function (e, idx) {
1244
+ var _a, _b, _c;
1245
+ if (idx === paths.length) {
1246
+ return {
1247
+ projection: {
1248
+ id: 1,
1249
+ userRelation$entity: {
1250
+ $entity: 'userRelation',
1251
+ data: {
1252
+ id: 1,
1253
+ relationId: 1,
1254
+ relation: {
1255
+ id: 1,
1256
+ name: 1,
1257
+ },
1258
+ entity: 1,
1259
+ entityId: 1,
1260
+ userId: 1,
1261
+ },
1262
+ filter: {
1263
+ relationId: {
1264
+ $in: relationIds,
1265
+ },
1266
+ },
1267
+ }
1268
+ },
1269
+ getData: function (d) {
1270
+ return d.userRelation$entity;
1271
+ },
1272
+ };
1273
+ }
1274
+ var attr = paths[idx];
1275
+ var rel = (0, relation_1.judgeRelation)(context.getSchema(), e, attr);
1276
+ if (rel === 2) {
1277
+ var _d = makeIter(attr, idx + 1), projection = _d.projection, getData_1 = _d.getData;
1278
+ return {
1279
+ projection: (_a = {
1280
+ id: 1
1281
+ },
1282
+ _a[attr] = projection,
1283
+ _a),
1284
+ getData: function (d) { return d[attr] && getData_1(d[attr]); },
1285
+ };
1286
+ }
1287
+ else if (typeof rel === 'string') {
1288
+ var _e = makeIter(rel, idx + 1), projection = _e.projection, getData_2 = _e.getData;
1289
+ return {
1290
+ projection: (_b = {
1291
+ id: 1
1292
+ },
1293
+ _b[attr] = projection,
1294
+ _b),
1295
+ getData: function (d) { return d[attr] && getData_2(d[attr]); },
1296
+ };
1297
+ }
1298
+ else {
1299
+ (0, assert_1.default)(rel instanceof Array);
1300
+ var _f = tslib_1.__read(rel, 2), e2 = _f[0], fk = _f[1];
1301
+ var _g = makeIter(e2, idx + 1), projection = _g.projection, getData_3 = _g.getData;
1302
+ return {
1303
+ projection: (_c = {
1304
+ id: 1
1305
+ },
1306
+ _c[attr] = {
1307
+ $entity: e2,
1308
+ data: projection,
1309
+ },
1310
+ _c),
1311
+ getData: function (d) { return d[attr] && d[attr].map(function (ele) { return getData_3(ele); }); },
1312
+ };
1313
+ }
1314
+ };
1315
+ return makeIter(entity, 0);
1316
+ };
1317
+ urAuthDict2 = {};
1318
+ urAuths.forEach(function (auth) {
1319
+ var paths = auth.paths, relationId = auth.relationId;
1320
+ paths.forEach(function (path) {
1321
+ if (!urAuthDict2[path]) {
1322
+ urAuthDict2[path] = [relationId];
1323
+ }
1324
+ else if (!urAuthDict2[path].includes(relationId)) {
1325
+ urAuthDict2[path].push(relationId);
1326
+ }
1327
+ });
1328
+ });
1329
+ return [4 /*yield*/, Promise.all(Object.keys(urAuthDict2).map(function (path) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1330
+ var relationIds, _a, projection, getData, rows, urs;
1331
+ return tslib_1.__generator(this, function (_b) {
1332
+ switch (_b.label) {
1333
+ case 0:
1334
+ relationIds = urAuthDict2[path];
1335
+ _a = makeRelationIterator(path, relationIds), projection = _a.projection, getData = _a.getData;
1336
+ return [4 /*yield*/, context.select(entity, {
1337
+ data: projection,
1338
+ filter: filter,
1339
+ }, { dontCollect: true })];
1340
+ case 1:
1341
+ rows = _b.sent();
1342
+ urs = rows.map(function (ele) { return getData(ele); }).flat().filter(function (ele) { return !!ele; });
1343
+ return [2 /*return*/, urs];
1344
+ }
1345
+ });
1346
+ }); }))];
1347
+ case 1:
1348
+ userRelations = _a.sent();
1349
+ return [2 /*return*/, userRelations.flat()];
1350
+ }
1351
+ });
1352
+ }); };
1353
+ getDirectUserEntities = function (directAuths) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1354
+ var makeRelationIterator, userEntities;
1355
+ var _this = this;
1356
+ return tslib_1.__generator(this, function (_a) {
1357
+ switch (_a.label) {
1358
+ case 0:
1359
+ makeRelationIterator = function (path) {
1360
+ var paths = path.split('.');
1361
+ var makeIter = function (e, idx) {
1362
+ var _a, _b, _c, _d;
1363
+ var attr = paths[idx];
1364
+ var rel = (0, relation_1.judgeRelation)(context.getSchema(), e, attr);
1365
+ if (idx === paths.length - 1) {
1366
+ if (rel === 2) {
1367
+ (0, assert_1.default)(attr === 'user');
1368
+ return {
1369
+ projection: {
1370
+ id: 1,
1371
+ entity: 1,
1372
+ entityId: 1,
1373
+ },
1374
+ getData: function (d) {
1375
+ if (d) {
1376
+ return {
1377
+ entity: e,
1378
+ entityId: d.id,
1379
+ userId: d.entityId,
1380
+ };
1381
+ }
1382
+ },
1383
+ };
1384
+ }
1385
+ else {
1386
+ (0, assert_1.default)(rel === 'user');
1387
+ return {
1388
+ projection: (_a = {
1389
+ id: 1
1390
+ },
1391
+ _a["".concat(attr, "Id")] = 1,
1392
+ _a),
1393
+ getData: function (d) {
1394
+ if (d) {
1395
+ return {
1396
+ entity: e,
1397
+ entityId: d.id,
1398
+ userId: d["".concat(attr, "Id")]
1399
+ };
1400
+ }
1401
+ },
1402
+ };
1403
+ }
1404
+ }
1405
+ if (rel === 2) {
1406
+ var _e = makeIter(attr, idx + 1), projection = _e.projection, getData_4 = _e.getData;
1407
+ return {
1408
+ projection: (_b = {
1409
+ id: 1
1410
+ },
1411
+ _b[attr] = projection,
1412
+ _b),
1413
+ getData: function (d) { return d[attr] && getData_4(d[attr]); },
1414
+ };
1415
+ }
1416
+ else if (typeof rel === 'string') {
1417
+ var _f = makeIter(rel, idx + 1), projection = _f.projection, getData_5 = _f.getData;
1418
+ return {
1419
+ projection: (_c = {
1420
+ id: 1
1421
+ },
1422
+ _c[attr] = projection,
1423
+ _c),
1424
+ getData: function (d) { return d[attr] && getData_5(d[attr]); },
1425
+ };
1426
+ }
1427
+ else {
1428
+ (0, assert_1.default)(rel instanceof Array);
1429
+ var _g = tslib_1.__read(rel, 2), e2 = _g[0], fk = _g[1];
1430
+ var _h = makeIter(e2, idx + 1), projection = _h.projection, getData_6 = _h.getData;
1431
+ return {
1432
+ projection: (_d = {
1433
+ id: 1
1434
+ },
1435
+ _d[attr] = {
1436
+ $entity: e2,
1437
+ data: projection,
1438
+ },
1439
+ _d),
1440
+ getData: function (d) { return d[attr] && d[attr].map(function (ele) { return getData_6(ele); }); },
1441
+ };
1442
+ }
1443
+ };
1444
+ return makeIter(entity, 0);
1445
+ };
1446
+ return [4 /*yield*/, Promise.all(directAuths.map(function (_a) {
1447
+ var paths = _a.paths;
1448
+ return tslib_1.__awaiter(_this, void 0, void 0, function () {
1449
+ var _this = this;
1450
+ return tslib_1.__generator(this, function (_b) {
1451
+ return [2 /*return*/, paths.map(function (path) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
1452
+ var _a, getData, projection, rows, userEntities;
1453
+ return tslib_1.__generator(this, function (_b) {
1454
+ switch (_b.label) {
1455
+ case 0:
1456
+ _a = makeRelationIterator(path), getData = _a.getData, projection = _a.projection;
1457
+ return [4 /*yield*/, context.select(entity, {
1458
+ data: projection,
1459
+ filter: filter,
1460
+ }, { dontCollect: true })];
1461
+ case 1:
1462
+ rows = _b.sent();
1463
+ userEntities = rows.map(function (ele) { return getData(ele); }).flat().filter(function (ele) { return !!ele; });
1464
+ return [2 /*return*/, userEntities];
1465
+ }
1466
+ });
1467
+ }); })];
1468
+ });
1469
+ });
1470
+ }))];
1471
+ case 1:
1472
+ userEntities = _a.sent();
1473
+ return [2 /*return*/, userEntities.flat()];
1474
+ }
1475
+ });
1476
+ }); };
1477
+ urAuths2 = actionAuths.filter(function (ele) { return !!ele.relationId; } // 有relation说明通过userRelation关联
1478
+ );
1479
+ directAuths2 = actionAuths.filter(function (ele) { return !ele.relationId; } // 没relation说明通过user关联
1480
+ );
1481
+ return [4 /*yield*/, Promise.all([getUserRelations(urAuths2), getDirectUserEntities(directAuths2)])];
1482
+ case 2:
1483
+ _a = tslib_1.__read.apply(void 0, [_b.sent(), 2]), userRelations = _a[0], userEntities = _a[1];
1484
+ return [2 /*return*/, {
1485
+ userRelations: userRelations,
1486
+ userEntities: userEntities,
1487
+ }];
1488
+ }
1489
+ });
1490
+ });
1491
+ }
1492
+ exports.getUserRelationsByActions = getUserRelationsByActions;