@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.
@@ -20,50 +20,4 @@ module.exports = fp(async (fastify, options) => {
20
20
  return request.tenantInfo;
21
21
  }
22
22
  );
23
-
24
- fastify.get(
25
- `${options.prefix}/tenant/getTenantUserList`,
26
- {
27
- onRequest: [authenticate.user, authenticate.tenant],
28
- schema: {
29
- query: {
30
- type: 'object',
31
- properties: {
32
- filter: {
33
- type: 'object',
34
- properties: {
35
- name: { type: 'string' }
36
- }
37
- },
38
- currentPage: { type: 'number' },
39
- perPage: { type: 'number' }
40
- }
41
- }
42
- }
43
- },
44
- async request => {
45
- const { id: tenantId } = request.tenantInfo.tenant;
46
- const { filter, currentPage, perPage } = Object.assign(
47
- {},
48
- {
49
- filter: {},
50
- currentPage: 1,
51
- perPage: 20
52
- },
53
- request.query
54
- );
55
- return await services.tenantUser.getTenantUserList({ tenantId, currentPage, perPage, filter });
56
- }
57
- );
58
-
59
- fastify.get(
60
- `${options.prefix}/tenant/orgList`,
61
- {
62
- onRequest: [authenticate.user, authenticate.tenant]
63
- },
64
- async request => {
65
- const { id: tenantId } = request.tenantInfo.tenant;
66
- return await services.tenantOrg.getTenantOrgList({ tenantId });
67
- }
68
- );
69
23
  });
