@kne/fastify-account 1.0.0-alpha.0

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 (37) hide show
  1. package/README.md +1436 -0
  2. package/index.js +54 -0
  3. package/libs/controllers/account.js +189 -0
  4. package/libs/controllers/admin.js +153 -0
  5. package/libs/controllers/adminPermission.js +230 -0
  6. package/libs/controllers/adminRole.js +145 -0
  7. package/libs/controllers/adminTenant.js +461 -0
  8. package/libs/controllers/tenant.js +22 -0
  9. package/libs/controllers/user.js +12 -0
  10. package/libs/models/admin-role.js +19 -0
  11. package/libs/models/application.js +36 -0
  12. package/libs/models/login-log.js +15 -0
  13. package/libs/models/permission.js +53 -0
  14. package/libs/models/tenant-application.js +28 -0
  15. package/libs/models/tenant-org.js +30 -0
  16. package/libs/models/tenant-permission.js +28 -0
  17. package/libs/models/tenant-role-application.js +32 -0
  18. package/libs/models/tenant-role-permission.js +32 -0
  19. package/libs/models/tenant-role.js +27 -0
  20. package/libs/models/tenant-share-group-permission.js +22 -0
  21. package/libs/models/tenant-share-group.js +22 -0
  22. package/libs/models/tenant-source-user-share-group.js +22 -0
  23. package/libs/models/tenant-token.js +32 -0
  24. package/libs/models/tenant-user-org.js +22 -0
  25. package/libs/models/tenant-user-role.js +22 -0
  26. package/libs/models/tenant-user-share-group.js +22 -0
  27. package/libs/models/tenant-user.js +56 -0
  28. package/libs/models/tenant.js +38 -0
  29. package/libs/models/user-account.js +26 -0
  30. package/libs/models/user.js +50 -0
  31. package/libs/models/verification-code.js +26 -0
  32. package/libs/services/account.js +200 -0
  33. package/libs/services/admin.js +183 -0
  34. package/libs/services/permission.js +465 -0
  35. package/libs/services/tenant.js +576 -0
  36. package/libs/services/user.js +108 -0
  37. package/package.json +61 -0
