@kne/fastify-account 1.0.0-alpha.17 → 1.0.0-alpha.18
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/README.md +1171 -335
- package/index.js +29 -3
- package/libs/controllers/account.js +12 -26
- package/libs/controllers/adminTenant.js +27 -259
- package/libs/controllers/adminTenantOrg.js +71 -0
- package/libs/controllers/adminTenantUser.js +168 -0
- package/libs/controllers/tenant.js +0 -46
- package/libs/controllers/tenantOrg.js +65 -0
- package/libs/controllers/tenantRole.js +219 -0
- package/libs/controllers/tenantUser.js +169 -0
- package/libs/models/company-info.js +25 -0
- package/libs/models/login-log.js +7 -1
- package/libs/models/request-log.js +27 -0
- package/libs/services/account.js +34 -42
- package/libs/services/application.js +4 -1
- package/libs/services/permission.js +24 -5
- package/libs/services/request-log.js +19 -0
- package/libs/services/tenant-org.js +20 -7
- package/libs/services/tenant-role.js +10 -2
- package/libs/services/tenant-user.js +16 -4
- package/libs/services/user.js +34 -1
- package/package.json +1 -1
- /package/libs/controllers/{adminRole.js → adminTenantRole.js} +0 -0
|
@@ -116,7 +116,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
116
116
|
}
|
|
117
117
|
};
|
|
118
118
|
|
|
119
|
-
const getApplicationList = async ({ tenantId }) => {
|
|
119
|
+
const getApplicationList = async ({ tenantId, appName }) => {
|
|
120
120
|
const query = {};
|
|
121
121
|
if (tenantId) {
|
|
122
122
|
const tenant = await services.tenant.getTenant({ id: tenantId });
|
|
@@ -130,6 +130,9 @@ module.exports = fp(async (fastify, options) => {
|
|
|
130
130
|
[fastify.sequelize.Sequelize.Op.in]: tenantApplications.map(({ applicationId }) => applicationId)
|
|
131
131
|
};
|
|
132
132
|
}
|
|
133
|
+
if (appName) {
|
|
134
|
+
query['code'] = appName;
|
|
135
|
+
}
|
|
133
136
|
const list = await models.application.findAll({
|
|
134
137
|
where: query
|
|
135
138
|
});
|
|
@@ -81,7 +81,12 @@ module.exports = fp(async (fastify, options) => {
|
|
|
81
81
|
const addPermissions = async (pid, applicationId) =>
|
|
82
82
|
await Promise.all(
|
|
83
83
|
(get(permissionsPidMapping, pid) || []).map(async ({ id, ...permissionProps }) => {
|
|
84
|
-
const permission = await services.permission.addPermission(
|
|
84
|
+
const permission = await services.permission.addPermission(
|
|
85
|
+
Object.assign({}, permissionProps, {
|
|
86
|
+
applicationId,
|
|
87
|
+
pid
|
|
88
|
+
})
|
|
89
|
+
);
|
|
85
90
|
await addPermissions(permission.id, applicationId);
|
|
86
91
|
})
|
|
87
92
|
);
|
|
@@ -95,7 +100,12 @@ module.exports = fp(async (fastify, options) => {
|
|
|
95
100
|
if (current) {
|
|
96
101
|
await addPermissions(current.id, applicationId, id);
|
|
97
102
|
} else {
|
|
98
|
-
const permission = await services.permission.addPermission(
|
|
103
|
+
const permission = await services.permission.addPermission(
|
|
104
|
+
Object.assign({}, permissionProps, {
|
|
105
|
+
applicationId,
|
|
106
|
+
pid
|
|
107
|
+
})
|
|
108
|
+
);
|
|
99
109
|
await addPermissions(permission.id, applicationId);
|
|
100
110
|
}
|
|
101
111
|
})
|
|
@@ -274,13 +284,17 @@ module.exports = fp(async (fastify, options) => {
|
|
|
274
284
|
}
|
|
275
285
|
};
|
|
276
286
|
|
|
277
|
-
const saveRolePermissionList = async ({ roleId, applications, permissions }) => {
|
|
287
|
+
const saveRolePermissionList = async ({ roleId, tenantId, applications, permissions }) => {
|
|
278
288
|
const role = await models.tenantRole.findByPk(roleId);
|
|
279
289
|
if (!role) {
|
|
280
290
|
throw new Error('角色不存在');
|
|
281
291
|
}
|
|
282
292
|
|
|
283
|
-
|
|
293
|
+
if (tenantId && role.tenantId !== tenantId) {
|
|
294
|
+
throw new Error('数据已过期,请刷新页面后重试');
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
tenantId = role.tenantId;
|
|
284
298
|
|
|
285
299
|
await services.tenant.getTenant({ id: tenantId });
|
|
286
300
|
|
|
@@ -399,11 +413,16 @@ module.exports = fp(async (fastify, options) => {
|
|
|
399
413
|
return { applications, permissions };
|
|
400
414
|
};
|
|
401
415
|
|
|
402
|
-
const getRolePermissionList = async ({ roleId }) => {
|
|
416
|
+
const getRolePermissionList = async ({ roleId, tenantId }) => {
|
|
403
417
|
const role = await models.tenantRole.findByPk(roleId);
|
|
404
418
|
if (!role) {
|
|
405
419
|
throw new Error('角色不存在');
|
|
406
420
|
}
|
|
421
|
+
|
|
422
|
+
if (tenantId && role.tenantId !== tenantId) {
|
|
423
|
+
throw new Error('数据已过期,请刷新页面后重试');
|
|
424
|
+
}
|
|
425
|
+
|
|
407
426
|
const applications = await models.tenantRoleApplication.findAll({
|
|
408
427
|
where: { roleId: role.id, tenantId: role.tenantId }
|
|
409
428
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const fp = require('fastify-plugin');
|
|
2
|
+
module.exports = fp(async (fastify, options) => {
|
|
3
|
+
const { models, services } = fastify.account;
|
|
4
|
+
|
|
5
|
+
const addRequestLog = async ({ userInfo, type, tenantId, appName, action, summary }) => {
|
|
6
|
+
const application = appName && (await services.application.getApplicationByCode({ code: appName }));
|
|
7
|
+
await models.requestLog.create({
|
|
8
|
+
userId: userInfo.id,
|
|
9
|
+
tenantId,
|
|
10
|
+
applicationId: application?.id,
|
|
11
|
+
type,
|
|
12
|
+
action,
|
|
13
|
+
summary
|
|
14
|
+
});
|
|
15
|
+
return {};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
services.requestLog = { addRequestLog };
|
|
19
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fp = require('fastify-plugin');
|
|
2
2
|
module.exports = fp(async (fastify, options) => {
|
|
3
3
|
const { models, services } = fastify.account;
|
|
4
|
-
|
|
4
|
+
const { Op } = fastify.sequelize.Sequelize;
|
|
5
5
|
const getTenantOrgInstance = async ({ id }) => {
|
|
6
6
|
const tenantOrg = await models.tenantOrg.findByPk(id, {
|
|
7
7
|
where: {
|
|
@@ -37,21 +37,30 @@ module.exports = fp(async (fastify, options) => {
|
|
|
37
37
|
});
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
const saveTenantOrg = async ({ id, ...otherInfo }) => {
|
|
40
|
+
const saveTenantOrg = async ({ id, tenantId, ...otherInfo }) => {
|
|
41
41
|
const tenantOrg = await getTenantOrgInstance({ id });
|
|
42
|
+
if (tenantId && tenantOrg.tenantId !== tenantId) {
|
|
43
|
+
throw new Error('数据已过期,请刷新页面后重试');
|
|
44
|
+
}
|
|
42
45
|
if (
|
|
43
46
|
await models.tenantOrg.count({
|
|
44
47
|
where: {
|
|
45
48
|
name: otherInfo.name,
|
|
46
49
|
pid: otherInfo.pid,
|
|
47
|
-
|
|
50
|
+
[Op.not]: {
|
|
51
|
+
id
|
|
52
|
+
}
|
|
48
53
|
}
|
|
49
54
|
})
|
|
50
55
|
) {
|
|
51
56
|
throw new Error('组织名称在同一父组织下有重复');
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
|
|
59
|
+
if (otherInfo.pid === tenantOrg.id) {
|
|
60
|
+
throw new Error('不能用自己作为自己的父节点');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
['name', 'enName', 'pid'].forEach(name => {
|
|
55
64
|
if (otherInfo[name]) {
|
|
56
65
|
tenantOrg[name] = otherInfo[name];
|
|
57
66
|
}
|
|
@@ -63,11 +72,15 @@ module.exports = fp(async (fastify, options) => {
|
|
|
63
72
|
const deleteTenantOrg = async ({ id, tenantId }) => {
|
|
64
73
|
const tenantOrg = await getTenantOrgInstance({ id });
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
if (tenantId && tenantOrg.tenantId !== tenantId) {
|
|
76
|
+
throw new Error('数据已过期,请刷新页面后重试');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const count = await models.tenantOrg.count({
|
|
80
|
+
where: { tenantId: tenantOrg.tenantId, pid: id }
|
|
68
81
|
});
|
|
69
82
|
|
|
70
|
-
if (
|
|
83
|
+
if (count > 0) {
|
|
71
84
|
throw new Error('组织下有用户或子组织无法删除');
|
|
72
85
|
}
|
|
73
86
|
|
|
@@ -42,9 +42,13 @@ module.exports = fp(async (fastify, options) => {
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
const saveTenantRole = async ({ id, ...otherInfo }) => {
|
|
45
|
+
const saveTenantRole = async ({ id, tenantId, ...otherInfo }) => {
|
|
46
46
|
const tenantRole = await getTenantRoleInstance({ id });
|
|
47
47
|
|
|
48
|
+
if (tenantId && tenantRole.tenantId !== tenantId) {
|
|
49
|
+
throw new Error('数据已过期,请刷新页面后重试');
|
|
50
|
+
}
|
|
51
|
+
|
|
48
52
|
['name', 'description'].forEach(name => {
|
|
49
53
|
if (otherInfo[name]) {
|
|
50
54
|
tenantRole[name] = otherInfo[name];
|
|
@@ -54,9 +58,13 @@ module.exports = fp(async (fastify, options) => {
|
|
|
54
58
|
await tenantRole.save();
|
|
55
59
|
};
|
|
56
60
|
|
|
57
|
-
const removeTenantRole = async ({ id }) => {
|
|
61
|
+
const removeTenantRole = async ({ id, tenantId }) => {
|
|
58
62
|
const tenantRole = await getTenantRoleInstance({ id });
|
|
59
63
|
|
|
64
|
+
if (tenantId && tenantRole.tenantId !== tenantId) {
|
|
65
|
+
throw new Error('数据已过期,请刷新页面后重试');
|
|
66
|
+
}
|
|
67
|
+
|
|
60
68
|
await services.tenantUser.checkTenantRoleUsed({ tenantRoleId: tenantRole.id });
|
|
61
69
|
|
|
62
70
|
if (tenantRole.type === 1) {
|
|
@@ -92,7 +92,8 @@ module.exports = fp(async (fastify, options) => {
|
|
|
92
92
|
const user = await services.user.getUser(authenticatePayload);
|
|
93
93
|
const tenantUserList = await models.tenantUser.findAll({
|
|
94
94
|
where: {
|
|
95
|
-
userId: user.id
|
|
95
|
+
userId: user.id,
|
|
96
|
+
status: 0
|
|
96
97
|
}
|
|
97
98
|
});
|
|
98
99
|
|
|
@@ -137,12 +138,19 @@ module.exports = fp(async (fastify, options) => {
|
|
|
137
138
|
return currentTenantUser;
|
|
138
139
|
};
|
|
139
140
|
|
|
140
|
-
const getTenantUserByUserId = async user => {
|
|
141
|
+
const getTenantUserByUserId = async ({ userInfo: user, appName }) => {
|
|
141
142
|
if (!user.currentTenantId) {
|
|
142
143
|
throw new Unauthorized('没有找到当前绑定租户');
|
|
143
144
|
}
|
|
145
|
+
|
|
144
146
|
const tenant = await services.tenant.getTenant({ id: user.currentTenantId });
|
|
145
147
|
|
|
148
|
+
const tenantApplications = await services.application.getApplicationList({ tenantId: tenant.id, appName });
|
|
149
|
+
|
|
150
|
+
if (appName && !tenantApplications.some(item => item.code === appName)) {
|
|
151
|
+
throw Unauthorized('当前租户没有开通该应用权限');
|
|
152
|
+
}
|
|
153
|
+
|
|
146
154
|
const tenantUser = await models.tenantUser.findOne({
|
|
147
155
|
attributes: ['uuid', 'avatar', 'name', 'description', 'phone', 'email'],
|
|
148
156
|
include: [
|
|
@@ -181,11 +189,15 @@ module.exports = fp(async (fastify, options) => {
|
|
|
181
189
|
const tenantRoleIds = tenantUser.tenantRoles.map(({ id }) => id);
|
|
182
190
|
tenantRoleIds.push(defaultTenant.id);
|
|
183
191
|
|
|
184
|
-
const { userPermissionList } = await getTenantUserPermissionList({ tenantRoleIds });
|
|
192
|
+
const { userPermissionList, applications: roleApplications } = await getTenantUserPermissionList({ tenantRoleIds });
|
|
185
193
|
if (!tenantUser) {
|
|
186
194
|
throw new Error('当前租户用户不存在或者已经被关闭');
|
|
187
195
|
}
|
|
188
196
|
|
|
197
|
+
if (appName && !roleApplications.some(item => item.code === appName)) {
|
|
198
|
+
throw Unauthorized('当前用户没有开通该应用权限');
|
|
199
|
+
}
|
|
200
|
+
|
|
189
201
|
const outputTenantUser = Object.assign({}, tenantUser.get({ plain: true }), { id: tenantUser.uuid });
|
|
190
202
|
outputTenantUser.tenantOrgs = outputTenantUser?.tenantOrgs.map(({ id, name }) => ({ id, name }));
|
|
191
203
|
outputTenantUser.tenantRoles = outputTenantUser?.tenantRoles.map(({ id, name }) => ({ id, name }));
|
|
@@ -194,7 +206,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
194
206
|
tenantUser: Object.assign({}, outputTenantUser, {
|
|
195
207
|
permissions: userPermissionList
|
|
196
208
|
}),
|
|
197
|
-
user
|
|
209
|
+
userInfo: user
|
|
198
210
|
};
|
|
199
211
|
};
|
|
200
212
|
|
package/libs/services/user.js
CHANGED
|
@@ -2,6 +2,12 @@ const fp = require('fastify-plugin');
|
|
|
2
2
|
const { Unauthorized } = require('http-errors');
|
|
3
3
|
const get = require('lodash/get');
|
|
4
4
|
const pick = require('lodash/pick');
|
|
5
|
+
const isNil = require('lodash/isNil');
|
|
6
|
+
|
|
7
|
+
function userNameIsEmail(username) {
|
|
8
|
+
return /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(username);
|
|
9
|
+
}
|
|
10
|
+
|
|
5
11
|
module.exports = fp(async (fastify, options) => {
|
|
6
12
|
const { models, services } = fastify.account;
|
|
7
13
|
|
|
@@ -19,6 +25,27 @@ module.exports = fp(async (fastify, options) => {
|
|
|
19
25
|
return user;
|
|
20
26
|
};
|
|
21
27
|
|
|
28
|
+
const getUserInstanceByName = async ({ name, status }) => {
|
|
29
|
+
const isEmail = userNameIsEmail(name);
|
|
30
|
+
const query = {};
|
|
31
|
+
if (!isNil(status)) {
|
|
32
|
+
query['status'] = Array.isArray(status)
|
|
33
|
+
? {
|
|
34
|
+
[fastify.sequelize.Sequelize.Op.or]: status
|
|
35
|
+
}
|
|
36
|
+
: status;
|
|
37
|
+
}
|
|
38
|
+
const user = await models.user.findOne({
|
|
39
|
+
where: Object.assign({}, isEmail ? { email: name } : { phone: name }, query)
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (!user) {
|
|
43
|
+
throw new Error('用户不存在');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return user;
|
|
47
|
+
};
|
|
48
|
+
|
|
22
49
|
const getUser = async authenticatePayload => {
|
|
23
50
|
if (!(authenticatePayload && authenticatePayload.id)) {
|
|
24
51
|
throw new Unauthorized();
|
|
@@ -127,7 +154,12 @@ module.exports = fp(async (fastify, options) => {
|
|
|
127
154
|
});
|
|
128
155
|
return {
|
|
129
156
|
pageData: rows.map(item => {
|
|
130
|
-
return Object.assign({}, item.get({ pain: true }), {
|
|
157
|
+
return Object.assign({}, item.get({ pain: true }), {
|
|
158
|
+
id: item.uuid,
|
|
159
|
+
tenants: item.tenants.map(({ uuid, name }) => {
|
|
160
|
+
return { id: uuid, name };
|
|
161
|
+
})
|
|
162
|
+
});
|
|
131
163
|
}),
|
|
132
164
|
totalCount: count
|
|
133
165
|
};
|
|
@@ -136,6 +168,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
136
168
|
services.user = {
|
|
137
169
|
getUser,
|
|
138
170
|
getUserInstance,
|
|
171
|
+
getUserInstanceByName,
|
|
139
172
|
saveUser,
|
|
140
173
|
accountIsExists,
|
|
141
174
|
addUser,
|
package/package.json
CHANGED
|
File without changes
|