@tachybase/plugin-sub-accounts 0.23.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +30 -0
- package/README.md +1 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.js +1 -0
- package/dist/externalVersion.js +9 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +39 -0
- package/dist/node_modules/minimatch/LICENSE +15 -0
- package/dist/node_modules/minimatch/lib/path.js +4 -0
- package/dist/node_modules/minimatch/minimatch.js +1 -0
- package/dist/node_modules/minimatch/package.json +1 -0
- package/dist/server/acl/RoleActionParamsMerge.d.ts +4 -0
- package/dist/server/acl/RoleActionParamsMerge.js +42 -0
- package/dist/server/acl/RoleSnippets.d.ts +9 -0
- package/dist/server/acl/RoleSnippets.js +127 -0
- package/dist/server/acl/RoleStrategy.d.ts +19 -0
- package/dist/server/acl/RoleStrategy.js +84 -0
- package/dist/server/addMergeRoles.d.ts +5 -0
- package/dist/server/addMergeRoles.js +46 -0
- package/dist/server/collections/roles.d.ts +2 -0
- package/dist/server/collections/roles.js +37 -0
- package/dist/server/collections/users.d.ts +2 -0
- package/dist/server/collections/users.js +37 -0
- package/dist/server/hooks/index.d.ts +5 -0
- package/dist/server/hooks/index.js +29 -0
- package/dist/server/hooks/merge-role-create.d.ts +6 -0
- package/dist/server/hooks/merge-role-create.js +34 -0
- package/dist/server/hooks/refresh-datasources.d.ts +8 -0
- package/dist/server/hooks/refresh-datasources.js +43 -0
- package/dist/server/hooks/source-role-destroy.d.ts +6 -0
- package/dist/server/hooks/source-role-destroy.js +46 -0
- package/dist/server/hooks/source-role-update.d.ts +6 -0
- package/dist/server/hooks/source-role-update.js +57 -0
- package/dist/server/hooks/user-change-roles.d.ts +9 -0
- package/dist/server/hooks/user-change-roles.js +55 -0
- package/dist/server/hooks/user-create.d.ts +2 -0
- package/dist/server/hooks/user-create.js +38 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +33 -0
- package/dist/server/middlewares/change-user-roles.d.ts +8 -0
- package/dist/server/middlewares/change-user-roles.js +66 -0
- package/dist/server/middlewares/set-self-role.d.ts +2 -0
- package/dist/server/middlewares/set-self-role.js +54 -0
- package/dist/server/model/MergeRoleModel.d.ts +49 -0
- package/dist/server/model/MergeRoleModel.js +205 -0
- package/dist/server/plugin.d.ts +11 -0
- package/dist/server/plugin.js +85 -0
- package/package.json +24 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var MergeRoleModel_exports = {};
|
|
19
|
+
__export(MergeRoleModel_exports, {
|
|
20
|
+
MergeRoleModel: () => MergeRoleModel
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(MergeRoleModel_exports);
|
|
23
|
+
var import_acl = require("@tachybase/acl");
|
|
24
|
+
var import_module_acl = require("@tachybase/module-acl");
|
|
25
|
+
var import_RoleActionParamsMerge = require("../acl/RoleActionParamsMerge");
|
|
26
|
+
var import_RoleSnippets = require("../acl/RoleSnippets");
|
|
27
|
+
var import_RoleStrategy = require("../acl/RoleStrategy");
|
|
28
|
+
class MergeRoleModel extends import_module_acl.RoleModel {
|
|
29
|
+
rootResource;
|
|
30
|
+
/**
|
|
31
|
+
* 获取源头角色
|
|
32
|
+
* @param transaction
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
async getSourceRoles(transaction) {
|
|
36
|
+
const user = await this.getOwnerUser({ transaction });
|
|
37
|
+
return await user.getRoles({ appends: ["menuUiSchemas"], transaction });
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 数据表操作权限更新
|
|
41
|
+
*/
|
|
42
|
+
async refreshDataSourcesAcl({ transaction, acl }) {
|
|
43
|
+
const strategyArray = [];
|
|
44
|
+
const resourcesMap = /* @__PURE__ */ new Map();
|
|
45
|
+
const transactionExist = !!transaction;
|
|
46
|
+
if (!transaction) {
|
|
47
|
+
transaction = await this.db.sequelize.transaction();
|
|
48
|
+
}
|
|
49
|
+
this.sourceRoles = await this.getSourceRoles(transaction);
|
|
50
|
+
if (this.sourceRoles.find((r) => r.name === "root")) {
|
|
51
|
+
if (!transactionExist) {
|
|
52
|
+
transaction.commit();
|
|
53
|
+
}
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
for (const sourceRole of this.sourceRoles) {
|
|
57
|
+
let sourceAclRole = acl.getRole(sourceRole.name);
|
|
58
|
+
if (!sourceAclRole) {
|
|
59
|
+
sourceAclRole = acl.define({
|
|
60
|
+
role: sourceRole.name,
|
|
61
|
+
strategy: {},
|
|
62
|
+
actions: {}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
strategyArray.push(sourceAclRole.strategy);
|
|
66
|
+
for (const [resourceName, value] of sourceAclRole.resources) {
|
|
67
|
+
let list = resourcesMap.get(resourceName);
|
|
68
|
+
if (!list) {
|
|
69
|
+
list = [];
|
|
70
|
+
resourcesMap.set(resourceName, list);
|
|
71
|
+
}
|
|
72
|
+
list.push(value.actions);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const aclRole = acl.getRole(this.name);
|
|
76
|
+
aclRole.setStrategy({ ...import_RoleStrategy.RoleStrategy.merge(strategyArray) });
|
|
77
|
+
const newResources = /* @__PURE__ */ new Map();
|
|
78
|
+
for (const [resourceName, actions] of resourcesMap) {
|
|
79
|
+
const actionMap = /* @__PURE__ */ new Map();
|
|
80
|
+
for (const action of actions) {
|
|
81
|
+
for (const [actionName, params] of action) {
|
|
82
|
+
let list = actionMap.get(actionName);
|
|
83
|
+
if (!list) {
|
|
84
|
+
list = [];
|
|
85
|
+
actionMap.set(actionName, list);
|
|
86
|
+
}
|
|
87
|
+
list.push(params);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const newActions = /* @__PURE__ */ new Map();
|
|
91
|
+
for (const [actionName, params] of actionMap) {
|
|
92
|
+
newActions.set(actionName, import_RoleActionParamsMerge.RoleActionParamsMerge.merge(params));
|
|
93
|
+
}
|
|
94
|
+
const newAclResource = new import_acl.ACLResource({ role: aclRole, name: resourceName });
|
|
95
|
+
newAclResource.actions = newActions;
|
|
96
|
+
newResources.set(resourceName, newAclResource);
|
|
97
|
+
}
|
|
98
|
+
aclRole.resources = newResources;
|
|
99
|
+
if (!transactionExist) {
|
|
100
|
+
transaction.commit();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 数据表操作权限更新
|
|
105
|
+
*/
|
|
106
|
+
refreshDataSourcesAclForResource(acl, resourceName, actionName) {
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* source变动后导致本身属性或者ui有关属性变动
|
|
110
|
+
*/
|
|
111
|
+
async resetAcl({
|
|
112
|
+
transaction,
|
|
113
|
+
acl,
|
|
114
|
+
changedFields
|
|
115
|
+
}) {
|
|
116
|
+
if (!this.ownerUserId) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const transactionExist = !!transaction;
|
|
120
|
+
if (!transaction) {
|
|
121
|
+
transaction = await this.db.sequelize.transaction();
|
|
122
|
+
}
|
|
123
|
+
this.sourceRoles = await this.getSourceRoles(transaction);
|
|
124
|
+
this.rootResource = this.sourceRoles.find((role) => role.name === "root");
|
|
125
|
+
this.resetRoleProperty(transaction);
|
|
126
|
+
if (!changedFields || changedFields.includes("snippets")) {
|
|
127
|
+
await this.mergeSnippets();
|
|
128
|
+
}
|
|
129
|
+
if (!changedFields || changedFields.includes("menuUiSchemas")) {
|
|
130
|
+
await this.mergeMenuUiSchemas(transaction);
|
|
131
|
+
}
|
|
132
|
+
await this.save({ transaction });
|
|
133
|
+
if (!transactionExist) {
|
|
134
|
+
await transaction.commit();
|
|
135
|
+
}
|
|
136
|
+
this.writeToAcl({ acl, withOutStrategy: true });
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* role本身属性变动
|
|
140
|
+
*/
|
|
141
|
+
resetRoleProperty(transaction) {
|
|
142
|
+
this.allowConfigure = this.sourceRoles.some((role) => role.allowConfigure);
|
|
143
|
+
this.allowNewMenu = this.sourceRoles.some((role) => role.allowNewMenu);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 融合策略, 整个系统中这个变量会被主数据库 data-source-manager的DataSourcesRolesModel.writeToAcl方法设置覆盖
|
|
147
|
+
* root为null
|
|
148
|
+
* data-source的actions体现在[权限页面][数据源][配置][通用操作权限] 但是整个role下的
|
|
149
|
+
* FIXME: strategy这个类型设置的很奇怪,目前只找到actions,依据AvailableStrategyOptions应该还有displayName,allowConfigure,resource
|
|
150
|
+
*/
|
|
151
|
+
mergeStrategy() {
|
|
152
|
+
throw new Error("Method not implemented.");
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 融合短语,体现在[权限页面][系统管理],主要影响[配置页面] [配置插件] [重启应用]
|
|
156
|
+
* 主要是 ui.* pm.* app.* 等短语
|
|
157
|
+
*/
|
|
158
|
+
mergeSnippets() {
|
|
159
|
+
if (this.rootResource) {
|
|
160
|
+
this.snippets = ["ui.*", "pm", "pm.*"];
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (this.sourceRoles.length === 0) {
|
|
164
|
+
this.snippets = ["!ui.*", "!pm", "!pm.*"];
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (this.sourceRoles.length === 1) {
|
|
168
|
+
this.snippets = this.sourceRoles[0].snippets;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const snippets = [];
|
|
172
|
+
for (const sourceRole of this.sourceRoles) {
|
|
173
|
+
snippets.push(new Set(sourceRole.snippets));
|
|
174
|
+
}
|
|
175
|
+
this.snippets = import_RoleSnippets.RoleSnippets.mergeSet(snippets);
|
|
176
|
+
}
|
|
177
|
+
async mergeMenuUiSchemas(transaction) {
|
|
178
|
+
if (this.rootResource) {
|
|
179
|
+
await this.setMenuUiSchemas([], { transaction });
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const menuUiSchemaNamesSet = [];
|
|
183
|
+
const menuUiSchemasList = [];
|
|
184
|
+
for (const sourceRole of this.sourceRoles) {
|
|
185
|
+
const menuUiSchemas = await sourceRole.getMenuUiSchemas();
|
|
186
|
+
for (const menuUiSchema of menuUiSchemas) {
|
|
187
|
+
const xUid = menuUiSchema.get("x-uid");
|
|
188
|
+
if (menuUiSchemaNamesSet.includes(xUid)) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
menuUiSchemaNamesSet.push(xUid);
|
|
192
|
+
menuUiSchemasList.push(menuUiSchema);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
await this.setMenuUiSchemas(menuUiSchemasList, { transaction });
|
|
196
|
+
}
|
|
197
|
+
// 由于数据库操作,还要分表,每个表还有不同的权限策略,此处不保存到数据库,而是在内存中进行操作
|
|
198
|
+
mergeDataSource(Transaction2) {
|
|
199
|
+
throw new Error("Method not implemented.");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
203
|
+
0 && (module.exports = {
|
|
204
|
+
MergeRoleModel
|
|
205
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Plugin } from '@tachybase/server';
|
|
2
|
+
export declare class PluginSubAccountsServer extends Plugin {
|
|
3
|
+
afterAdd(): Promise<void>;
|
|
4
|
+
beforeLoad(): Promise<void>;
|
|
5
|
+
load(): Promise<void>;
|
|
6
|
+
install(): Promise<void>;
|
|
7
|
+
afterEnable(): Promise<void>;
|
|
8
|
+
afterDisable(): Promise<void>;
|
|
9
|
+
remove(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export default PluginSubAccountsServer;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var plugin_exports = {};
|
|
19
|
+
__export(plugin_exports, {
|
|
20
|
+
PluginSubAccountsServer: () => PluginSubAccountsServer,
|
|
21
|
+
default: () => plugin_default
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(plugin_exports);
|
|
24
|
+
var import_server = require("@tachybase/server");
|
|
25
|
+
var import_addMergeRoles = require("./addMergeRoles");
|
|
26
|
+
var import_hooks = require("./hooks");
|
|
27
|
+
var import_user_create = require("./hooks/user-create");
|
|
28
|
+
var import_change_user_roles = require("./middlewares/change-user-roles");
|
|
29
|
+
var import_set_self_role = require("./middlewares/set-self-role");
|
|
30
|
+
var import_MergeRoleModel = require("./model/MergeRoleModel");
|
|
31
|
+
class PluginSubAccountsServer extends import_server.Plugin {
|
|
32
|
+
async afterAdd() {
|
|
33
|
+
}
|
|
34
|
+
async beforeLoad() {
|
|
35
|
+
this.app.db.registerModels({
|
|
36
|
+
RoleModel: import_MergeRoleModel.MergeRoleModel
|
|
37
|
+
});
|
|
38
|
+
this.app.on("dataSourceAfterStart", async () => {
|
|
39
|
+
await (0, import_addMergeRoles.addMergeRole)(this.app);
|
|
40
|
+
import_hooks.refreshDataSourcesAclAtAppStart.bind(this.app)();
|
|
41
|
+
});
|
|
42
|
+
this.app.db.on("roles.afterUpdate", import_hooks.sourceRoleUpdate.bind(this.app));
|
|
43
|
+
this.app.db.on("roles.afterDestroy", import_hooks.sourceRoleDestroy.bind(this.app));
|
|
44
|
+
this.app.db.on("roles.afterCreate", import_hooks.mergeRoleCreate.bind(this.app));
|
|
45
|
+
this.app.db.on("users.afterCreateWithAssociations", import_user_create.createMergeRole.bind(this.app));
|
|
46
|
+
this.app.db.on("users.afterUpdateWithAssociations", import_hooks.userChangeRoles.bind(this.app));
|
|
47
|
+
this.app.on("dataSource:writeToAcl", async ({ roleName, transaction }) => {
|
|
48
|
+
const affectedUsers = await this.app.db.getRepository("users").find({
|
|
49
|
+
filter: {
|
|
50
|
+
"roles.name": roleName
|
|
51
|
+
},
|
|
52
|
+
appends: ["selfRole"]
|
|
53
|
+
});
|
|
54
|
+
if (!affectedUsers.length) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const affectedRoles = affectedUsers.map((u) => u.selfRole);
|
|
58
|
+
const acl = this.app.acl;
|
|
59
|
+
for (const affectedRole of affectedRoles) {
|
|
60
|
+
await affectedRole.refreshDataSourcesAcl({ transaction, acl });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async load() {
|
|
65
|
+
const ignoreMerged = () => ({ filter: { ownerUserId: null } });
|
|
66
|
+
this.app.acl.addFixedParams("roles", "list", ignoreMerged);
|
|
67
|
+
this.app.acl.addFixedParams("roles", "update", ignoreMerged);
|
|
68
|
+
this.app.acl.addFixedParams("roles", "destroy", ignoreMerged);
|
|
69
|
+
this.app.resourcer.use(import_set_self_role.setSelfRole, { tag: "setSelfRole", before: "setCurrentRole", after: "setDepartmentsInfo" });
|
|
70
|
+
this.app.resourcer.use(import_change_user_roles.changeUserRolesMiddleware, { tag: "changeUserRolesMiddleware" });
|
|
71
|
+
}
|
|
72
|
+
async install() {
|
|
73
|
+
}
|
|
74
|
+
async afterEnable() {
|
|
75
|
+
}
|
|
76
|
+
async afterDisable() {
|
|
77
|
+
}
|
|
78
|
+
async remove() {
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
var plugin_default = PluginSubAccountsServer;
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
PluginSubAccountsServer
|
|
85
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tachybase/plugin-sub-accounts",
|
|
3
|
+
"version": "0.23.8",
|
|
4
|
+
"description": "Generates synthetic roles, each user can create their own sub-accounts (unfinished)",
|
|
5
|
+
"main": "dist/server/index.js",
|
|
6
|
+
"devDependencies": {
|
|
7
|
+
"minimatch": "^5.1.6"
|
|
8
|
+
},
|
|
9
|
+
"peerDependencies": {
|
|
10
|
+
"@tachybase/actions": "0.23.8",
|
|
11
|
+
"@tachybase/client": "0.23.8",
|
|
12
|
+
"@tachybase/server": "0.23.8",
|
|
13
|
+
"@tachybase/test": "0.23.8",
|
|
14
|
+
"@tachybase/database": "0.23.8",
|
|
15
|
+
"@tachybase/acl": "0.23.8",
|
|
16
|
+
"@tachybase/utils": "0.23.8",
|
|
17
|
+
"@tachybase/module-acl": "0.23.8"
|
|
18
|
+
},
|
|
19
|
+
"description.zh-CN": "生成合成角色,每个用户可以生成自己的子账户(未完成)",
|
|
20
|
+
"displayName.zh-CN": "子账户和合成角色",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tachybase-build --no-dts @tachybase/plugin-sub-accounts"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/server.d.ts
ADDED
package/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/server/index.js');
|