@things-factory/auth-base 8.0.0-alpha.29 โ 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-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/constants/error-code.d.ts +2 -0
- package/dist-server/constants/error-code.js +3 -1
- package/dist-server/constants/error-code.js.map +1 -1
- package/dist-server/controllers/change-pwd.js +2 -2
- package/dist-server/controllers/change-pwd.js.map +1 -1
- package/dist-server/controllers/delete-user.js +13 -12
- package/dist-server/controllers/delete-user.js.map +1 -1
- package/dist-server/controllers/invitation.d.ts +2 -1
- package/dist-server/controllers/invitation.js +30 -5
- package/dist-server/controllers/invitation.js.map +1 -1
- package/dist-server/controllers/profile.d.ts +4 -3
- package/dist-server/controllers/profile.js +20 -2
- package/dist-server/controllers/profile.js.map +1 -1
- package/dist-server/controllers/signin.d.ts +4 -1
- package/dist-server/controllers/signin.js +17 -1
- package/dist-server/controllers/signin.js.map +1 -1
- package/dist-server/controllers/signup.js +13 -4
- package/dist-server/controllers/signup.js.map +1 -1
- package/dist-server/controllers/unlock-user.js +1 -0
- package/dist-server/controllers/unlock-user.js.map +1 -1
- package/dist-server/controllers/verification.js +1 -0
- package/dist-server/controllers/verification.js.map +1 -1
- package/dist-server/middlewares/signin-middleware.js +3 -3
- package/dist-server/middlewares/signin-middleware.js.map +1 -1
- package/dist-server/migrations/1548206416130-SeedUser.js +2 -1
- package/dist-server/migrations/1548206416130-SeedUser.js.map +1 -1
- package/dist-server/router/auth-checkin-router.js +8 -2
- package/dist-server/router/auth-checkin-router.js.map +1 -1
- package/dist-server/router/auth-private-process-router.js +12 -7
- package/dist-server/router/auth-private-process-router.js.map +1 -1
- package/dist-server/router/auth-public-process-router.js +20 -9
- package/dist-server/router/auth-public-process-router.js.map +1 -1
- package/dist-server/router/auth-signin-router.js +3 -3
- package/dist-server/router/auth-signin-router.js.map +1 -1
- package/dist-server/service/invitation/invitation-mutation.d.ts +3 -2
- package/dist-server/service/invitation/invitation-mutation.js +20 -8
- package/dist-server/service/invitation/invitation-mutation.js.map +1 -1
- package/dist-server/service/user/user-mutation.d.ts +10 -9
- package/dist-server/service/user/user-mutation.js +112 -54
- package/dist-server/service/user/user-mutation.js.map +1 -1
- package/dist-server/service/user/user-types.d.ts +1 -0
- package/dist-server/service/user/user-types.js +4 -0
- package/dist-server/service/user/user-types.js.map +1 -1
- package/dist-server/service/user/user.d.ts +1 -0
- package/dist-server/service/user/user.js +40 -14
- package/dist-server/service/user/user.js.map +1 -1
- package/dist-server/templates/account-unlock-email.d.ts +2 -1
- package/dist-server/templates/account-unlock-email.js +1 -1
- package/dist-server/templates/account-unlock-email.js.map +1 -1
- package/dist-server/templates/invitation-email.d.ts +2 -1
- package/dist-server/templates/invitation-email.js +1 -1
- package/dist-server/templates/invitation-email.js.map +1 -1
- package/dist-server/templates/verification-email.d.ts +2 -1
- package/dist-server/templates/verification-email.js +1 -1
- package/dist-server/templates/verification-email.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/server/constants/error-code.ts +2 -0
- package/server/controllers/change-pwd.ts +3 -2
- package/server/controllers/delete-user.ts +16 -13
- package/server/controllers/invitation.ts +36 -5
- package/server/controllers/profile.ts +29 -2
- package/server/controllers/signin.ts +21 -2
- package/server/controllers/signup.ts +16 -4
- package/server/controllers/unlock-user.ts +1 -0
- package/server/controllers/verification.ts +1 -0
- package/server/middlewares/signin-middleware.ts +3 -3
- package/server/migrations/1548206416130-SeedUser.ts +2 -1
- package/server/router/auth-checkin-router.ts +11 -5
- package/server/router/auth-private-process-router.ts +14 -7
- package/server/router/auth-public-process-router.ts +22 -10
- package/server/router/auth-signin-router.ts +3 -3
- package/server/service/invitation/invitation-mutation.ts +24 -9
- package/server/service/user/user-mutation.ts +123 -54
- package/server/service/user/user-types.ts +3 -0
- package/server/service/user/user.ts +41 -14
- package/server/templates/account-unlock-email.ts +1 -1
- package/server/templates/invitation-email.ts +1 -1
- package/server/templates/verification-email.ts +1 -1
- package/translations/en.json +5 -1
- package/translations/ja.json +5 -1
- package/translations/ko.json +6 -3
- package/translations/ms.json +5 -1
- package/translations/zh.json +5 -1
@@ -10,6 +10,7 @@ import { buildDomainUsersQueryBuilder } from '../../utils/get-domain-users'
|
|
10
10
|
import { Role } from '../role/role'
|
11
11
|
import { User, UserStatus } from './user'
|
12
12
|
import { NewUser, UserPatch } from './user-types'
|
13
|
+
import { USERNAME_ALREADY_EXISTS, EMAIL_ALREADY_EXISTS } from '../../constants/error-code'
|
13
14
|
|
14
15
|
@Resolver(User)
|
15
16
|
export class UserMutation {
|
@@ -19,17 +20,27 @@ export class UserMutation {
|
|
19
20
|
async createUser(@Arg('user') user: NewUser, @Ctx() context: ResolverContext) {
|
20
21
|
const { domain, tx } = context.state
|
21
22
|
const { defaultPassword } = config.get('password')
|
22
|
-
const { email } = user
|
23
|
+
const { username, email } = user
|
24
|
+
const userRepository = getRepository(User, tx)
|
23
25
|
|
26
|
+
user.username = username.trim()
|
24
27
|
user.email = email.trim()
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
if (await userRepository.findOne({ where: { username: user.username } })) {
|
30
|
+
throw new Error(context.t(USERNAME_ALREADY_EXISTS))
|
31
|
+
}
|
32
|
+
|
33
|
+
if (await userRepository.findOne({ where: { email: ILike(user.email) } })) {
|
34
|
+
throw new Error(context.t(EMAIL_ALREADY_EXISTS))
|
29
35
|
}
|
30
36
|
|
31
37
|
if (!user.password && !defaultPassword) {
|
32
|
-
throw new Error(
|
38
|
+
throw new Error('initial password or default password should be supported.')
|
39
|
+
}
|
40
|
+
|
41
|
+
// TODO username์ ๋ค์ ํจํด์ ๋ฐ๋ผ์ผ ํ๋ค. pattern="^[A-Za-z0-9]*$"
|
42
|
+
if (!/^[A-Za-z0-9]*$/.test(user.username)) {
|
43
|
+
throw new Error(context.t('error.invalid x', { x: context.t('field.username') }))
|
33
44
|
}
|
34
45
|
|
35
46
|
// consider if validation password rule is required
|
@@ -38,7 +49,7 @@ export class UserMutation {
|
|
38
49
|
|
39
50
|
const salt = User.generateSalt()
|
40
51
|
|
41
|
-
return await
|
52
|
+
return await userRepository.save({
|
42
53
|
creator: context.state.user,
|
43
54
|
updater: context.state.user,
|
44
55
|
...user,
|
@@ -185,10 +196,10 @@ export class UserMutation {
|
|
185
196
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
186
197
|
@Directive('@transaction')
|
187
198
|
@Mutation(returns => Boolean, { description: 'To delete a user' })
|
188
|
-
async deleteUser(@Arg('
|
199
|
+
async deleteUser(@Arg('username') username: string, @Ctx() context: ResolverContext) {
|
189
200
|
const { tx } = context.state
|
190
201
|
|
191
|
-
await commonDeleteUser({
|
202
|
+
await commonDeleteUser({ username }, tx)
|
192
203
|
|
193
204
|
return true
|
194
205
|
}
|
@@ -196,25 +207,31 @@ export class UserMutation {
|
|
196
207
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
197
208
|
@Directive('@transaction')
|
198
209
|
@Mutation(returns => Boolean, { description: 'To delete some users' })
|
199
|
-
async deleteUsers(@Arg('
|
210
|
+
async deleteUsers(@Arg('usernames', type => [String]) usernames: string[], @Ctx() context: ResolverContext) {
|
200
211
|
const { tx } = context.state
|
201
|
-
await commonDeleteUsers({
|
212
|
+
await commonDeleteUsers({ usernames }, tx)
|
202
213
|
|
203
214
|
return true
|
204
215
|
}
|
205
216
|
|
206
217
|
@Directive('@transaction')
|
207
218
|
@Mutation(returns => Boolean, { description: 'To invite new user' })
|
208
|
-
async inviteUser(
|
209
|
-
@Arg('email', type => GraphQLEmailAddress) email: string,
|
210
|
-
@Ctx() context: ResolverContext
|
211
|
-
): Promise<boolean> {
|
219
|
+
async inviteUser(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
212
220
|
const { domain, tx } = context.state
|
213
|
-
const
|
214
|
-
|
221
|
+
const userRepository = getRepository(User, tx)
|
222
|
+
|
223
|
+
var invitee: User = await userRepository.findOne({
|
224
|
+
where: { username },
|
215
225
|
relations: ['domains']
|
216
226
|
})
|
217
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
|
+
|
218
235
|
if (!invitee) {
|
219
236
|
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
220
237
|
}
|
@@ -223,8 +240,9 @@ export class UserMutation {
|
|
223
240
|
if (existingDomains.find((d: Domain) => d.id === domain.id)) {
|
224
241
|
throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: domain.name }))
|
225
242
|
}
|
243
|
+
|
226
244
|
invitee.domains = [...existingDomains, domain]
|
227
|
-
await
|
245
|
+
await userRepository.save(invitee)
|
228
246
|
|
229
247
|
return true
|
230
248
|
}
|
@@ -232,16 +250,22 @@ export class UserMutation {
|
|
232
250
|
@Directive('@transaction')
|
233
251
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
234
252
|
@Mutation(returns => Boolean, { description: 'To delete domain user' })
|
235
|
-
async deleteDomainUser(
|
236
|
-
@Arg('email', type => GraphQLEmailAddress) email: string,
|
237
|
-
@Ctx() context: ResolverContext
|
238
|
-
): Promise<boolean> {
|
253
|
+
async deleteDomainUser(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
239
254
|
const { tx, domain } = context.state
|
255
|
+
const userRepository = getRepository(User, tx)
|
240
256
|
|
241
|
-
|
242
|
-
where: {
|
243
|
-
relations: ['domains', 'roles'
|
257
|
+
var user: User = await userRepository.findOne({
|
258
|
+
where: { username },
|
259
|
+
relations: ['domains', 'roles']
|
244
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
|
+
|
245
269
|
if (!user) {
|
246
270
|
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
247
271
|
}
|
@@ -255,9 +279,9 @@ export class UserMutation {
|
|
255
279
|
user.domains.splice(targetDomainIdx, 1)
|
256
280
|
|
257
281
|
// Remove domain's roles that user has
|
258
|
-
user.roles = user.roles.filter((role: Role) => role.
|
282
|
+
user.roles = user.roles.filter((role: Role) => role.domainId !== domain.id)
|
259
283
|
|
260
|
-
await
|
284
|
+
await userRepository.save(user)
|
261
285
|
|
262
286
|
return true
|
263
287
|
}
|
@@ -265,18 +289,24 @@ export class UserMutation {
|
|
265
289
|
@Directive('@privilege(domainOwnerGranted: true, superUserGranted: true)')
|
266
290
|
@Directive('@transaction')
|
267
291
|
@Mutation(returns => Boolean, { description: 'To transfer owner of domain' })
|
268
|
-
async transferOwner(
|
269
|
-
@Arg('email', type => GraphQLEmailAddress) email: string,
|
270
|
-
@Ctx() context: ResolverContext
|
271
|
-
): Promise<boolean> {
|
292
|
+
async transferOwner(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
272
293
|
const { domain, tx } = context.state
|
273
|
-
const
|
274
|
-
|
275
|
-
|
294
|
+
const userRepository = getRepository(User, tx)
|
295
|
+
|
296
|
+
var user: User = await userRepository.findOne({
|
297
|
+
where: { username },
|
298
|
+
relations: ['domains']
|
276
299
|
})
|
277
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
|
+
|
278
308
|
if (!user) {
|
279
|
-
throw new Error('
|
309
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
280
310
|
}
|
281
311
|
|
282
312
|
if (user.status !== UserStatus.ACTIVATED) {
|
@@ -300,15 +330,24 @@ export class UserMutation {
|
|
300
330
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
301
331
|
@Directive('@transaction')
|
302
332
|
@Mutation(returns => Boolean, { description: 'To activate user' })
|
303
|
-
async activateUser(@Arg('
|
333
|
+
async activateUser(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
304
334
|
const { tx, domain } = context.state
|
335
|
+
const userRepository = getRepository(User, tx)
|
305
336
|
|
306
|
-
|
307
|
-
where: {
|
337
|
+
var targetUser: User = await userRepository.findOne({
|
338
|
+
where: { username },
|
308
339
|
relations: ['domains']
|
309
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
|
+
|
310
349
|
if (!targetUser) {
|
311
|
-
throw new Error('
|
350
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
312
351
|
}
|
313
352
|
|
314
353
|
if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {
|
@@ -318,7 +357,7 @@ export class UserMutation {
|
|
318
357
|
targetUser.failCount = 0
|
319
358
|
targetUser.status = UserStatus.ACTIVATED
|
320
359
|
|
321
|
-
await
|
360
|
+
await userRepository.save(targetUser)
|
322
361
|
|
323
362
|
return true
|
324
363
|
}
|
@@ -326,15 +365,24 @@ export class UserMutation {
|
|
326
365
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
327
366
|
@Directive('@transaction')
|
328
367
|
@Mutation(returns => Boolean, { description: 'To inactivate user' })
|
329
|
-
async inactivateUser(@Arg('
|
368
|
+
async inactivateUser(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
330
369
|
const { tx, domain } = context.state
|
370
|
+
const userRepository = getRepository(User, tx)
|
331
371
|
|
332
|
-
|
333
|
-
where: {
|
372
|
+
var targetUser: User = await userRepository.findOne({
|
373
|
+
where: { username },
|
334
374
|
relations: ['domains']
|
335
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
|
+
|
336
384
|
if (!targetUser) {
|
337
|
-
throw new Error('
|
385
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
338
386
|
}
|
339
387
|
|
340
388
|
if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {
|
@@ -347,7 +395,7 @@ export class UserMutation {
|
|
347
395
|
|
348
396
|
targetUser.status = UserStatus.INACTIVE
|
349
397
|
|
350
|
-
await
|
398
|
+
await userRepository.save(targetUser)
|
351
399
|
|
352
400
|
return true
|
353
401
|
}
|
@@ -355,7 +403,7 @@ export class UserMutation {
|
|
355
403
|
@Directive('@privilege(category: "user", privilege: "mutation", domainOwnerGranted: true)')
|
356
404
|
@Directive('@transaction')
|
357
405
|
@Mutation(returns => Boolean, { description: 'To reset password to default' })
|
358
|
-
async resetPasswordToDefault(@Arg('
|
406
|
+
async resetPasswordToDefault(@Arg('username') username: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
359
407
|
const { tx, domain } = context.state
|
360
408
|
|
361
409
|
const { defaultPassword } = config.get('password')
|
@@ -363,12 +411,22 @@ export class UserMutation {
|
|
363
411
|
throw new Error('No default password found')
|
364
412
|
}
|
365
413
|
|
366
|
-
const
|
367
|
-
|
414
|
+
const userRepository = getRepository(User, tx)
|
415
|
+
|
416
|
+
var targetUser: User = await userRepository.findOne({
|
417
|
+
where: { username },
|
368
418
|
relations: ['domains']
|
369
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
|
+
|
370
428
|
if (!targetUser) {
|
371
|
-
throw new Error('
|
429
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
372
430
|
}
|
373
431
|
|
374
432
|
if (!targetUser?.domains?.find((userDomain: Domain) => userDomain.id === domain.id)) {
|
@@ -377,7 +435,8 @@ export class UserMutation {
|
|
377
435
|
|
378
436
|
targetUser.salt = User.generateSalt()
|
379
437
|
targetUser.password = User.encode(defaultPassword, targetUser.salt)
|
380
|
-
|
438
|
+
|
439
|
+
await userRepository.save(targetUser)
|
381
440
|
|
382
441
|
return true
|
383
442
|
}
|
@@ -386,18 +445,28 @@ export class UserMutation {
|
|
386
445
|
@Directive('@transaction')
|
387
446
|
@Mutation(returns => User, { description: 'To update roles for a user' })
|
388
447
|
async updateUserRoles(
|
389
|
-
@Arg('
|
448
|
+
@Arg('username') username: string,
|
390
449
|
@Arg('availableRoles', type => [ObjectRef]) availableRoles: ObjectRef[],
|
391
450
|
@Arg('selectedRoles', type => [ObjectRef]) selectedRoles: ObjectRef[],
|
392
451
|
@Ctx() context: ResolverContext
|
393
452
|
) {
|
394
453
|
const { domain, tx } = context.state
|
395
|
-
|
396
|
-
|
454
|
+
const userRepository = getRepository(User, tx)
|
455
|
+
|
456
|
+
var user: User = await userRepository.findOne({
|
457
|
+
where: { username },
|
397
458
|
relations: ['domains', 'roles']
|
398
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
|
+
|
399
468
|
if (!user) {
|
400
|
-
throw new Error('
|
469
|
+
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
401
470
|
}
|
402
471
|
|
403
472
|
if (user.domains.map((d: Domain) => d.id).indexOf(domain.id) < 0) {
|
@@ -408,6 +477,6 @@ export class UserMutation {
|
|
408
477
|
user.roles = user.roles.filter((r: Role) => availableRoleIds.indexOf(r.id) < 0)
|
409
478
|
user.roles = user.roles.concat(selectedRoles as Role[])
|
410
479
|
|
411
|
-
return await
|
480
|
+
return await userRepository.save(user)
|
412
481
|
}
|
413
482
|
}
|
@@ -6,6 +6,7 @@ import {
|
|
6
6
|
Column,
|
7
7
|
CreateDateColumn,
|
8
8
|
Entity,
|
9
|
+
ILike,
|
9
10
|
Index,
|
10
11
|
JoinTable,
|
11
12
|
ManyToMany,
|
@@ -43,13 +44,23 @@ export enum UserStatus {
|
|
43
44
|
}
|
44
45
|
|
45
46
|
@Entity()
|
46
|
-
@Index('ix_user_0', (user: User) => [user.email], {
|
47
|
+
@Index('ix_user_0', (user: User) => [user.email], {
|
48
|
+
unique: true
|
49
|
+
})
|
50
|
+
@Index('ix_user_1', (user: User) => [user.username], {
|
51
|
+
unique: true,
|
52
|
+
where: '"username" IS NOT NULL'
|
53
|
+
})
|
47
54
|
@ObjectType()
|
48
55
|
export class User {
|
49
56
|
@PrimaryGeneratedColumn('uuid')
|
50
57
|
@Field(type => ID)
|
51
58
|
readonly id: string
|
52
59
|
|
60
|
+
@Column({ nullable: true })
|
61
|
+
@Field({ nullable: true })
|
62
|
+
username: string
|
63
|
+
|
53
64
|
@Column()
|
54
65
|
@Field({ nullable: true })
|
55
66
|
name: string
|
@@ -165,15 +176,10 @@ export class User {
|
|
165
176
|
|
166
177
|
/* signing for jsonwebtoken */
|
167
178
|
async sign(options?) {
|
168
|
-
var { expiresIn = sessionExpirySeconds
|
179
|
+
var { expiresIn = sessionExpirySeconds } = options || {}
|
169
180
|
|
170
181
|
var user = {
|
171
|
-
|
172
|
-
userType: this.userType,
|
173
|
-
status: this.status,
|
174
|
-
domain: {
|
175
|
-
subdomain
|
176
|
-
}
|
182
|
+
username: this.username || this.email
|
177
183
|
}
|
178
184
|
|
179
185
|
return await jwt.sign(user, SECRET, {
|
@@ -262,18 +268,39 @@ export class User {
|
|
262
268
|
}
|
263
269
|
|
264
270
|
static async checkAuth(decoded) {
|
265
|
-
|
271
|
+
// id ๋ ํ์ํธํ์ฑ์ ์ํด ๋จ๊ธฐ์ ์ผ๋ก ์ ์งํจ
|
272
|
+
const { id, username } = decoded || {}
|
273
|
+
|
274
|
+
if (!id && !username) {
|
266
275
|
throw new AuthError({
|
267
276
|
errorCode: AuthError.ERROR_CODES.USER_NOT_FOUND
|
268
277
|
})
|
269
278
|
}
|
270
279
|
|
271
280
|
const repository = getRepository(User)
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
281
|
+
if (id) {
|
282
|
+
var user = await repository.findOne({
|
283
|
+
where: { id },
|
284
|
+
relations: ['domains', 'credentials'],
|
285
|
+
cache: true
|
286
|
+
})
|
287
|
+
} else {
|
288
|
+
var user = await repository.findOne({
|
289
|
+
where: { username },
|
290
|
+
relations: ['domains', 'credentials'],
|
291
|
+
cache: true
|
292
|
+
})
|
293
|
+
|
294
|
+
if (!user && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(username)) {
|
295
|
+
user = await repository.findOne({
|
296
|
+
where: {
|
297
|
+
email: ILike(username)
|
298
|
+
},
|
299
|
+
relations: ['domains', 'credentials'],
|
300
|
+
cache: true
|
301
|
+
})
|
302
|
+
}
|
303
|
+
}
|
277
304
|
|
278
305
|
if (!user)
|
279
306
|
throw new AuthError({
|
package/translations/en.json
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
"error.confirm password not matched": "new password and confirm password is not matched",
|
5
5
|
"error.domain mismatch": "certificate is not for this domain",
|
6
6
|
"error.domain not allowed": "user not allowed domain `{subdomain}`",
|
7
|
+
"error.email already exists": "email already used by another user",
|
7
8
|
"error.failed to find x": "failed to find {x}",
|
8
9
|
"error.password should be supported": "initial password or default password should be supported",
|
9
10
|
"error.password should match the rule": "password should match following rule. ${rule}",
|
@@ -11,13 +12,15 @@
|
|
11
12
|
"error.subdomain not found": "domain not found",
|
12
13
|
"error.token or password is invalid": "token or password is invalid",
|
13
14
|
"error.unavailable-domain": "unavailable domain",
|
15
|
+
"error.user credential not found": "user credential not found. You need to register device to use biometric authentication.",
|
14
16
|
"error.user credential registeration failed": "user credential registration failed. It may be an already registered credential.",
|
15
17
|
"error.user credential registration not allowed": "user credential registration failed. The registration timed out or was not allowed.",
|
16
|
-
"error.user duplicated": "user
|
18
|
+
"error.user duplicated.": "there is a user account using same email or user ID.",
|
17
19
|
"error.user not activated": "user is not activated",
|
18
20
|
"error.user not found": "user not found",
|
19
21
|
"error.user or verification token not found": "user or verification token not found",
|
20
22
|
"error.user validation failed": "user validation failed",
|
23
|
+
"error.username already exists": "username already used by another user",
|
21
24
|
"error.x is not a member of y": "{x} is not a member of {y}",
|
22
25
|
"field.active": "active",
|
23
26
|
"field.appliance_id": "appliance id",
|
@@ -56,6 +59,7 @@
|
|
56
59
|
"text.signout successfully": "signout successfully",
|
57
60
|
"text.user activated successfully": "user activated successfully",
|
58
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",
|
59
63
|
"text.user registered successfully": "user registered successfully. find your email to activate account",
|
60
64
|
"text.verification email sent": "verification email sent"
|
61
65
|
}
|
package/translations/ja.json
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
"error.confirm password not matched": "ๆฐใใใในใฏใผใใจ็ขบ่ชใในใฏใผใใไธ่ดใใพใใ.",
|
5
5
|
"error.domain mismatch": "่จผๆๆธใฎใใกใคใณใจ็พๅจใฎใใกใคใณใไธ่ดใใพใใ.",
|
6
6
|
"error.domain not allowed": "'{subdomain}' ้ ๅใฏใใฎใฆใผใถใซ่จฑๅฏใใใฆใใพใใ.",
|
7
|
+
"error.email already exists": "ใกใผใซใฏใใงใซไปใฎใฆใผใถใผใซใใฃใฆไฝฟ็จใใใฆใใพใ.",
|
7
8
|
"error.failed to find x": "{x}ใ่ฆใคใใใพใใ.",
|
8
9
|
"error.password should be supported": "ๅๆใในใฏใผใใพใใฏใใใฉใซใใในใฏใผใใใตใใผใใใใในใใงใ",
|
9
10
|
"error.password should match the rule": "ใในใฏใผใใฏๆฌกใฎ่ฆๅใๅฎใใชใใใฐใชใใพใใ. {rule}",
|
@@ -11,13 +12,15 @@
|
|
11
12
|
"error.subdomain not found": "ใตใใใกใคใณใ่ฆใคใใใพใใ.",
|
12
13
|
"error.token or password is invalid": "ใใผใฏใณใพใใฏใในใฏใผใใ็กๅนใงใ.",
|
13
14
|
"error.unavailable-domain": "ไฝฟ็จใงใใชใใใกใคใณใงใ.",
|
15
|
+
"error.user credential not found": "ใฆใผใถใผ่ณๆ ผๆ
ๅ ฑใ่ฆใคใใใพใใ. ็ไฝ่ช่จผใไฝฟ็จใใใซใฏใใใคในใ็ป้ฒใใๅฟ
่ฆใใใใพใ.",
|
14
16
|
"error.user credential registeration failed": "ใฆใผใถใผ่ณๆ ผๆ
ๅ ฑใฎ็ป้ฒใซๅคฑๆใใพใใใๆขใซ็ป้ฒใใใฆใใ่ณๆ ผๆ
ๅ ฑใฎๅฏ่ฝๆงใใใใพใใ",
|
15
17
|
"error.user credential registration not allowed": "ใฆใผใถใผ่ณๆ ผๆ
ๅ ฑใฎ็ป้ฒใซๅคฑๆใใพใใใ็ป้ฒใฎใฟใคใ ใขใฆใใพใใฏ็ป้ฒใ่จฑๅฏใใใฆใใพใใใ",
|
16
|
-
"error.user duplicated": "
|
18
|
+
"error.user duplicated.": "ใฆใผใถใผใ้่คใใฆใใพใ.",
|
17
19
|
"error.user not activated": "ใฆใผใถใผใใขใฏใใฃใๅใใใฆใใพใใ.",
|
18
20
|
"error.user not found": "ใฆใผใถใผใๅญๅจใใพใใ.",
|
19
21
|
"error.user or verification token not found": "ใฆใผใถใผใพใใฏ็ขบ่ชใใผใฏใณใ่ฆใคใใใพใใ.",
|
20
22
|
"error.user validation failed": "ใฆใผใถใผ็ขบ่ชใซๅคฑๆใใพใใ.",
|
23
|
+
"error.username already exists": "ใฆใผใถใผๅใฏใใงใซไปใฎใฆใผใถใผใซใใฃใฆไฝฟ็จใใใฆใใพใ.",
|
21
24
|
"error.x is not a member of y": "{x}ใฏ{y}ใฎใกใณใใผใงใฏใใใพใใ.",
|
22
25
|
"field.active": "ใขใฏใใฃใ",
|
23
26
|
"field.appliance_id": "ๅจๅ
ทID",
|
@@ -56,6 +59,7 @@
|
|
56
59
|
"text.signout successfully": "ใญใฐใขใฆใใซๆๅใใพใใ.",
|
57
60
|
"text.user activated successfully": "ใฆใผใถใผใๆญฃๅธธใซๆดปๆงๅใใใพใใ.",
|
58
61
|
"text.user credential registered successfully": "ใใใคในใฎ็ป้ฒใๆญฃๅธธใซๅฎไบใใพใใใไปๅพใฏ็ไฝ่ช่จผใไฝฟ็จใงใใพใใ",
|
62
|
+
"text.user inactivated successfully": "ใฆใผใถใผใๆญฃๅธธใซ้ใขใฏใใฃใๅใใใพใใ.",
|
59
63
|
"text.user registered successfully": "ใฆใผใถใผใๆญฃๅธธใซ็ป้ฒใใใพใใ. ็ขบ่ชใกใผใซใงใขใซใฆใณใใๆๅนใซใใฆใใ ใใ.",
|
60
64
|
"text.verification email sent": "็ขบ่ชใกใผใซใ้ใใพใใ."
|
61
65
|
}
|
package/translations/ko.json
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
"error.confirm password not matched": "์ ๋น๋ฐ๋ฒํธ์ ํ์ธ ๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.",
|
5
5
|
"error.domain mismatch": "์ธ์ฆ์์ ๋๋ฉ์ธ๊ณผ ํ์ฌ ๋๋ฉ์ธ์ด ์ผ์นํ์ง ์์ต๋๋ค.",
|
6
6
|
"error.domain not allowed": "'{subdomain}' ์์ญ์ ์ด ์ฌ์ฉ์์๊ฒ ํ๊ฐ๋์ง ์์์ต๋๋ค.",
|
7
|
+
"error.email already exists": "์ด๋ฉ์ผ์ด ์ด๋ฏธ ์ฌ์ฉ๋๊ณ ์์ต๋๋ค.",
|
7
8
|
"error.failed to find x": "{x}์(๋ฅผ) ์ฐพ์ ์ ์์ต๋๋ค.",
|
8
9
|
"error.password should be supported": "์ด๊ธฐ ๋น๋ฐ๋ฒํธ๋ ๋ํดํธ ๋น๋ฐ๋ฒํธ๊ฐ ์ ๊ณต๋์ด์ผ ํฉ๋๋ค.",
|
9
10
|
"error.password should match the rule": "๋น๋ฐ๋ฒํธ๋ ๋ค์ ๊ท์น์ ์ง์ผ์ผ ํฉ๋๋ค. {rule}",
|
@@ -12,13 +13,14 @@
|
|
12
13
|
"error.token or password is invalid": "ํ ํฐ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ์ ํจํ์ง ์์ต๋๋ค.",
|
13
14
|
"error.unavailable-domain": "์ฌ์ฉํ ์ ์๋ ๋๋ฉ์ธ์
๋๋ค.",
|
14
15
|
"error.user credential not found": "์ฌ์ฉ์ ์๊ฒฉ ์ฆ๋ช
์ ์ฐพ์ ์ ์์ต๋๋ค. ๋ฐ์ด์ค๋ฉํธ๋ฆญ ์ธ์ฆ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋จผ์ ๊ธฐ๊ธฐ๋ฅผ ๋ฑ๋กํด์ผ ํฉ๋๋ค.",
|
15
|
-
"error.user
|
16
|
+
"error.user credential registeration failed": "์ฌ์ฉ์ ์ธ์ฆ์ ๋ฑ๋ก์ด ์คํจํ์์ต๋๋ค. ์ด๋ฏธ ๋ฑ๋ก๋ ์ธ์ฆ์์ผ ์ ์์ต๋๋ค.",
|
17
|
+
"error.user credential registration not allowed": "์ฌ์ฉ์ ์ธ์ฆ์ ๋ฑ๋ก์ด ์คํจํ์์ต๋๋ค. ๋ฑ๋ก ์๊ฐ์ด ์ด๊ณผ๋์๊ฑฐ๋ ๋ฑ๋ก์ด ํ์ฉ๋์ง ์์์ต๋๋ค.",
|
18
|
+
"error.user duplicated": "๋์ผํ ์ด๋ฉ์ผ์ด๋ ์ฌ์ฉ์์์ด๋๋ก ๊ฐ์
๋ ๊ณ์ ์ด ์ด๋ฏธ ์กด์ฌํฉ๋๋ค.",
|
16
19
|
"error.user not activated": "์ฌ์ฉ์๊ฐ ํ์ฑํ๋์ง ์์์ต๋๋ค.",
|
17
20
|
"error.user not found": "์ฌ์ฉ์๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.",
|
18
21
|
"error.user or verification token not found": "์ฌ์ฉ์ ๋๋ ํ์ธํ ํฐ์ ์ฐพ์ ์ ์์ต๋๋ค.",
|
19
|
-
"error.user credential registeration failed": "์ฌ์ฉ์ ์ธ์ฆ์ ๋ฑ๋ก์ด ์คํจํ์์ต๋๋ค. ์ด๋ฏธ ๋ฑ๋ก๋ ์ธ์ฆ์์ผ ์ ์์ต๋๋ค.",
|
20
|
-
"error.user credential registration not allowed": "์ฌ์ฉ์ ์ธ์ฆ์ ๋ฑ๋ก์ด ์คํจํ์์ต๋๋ค. ๋ฑ๋ก ์๊ฐ์ด ์ด๊ณผ๋์๊ฑฐ๋ ๋ฑ๋ก์ด ํ์ฉ๋์ง ์์์ต๋๋ค.",
|
21
22
|
"error.user validation failed": "์ฌ์ฉ์ ํ์ธ์ ์คํจํ์์ต๋๋ค.",
|
23
|
+
"error.username already exists": "์ฌ์ฉ์ ์์ด๋๊ฐ ์ด๋ฏธ ์ฌ์ฉ๋๊ณ ์์ต๋๋ค.",
|
22
24
|
"error.x is not a member of y": "{x}์(๋) {y}์ ๋ฉค๋ฒ๊ฐ ์๋๋๋ค.",
|
23
25
|
"field.active": "ํ์ฑํ",
|
24
26
|
"field.appliance_id": "๊ธฐ๊ตฌ ์์ด๋",
|
@@ -57,6 +59,7 @@
|
|
57
59
|
"text.signout successfully": "์ฑ๊ณต์ ์ผ๋ก ๋ก๊ทธ์์ ํ์์ต๋๋ค.",
|
58
60
|
"text.user activated successfully": "์ฌ์ฉ์๊ฐ ์ฑ๊ณต์ ์ผ๋ก ํ์ฑํ๋์์ต๋๋ค.",
|
59
61
|
"text.user credential registered successfully": "๊ธฐ๊ธฐ ๋ฑ๋ก์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค. ์ด์ ๋ฐ์ด์ค๋ฉํธ๋ฆญ ์ธ์ฆ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.",
|
62
|
+
"text.user inactivated successfully": "์ฌ์ฉ์๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋นํ์ฑํ๋์์ต๋๋ค.",
|
60
63
|
"text.user registered successfully": "์ฌ์ฉ์๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋ฑ๋ก๋์์ต๋๋ค. ํ์ธ ์ด๋ฉ์ผ์ ํตํด์ ๊ณ์ ์ ํ์ฑํํ์๊ธฐ ๋ฐ๋๋๋ค.",
|
61
64
|
"text.verification email sent": "ํ์ธ ์ด๋ฉ์ผ์ ๋ณด๋์ต๋๋ค."
|
62
65
|
}
|
package/translations/ms.json
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
"error.confirm password not matched": "Kata laluan baru dan pengesahan kata laluan tidak sepadan",
|
5
5
|
"error.domain mismatch": "Sijil tidak sesuai untuk domain ini",
|
6
6
|
"error.domain not allowed": "Pengguna tidak dibenarkan domain `{subdomain}`",
|
7
|
+
"error.email already exists": "Emel telah digunakan oleh pengguna lain",
|
7
8
|
"error.failed to find x": "Gagal mencari {x}",
|
8
9
|
"error.password should be supported": "kata laluan awal atau kata laluan lalai harus disokong",
|
9
10
|
"error.password should match the rule": "Kata laluan harus mematuhi peraturan berikut. ${rule}",
|
@@ -11,13 +12,15 @@
|
|
11
12
|
"error.subdomain not found": "Domain tidak ditemui",
|
12
13
|
"error.token or password is invalid": "Token atau kata laluan tidak sah",
|
13
14
|
"error.unavailable-domain": "Domain tidak tersedia",
|
15
|
+
"error.user credential not found": "kelayakan pengguna tidak ditemui. Anda perlu mendaftarkan peranti untuk menggunakan pengesahan biometrik.",
|
14
16
|
"error.user credential registeration failed": "pendaftaran kelayakan pengguna gagal. Mungkin kelayakan tersebut sudah didaftarkan.",
|
15
17
|
"error.user credential registration not allowed": "pendaftaran kelayakan pengguna gagal. Masa pendaftaran telah tamat atau pendaftaran tidak dibenarkan.",
|
16
|
-
"error.user duplicated": "
|
18
|
+
"error.user duplicated": "terdapat akaun pengguna yang menggunakan e-mel atau ID pengguna yang sama.",
|
17
19
|
"error.user not activated": "Pengguna tidak diaktifkan",
|
18
20
|
"error.user not found": "Pengguna tidak ditemui",
|
19
21
|
"error.user or verification token not found": "Pengguna atau token pengesahan tidak ditemui",
|
20
22
|
"error.user validation failed": "Validasi pengguna gagal",
|
23
|
+
"error.username already exists": "Nama pengguna telah digunakan oleh pengguna lain",
|
21
24
|
"error.x is not a member of y": "{x} bukan ahli {y}",
|
22
25
|
"field.active": "Aktif",
|
23
26
|
"field.appliance_id": "Perkakas",
|
@@ -56,6 +59,7 @@
|
|
56
59
|
"text.signout successfully": "Berjaya keluar",
|
57
60
|
"text.user activated successfully": "Pengguna diaktifkan dengan berjaya",
|
58
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",
|
59
63
|
"text.user registered successfully": "Pengguna berjaya didaftarkan. Cari e-mel anda untuk mengaktifkan akaun",
|
60
64
|
"text.verification email sent": "E-mel pengesahan telah dihantar"
|
61
65
|
}
|
package/translations/zh.json
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
"error.confirm password not matched": "ๆฐๅฏ็ ไธ็กฎ่ฎคๅฏ็ ไธๅน้
๏ผ",
|
6
6
|
"error.domain mismatch": "่ฏไนฆไธ้็จไบ่ฏฅๅ๏ผ",
|
7
7
|
"error.domain not allowed": "็จๆทๆ ๆ้ไฝฟ็จ`{subdomain}`ๅ๏ผ",
|
8
|
+
"error.email already exists": "็ตๅญ้ฎไปถๅทฒ่ขซๅ
ถไป็จๆทไฝฟ็จ๏ผ",
|
8
9
|
"error.failed to find x": "ๆฅ่ฏข{x}ๅคฑ่ดฅ๏ผ",
|
9
10
|
"error.password should be supported": "ๅบๆฏๆๅๅงๅฏ็ ๆ้ป่ฎคๅฏ็ ",
|
10
11
|
"error.password should match the rule": "ๅฏ็ ๅบ็ฌฆๅไปฅไธ่งๅใ${rule}",
|
@@ -12,13 +13,15 @@
|
|
12
13
|
"error.subdomain not found": "็จๆทๅๆฅ่ฏขๅคฑ่ดฅ๏ผ",
|
13
14
|
"error.token or password is invalid": "ไปค็ๆๅฏ็ ๆ ๆ๏ผ",
|
14
15
|
"error.unavailable-domain": "ไธๅฏ็จ็ๅๅ",
|
16
|
+
"error.user credential not found": "็จๆทๅญ่ฏๆชๆพๅฐใๆจ้่ฆๆณจๅ่ฎพๅคไปฅไฝฟ็จ็็ฉ่ฏๅซ่ฎค่ฏใ",
|
15
17
|
"error.user credential registeration failed": "็จๆทๅญ่ฏๆณจๅๅคฑ่ดฅใๅฏ่ฝๆฏๅทฒๆณจๅ็ๅญ่ฏใ",
|
16
18
|
"error.user credential registration not allowed": "็จๆทๅญ่ฏๆณจๅๅคฑ่ดฅใๆณจๅ่ถ
ๆถๆๆณจๅไธ่ขซๅ
่ฎธใ",
|
17
|
-
"error.user duplicated": "
|
19
|
+
"error.user duplicated": "ๅญๅจไธไธช็จๆทๅธๆทไฝฟ็จ็ธๅ็็ตๅญ้ฎไปถๆ็จๆทIDใ",
|
18
20
|
"error.user not activated": "็จๆทๆชๆฟๆดป๏ผ",
|
19
21
|
"error.user not found": "ๆพไธๅฐ็จๆท",
|
20
22
|
"error.user or verification token not found": "ๆพไธๅฐ็จๆทๆ้ช่ฏไปค็ใ",
|
21
23
|
"error.user validation failed": "็จๆท้ช่ฏๅคฑ่ดฅ๏ผ",
|
24
|
+
"error.username already exists": "็จๆทๅๅทฒ่ขซๅ
ถไป็จๆทไฝฟ็จ",
|
22
25
|
"error.x is not a member of y": "{x}ไธๆฏ{y}็ๆๅ",
|
23
26
|
"field.active": "ๆฟๆดป",
|
24
27
|
"field.appliance_id": "็ป็ซฏๆบID",
|
@@ -57,6 +60,7 @@
|
|
57
60
|
"text.signout successfully": "็ปๅบๆๅใ",
|
58
61
|
"text.user activated successfully": "็จๆทๆฟๆดปๆๅ",
|
59
62
|
"text.user credential registered successfully": "่ฎพๅคๆณจๅๅทฒๆๅๅฎๆใ็ฐๅจๅฏไปฅไฝฟ็จ็็ฉ่ฏๅซ่ฎค่ฏใ",
|
63
|
+
"text.user inactivated successfully": "็จๆทๅทฒๆๅๅ็จ",
|
60
64
|
"text.user registered successfully": "็จๆทๆณจๅๆๅใ ่ฏทๆฅ็็ตๅญ้ฎไปถไปฅๆฟๆดปๅธๆทใ",
|
61
65
|
"text.verification email sent": "้ช่ฏ้ฎไปถๅทฒๅ้"
|
62
66
|
}
|