@@ -0,0 +1,65 @@
1
+ const fp = require('fastify-plugin');
2
+
3
+ module.exports = fp(async (fastify, options) => {
4
+ const { authenticate, services } = fastify.account;
5
+ fastify.post(
6
+ `${options.prefix}/tenant/addOrg`,
7
+ {
8
+ onRequest: [authenticate.user, authenticate.tenant],
9
+ required: ['name', 'pid'],
10
+ properties: {
11
+ name: { type: 'string' },
12
+ pid: { type: 'number' }
13
+ }
14
+ },
15
+ async request => {
16
+ const { id: tenantId } = request.tenantInfo.tenant;
17
+ return await services.tenantOrg.addTenantOrg(Object.assign({}, request.body, { tenantId }));
18
+ }
19
+ );
20
+
21
+ fastify.get(
22
+ `${options.prefix}/tenant/orgList`,
23
+ {
24
+ onRequest: [authenticate.user, authenticate.tenant],
25
+ schema: {}
26
+ },
27
+ async request => {
28
+ const { id: tenantId } = request.tenantInfo.tenant;
29
+ return await services.tenantOrg.getTenantOrgList({ tenantId });
30
+ }
31
+ );
32
+
33
+ fastify.post(
34
+ `${options.prefix}/tenant/editOrg`,
35
+ {
36
+ onRequest: [authenticate.user, authenticate.tenant],
37
+ required: ['name', 'pid'],
38
+ properties: {
39
+ name: { type: 'string' },
40
+ pid: { type: 'number' }
41
+ }
42
+ },
43
+ async request => {
44
+ const { id: tenantId } = request.tenantInfo.tenant;
45
+ await services.tenantOrg.saveTenantOrg(Object.assign({}, request.body, { tenantId }));
46
+ return {};
47
+ }
48
+ );
49
+
50
+ fastify.post(
51
+ `${options.prefix}/tenant/removeOrg`,
52
+ {
53
+ onRequest: [authenticate.user, authenticate.tenant],
54
+ required: ['id'],
55
+ properties: {
56
+ id: { type: 'number' }
57
+ }
58
+ },
59
+ async request => {
60
+ const { id: tenantId } = request.tenantInfo.tenant;
61
+ await services.tenantOrg.deleteTenantOrg(Object.assign({}, request.body, { tenantId }));
62
+ return {};
63
+ }
64
+ );
65
+ });
@@ -0,0 +1,219 @@
1
+ const fp = require('fastify-plugin');
2
+
3
+ module.exports = fp(async (fastify, options) => {
4
+ const { authenticate, services } = fastify.account;
5
+ fastify.get(
6
+ `${options.prefix}/tenant/getRoleList`,
7
+ {
8
+ onRequest: [authenticate.user, authenticate.tenant],
9
+ schema: {
10
+ query: {
11
+ type: 'object',
12
+ properties: {
13
+ perPage: { type: 'number' },
14
+ currentPage: { type: 'number' },
15
+ filter: {
16
+ type: 'object',
17
+ properties: {
18
+ type: { type: 'number' }
19
+ }
20
+ }
21
+ }
22
+ }
23
+ }
24
+ },
25
+ async request => {
26
+ const { id: tenantId } = request.tenantInfo.tenant;
27
+ const { filter, perPage, currentPage } = Object.assign(
28
+ {
29
+ perPage: 20,
30
+ currentPage: 1,
31
+ filter: {}
32
+ },
33
+ request.query
34
+ );
35
+ return await services.tenantRole.getTenantRoleList({ tenantId, perPage, currentPage, filter });
36
+ }
37
+ );
38
+
39
+ fastify.post(
40
+ `${options.prefix}/tenant/addRole`,
41
+ {
42
+ onRequest: [authenticate.user, authenticate.tenant],
43
+ schema: {
44
+ body: {
45
+ type: 'object',
46
+ required: ['name'],
47
+ properties: {
48
+ name: { type: 'string' },
49
+ description: { type: 'string' }
50
+ }
51
+ }
52
+ }
53
+ },
54
+ async request => {
55
+ const { id: tenantId } = request.tenantInfo.tenant;
56
+ const { name, description } = request.body;
57
+ await services.tenantRole.addTenantRole({ tenantId, name, description });
58
+
59
+ return {};
60
+ }
61
+ );
62
+
63
+ fastify.post(
64
+ `${options.prefix}/tenant/saveRole`,
65
+ {
66
+ onRequest: [authenticate.user, authenticate.tenant],
67
+ schema: {
68
+ body: {
69
+ type: 'object',
70
+ required: ['name', 'id'],
71
+ properties: {
72
+ id: { type: 'number' },
73
+ name: { type: 'string' },
74
+ description: { type: 'string' }
75
+ }
76
+ }
77
+ }
78
+ },
79
+ async request => {
80
+ const { id: tenantId } = request.tenantInfo.tenant;
81
+ await services.tenantRole.saveTenantRole(Object.assign({}, request.body, { tenantId }));
82
+ return {};
83
+ }
84
+ );
85
+
86
+ fastify.post(
87
+ `${options.prefix}/tenant/removeRole`,
88
+ {
89
+ onRequest: [authenticate.user, authenticate.tenant],
90
+ schema: {
91
+ body: {
92
+ type: 'object',
93
+ required: ['id'],
94
+ properties: {
95
+ id: { type: 'number' }
96
+ }
97
+ }
98
+ }
99
+ },
100
+ async request => {
101
+ const { id: tenantId } = request.tenantInfo.tenant;
102
+ const { id } = request.body;
103
+ await services.tenantRole.removeTenantRole({ id, tenantId });
104
+ return {};
105
+ }
106
+ );
107
+
108
+ fastify.get(
109
+ `${options.prefix}/tenant/getRolePermissionList`,
110
+ {
111
+ onRequest: [authenticate.user, authenticate.tenant],
112
+ schema: {
113
+ query: {
114
+ type: 'object',
115
+ required: ['id'],
116
+ properties: {
117
+ id: { type: 'number' }
118
+ }
119
+ }
120
+ }
121
+ },
122
+ async request => {
123
+ const { id: tenantId } = request.tenantInfo.tenant;
124
+ const { id } = request.query;
125
+ return await services.permission.getRolePermissionList({ roleId: id, tenantId });
126
+ }
127
+ );
128
+
129
+ fastify.post(
130
+ `${options.prefix}/tenant/saveRolePermissionList`,
131
+ {
132
+ onRequest: [authenticate.user, authenticate.tenant],
133
+ schema: {
134
+ roleId: { type: 'string' },
135
+ applications: {
136
+ type: 'array',
137
+ items: { type: 'string' }
138
+ },
139
+ permissions: {
140
+ type: 'array',
141
+ items: { type: 'number' }
142
+ }
143
+ }
144
+ },
145
+ async request => {
146
+ const { id: tenantId } = request.tenantInfo.tenant;
147
+ await services.permission.saveRolePermissionList(Object.assign({}, request.body, { tenantId }));
148
+ return {};
149
+ }
150
+ );
151
+
152
+ fastify.get(
153
+ `${options.prefix}/tenant/getApplicationList`,
154
+ {
155
+ onRequest: [authenticate.user, authenticate.tenant],
156
+ schema: {
157
+ tags: ['租户管理-权限'],
158
+ summary: '获取应用列表'
159
+ }
160
+ },
161
+ async request => {
162
+ const { id: tenantId } = request.tenantInfo.tenant;
163
+ const appName = request.headers['x-app-name'];
164
+ return await services.application.getApplicationList({ tenantId, appName });
165
+ }
166
+ );
167
+
168
+ fastify.get(
169
+ `${options.prefix}/tenant/getPermissionList`,
170
+ {
171
+ onRequest: [authenticate.user, authenticate.tenant],
172
+ schema: {
173
+ tags: ['租户管理-权限'],
174
+ summary: '获取应用权限列表',
175
+ query: {
176
+ type: 'object',
177
+ required: ['applicationId'],
178
+ properties: {
179
+ applicationId: { type: 'string' }
180
+ }
181
+ },
182
+ response: {
183
+ 200: {
184
+ content: {
185
+ 'application/json': {
186
+ schema: {
187
+ type: 'array',
188
+ items: {
189
+ type: 'object',
190
+ properties: {
191
+ id: { type: 'number' },
192
+ code: { type: 'string' },
193
+ name: { type: 'string' },
194
+ isModule: { type: 'number' },
195
+ isMust: { type: 'number' },
196
+ type: { type: 'number' },
197
+ pid: { type: 'number' },
198
+ paths: { type: 'array', items: { type: 'number' } },
199
+ description: { type: 'string' },
200
+ status: { type: 'number' },
201
+ createdAt: { type: 'string' },
202
+ updatedAt: { type: 'string' },
203
+ deletedAt: { type: 'string' }
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+ },
213
+ async request => {
214
+ const { id: tenantId } = request.tenantInfo.tenant;
215
+ const { applicationId } = request.query;
216
+ return await services.permission.getPermissionList({ applicationId, tenantId });
217
+ }
218
+ );
219
+ });
@@ -0,0 +1,169 @@
1
+ const fp = require('fastify-plugin');
2
+
3
+ module.exports = fp(async (fastify, options) => {
4
+ const { authenticate, services } = fastify.account;
5
+
6
+ fastify.get(
7
+ `${options.prefix}/tenant/getTenantUserList`,
8
+ {
9
+ onRequest: [authenticate.user, authenticate.tenant],
10
+ schema: {
11
+ query: {
12
+ type: 'object',
13
+ properties: {
14
+ filter: {
15
+ type: 'object',
16
+ properties: {
17
+ name: { type: 'string' }
18
+ }
19
+ },
20
+ currentPage: { type: 'number' },
21
+ perPage: { type: 'number' }
22
+ }
23
+ }
24
+ }
25
+ },
26
+ async request => {
27
+ const { id: tenantId } = request.tenantInfo.tenant;
28
+ const { filter, currentPage, perPage } = Object.assign(
29
+ {},
30
+ {
31
+ filter: {},
32
+ currentPage: 1,
33
+ perPage: 20
34
+ },
35
+ request.query
36
+ );
37
+ return await services.tenantUser.getTenantUserList({ tenantId, currentPage, perPage, filter });
38
+ }
39
+ );
40
+
41
+ fastify.post(
42
+ `${options.prefix}/tenant/addTenantUser`,
43
+ {
44
+ onRequest: [authenticate.user, authenticate.tenant],
45
+ schema: {
46
+ body: {
47
+ type: 'object',
48
+ required: ['userId', 'name'],
49
+ properties: {
50
+ roleIds: { type: 'array', items: { type: 'number' }, default: [] },
51
+ orgIds: {
52
+ type: 'array',
53
+ items: { type: 'number' },
54
+ default: []
55
+ },
56
+ userId: { type: 'string' },
57
+ name: { type: 'string' },
58
+ avatar: { type: 'string' },
59
+ phone: { type: 'string' },
60
+ email: { type: 'string' },
61
+ description: { type: 'string' }
62
+ }
63
+ }
64
+ }
65
+ },
66
+ async request => {
67
+ const { id: tenantId } = request.tenantInfo.tenant;
68
+ await services.tenantUser.addTenantUser(Object.assign({}, request.body, { tenantId }));
69
+ return {};
70
+ }
71
+ );
72
+
73
+ fastify.post(
74
+ `${options.prefix}/tenant/saveTenantUser`,
75
+ {
76
+ onRequest: [authenticate.user, authenticate.tenant],
77
+ schema: {
78
+ body: {
79
+ type: 'object',
80
+ required: ['name'],
81
+ properties: {
82
+ roleIds: { type: 'array', items: { type: 'number' }, default: [] },
83
+ orgIds: {
84
+ type: 'array',
85
+ items: { type: 'number' },
86
+ default: []
87
+ },
88
+ name: { type: 'string' },
89
+ avatar: { type: 'string' },
90
+ phone: { type: 'string' },
91
+ email: { type: 'string' },
92
+ description: { type: 'string' }
93
+ }
94
+ }
95
+ }
96
+ },
97
+ async request => {
98
+ const { id: tenantId } = request.tenantInfo.tenant;
99
+ await services.tenantUser.saveTenantUser(Object.assign({}, request.body, { tenantId }));
100
+ return {};
101
+ }
102
+ );
103
+
104
+ fastify.post(
105
+ `${options.prefix}/tenant/deleteTenantUser`,
106
+ {
107
+ onRequest: [authenticate.user, authenticate.tenant],
108
+ schema: {
109
+ body: {
110
+ type: 'object',
111
+ required: ['tenantUserId'],
112
+ properties: {
113
+ tenantUserId: { type: 'string' }
114
+ }
115
+ }
116
+ }
117
+ },
118
+ async request => {
119
+ const { id: tenantId } = request.tenantInfo.tenant;
120
+ const { tenantUserId } = request.body;
121
+ await services.tenantUser.deleteTenantUser({ tenantId, tenantUserId });
122
+ return {};
123
+ }
124
+ );
125
+
126
+ fastify.post(
127
+ `${options.prefix}/tenant/closeTenantUser`,
128
+ {
129
+ onRequest: [authenticate.user, authenticate.tenant],
130
+ schema: {
131
+ body: {
132
+ type: 'object',
133
+ required: ['tenantUserId'],
134
+ properties: {
135
+ tenantUserId: { type: 'string' }
136
+ }
137
+ }
138
+ }
139
+ },
140
+ async request => {
141
+ const { id: tenantId } = request.tenantInfo.tenant;
142
+ const { tenantUserId } = request.body;
143
+ await services.tenantUser.closeTenantUser({ tenantId, tenantUserId });
144
+ return {};
145
+ }
146
+ );
147
+
148
+ fastify.post(
149
+ `${options.prefix}/tenant/openTenantUser`,
150
+ {
151
+ onRequest: [authenticate.user, authenticate.tenant],
152
+ schema: {
153
+ body: {
154
+ type: 'object',
155
+ required: ['tenantUserId'],
156
+ properties: {
157
+ tenantUserId: { type: 'string' }
158
+ }
159
+ }
160
+ }
161
+ },
162
+ async request => {
163
+ const { id: tenantId } = request.tenantInfo.tenant;
164
+ const { tenantUserId } = request.body;
165
+ await services.tenantUser.openTenantUser({ tenantId, tenantUserId });
166
+ return {};
167
+ }
168
+ );
169
+ });
@@ -0,0 +1,25 @@
1
+ module.exports = ({ DataTypes }) => {
2
+ return {
3
+ model: {
4
+ tenantId: {
5
+ type: DataTypes.UUID,
6
+ allowNull: false
7
+ },
8
+ name: {
9
+ type: DataTypes.STRING
10
+ },
11
+ shortName: {
12
+ type: DataTypes.STRING
13
+ },
14
+ themeColor: {
15
+ type: DataTypes.STRING
16
+ },
17
+ logo: {
18
+ type: DataTypes.STRING
19
+ },
20
+ description: {
21
+ type: DataTypes.TEXT
22
+ }
23
+ }
24
+ };
25
+ };
@@ -5,7 +5,13 @@ module.exports = ({ DataTypes }) => {
5
5
  type: DataTypes.UUID,
6
6
  allowNull: false
7
7
  },
8
- ip: DataTypes.STRING
8
+ ip: DataTypes.STRING,
9
+ currentTenantId: {
10
+ type: DataTypes.UUID
11
+ },
12
+ applicationId: {
13
+ type: DataTypes.UUID
14
+ }
9
15
  }
10
16
  };
11
17
  };
@@ -0,0 +1,27 @@
1
+ module.exports = ({ DataTypes }) => {
2
+ return {
3
+ model: {
4
+ userId: {
5
+ type: DataTypes.UUID, allowNull: false
6
+ }, tenantId: {
7
+ type: DataTypes.UUID
8
+ }, type: {
9
+ type: DataTypes.STRING, comment: 'user,tenant,admin'
10
+ }, applicationId: {
11
+ type: DataTypes.UUID
12
+ }, action: {
13
+ type: DataTypes.TEXT
14
+ }, summary: {
15
+ type: DataTypes.TEXT
16
+ }
17
+ }, options: {
18
+ indexes: [{
19
+ fields: ['user_id', 'type']
20
+ }, {
21
+ fields: ['tenant_id', 'type']
22
+ }, {
23
+ fields: ['action', 'type']
24
+ }]
25
+ }
26
+ };
27
+ };
@@ -14,7 +14,7 @@ function userNameIsEmail(username) {
14
14
 
15
15
  module.exports = fp(async (fastify, options) => {
16
16
  const { models, services } = fastify.account;
17
- const login = async ({ username, password, ip }) => {
17
+ const login = async ({ username, password, ip, appName }) => {
18
18
  const isEmail = userNameIsEmail(username);
19
19
  const user = await models.user.findOne({
20
20
  where: Object.assign(
@@ -40,9 +40,13 @@ module.exports = fp(async (fastify, options) => {
40
40
 
41
41
  await passwordAuthentication({ accountId: user.userAccountId, password });
42
42
 
43
+ const application = appName && (await services.application.getApplicationByCode({ code: appName }));
44
+
43
45
  await models.loginLog.create({
44
46
  userId: user.uuid,
45
- ip
47
+ ip,
48
+ currentTenantId: user.currentTenantId,
49
+ applicationId: application?.id
46
50
  });
47
51
 
48
52
  return {
@@ -51,22 +55,25 @@ module.exports = fp(async (fastify, options) => {
51
55
  };
52
56
  };
53
57
 
58
+ const resetPassword = async ({ password, userId }) => {
59
+ const userInfo = await services.user.getUserInstance({ id: userId });
60
+ const account = await models.userAccount.create(
61
+ Object.assign({}, await passwordEncryption(password), {
62
+ belongToUserId: userInfo.uuid
63
+ })
64
+ );
65
+
66
+ await userInfo.update({ userAccountId: account.uuid });
67
+ };
68
+
69
+ const resetPasswordByToken = async ({ password, token }) => {
70
+ const { name } = await verificationJWTCodeValidate({ token });
71
+ const user = await services.user.getUserInstanceByName({ name, status: [0, 1] });
72
+ await resetPassword({ password, userId: user.uuid });
73
+ };
74
+
54
75
  const modifyPassword = async ({ email, phone, oldPwd, newPwd }) => {
55
- const user = await models.user.findOne({
56
- where: Object.assign(
57
- {},
58
- email
59
- ? {
60
- email
61
- }
62
- : {
63
- phone
64
- },
65
- {
66
- status: 1
67
- }
68
- )
69
- });
76
+ const user = await services.user.getUserInstanceByName({ name: email || phone, status: 1 });
70
77
  if (!user) {
71
78
  throw new Error('新用户密码只能初始化一次');
72
79
  }
@@ -111,30 +118,9 @@ module.exports = fp(async (fastify, options) => {
111
118
  return hash.digest('hex');
112
119
  };
113
120
 
114
- const resetPassword = async ({ password, token }) => {
115
- const { name } = await verificationJWTCodeValidate({ token });
116
-
117
- const isEmail = userNameIsEmail(name);
118
-
119
- const userInfo = await models.user.findOne({
120
- where: isEmail ? { email: name } : { phone: name }
121
- });
122
- if (!userInfo) {
123
- throw new Error('用户不存在');
124
- }
125
- const account = await models.userAccount.create(
126
- Object.assign({}, await passwordEncryption(password), {
127
- belongToUserId: userInfo.uuid
128
- })
129
- );
130
-
131
- await userInfo.update({ userAccountId: account.uuid });
132
- };
133
-
134
121
  const register = async ({ avatar, nickname, gender, birthday, description, phone, email, code, password, status, invitationCode }) => {
135
122
  const type = phone ? 0 : 1;
136
-
137
- if (!(await verificationCodeValidate({ name: type === 0 ? phone : email, type, code }))) {
123
+ if (!(await verificationCodeValidate({ name: type === 0 ? phone : email, type: 0, code }))) {
138
124
  throw new Error('验证码不正确或者已经过期');
139
125
  }
140
126
 
@@ -173,9 +159,12 @@ module.exports = fp(async (fastify, options) => {
173
159
  return code;
174
160
  };
175
161
 
176
- const sendVerificationCode = async ({ name, type, messageType }) => {
162
+ const sendVerificationCode = async ({ name, type }) => {
163
+ // messageType: 0:短信验证码,1:邮件验证码 type: 0:注册,2:登录,4:验证租户管理员,5:忘记密码
177
164
  const code = await generateVerificationCode({ name, type });
165
+ const isEmail = userNameIsEmail(name);
178
166
  // 这里写发送逻辑
167
+ await options.sendMessage({ name, type, messageType: isEmail ? 1 : 0, props: { code } });
179
168
  return code;
180
169
  };
181
170
 
@@ -200,10 +189,12 @@ module.exports = fp(async (fastify, options) => {
200
189
  return isPass;
201
190
  };
202
191
 
203
- const sendJWTVerificationCode = async ({ name, type, messageType }) => {
192
+ const sendJWTVerificationCode = async ({ name, type }) => {
204
193
  const code = await generateVerificationCode({ name, type });
205
194
  const token = fastify.jwt.sign({ name, type, code });
195
+ const isEmail = userNameIsEmail(name);
206
196
  // 这里写发送逻辑
197
+ await options.sendMessage({ name, type, messageType: isEmail ? 1 : 0, props: { token } });
207
198
  return token;
208
199
  };
209
200
 
@@ -227,6 +218,7 @@ module.exports = fp(async (fastify, options) => {
227
218
  verificationJWTCodeValidate,
228
219
  passwordEncryption,
229
220
  passwordAuthentication,
230
- resetPassword
221
+ resetPassword,
222
+ resetPasswordByToken
231
223
  };
232
224
  });