@kne/fastify-account 1.0.0-alpha.1 → 1.0.0-alpha.3

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 (42) hide show
  1. package/README.md +101 -5
  2. package/index.js +10 -4
  3. package/libs/controllers/account.js +8 -7
  4. package/libs/controllers/admin.js +16 -15
  5. package/libs/controllers/adminPermission.js +42 -35
  6. package/libs/controllers/adminRole.js +13 -12
  7. package/libs/controllers/adminTenant.js +39 -36
  8. package/libs/controllers/tenant.js +16 -4
  9. package/libs/controllers/user.js +23 -1
  10. package/libs/models/admin-role.js +4 -8
  11. package/libs/models/application.js +16 -10
  12. package/libs/models/login-log.js +4 -8
  13. package/libs/models/permission.js +7 -9
  14. package/libs/models/tenant-application.js +8 -10
  15. package/libs/models/tenant-org.js +5 -9
  16. package/libs/models/tenant-permission.js +7 -9
  17. package/libs/models/tenant-role-application.js +14 -10
  18. package/libs/models/tenant-role-permission.js +10 -9
  19. package/libs/models/tenant-role.js +5 -9
  20. package/libs/models/tenant-share-group-permission.js +5 -9
  21. package/libs/models/tenant-share-group.js +5 -9
  22. package/libs/models/tenant-source-user-share-group.js +5 -9
  23. package/libs/models/tenant-token.js +7 -9
  24. package/libs/models/tenant-user-org.js +11 -10
  25. package/libs/models/tenant-user-role.js +11 -10
  26. package/libs/models/tenant-user-share-group.js +6 -10
  27. package/libs/models/tenant-user.js +35 -16
  28. package/libs/models/tenant.js +17 -9
  29. package/libs/models/user-account.js +17 -9
  30. package/libs/models/user.js +27 -17
  31. package/libs/models/verification-code.js +4 -8
  32. package/libs/services/account.js +26 -16
  33. package/libs/services/admin.js +14 -116
  34. package/libs/services/application.js +151 -0
  35. package/libs/services/permission.js +47 -145
  36. package/libs/services/tenant-invite.js +62 -0
  37. package/libs/services/tenant-org.js +84 -0
  38. package/libs/services/tenant-role.js +108 -0
  39. package/libs/services/tenant-user.js +486 -0
  40. package/libs/services/tenant.js +68 -512
  41. package/libs/services/user.js +69 -30
  42. package/package.json +3 -3
@@ -1,438 +1,72 @@
1
1
  const fp = require('fastify-plugin');