@@ -0,0 +1,465 @@
1
+ const fp = require('fastify-plugin');
2
+ const isNil = require('lodash/isNil');
3
+ module.exports = fp(async (fastify, options) => {
4
+ const addApplication = async application => {
5
+ return fastify.account.models.application.create(application);
6
+ };
7
+ const saveApplication = async ({ id, ...others }) => {
8
+ const application = await fastify.account.models.application.findByPk(id);
9
+ if (!application) {
10
+ throw new Error('应用不存在');
11
+ }
12
+ ['name', 'code', 'avatar', 'url', 'description'].forEach(name => {
13
+ if (!isNil(others[name])) {
14
+ application[name] = others[name];
15
+ }
16
+ });
17
+
18
+ await application.save();
19
+ };
20
+
21
+ const deleteApplication = async ({ id }) => {
22
+ const application = await fastify.account.models.application.findByPk(id);
23
+ if (!application) {
24
+ throw new Error('应用不存在');
25
+ }
26
+ if (
27
+ (await fastify.account.models.tenantApplication.count({
28
+ where: {
29
+ applicationId: application.id
30
+ }
31
+ })) > 0
32
+ ) {
33
+ throw new Error('应用已经开放给其他租户使用,不能删除');
34
+ }
35
+
36
+ const permissionIdList = (
37
+ await fastify.account.models.permission.findAll({
38
+ where: { applicationId: application.id }
39
+ })
40
+ ).map(({ id }) => id);
41
+
42
+ const t = await fastify.sequelize.instance.transaction();
43
+
44
+ try {
45
+ await fastify.account.models.tenantPermission.destroy(
46
+ {
47
+ where: {
48
+ permissionId: {
49
+ [fastify.sequelize.Sequelize.Op.in]: permissionIdList
50
+ }
51
+ }
52
+ },
53
+ { transaction: t }
54
+ );
55
+
56
+ await fastify.account.models.tenantRolePermission.destroy(
57
+ {
58
+ where: {
59
+ permissionId: {
60
+ [fastify.sequelize.Sequelize.Op.in]: permissionIdList
61
+ }
62
+ }
63
+ },
64
+ { transaction: t }
65
+ );
66
+
67
+ await fastify.account.models.permission.destroy({
68
+ where: {
69
+ applicationId: application.id
70
+ },
71
+ transaction: t
72
+ });
73
+ await application.destroy({ transaction: t });
74
+ await t.commit();
75
+ } catch (e) {
76
+ await t.rollback();
77
+ throw e;
78
+ }
79
+ };
80
+
81
+ const getApplicationList = async ({ tenantId }) => {
82
+ const query = {};
83
+ if (tenantId) {
84
+ const tenant = await fastify.account.models.tenant.findByPk(tenantId);
85
+ if (!tenant) {
86
+ throw new Error('租户不存在');
87
+ }
88
+ const tenantApplications = await fastify.account.models.tenantApplication.findAll({
89
+ where: { tenantId }
90
+ });
91
+ query.id = {
92
+ [fastify.sequelize.Sequelize.Op.in]: tenantApplications.map(({ applicationId }) => applicationId)
93
+ };
94
+ }
95
+ return await fastify.account.models.application.findAll({
96
+ where: query
97
+ });
98
+ };
99
+
100
+ const addPermission = async ({ applicationId, pid, code, name, type, isModule, isMust, description }) => {
101
+ if (!(await fastify.account.models.application.findByPk(applicationId))) {
102
+ throw new Error('应用不存在');
103
+ }
104
+ const paths = [];
105
+ if (pid > 0) {
106
+ const parentNode = await fastify.account.models.permission.findByPk(pid);
107
+ if (!parentNode) {
108
+ throw new Error('未找到父级');
109
+ }
110
+ paths.push(...parentNode.paths, parentNode.id);
111
+ }
112
+ if (
113
+ (await fastify.account.models.permission.count({
114
+ where: {
115
+ pid,
116
+ code,
117
+ applicationId
118
+ }
119
+ })) > 0
120
+ ) {
121
+ throw new Error('同一级权限code不能重复');
122
+ }
123
+ return await fastify.account.models.permission.create({
124
+ applicationId,
125
+ code,
126
+ description,
127
+ name,
128
+ type,
129
+ pid,
130
+ isModule,
131
+ isMust,
132
+ paths
133
+ });
134
+ };
135
+
136
+ const getPermissionList = async ({ applicationId, tenantId }) => {
137
+ const query = {};
138
+ if (tenantId) {
139
+ const tenant = await fastify.account.models.tenant.findByPk(tenantId);
140
+ if (!tenant) {
141
+ throw new Error('租户不存在');
142
+ }
143
+ const tenantPermissions = await fastify.account.models.tenantPermission.findAll({
144
+ where: { tenantId }
145
+ });
146
+ query[fastify.sequelize.Sequelize.Op.or] = [
147
+ {
148
+ id: {
149
+ [fastify.sequelize.Sequelize.Op.in]: tenantPermissions.map(({ permissionId }) => permissionId)
150
+ }
151
+ },
152
+ { isMust: 1 }
153
+ ];
154
+ }
155
+ return await fastify.account.models.permission.findAll({
156
+ where: Object.assign({}, { applicationId }, query)
157
+ });
158
+ };
159
+
160
+ const deletePermission = async ({ id }) => {
161
+ const currentPermission = await fastify.account.models.permission.findByPk(id);
162
+
163
+ if (!currentPermission) {
164
+ throw new Error('权限不存在');
165
+ }
166
+
167
+ const permissionList = await fastify.account.models.permission.findAll({
168
+ where: {
169
+ applicationId: currentPermission.applicationId
170
+ }
171
+ });
172
+
173
+ const childrenNode = permissionList.filter(({ paths }) => {
174
+ return paths.indexOf(currentPermission.id) > -1;
175
+ });
176
+
177
+ const permissionIdList = [currentPermission.id, ...childrenNode.map(({ id }) => id)];
178
+
179
+ const t = await fastify.sequelize.instance.transaction();
180
+ try {
181
+ await fastify.account.models.tenantPermission.destroy({
182
+ where: {
183
+ permissionId: {
184
+ [fastify.sequelize.Sequelize.Op.in]: permissionIdList
185
+ }
186
+ },
187
+ transaction: t
188
+ });
189
+ await fastify.account.models.tenantRolePermission.destroy({
190
+ where: {
191
+ permissionId: {
192
+ [fastify.sequelize.Sequelize.Op.in]: permissionIdList
193
+ }
194
+ },
195
+ transaction: t
196
+ });
197
+ await fastify.account.models.permission.destroy({
198
+ where: {
199
+ id: {
200
+ [fastify.sequelize.Sequelize.Op.in]: permissionIdList
201
+ }
202
+ },
203
+ transaction: t
204
+ });
205
+ await t.commit();
206
+ } catch (e) {
207
+ await t.rollback();
208
+ throw e;
209
+ }
210
+ };
211
+
212
+ const savePermission = async permission => {
213
+ const currentPermission = await fastify.account.models.permission.findByPk(permission.id);
214
+
215
+ if (!permission) {
216
+ throw new Error('权限不存在');
217
+ }
218
+
219
+ ['name', 'type', 'isMust', 'description'].forEach(name => {
220
+ if (!isNil(permission[name])) {
221
+ currentPermission[name] = permission[name];
222
+ }
223
+ });
224
+
225
+ await currentPermission.save();
226
+ };
227
+
228
+ const saveTenantPermissionList = async ({ tenantId, applications, permissions }) => {
229
+ if (!(await fastify.account.models.tenant.findByPk(tenantId))) {
230
+ throw new Error('租户不存在');
231
+ }
232
+ const currentApplications = await fastify.account.models.tenantApplication.findAll({
233
+ where: { tenantId }
234
+ });
235
+
236
+ const currentApplicationIds = currentApplications.map(({ applicationId }) => applicationId);
237
+
238
+ const currentPermissions = await fastify.account.models.tenantPermission.findAll({
239
+ where: { tenantId }
240
+ });
241
+
242
+ const currentPermissionIds = currentPermissions.map(({ permissionId }) => permissionId);
243
+
244
+ const t = await fastify.sequelize.instance.transaction();
245
+ try {
246
+ //先删除,后添加
247
+ const needDeleteApplications = currentApplications.filter(item => applications.indexOf(item.applicationId) === -1).map(({ applicationId }) => applicationId);
248
+ const needAddApplications = applications.filter(applicationId => currentApplicationIds.indexOf(applicationId) === -1);
249
+ const needDeletePermissions = currentPermissions.filter(item => permissions.indexOf(item.permissionId) === -1).map(({ permissionId }) => permissionId);
250
+ const needAddPermissions = permissions.filter(permissionId => currentPermissionIds.indexOf(permissionId) === -1);
251
+
252
+ await fastify.account.models.tenantRoleApplication.destroy({
253
+ where: {
254
+ applicationId: {
255
+ [fastify.sequelize.Sequelize.Op.in]: needDeleteApplications
256
+ },
257
+ tenantId
258
+ },
259
+ transaction: t
260
+ });
261
+
262
+ await fastify.account.models.tenantRolePermission.destroy({
263
+ where: {
264
+ permissionId: {
265
+ [fastify.sequelize.Sequelize.Op.in]: needDeletePermissions
266
+ },
267
+ tenantId
268
+ },
269
+ transaction: t
270
+ });
271
+
272
+ await fastify.account.models.tenantApplication.destroy({
273
+ where: {
274
+ applicationId: {
275
+ [fastify.sequelize.Sequelize.Op.in]: needDeleteApplications
276
+ },
277
+ tenantId
278
+ },
279
+ transaction: t
280
+ });
281
+
282
+ await fastify.account.models.tenantPermission.destroy({
283
+ where: {
284
+ permissionId: {
285
+ [fastify.sequelize.Sequelize.Op.in]: needDeletePermissions
286
+ },
287
+ tenantId
288
+ },
289
+ transaction: t
290
+ });
291
+
292
+ needAddApplications.length > 0 &&
293
+ (await fastify.account.models.tenantApplication.bulkCreate(
294
+ needAddApplications.map(applicationId => {
295
+ return { tenantId, applicationId };
296
+ }),
297
+ { transaction: t }
298
+ ));
299
+
300
+ needAddPermissions.length > 0 &&
301
+ (await fastify.account.models.tenantPermission.bulkCreate(
302
+ needAddPermissions.map(permissionId => {
303
+ return { tenantId, permissionId };
304
+ }),
305
+ { transaction: t }
306
+ ));
307
+
308
+ await t.commit();
309
+ } catch (e) {
310
+ await t.rollback();
311
+ throw e;
312
+ }
313
+ };
314
+
315
+ const saveRolePermissionList = async ({ roleId, applications, permissions }) => {
316
+ const role = await fastify.account.models.tenantRole.findByPk(roleId);
317
+ if (!role) {
318
+ throw new Error('角色不存在');
319
+ }
320
+ if (!(await fastify.account.models.tenant.findByPk(role.tenantId))) {
321
+ throw new Error('租户不存在');
322
+ }
323
+
324
+ const tenantId = role.tenantId;
325
+
326
+ const tenantApplications = await fastify.account.models.tenantApplication.findAll({
327
+ attributes: ['applicationId'],
328
+ where: { tenantId }
329
+ });
330
+
331
+ const tenantPermissions = await fastify.account.models.tenantPermission.findAll({
332
+ attributes: ['permissionId'],
333
+ where: { tenantId }
334
+ });
335
+
336
+ const tenantApplicationIds = tenantApplications.map(({ applicationId }) => applicationId);
337
+ const tenantPermissionIds = tenantPermissions.map(({ permissionId }) => permissionId);
338
+
339
+ const currentApplications = await fastify.account.models.tenantRoleApplication.findAll({
340
+ where: {
341
+ roleId: role.id,
342
+ tenantId,
343
+ applicationId: {
344
+ [fastify.sequelize.Sequelize.Op.in]: tenantApplicationIds
345
+ }
346
+ }
347
+ });
348
+
349
+ const currentPermissions = await fastify.account.models.tenantRolePermission.findAll({
350
+ where: {
351
+ roleId: role.id,
352
+ tenantId,
353
+ permissionId: { [fastify.sequelize.Sequelize.Op.in]: tenantPermissionIds }
354
+ }
355
+ });
356
+
357
+ const currentApplicationIds = currentApplications.map(({ applicationId }) => applicationId);
358
+ const currentPermissionIds = currentPermissions.map(({ permissionId }) => permissionId);
359
+
360
+ const t = await fastify.sequelize.instance.transaction();
361
+
362
+ try {
363
+ //先删除,后添加
364
+ const needDeleteApplications = currentApplicationIds.filter(applicationId => applications.indexOf(applicationId) === -1);
365
+ const needAddApplications = applications.filter(applicationId => currentApplicationIds.indexOf(applicationId) === -1 && tenantApplicationIds.indexOf(applicationId) > -1);
366
+ const needDeletePermissions = currentPermissionIds.filter(permissionId => permissions.indexOf(permissionId) === -1);
367
+ const needAddPermissions = permissions.filter(permissionId => currentPermissionIds.indexOf(permissionId) === -1 && tenantPermissionIds.indexOf(permissionId) > -1);
368
+
369
+ needDeleteApplications.length > 0 &&
370
+ (await fastify.account.models.tenantRoleApplication.destroy({
371
+ where: {
372
+ applicationId: {
373
+ [fastify.sequelize.Sequelize.Op.in]: needDeleteApplications
374
+ },
375
+ tenantId
376
+ },
377
+ transaction: t
378
+ }));
379
+
380
+ needDeletePermissions.length > 0 &&
381
+ (await fastify.account.models.tenantRolePermission.destroy({
382
+ where: {
383
+ permissionId: {
384
+ [fastify.sequelize.Sequelize.Op.in]: needDeletePermissions
385
+ },
386
+ tenantId
387
+ },
388
+ transaction: t
389
+ }));
390
+
391
+ needAddApplications.length > 0 &&
392
+ (await fastify.account.models.tenantRoleApplication.bulkCreate(
393
+ needAddApplications.map(applicationId => {
394
+ return {
395
+ tenantId,
396
+ roleId,
397
+ applicationId
398
+ };
399
+ }),
400
+ { transaction: t }
401
+ ));
402
+
403
+ needAddPermissions.length > 0 &&
404
+ (await fastify.account.models.tenantRolePermission.bulkCreate(
405
+ needAddPermissions.map(permissionId => {
406
+ return {
407
+ tenantId,
408
+ roleId,
409
+ permissionId
410
+ };
411
+ }),
412
+ { transaction: t }
413
+ ));
414
+
415
+ await t.commit();
416
+ } catch (e) {
417
+ await t.rollback();
418
+ throw e;
419
+ }
420
+ };
421
+
422
+ const getTenantPermissionList = async ({ tenantId }) => {
423
+ await fastify.account.services.tenant.getTenantInfo({ id: tenantId });
424
+
425
+ const applications = await fastify.account.models.tenantApplication.findAll({
426
+ where: { tenantId, status: 0 }
427
+ });
428
+
429
+ const permissions = await fastify.account.models.tenantPermission.findAll({
430
+ where: { tenantId, status: 0 }
431
+ });
432
+
433
+ return { applications, permissions };
434
+ };
435
+
436
+ const getRolePermissionList = async ({ roleId }) => {
437
+ const role = await fastify.account.models.tenantRole.findByPk(roleId);
438
+ if (!role) {
439
+ throw new Error('角色不存在');
440
+ }
441
+ const applications = await fastify.account.models.tenantRoleApplication.findAll({
442
+ where: { roleId: role.id, tenantId: role.tenantId }
443
+ });
444
+ const permissions = await fastify.account.models.tenantRolePermission.findAll({
445
+ where: { roleId: role.id, tenantId: role.tenantId }
446
+ });
447
+
448
+ return { applications, permissions };
449
+ };
450
+
451
+ fastify.account.services.permission = {
452
+ addApplication,
453
+ saveApplication,
454
+ deleteApplication,
455
+ getApplicationList,
456
+ addPermission,
457
+ getPermissionList,
458
+ deletePermission,
459
+ savePermission,
460
+ saveTenantPermissionList,
461
+ saveRolePermissionList,
462
+ getTenantPermissionList,
463
+ getRolePermissionList
464
+ };
465
+ });