@things-factory/auth-base 8.0.0-alpha.35 → 8.0.0-alpha.36
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/dist-server/router/auth-public-process-router.js +6 -4
- package/dist-server/router/auth-public-process-router.js.map +1 -1
- package/dist-server/service/user/user-mutation.d.ts +7 -7
- package/dist-server/service/user/user-mutation.js +91 -42
- package/dist-server/service/user/user-mutation.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/server/router/auth-public-process-router.ts +6 -5
- package/server/service/user/user-mutation.ts +102 -44
- package/translations/en.json +1 -0
- package/translations/ja.json +1 -0
- package/translations/ko.json +1 -0
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@things-factory/auth-base",
|
3
|
-
"version": "8.0.0-alpha.
|
3
|
+
"version": "8.0.0-alpha.36",
|
4
4
|
"main": "dist-server/index.js",
|
5
5
|
"browser": "dist-client/index.js",
|
6
6
|
"things-factory": true,
|
@@ -46,5 +46,5 @@
|
|
46
46
|
"passport-jwt": "^4.0.0",
|
47
47
|
"passport-local": "^1.0.0"
|
48
48
|
},
|
49
|
-
"gitHead": "
|
49
|
+
"gitHead": "7529955cea0ce5eaa29069374ceac5de848ca1a0"
|
50
50
|
}
|
@@ -211,10 +211,9 @@ authPublicProcessRouter.post('/forgot-password', async (context, next) => {
|
|
211
211
|
|
212
212
|
authPublicProcessRouter.post('/reset-password', async (context, next) => {
|
213
213
|
const { header, t } = context
|
214
|
+
const { password, token } = context.request.body
|
214
215
|
|
215
216
|
try {
|
216
|
-
const { password, token } = context.request.body
|
217
|
-
|
218
217
|
if (!(token && password)) {
|
219
218
|
let message = t('error.token or password is invalid')
|
220
219
|
|
@@ -243,7 +242,7 @@ authPublicProcessRouter.post('/reset-password', async (context, next) => {
|
|
243
242
|
|
244
243
|
await resetPassword(token, password, context)
|
245
244
|
|
246
|
-
var message = t('text.password
|
245
|
+
var message = t('text.password changed successfully')
|
247
246
|
context.body = message
|
248
247
|
|
249
248
|
clearAccessTokenCookie(context)
|
@@ -266,10 +265,12 @@ authPublicProcessRouter.post('/reset-password', async (context, next) => {
|
|
266
265
|
|
267
266
|
if (accepts(header.accept, ['text/html', '*/*'])) {
|
268
267
|
await context.render('auth-page', {
|
269
|
-
pageElement: '
|
270
|
-
elementScript: '/auth/
|
268
|
+
pageElement: 'reset-password',
|
269
|
+
elementScript: '/auth/reset-password.js',
|
271
270
|
data: {
|
271
|
+
token,
|
272
272
|
message: e.message,
|
273
|
+
passwordRule,
|
273
274
|
disableUserSignupProcess,
|
274
275
|
disableUserFavoredLanguage,
|
275
276
|
languages
|
@@ -216,16 +216,22 @@ export class UserMutation {
|
|
216
216
|
|
217
217
|
@Directive('@transaction')
|
218
218
|
@Mutation(returns => Boolean, { description: 'To invite new user' })
|
219
|
-
async inviteUser(
|
220
|
-
@Arg('email', type => GraphQLEmailAddress) email: string,
|
221
|
-
@Ctx() context: ResolverContext
|
222
|
-
): Promise<boolean> {
|
219
|
+
async inviteUser(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
223
220
|
const { domain, tx } = context.state
|
224
|
-
const
|
225
|
-
|
221
|
+
const userRepository = getRepository(User, tx)
|
222
|
+
|
223
|
+
var invitee: User = await userRepository.findOne({
|
224
|
+
where: { username },
|
226
225
|
relations: ['domains']
|
227
226
|
})
|
228
227
|
|
228
|
+
if (!invitee && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
229
|
+
invitee = await userRepository.findOne({
|
230
|
+
where: { email: ILike(username) },
|
231
|
+
relations: ['domains']
|
232
|
+
})
|
233
|
+
}
|
234
|
+
|
229
235
|
if (!invitee) {
|
230
236
|
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
231
237
|
}
|
@@ -234,8 +240,9 @@ export class UserMutation {
|
|
234
240
|
if (existingDomains.find((d: Domain) => d.id === domain.id)) {
|
235
241
|
throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: domain.name }))
|
236
242
|
}
|
243
|
+
|
237
244
|
invitee.domains = [...existingDomains, domain]
|
238
|
-
await
|
245
|
+
await userRepository.save(invitee)
|
239
246
|
|
240
247
|
return true
|
241
248
|
}
|
@@ -243,16 +250,22 @@ export class UserMutation {
|
|
243
250
|
@Directive('@transaction')
|
244
251
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
245
252
|
@Mutation(returns => Boolean, { description: 'To delete domain user' })
|
246
|
-
async deleteDomainUser(
|
247
|
-
@Arg('email', type => GraphQLEmailAddress) email: string,
|
248
|
-
@Ctx() context: ResolverContext
|
249
|
-
): Promise<boolean> {
|
253
|
+
async deleteDomainUser(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
250
254
|
const { tx, domain } = context.state
|
255
|
+
const userRepository = getRepository(User, tx)
|
251
256
|
|
252
|
-
|
253
|
-
where: {
|
254
|
-
relations: ['domains', 'roles'
|
257
|
+
var user: User = await userRepository.findOne({
|
258
|
+
where: { username },
|
259
|
+
relations: ['domains', 'roles']
|
255
260
|
})
|
261
|
+
|
262
|
+
if (!user && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
263
|
+
user = await userRepository.findOne({
|
264
|
+
where: { email: ILike(username) },
|
265
|
+
relations: ['domains', 'roles']
|
266
|
+
})
|
267
|
+
}
|
268
|
+
|
256
269
|
if (!user) {
|
257
270
|
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
258
271
|
}
|
@@ -266,9 +279,9 @@ export class UserMutation {
|
|
266
279
|
user.domains.splice(targetDomainIdx, 1)
|
267
280
|
|
268
281
|
// Remove domain's roles that user has
|
269
|
-
user.roles = user.roles.filter((role: Role) => role.
|
282
|
+
user.roles = user.roles.filter((role: Role) => role.domainId !== domain.id)
|
270
283
|
|
271
|
-
await
|
284
|
+
await userRepository.save(user)
|
272
285
|
|
273
286
|
return true
|
274
287
|
}
|
@@ -276,18 +289,24 @@ export class UserMutation {
|
|
276
289
|
@Directive('@privilege(domainOwnerGranted: true, superUserGranted: true)')
|
277
290
|
@Directive('@transaction')
|
278
291
|
@Mutation(returns => Boolean, { description: 'To transfer owner of domain' })
|
279
|
-
async transferOwner(
|
280
|
-
@Arg('email', type => GraphQLEmailAddress) email: string,
|
281
|
-
@Ctx() context: ResolverContext
|
282
|
-
): Promise<boolean> {
|
292
|
+
async transferOwner(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
283
293
|
const { domain, tx } = context.state
|
284
|
-
const
|
285
|
-
|
286
|
-
|
294
|
+
const userRepository = getRepository(User, tx)
|
295
|
+
|
296
|
+
var user: User = await userRepository.findOne({
|
297
|
+
where: { username },
|
298
|
+
relations: ['domains']
|
287
299
|
})
|
288
300
|
|
301
|
+
if (!user && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
302
|
+
user = await userRepository.findOne({
|
303
|
+
where: { email: ILike(username) },
|
304
|
+
relations: ['domains']
|
305
|
+
})
|
306
|
+
}
|
307
|
+
|
289
308
|
if (!user) {
|
290
|
-
throw new Error('
|
309
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
291
310
|
}
|
292
311
|
|
293
312
|
if (user.status !== UserStatus.ACTIVATED) {
|
@@ -311,15 +330,24 @@ export class UserMutation {
|
|
311
330
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
312
331
|
@Directive('@transaction')
|
313
332
|
@Mutation(returns => Boolean, { description: 'To activate user' })
|
314
|
-
async activateUser(@Arg('
|
333
|
+
async activateUser(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
315
334
|
const { tx, domain } = context.state
|
335
|
+
const userRepository = getRepository(User, tx)
|
316
336
|
|
317
|
-
|
318
|
-
where: {
|
337
|
+
var targetUser: User = await userRepository.findOne({
|
338
|
+
where: { username },
|
319
339
|
relations: ['domains']
|
320
340
|
})
|
341
|
+
|
342
|
+
if (!targetUser && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
343
|
+
targetUser = await userRepository.findOne({
|
344
|
+
where: { email: ILike(username) },
|
345
|
+
relations: ['domains']
|
346
|
+
})
|
347
|
+
}
|
348
|
+
|
321
349
|
if (!targetUser) {
|
322
|
-
throw new Error('
|
350
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
323
351
|
}
|
324
352
|
|
325
353
|
if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {
|
@@ -329,7 +357,7 @@ export class UserMutation {
|
|
329
357
|
targetUser.failCount = 0
|
330
358
|
targetUser.status = UserStatus.ACTIVATED
|
331
359
|
|
332
|
-
await
|
360
|
+
await userRepository.save(targetUser)
|
333
361
|
|
334
362
|
return true
|
335
363
|
}
|
@@ -337,15 +365,24 @@ export class UserMutation {
|
|
337
365
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
338
366
|
@Directive('@transaction')
|
339
367
|
@Mutation(returns => Boolean, { description: 'To inactivate user' })
|
340
|
-
async inactivateUser(@Arg('
|
368
|
+
async inactivateUser(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
341
369
|
const { tx, domain } = context.state
|
370
|
+
const userRepository = getRepository(User, tx)
|
342
371
|
|
343
|
-
|
344
|
-
where: {
|
372
|
+
var targetUser: User = await userRepository.findOne({
|
373
|
+
where: { username },
|
345
374
|
relations: ['domains']
|
346
375
|
})
|
376
|
+
|
377
|
+
if (!targetUser && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
378
|
+
targetUser = await userRepository.findOne({
|
379
|
+
where: { email: ILike(username) },
|
380
|
+
relations: ['domains']
|
381
|
+
})
|
382
|
+
}
|
383
|
+
|
347
384
|
if (!targetUser) {
|
348
|
-
throw new Error('
|
385
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
349
386
|
}
|
350
387
|
|
351
388
|
if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {
|
@@ -358,7 +395,7 @@ export class UserMutation {
|
|
358
395
|
|
359
396
|
targetUser.status = UserStatus.INACTIVE
|
360
397
|
|
361
|
-
await
|
398
|
+
await userRepository.save(targetUser)
|
362
399
|
|
363
400
|
return true
|
364
401
|
}
|
@@ -366,7 +403,7 @@ export class UserMutation {
|
|
366
403
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
367
404
|
@Directive('@transaction')
|
368
405
|
@Mutation(returns => Boolean, { description: 'To reset password to default' })
|
369
|
-
async resetPasswordToDefault(@Arg('
|
406
|
+
async resetPasswordToDefault(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
370
407
|
const { tx, domain } = context.state
|
371
408
|
|
372
409
|
const { defaultPassword } = config.get('password')
|
@@ -374,12 +411,22 @@ export class UserMutation {
|
|
374
411
|
throw new Error('No default password found')
|
375
412
|
}
|
376
413
|
|
377
|
-
const
|
378
|
-
|
414
|
+
const userRepository = getRepository(User, tx)
|
415
|
+
|
416
|
+
var targetUser: User = await userRepository.findOne({
|
417
|
+
where: { username },
|
379
418
|
relations: ['domains']
|
380
419
|
})
|
420
|
+
|
421
|
+
if (!targetUser && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
422
|
+
targetUser = await userRepository.findOne({
|
423
|
+
where: { email: ILike(username) },
|
424
|
+
relations: ['domains']
|
425
|
+
})
|
426
|
+
}
|
427
|
+
|
381
428
|
if (!targetUser) {
|
382
|
-
throw new Error('
|
429
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
383
430
|
}
|
384
431
|
|
385
432
|
if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {
|
@@ -388,7 +435,8 @@ export class UserMutation {
|
|
388
435
|
|
389
436
|
targetUser.salt = User.generateSalt()
|
390
437
|
targetUser.password = User.encode(defaultPassword, targetUser.salt)
|
391
|
-
|
438
|
+
|
439
|
+
await userRepository.save(targetUser)
|
392
440
|
|
393
441
|
return true
|
394
442
|
}
|
@@ -397,18 +445,28 @@ export class UserMutation {
|
|
397
445
|
@Directive('@transaction')
|
398
446
|
@Mutation(returns => User, { description: 'To update roles for a user' })
|
399
447
|
async updateUserRoles(
|
400
|
-
@Arg('
|
448
|
+
@Arg('username') username: string,
|
401
449
|
@Arg('availableRoles', type => [ObjectRef]) availableRoles: ObjectRef[],
|
402
450
|
@Arg('selectedRoles', type => [ObjectRef]) selectedRoles: ObjectRef[],
|
403
451
|
@Ctx() context: ResolverContext
|
404
452
|
) {
|
405
453
|
const { domain, tx } = context.state
|
406
|
-
|
407
|
-
|
454
|
+
const userRepository = getRepository(User, tx)
|
455
|
+
|
456
|
+
var user: User = await userRepository.findOne({
|
457
|
+
where: { username },
|
408
458
|
relations: ['domains', 'roles']
|
409
459
|
})
|
460
|
+
|
461
|
+
if (!user && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
462
|
+
user = await userRepository.findOne({
|
463
|
+
where: { email: ILike(username) },
|
464
|
+
relations: ['domains', 'roles']
|
465
|
+
})
|
466
|
+
}
|
467
|
+
|
410
468
|
if (!user) {
|
411
|
-
throw new Error('
|
469
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
412
470
|
}
|
413
471
|
|
414
472
|
if (user.domains.map((d: Domain) => d.id).indexOf(domain.id) < 0) {
|
@@ -419,6 +477,6 @@ export class UserMutation {
|
|
419
477
|
user.roles = user.roles.filter((r: Role) => availableRoleIds.indexOf(r.id) < 0)
|
420
478
|
user.roles = user.roles.concat(selectedRoles as Role[])
|
421
479
|
|
422
|
-
return await
|
480
|
+
return await userRepository.save(user)
|
423
481
|
}
|
424
482
|
}
|
package/translations/en.json
CHANGED
@@ -59,6 +59,7 @@
|
|
59
59
|
"text.signout successfully": "signout successfully",
|
60
60
|
"text.user activated successfully": "user activated successfully",
|
61
61
|
"text.user credential registered successfully": "device registration has been successfully completed. You can now use biometric authentication.",
|
62
|
+
"text.user inactivated successfully": "user inactivated successfully",
|
62
63
|
"text.user registered successfully": "user registered successfully. find your email to activate account",
|
63
64
|
"text.verification email sent": "verification email sent"
|
64
65
|
}
|
package/translations/ja.json
CHANGED
@@ -59,6 +59,7 @@
|
|
59
59
|
"text.signout successfully": "ログアウトに成功しました.",
|
60
60
|
"text.user activated successfully": "ユーザーが正常に活性化されました.",
|
61
61
|
"text.user credential registered successfully": "デバイスの登録が正常に完了しました。今後は生体認証を使用できます。",
|
62
|
+
"text.user inactivated successfully": "ユーザーが正常に非アクティブ化されました.",
|
62
63
|
"text.user registered successfully": "ユーザーが正常に登録されました. 確認メールでアカウントを有効にしてください.",
|
63
64
|
"text.verification email sent": "確認メールを送りました."
|
64
65
|
}
|
package/translations/ko.json
CHANGED
@@ -59,6 +59,7 @@
|
|
59
59
|
"text.signout successfully": "성공적으로 로그아웃 하였습니다.",
|
60
60
|
"text.user activated successfully": "사용자가 성공적으로 활성화되었습니다.",
|
61
61
|
"text.user credential registered successfully": "기기 등록이 성공적으로 완료되었습니다. 이제 바이오메트릭 인증을 사용할 수 있습니다.",
|
62
|
+
"text.user inactivated successfully": "사용자가 성공적으로 비활성화되었습니다.",
|
62
63
|
"text.user registered successfully": "사용자가 성공적으로 등록되었습니다. 확인 이메일을 통해서 계정을 활성화하시기 바랍니다.",
|
63
64
|
"text.verification email sent": "확인 이메일을 보냈습니다."
|
64
65
|
}
|
package/translations/ms.json
CHANGED
@@ -59,6 +59,7 @@
|
|
59
59
|
"text.signout successfully": "Berjaya keluar",
|
60
60
|
"text.user activated successfully": "Pengguna diaktifkan dengan berjaya",
|
61
61
|
"text.user credential registered successfully": "pendaftaran peranti berjaya diselesaikan. Kini anda boleh menggunakan pengesahan biometrik.",
|
62
|
+
"text.user inactivated successfully": "Pengguna tidak aktif dengan berjaya",
|
62
63
|
"text.user registered successfully": "Pengguna berjaya didaftarkan. Cari e-mel anda untuk mengaktifkan akaun",
|
63
64
|
"text.verification email sent": "E-mel pengesahan telah dihantar"
|
64
65
|
}
|
package/translations/zh.json
CHANGED
@@ -60,6 +60,7 @@
|
|
60
60
|
"text.signout successfully": "登出成功。",
|
61
61
|
"text.user activated successfully": "用户激活成功",
|
62
62
|
"text.user credential registered successfully": "设备注册已成功完成。现在可以使用生物识别认证。",
|
63
|
+
"text.user inactivated successfully": "用户已成功停用",
|
63
64
|
"text.user registered successfully": "用户注册成功。 请查看电子邮件以激活帐户。",
|
64
65
|
"text.verification email sent": "验证邮件已发送"
|
65
66
|
}
|