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

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 +13 -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 +34 -16
  33. package/libs/services/admin.js +17 -121
  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 +97 -0
  38. package/libs/services/tenant-role.js +108 -0
  39. package/libs/services/tenant-user.js +555 -0
  40. package/libs/services/tenant.js +68 -512
  41. package/libs/services/user.js +69 -30
  42. package/package.json +3 -3
@@ -1,6 +1,7 @@
1
1
  const fp = require('fastify-plugin');
2
2
  const dayjs = require('dayjs');
3
3
  const bcrypt = require('bcryptjs');
4
+ const crypto = require('crypto');
4
5
 
5
6
  function generateRandom6DigitNumber() {
6
7
  const randomNumber = Math.random() * 1000000;
@@ -12,9 +13,10 @@ function userNameIsEmail(username) {
12
13
  }
13
14
 
14
15
  module.exports = fp(async (fastify, options) => {
16
+ const { models, services } = fastify.account;
15
17
  const login = async ({ username, password, ip }) => {
16
18
  const isEmail = userNameIsEmail(username);
17
- const user = await fastify.account.models.user.findOne({
19
+ const user = await models.user.findOne({
18
20
  where: Object.assign(
19
21
  {},
20
22
  isEmail
@@ -38,16 +40,23 @@ module.exports = fp(async (fastify, options) => {
38
40
 
39
41
  await passwordAuthentication({ accountId: user.userAccountId, password });
40
42
 
41
- await fastify.account.models.loginLog.create({
42
- userId: user.id,
43
+ await models.loginLog.create({
44
+ userId: user.uuid,
43
45
  ip
44
46
  });
45
47
 
46
- return fastify.jwt.sign({ payload: { id: user.id } });
48
+ return {
49
+ token: fastify.jwt.sign({ payload: { id: user.uuid } }),
50
+ user: Object.assign({}, user.get({ plain: true }), { id: user.uuid })
51
+ };
47
52
  };
48
53
 
49
54
  const passwordAuthentication = async ({ accountId, password }) => {
50
- const userAccount = await fastify.account.models.userAccount.findByPk(accountId);
55
+ const userAccount = await models.userAccount.findOne({
56
+ where: {
57
+ uuid: accountId
58
+ }
59
+ });
51
60
  if (!userAccount) {
52
61
  throw new Error('账号不存在');
53
62
  }
@@ -68,23 +77,31 @@ module.exports = fp(async (fastify, options) => {
68
77
  };
69
78
  };
70
79
 
80
+ const md5 = value => {
81
+ const hash = crypto.createHash('md5');
82
+ hash.update(value);
83
+ return hash.digest('hex');
84
+ };
85
+
71
86
  const resetPassword = async ({ userId, password }) => {
72
- const userInfo = await fastify.account.models.user.findByPk(userId);
87
+ const userInfo = await models.user.findOne({
88
+ where: { uuid: userId }
89
+ });
73
90
  if (!userInfo) {
74
91
  throw new Error('用户不存在');
75
92
  }
76
- const account = await fastify.account.models.userAccount.create(
93
+ const account = await models.userAccount.create(
77
94
  Object.assign({}, await passwordEncryption(password), {
78
95
  belongToUserId: userId
79
96
  })
80
97
  );
81
98
 
82
- await userInfo.update({ userAccountId: account.id });
99
+ await userInfo.update({ userAccountId: account.uuid });
83
100
  };
84
101
 
85
102
  const register = async ({ avatar, nickname, gender, birthday, description, phone, email, code, password, status, invitationCode }) => {
86
103
  const type = phone ? 0 : 1;
87
- const verificationCode = await fastify.account.models.verificationCode.findOne({
104
+ const verificationCode = await models.verificationCode.findOne({
88
105
  where: {
89
106
  name: type === 0 ? phone : email,
90
107
  type,
@@ -99,7 +116,7 @@ module.exports = fp(async (fastify, options) => {
99
116
  verificationCode.status = 2;
100
117
  await verificationCode.save();
101
118
 
102
- return await fastify.account.services.user.addUser({
119
+ return await services.user.addUser({
103
120
  avatar,
104
121
  nickname,
105
122
  gender,
@@ -117,7 +134,7 @@ module.exports = fp(async (fastify, options) => {
117
134
 
118
135
  // 这里写发送逻辑
119
136
 
120
- await fastify.account.models.verificationCode.update(
137
+ await models.verificationCode.update(
121
138
  {
122
139
  status: 2
123
140
  },
@@ -130,7 +147,7 @@ module.exports = fp(async (fastify, options) => {
130
147
  }
131
148
  );
132
149
 
133
- await fastify.account.models.verificationCode.create({
150
+ await models.verificationCode.create({
134
151
  name: email,
135
152
  type: 1,
136
153
  code
@@ -140,7 +157,7 @@ module.exports = fp(async (fastify, options) => {
140
157
  };
141
158
 
142
159
  const verificationCodeValidate = async ({ name, type, code }) => {
143
- const verificationCode = await fastify.account.models.verificationCode.findOne({
160
+ const verificationCode = await models.verificationCode.findOne({
144
161
  where: {
145
162
  name,
146
163
  type,
@@ -165,7 +182,7 @@ module.exports = fp(async (fastify, options) => {
165
182
 
166
183
  // 这里写发送逻辑
167
184
 
168
- await fastify.account.models.verificationCode.update(
185
+ await models.verificationCode.update(
169
186
  {
170
187
  status: 2
171
188
  },
@@ -178,7 +195,7 @@ module.exports = fp(async (fastify, options) => {
178
195
  }
179
196
  );
180
197
 
181
- await fastify.account.models.verificationCode.create({
198
+ await models.verificationCode.create({
182
199
  name: phone,
183
200
  type: 0,
184
201
  code
@@ -187,7 +204,8 @@ module.exports = fp(async (fastify, options) => {
187
204
  return code;
188
205
  };
189
206
 
190
- fastify.account.services.account = {
207
+ services.account = {
208
+ md5,
191
209
  login,
192
210
  register,
193
211
  sendEmailCode,
@@ -6,31 +6,30 @@ const ROLE = {
6
6
  };
7
7
 
8
8
  module.exports = fp(async (fastify, options) => {
9
+ const { models, services } = fastify.account;
9
10
  const initSuperAdmin = async user => {
10
- if ((await fastify.account.models.adminRole.count()) > 0) {
11
+ if ((await models.adminRole.count()) > 0) {
11
12
  throw new Error('系统已经初始化完成,不能执行该操作');
12
13
  }
13
- await fastify.account.models.adminRole.create({
14
+ await models.adminRole.create({
14
15
  userId: user.id,
15
16
  role: ROLE['SuperAdmin']
16
17
  });
17
18
  };
18
19
 
19
- const superAdminAuthenticate = async user => {
20
- if (
21
- (await fastify.account.models.adminRole.count({
20
+ const checkIsSuperAdmin = async user => {
21
+ return (
22
+ (await models.adminRole.count({
22
23
  where: {
23
24
  userId: user.id,
24
25
  role: ROLE['SuperAdmin']
25
26
  }
26
- })) === 0
27
- ) {
28
- throw new Error('不能执行该操作,需要超级管理员权限');
29
- }
27
+ })) > 0
28
+ );
30
29
  };
31
30
 
32
31
  const addUser = async ({ avatar, nickname, phone, email, password, description }) => {
33
- return await fastify.account.services.user.addUser({
32
+ return await services.user.addUser({
34
33
  avatar,
35
34
  nickname,
36
35
  phone,
@@ -42,9 +41,9 @@ module.exports = fp(async (fastify, options) => {
42
41
  };
43
42
 
44
43
  const setSuperAdmin = async targetUser => {
45
- const user = await fastify.account.services.user.getUserInfo(targetUser);
44
+ const user = await services.user.getUserInfo(targetUser);
46
45
  if (
47
- (await fastify.account.models.adminRole.count({
46
+ (await models.adminRole.count({
48
47
  where: {
49
48
  userId: user.id,
50
49
  role: ROLE['SuperAdmin']
@@ -54,130 +53,27 @@ module.exports = fp(async (fastify, options) => {
54
53
  throw new Error('当前用户已经是超级管理员');
55
54
  }
56
55
 
57
- await fastify.account.models.adminRole.create({
56
+ await models.adminRole.create({
58
57
  userId: user.id,
59
58
  role: ROLE['SuperAdmin']
60
59
  });
61
60
  };
62
61
 
63
- const getAllUserList = async ({ filter, perPage, currentPage }) => {
64
- const { count, rows } = await fastify.account.models.user.findAndCountAll({
65
- include: [
66
- {
67
- attributes: ['role'],
68
- model: fastify.account.models.adminRole
69
- },
70
- {
71
- model: fastify.account.models.tenant
72
- }
73
- ]
74
- });
75
- return {
76
- pageData: rows,
77
- totalCount: count
78
- };
79
- };
80
-
81
- const getAllTenantList = async ({ filter, perPage, currentPage }) => {
82
- const queryFilter = {};
83
- if (filter?.name) {
84
- queryFilter.name = {
85
- [fastify.sequelize.Sequelize.Op.like]: `%${filter.name}%`
86
- };
87
- }
88
-
89
- if (filter?.serviceStartTime) {
90
- queryFilter.serviceStartTime = {
91
- [fastify.sequelize.Sequelize.Op.gt]: filter.serviceStartTime
92
- };
93
- }
94
-
95
- if (filter?.serviceEndTime) {
96
- queryFilter.serviceEndTime = {
97
- [fastify.sequelize.Sequelize.Op.lt]: filter.serviceEndTime
98
- };
99
- }
100
-
101
- const { count, rows } = await fastify.account.models.tenant.findAndCountAll({
102
- where: queryFilter,
103
- offset: currentPage * (currentPage - 1),
104
- limit: perPage
105
- });
106
-
107
- const res = await fastify.account.models.tenantUser.findAll({
108
- attributes: ['tenantId', fastify.sequelize.instance.fn('count', fastify.sequelize.instance.col('tenantId'))],
109
- where: {
110
- tenantId: {
111
- [fastify.sequelize.Sequelize.Op.in]: rows.map(({ id }) => id)
112
- }
113
- },
114
- group: 'tenantId'
115
- });
116
-
117
- return {
118
- pageData: rows,
119
- totalCount: count
120
- };
121
- };
122
-
123
- const addTenant = async tenant => {
124
- if (await fastify.account.models.tenant.count({ where: { name: tenant.name } })) {
125
- throw new Error('租户名称不能重复');
126
- }
127
-
128
- const t = await fastify.sequelize.instance.transaction();
129
- try {
130
- const currentTenant = await fastify.account.models.tenant.create(tenant);
131
- await fastify.account.models.tenantRole.create(
132
- {
133
- name: '系统默认角色',
134
- tenantId: currentTenant.id,
135
- description: '创建租户时自动生成,可以设置权限,不可更改删除,所有租户用户默认拥有该角色',
136
- type: 1
137
- },
138
- { transaction: t }
139
- );
140
- await fastify.account.models.tenantOrg.create(
141
- {
142
- name: '根组织',
143
- tenantId: currentTenant.id
144
- },
145
- { transaction: t }
146
- );
147
- await t.commit();
148
- } catch (e) {
149
- await t.rollback();
150
- throw e;
151
- }
152
- };
153
-
154
- const saveTenant = async tenant => {
155
- const currentTenant = await fastify.account.models.tenant.findByPk(tenant.id);
156
- if (!currentTenant) {
157
- throw new Error('租户不存在,请刷新以后重试');
158
- }
159
- await currentTenant.update(tenant);
160
- };
161
-
162
62
  const generateTenantAdminVerifyCode = async () => {};
163
63
 
164
64
  const verifyTenantAdmin = async () => {};
165
65
 
166
66
  const resetUserPassword = async ({ userId, password }) => {
167
- await fastify.account.services.account.resetPassword({ userId, password });
67
+ await services.account.resetPassword({ userId, password });
168
68
  };
169
69
 
170
- fastify.account.services.admin = {
70
+ services.admin = {
171
71
  initSuperAdmin,
172
72
  setSuperAdmin,
173
- getAllUserList,
174
- getAllTenantList,
175
- addTenant,
176
- saveTenant,
177
- superAdminAuthenticate,
73
+ checkIsSuperAdmin,
178
74
  generateTenantAdminVerifyCode,
179
75
  verifyTenantAdmin,
180
- resetUserPassword,
181
- addUser
76
+ addUser,
77
+ resetUserPassword
182
78
  };
183
79
  });
@@ -0,0 +1,151 @@
1
+ const fp = require('fastify-plugin');
2
+ const isNil = require('lodash/isNil');
3
+ module.exports = fp(async (fastify, options) => {
4
+ const { models, services } = fastify.account;
5
+
6
+ const getApplicationInstance = async ({ id }) => {
7
+ if (!id) {
8
+ throw new Error('应用Id不能为空');
9
+ }
10
+ const application = await models.application.findOne({
11
+ where: {
12
+ uuid: id
13
+ }
14
+ });
15
+ if (!application) {
16
+ throw new Error('应用不存在');
17
+ }
18
+
19
+ return application;
20
+ };
21
+
22
+ const getApplication = async ({ id }) => {
23
+ const application = await getApplicationInstance({ id });
24
+ return Object.assign({}, application.get({ plain: true }), {
25
+ id: application.uuid
26
+ });
27
+ };
28
+
29
+ const addApplication = async application => {
30
+ const currentApplication = await models.application.create(application);
31
+ return Object.assign({}, currentApplication.get({ plain: true }), {
32
+ id: currentApplication.uuid
33
+ });
34
+ };
35
+
36
+ const saveApplication = async ({ id, ...others }) => {
37
+ const application = await getApplicationInstance({ id });
38
+ ['name', 'code', 'avatar', 'url', 'description'].forEach(name => {
39
+ if (!isNil(others[name])) {
40
+ application[name] = others[name];
41
+ }
42
+ });
43
+
44
+ await application.save();
45
+ };
46
+
47
+ const deleteApplication = async ({ id }) => {
48
+ const application = await getApplicationInstance({ id });
49
+ if (
50
+ (await models.tenantApplication.count({
51
+ where: {
52
+ applicationId: application.uuid
53
+ }
54
+ })) > 0
55
+ ) {
56
+ throw new Error('应用已经开放给其他租户使用,不能删除');
57
+ }
58
+
59
+ const permissionIdList = (
60
+ await models.permission.findAll({
61
+ where: { applicationId: application.uuid }
62
+ })
63
+ ).map(({ id }) => id);
64
+
65
+ const t = await fastify.sequelize.instance.transaction();
66
+
67
+ try {
68
+ await models.tenantPermission.destroy(
69
+ {
70
+ where: {
71
+ permissionId: {
72
+ [fastify.sequelize.Sequelize.Op.in]: permissionIdList
73
+ }
74
+ }
75
+ },
76
+ { transaction: t }
77
+ );
78
+
79
+ await models.tenantRolePermission.destroy(
80
+ {
81
+ where: {
82
+ permissionId: {
83
+ [fastify.sequelize.Sequelize.Op.in]: permissionIdList
84
+ }
85
+ }
86
+ },
87
+ { transaction: t }
88
+ );
89
+
90
+ await models.permission.destroy({
91
+ where: {
92
+ applicationId: application.uuid
93
+ },
94
+ transaction: t
95
+ });
96
+ await application.destroy({ transaction: t });
97
+ await t.commit();
98
+ } catch (e) {
99
+ await t.rollback();
100
+ throw e;
101
+ }
102
+ };
103
+
104
+ const getApplicationList = async ({ tenantId }) => {
105
+ const query = {};
106
+ if (tenantId) {
107
+ const tenant = await services.tenant.getTenant({ id: tenantId });
108
+ if (!tenant) {
109
+ throw new Error('租户不存在');
110
+ }
111
+ const tenantApplications = await models.tenantApplication.findAll({
112
+ where: { tenantId }
113
+ });
114
+ query.uuid = {
115
+ [fastify.sequelize.Sequelize.Op.in]: tenantApplications.map(({ applicationId }) => applicationId)
116
+ };
117
+ }
118
+ const list = await models.application.findAll({
119
+ where: query
120
+ });
121
+
122
+ return list.map(item => {
123
+ return Object.assign({}, item.get({ plain: true }), {
124
+ id: item.uuid
125
+ });
126
+ });
127
+ };
128
+
129
+ const getApplicationListByIds = async ({ ids }) => {
130
+ const applications = await models.application.findAll({
131
+ where: {
132
+ uuid: {
133
+ [fastify.sequelize.Sequelize.Op.in]: ids
134
+ }
135
+ }
136
+ });
137
+
138
+ return applications.map(item => {
139
+ return Object.assign({}, item.get({ plain: true }), { id: item.uuid });
140
+ });
141
+ };
142
+
143
+ services.application = {
144
+ addApplication,
145
+ getApplication,
146
+ saveApplication,
147
+ deleteApplication,
148
+ getApplicationList,
149
+ getApplicationListByIds
150
+ };
151
+ });