2
- const isNil = require('lodash/isNil');
2
+
3
3
  module.exports = fp(async (fastify, options) => {
4
- const getUserTenant = async authenticatePayload => {
5
- const user = await fastify.account.services.user.getUserInfo(authenticatePayload);
6
- const tenantUserList = await fastify.account.models.tenantUser.findAll({
4
+ const { models, services } = fastify.account;
5
+
6
+ const getTenantInstance = async ({ id }) => {
7
+ const tenant = await models.tenant.findOne({
7
8
  where: {
8
- userId: user.id
9
+ uuid: id
9
10
  }
10
11
  });
11
-
12
- const tenantList =
13
- tenantUserList.length > 0
14
- ? await fastify.account.models.tenant.findAll({
15
- where: {
16
- id: {
17
- [fastify.sequelize.Sequelize.Op.in]: tenantUserList.map(({ tenantId }) => tenantId)
18
- },
19
- status: 0
20
- }
21
- })
22
- : [];
23
-
24
- const currentTenantUser = user.currentTenantId && tenantUserList.find(({ tenantId }) => tenantId === user.currentTenantId);
25
- const currentTenant = currentTenantUser && tenantList.find(({ id }) => id === currentTenantUser.tenantId);
26
-
27
- return {
28
- currentTenant,
29
- currentTenantUser,
30
- tenantList,
31
- tenantUserList,
32
- userInfo: user
33
- };
34
- };
35
-
36
- const getTenantInfo = async ({ id }) => {
37
- const tenant = await fastify.account.models.tenant.findByPk(id);
38
12
  if (!tenant) {
39
13
  throw new Error('租户不存在');
40
14
  }
41
- return tenant;
42
- };
43
-
44
- const getRoleList = async ({ tenantId, currentPage, perPage, filter }) => {
45
- const queryFilter = {};
46
- if (!isNil(filter?.type)) {
47
- queryFilter.type = filter.type;
48
- }
49
- const { count, rows } = await fastify.account.models.tenantRole.findAndCountAll({
50
- where: Object.assign({}, queryFilter, { tenantId }),
51
- offset: currentPage * (currentPage - 1),
52
- limit: perPage
53
- });
54
-
55
- return { pageData: rows, totalCount: count };
56
- };
57
-
58
- const addRole = async ({ tenantId, name, description }) => {
59
- if (!(await fastify.account.models.tenant.findByPk(tenantId))) {
60
- throw new Error('租户不存在');
61
- }
62
-
63
- return await fastify.account.models.tenantRole.create({
64
- tenantId,
65
- name,
66
- description
67
- });
68
- };
69
-
70
- const saveRole = async ({ id, ...otherInfo }) => {
71
- const tenantRole = await fastify.account.models.tenantRole.findByPk(id, {
72
- where: {
73
- type: 0
74
- }
75
- });
76
-
77
- if (!tenantRole) {
78
- throw new Error('角色不存在');
79
- }
80
-
81
- ['name', 'description'].forEach(name => {
82
- if (otherInfo[name]) {
83
- tenantRole[name] = otherInfo[name];
84
- }
85
- });
86
-
87
- await tenantRole.save();
88
- };
89
-
90
- const removeRole = async ({ id }) => {
91
- const tenantRole = await fastify.account.models.tenantRole.findByPk(id, {
92
- where: {
93
- type: 0
94
- }
95
- });
96
-
97
- if (!tenantRole) {
98
- throw new Error('角色不存在');
99
- }
100
-
101
- if (
102
- (await fastify.account.models.tenantUserRole.count({
103
- where: {
104
- tenantRoleId: tenantRole.id
105
- }
106
- })) > 0
107
- ) {
108
- throw new Error('该角色已经被使用,请在租户用户种处理掉所有使用该角色的租户用户后重试');
109
- }
110
15
 
111
- if (tenantRole.type === 1) {
112
- throw new Error('该角色为系统默认角色,不能删除');
16
+ if (tenant.status !== 0) {
17
+ throw new Error('租户已关闭');
113
18
  }
114
-
115
- await tenantRole.destroy();
19
+ return tenant;
116
20
  };
117
21
 
118
- const tenantUserAuthenticate = async user => {
119
- if (!user.currentTenantId) {
120
- throw new Error('没有找到当前绑定租户');
121
- }
122
- const tenant = await fastify.account.models.tenant.findByPk(user.currentTenantId, {
123
- where: {
124
- status: 0
125
- }
126
- });
127
- if (!tenant) {
128
- throw new Error('当前绑定租户不存在或者已经被关闭');
129
- }
130
-
131
- const tenantUser = await fastify.account.models.tenantUser.findOne({
132
- where: {
133
- tenantId: tenant.id,
134
- userId: user.id,
135
- status: 0
136
- }
137
- });
138
-
139
- if (!tenantUser) {
140
- throw new Error('当前租户用户不存在或者已经被关闭');
141
- }
22
+ const getTenant = async ({ id }) => {
23
+ const tenant = await getTenantInstance({ id });
142
24
 
143
- return {
144
- tenant,
145
- tenantUser
146
- };
25
+ return Object.assign({}, tenant.get({ plain: true }), { id: tenant.uuid });
147
26
  };
148
27
 
149
28
  const closeTenant = async ({ tenantId }) => {
150
- const tenant = await getTenantInfo({ id: tenantId });
29
+ const tenant = await getTenant({ id: tenantId });
151
30
  tenant.status = 12;
152
31
  await tenant.save();
153
32
  };
154
33
 
155
34
  const openTenant = async ({ tenantId }) => {
156
- const tenant = await getTenantInfo({ id: tenantId });
35
+ const tenant = await getTenant({ id: tenantId });
157
36
  tenant.status = 0;
158
37
  await tenant.save();
159
38
  };
160
39
 
161
- const addTenantOrg = async org => {
162
- if (await fastify.account.models.tenantOrg.count({ where: { name: org.name } })) {
163
- throw new Error('组织名称不能重复');
164
- }
165
-
166
- return await fastify.account.models.tenantOrg.create({
167
- name: org.name,
168
- enName: org.enName,
169
- tenantId: org.tenantId,
170
- pid: org.pid
171
- });
172
- };
173
-
174
- const saveTenantOrg = async ({ id, ...otherInfo }) => {
175
- const tenantOrg = await fastify.account.models.tenantOrg.findByPk(id, {
176
- where: {
177
- type: 0
178
- }
179
- });
180
-
181
- if (!tenantOrg) {
182
- throw new Error('该组织不存在');
183
- }
184
- if (
185
- await fastify.account.models.tenantOrg.count({
186
- where: {
187
- name: otherInfo.name,
188
- pid: otherInfo.pid,
189
- tenantId: otherInfo.tenantId
190
- }
191
- })
192
- ) {
193
- throw new Error('组织名称在同一父组织下有重复');
194
- }
195
-
196
- ['name', 'enName', 'tenantId', 'pid'].forEach(name => {
197
- if (otherInfo[name]) {
198
- tenantOrg[name] = otherInfo[name];
199
- }
200
- });
201
-
202
- await tenantOrg.save();
203
- };
204
-
205
- const deleteTenantOrg = async ({ id, tenantId }) => {
206
- const tenantOrg = await fastify.account.models.tenantOrg.findByPk(id, {
207
- where: {
208
- type: 0
209
- }
210
- });
211
-
212
- if (!tenantOrg) {
213
- throw new Error('该组织不存在');
214
- }
215
-
216
- const { rows } = await fastify.account.models.tenantOrg.findAndCountAll({
217
- where: { tenantId, pid: id }
218
- });
219
-
220
- if (rows?.length) {
221
- throw new Error('组织下有用户或子组织无法删除');
222
- }
223
-
224
- await tenantOrg.destroy();
225
- };
226
-
227
- const getTenantOrgList = async ({ tenantId }) => {
228
- const { count, rows } = await fastify.account.models.tenantOrg.findAndCountAll({
229
- where: { tenantId }
230
- });
231
-
232
- return { pageData: rows, totalCount: count };
233
- };
234
-
235
- const getTenantUserList = async ({ tenantId }) => {
236
- if (!(await fastify.account.models.tenant.findByPk(tenantId))) {
237
- throw new Error('租户不存在');
238
- }
239
- const { count, rows } = await fastify.account.models.tenantUser.findAndCountAll({
240
- include: [fastify.account.models.tenantRole, fastify.account.models.tenantOrg, fastify.account.models.user],
241
- where: { tenantId }
242
- });
243
-
244
- return { pageData: rows, totalCount: count };
245
- };
246
-
247
- const saveTenantUserInfoValidate = async ({ tenantId, roleIds, orgIds, userId }) => {
248
- await getTenantInfo({ id: tenantId });
249
- if (
250
- roleIds.length > 0 &&
251
- (await fastify.account.models.tenantRole.count({
252
- where: {
253
- id: {
254
- [fastify.sequelize.Sequelize.Op.in]: roleIds
255
- }
256
- }
257
- })) < roleIds.length
258
- ) {
259
- throw new Error('包含租户不存在的角色');
260
- }
261
- if (orgIds.length === 0) {
262
- const tenantOrg = await fastify.account.models.tenantOrg.findOne({
263
- where: {
264
- pid: 0,
265
- tenantId
266
- }
267
- });
268
- if (!tenantOrg) {
269
- throw new Error('租户根节点不存在');
270
- }
271
- orgIds = [tenantOrg.id];
272
- }
273
-
274
- if (
275
- (await fastify.account.models.tenantOrg.count({
276
- where: {
277
- tenantId,
278
- id: {
279
- [fastify.sequelize.Sequelize.Op.in]: orgIds
280
- }
281
- }
282
- })) < orgIds.length
283
- ) {
284
- throw new Error('包含租户不存在组织');
285
- }
286
-
287
- if (!(await fastify.account.models.user.findByPk(userId))) {
288
- throw new Error('用户不存在,应该先创建用户再创建租户用户');
40
+ const saveTenant = async tenant => {
41
+ const currentTenant = await services.tenant.getTenantInstance({ id: tenant.id });
42
+ if (!currentTenant) {
43
+ throw new Error('租户不存在,请刷新以后重试');
289
44
  }
45
+ await currentTenant.update(tenant);
290
46
  };
291
47
 
292
- const addTenantUser = async ({ tenantId, roleIds, orgIds, userId, ...tenantUser }) => {
293
- const tenant = await getTenantInfo({ id: tenantId });
294
-
295
- const currentAccountNumber = await fastify.account.models.tenantUser.count({
296
- where: { tenantId }
297
- });
298
-
299
- if (currentAccountNumber >= tenant.accountNumber) {
300
- throw new Error('租户用户数量已达上限');
48
+ const addTenant = async tenant => {
49
+ if (await models.tenant.count({ where: { name: tenant.name } })) {
50
+ throw new Error('租户名称不能重复');
301
51
  }
302
52
 
303
- await saveTenantUserInfoValidate({ tenantId, roleIds, orgIds, userId });
304
-
305
53
  const t = await fastify.sequelize.instance.transaction();
306
-
307
- if (
308
- (await fastify.account.models.tenantUser.count({
309
- where: {
310
- userId,
311
- tenantId
312
- }
313
- })) > 0
314
- ) {
315
- throw new Error('该用户已经属于该租户,不能重复添加');
316
- }
317
-
318
54
  try {
319
- const currentTenantUser = await fastify.account.models.tenantUser.create(
55
+ const currentTenant = await models.tenant.create(tenant);
56
+ await models.tenantRole.create(
320
57
  {
321
- name: tenantUser.name,
322
- avatar: tenantUser.avatar,
323
- phone: tenantUser.phone,
324
- email: tenantUser.email,
325
- description: tenantUser.description,
326
- tenantId,
327
- userId
328
- },
329
- { transaction: t }
330
- );
331
- roleIds.length > 0 &&
332
- (await fastify.account.models.tenantUserRole.bulkCreate(
333
- roleIds.map(roleId => {
334
- return {
335
- tenantRoleId: roleId,
336
- tenantId,
337
- tenantUserId: currentTenantUser.id
338
- };
339
- }),
340
- { transaction: t }
341
- ));
342
-
343
- await fastify.account.models.tenantUserOrg.bulkCreate(
344
- orgIds.map(orgId => {
345
- return {
346
- tenantOrgId: orgId,
347
- tenantId,
348
- tenantUserId: currentTenantUser.id
349
- };
350
- }),
351
- { transaction: t }
352
- );
353
-
354
- await t.commit();
355
- } catch (e) {
356
- await t.rollback();
357
- throw e;
358
- }
359
- };
360
-
361
- const saveTenantUser = async ({ id, tenantId, roleIds, orgIds, userId, ...tenantUser }) => {
362
- const currentTenantUser = await fastify.account.models.tenantUser.findByPk(id);
363
- if (!currentTenantUser) {
364
- throw new Error('租户用户不存在');
365
- }
366
- if (tenantId !== currentTenantUser.tenantId) {
367
- throw new Error('租户Id和当前租户用户的租户Id不一致');
368
- }
369
- await saveTenantUserInfoValidate({ tenantId, roleIds, orgIds, userId: currentTenantUser.userId });
370
-
371
- const tenantRoleIds = (
372
- await fastify.account.models.tenantUserRole.findAll({
373
- attributes: ['tenantRoleId'],
374
- where: {
375
- tenantId,
376
- tenantUserId: currentTenantUser.id
377
- }
378
- })
379
- ).map(({ tenantRoleId }) => tenantRoleId);
380
-
381
- const tenantOrgIds = (
382
- await fastify.account.models.tenantUserOrg.findAll({
383
- attributes: ['tenantOrgId'],
384
- where: {
385
- tenantId,
386
- tenantUserId: currentTenantUser.id
387
- }
388
- })
389
- ).map(({ tenantOrgId }) => tenantOrgId);
390
-
391
- const t = await fastify.sequelize.instance.transaction();
392
-
393
- try {
394
- ['name', 'avatar', 'phone', 'email', 'description'].forEach(name => {
395
- if (!isNil(tenantUser[name])) {
396
- currentTenantUser[name] = tenantUser[name];
397
- }
398
- });
399
- await currentTenantUser.save({ transaction: t });
400
- // 修改角色
401
- const needDeleteTenantRole = tenantRoleIds.filter(targetId => roleIds.indexOf(targetId) === -1);
402
- const needAddTenantRole = roleIds.filter(targetId => tenantRoleIds.indexOf(targetId) === -1);
403
- await fastify.account.models.tenantUserRole.destroy({
404
- where: {
405
- tenantId,
406
- tenantUserId: currentTenantUser.id,
407
- tenantRoleId: {
408
- [fastify.sequelize.Sequelize.Op.in]: needDeleteTenantRole
409
- }
58
+ name: '系统默认角色',
59
+ tenantId: currentTenant.uuid,
60
+ description: '创建租户时自动生成,可以设置权限,不可更改删除,所有租户用户默认拥有该角色',
61
+ type: 1
410
62
  },
411
- transaction: t
412
- });
413
- await fastify.account.models.tenantUserRole.bulkCreate(
414
- needAddTenantRole.map(tenantRoleId => {
415
- return { tenantId, tenantUserId: currentTenantUser.id, tenantRoleId };
416
- }),
417
63
  { transaction: t }
418
64
  );
419
- //修改组织
420
- const needDeleteTenantOrg = tenantOrgIds.filter(targetId => orgIds.indexOf(targetId) === -1);
421
- const needAddTenantOrg = orgIds.filter(targetId => tenantOrgIds.indexOf(targetId) === -1);
422
- await fastify.account.models.tenantUserOrg.destroy({
423
- where: {
424
- tenantId,
425
- tenantUserId: currentTenantUser.id,
426
- tenantOrgId: {
427
- [fastify.sequelize.Sequelize.Op.in]: needDeleteTenantOrg
428
- }
65
+ await models.tenantOrg.create(
66
+ {
67
+ name: '根组织',
68
+ tenantId: currentTenant.uuid
429
69
  },
430
- transaction: t
431
- });
432
- await fastify.account.models.tenantUserOrg.bulkCreate(
433
- needAddTenantOrg.map(tenantOrgId => {
434
- return { tenantId, tenantUserId: currentTenantUser.id, tenantOrgId };
435
- }),
436
70
  { transaction: t }
437
71
  );
438
72
  await t.commit();
@@ -442,135 +76,57 @@ module.exports = fp(async (fastify, options) => {
442
76
  }
443
77
  };
444
78
 
445
- const deleteTenantUser = async ({ tenantId, tenantUserId }) => {
446
- await getTenantInfo({ id: tenantId });
447
- const tenantUser = await fastify.account.models.tenantUser.findByPk(tenantUserId);
448
- if (!tenantUser) {
449
- throw new Error('租户用户不存在');
450
- }
451
-
452
- const t = await fastify.sequelize.instance.transaction();
453
-
454
- try {
455
- await fastify.account.models.tenantUserOrg.destroy({
456
- where: {
457
- tenantId,
458
- tenantUserId: tenantUser.id
459
- },
460
- transaction: t
461
- });
462
- await fastify.account.models.tenantUserRole.destroy({
463
- where: {
464
- tenantId,
465
- tenantUserId: tenantUser.id
466
- },
467
- transaction: t
468
- });
469
- await tenantUser.destroy({ transaction: t });
470
- await t.commit();
471
- } catch (e) {
472
- await t.rollback();
473
- throw e;
79
+ const getAllTenantList = async ({ filter, perPage, currentPage }) => {
80
+ const queryFilter = {};
81
+ if (filter?.name) {
82
+ queryFilter.name = {
83
+ [fastify.sequelize.Sequelize.Op.like]: `%${filter.name}%`
84
+ };
474
85
  }
475
- };
476
86
 
477
- const closeTenantUser = async ({ tenantId, tenantUserId }) => {
478
- await getTenantInfo({ id: tenantId });
479
- const tenantUser = await fastify.account.models.tenantUser.findByPk(tenantUserId);
480
- if (!tenantUser) {
481
- throw new Error('租户用户不存在');
87
+ if (filter?.serviceStartTime) {
88
+ queryFilter.serviceStartTime = {
89
+ [fastify.sequelize.Sequelize.Op.gt]: filter.serviceStartTime
90
+ };
482
91
  }
483
- tenantUser.status = 12;
484
92
 
485
- await tenantUser.save();
486
- };
487
-
488
- const openTenantUser = async ({ tenantId, tenantUserId }) => {
489
- await getTenantInfo({ id: tenantId });
490
- const tenantUser = await fastify.account.models.tenantUser.findByPk(tenantUserId);
491
- if (!tenantUser) {
492
- throw new Error('租户用户不存在');
93
+ if (filter?.serviceEndTime) {
94
+ queryFilter.serviceEndTime = {
95
+ [fastify.sequelize.Sequelize.Op.lt]: filter.serviceEndTime
96
+ };
493
97
  }
494
- tenantUser.status = 0;
495
98
 
496
- await tenantUser.save();
497
- };
498
-
499
- const getInviteList = async ({ tenantId, filter, currentPage, perPage }) => {
500
- const queryFilter = {};
501
- const { count, rows } = await fastify.account.models.tenantToken.findAndCountAll({
502
- where: Object.assign({}, queryFilter, { tenantId, type: 10 }),
99
+ const { count, rows } = await models.tenant.findAndCountAll({
100
+ where: queryFilter,
503
101
  offset: currentPage * (currentPage - 1),
504
102
  limit: perPage
505
103
  });
506
- return { pageData: rows, totalCount: count };
507
- };
508
-
509
- const generateTenantToken = async ({ type, tenantId, info, tenantUserId }) => {
510
- await getTenantInfo({ id: tenantId });
511
- const token = fastify.jwt.sign({ tenantId });
512
- return await fastify.account.models.tenantToken.create({
513
- token,
514
- tenantId,
515
- info,
516
- tenantUserId,
517
- type
518
- });
519
- };
520
104
 
521
- const decodeTenantToken = async ({ type, tenantId, token }) => {
522
- if (
523
- (await fastify.account.models.tenantToken.count({
524
- where: {
525
- type,
526
- tenantId,
527
- token
105
+ /*const res = await models.tenantUser.findAll({
106
+ attributes: ['tenantId', fastify.sequelize.instance.fn('count', fastify.sequelize.instance.col('tenantId'))],
107
+ where: {
108
+ tenantId: {
109
+ [fastify.sequelize.Sequelize.Op.in]: rows.map(({ id }) => id)
528
110
  }
529
- })) === 0
530
- ) {
531
- throw new Error('token已过期');
532
- }
111
+ },
112
+ group: 'tenantId'
113
+ });*/
533
114
 
534
- return fastify.jwt.decode(token);
535
- };
536
-
537
- const addInviteToken = async ({ info, tenantId, tenantUserId }) => {
538
- return await generateTenantToken({ info, tenantId, tenantUserId, type: 10 });
539
- };
540
-
541
- const deleteInviteToken = async ({ id }) => {
542
- const token = await fastify.account.models.tenantToken.findByPk(id);
543
- if (!token) {
544
- throw new Error('数据不存在');
545
- }
546
-
547
- await token.destroy();
115
+ return {
116
+ pageData: rows.map(item => {
117
+ return Object.assign({}, item.get({ pain: true }), { id: item.uuid });
118
+ }),
119
+ totalCount: count
120
+ };
548
121
  };
549
122
 
550
- fastify.account.services.tenant = {
551
- getUserTenant,
123
+ services.tenant = {
124
+ getTenantInstance,
125
+ getTenant,
552
126
  closeTenant,
553
127
  openTenant,
554
- tenantUserAuthenticate,
555
- getTenantInfo,
556
- getRoleList,
557
- addRole,
558
- saveRole,
559
- removeRole,
560
- addTenantOrg,
561
- deleteTenantOrg,
562
- saveTenantOrg,
563
- getTenantOrgList,
564
- getTenantUserList,
565
- addTenantUser,
566
- saveTenantUser,
567
- deleteTenantUser,
568
- closeTenantUser,
569
- openTenantUser,
570
- getInviteList,
571
- generateTenantToken,
572
- decodeTenantToken,
573
- addInviteToken,
574
- deleteInviteToken
128
+ saveTenant,
129
+ addTenant,
130
+ getAllTenantList
575
131
  };
576
132
  });