@things-factory/auth-base 8.0.0-alpha.28 → 8.0.0-alpha.29
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/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.29",
|
4
4
|
"main": "dist-server/index.js",
|
5
5
|
"browser": "dist-client/index.js",
|
6
6
|
"things-factory": true,
|
@@ -32,10 +32,10 @@
|
|
32
32
|
"dependencies": {
|
33
33
|
"@simplewebauthn/browser": "^10.0.0",
|
34
34
|
"@simplewebauthn/server": "^10.0.0",
|
35
|
-
"@things-factory/email-base": "^8.0.0-alpha.
|
35
|
+
"@things-factory/email-base": "^8.0.0-alpha.29",
|
36
36
|
"@things-factory/env": "^8.0.0-alpha.8",
|
37
|
-
"@things-factory/shell": "^8.0.0-alpha.
|
38
|
-
"@things-factory/utils": "^8.0.0-alpha.
|
37
|
+
"@things-factory/shell": "^8.0.0-alpha.29",
|
38
|
+
"@things-factory/utils": "^8.0.0-alpha.29",
|
39
39
|
"@types/webappsec-credential-management": "^0.6.8",
|
40
40
|
"jsonwebtoken": "^9.0.0",
|
41
41
|
"koa-passport": "^6.0.0",
|
@@ -46,5 +46,5 @@
|
|
46
46
|
"passport-jwt": "^4.0.0",
|
47
47
|
"passport-local": "^1.0.0"
|
48
48
|
},
|
49
|
-
"gitHead": "
|
49
|
+
"gitHead": "a7592d7dc0886734d2798ee5756c51b0c0aa13fa"
|
50
50
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
2
2
|
import { GraphQLEmailAddress } from 'graphql-scalars'
|
3
|
-
import { ILike, In, SelectQueryBuilder } from 'typeorm'
|
3
|
+
import { ILike, In, SelectQueryBuilder, EntityManager } from 'typeorm'
|
4
4
|
|
5
5
|
import { config } from '@things-factory/env'
|
6
6
|
import { Domain, getRepository, ObjectRef } from '@things-factory/shell'
|
@@ -17,13 +17,13 @@ export class UserMutation {
|
|
17
17
|
@Directive('@transaction')
|
18
18
|
@Mutation(returns => User, { description: 'To create new user' })
|
19
19
|
async createUser(@Arg('user') user: NewUser, @Ctx() context: ResolverContext) {
|
20
|
-
const { domain } = context.state
|
20
|
+
const { domain, tx } = context.state
|
21
21
|
const { defaultPassword } = config.get('password')
|
22
22
|
const { email } = user
|
23
23
|
|
24
24
|
user.email = email.trim()
|
25
25
|
|
26
|
-
const oldUser: User = await getRepository(User).findOne({ where: { email: ILike(user.email) } })
|
26
|
+
const oldUser: User = await getRepository(User, tx).findOne({ where: { email: ILike(user.email) } })
|
27
27
|
if (oldUser) {
|
28
28
|
throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: 'operato' }))
|
29
29
|
}
|
@@ -38,14 +38,14 @@ export class UserMutation {
|
|
38
38
|
|
39
39
|
const salt = User.generateSalt()
|
40
40
|
|
41
|
-
return await getRepository(User).save({
|
41
|
+
return await getRepository(User, tx).save({
|
42
42
|
creator: context.state.user,
|
43
43
|
updater: context.state.user,
|
44
44
|
...user,
|
45
45
|
domains: [domain],
|
46
46
|
roles:
|
47
47
|
user.roles && user.roles.length
|
48
|
-
? await getRepository(Role).findBy({
|
48
|
+
? await getRepository(Role, tx).findBy({
|
49
49
|
id: In(user.roles.map(role => role.id)),
|
50
50
|
domain: { id: domain.id }
|
51
51
|
})
|
@@ -64,7 +64,7 @@ export class UserMutation {
|
|
64
64
|
@Arg('patch') patch: UserPatch,
|
65
65
|
@Ctx() context: ResolverContext
|
66
66
|
) {
|
67
|
-
const { domain, user: updater }: { domain: Domain; user: User } = context.state
|
67
|
+
const { domain, user: updater, tx }: { domain: Domain; user: User; tx?: EntityManager } = context.state
|
68
68
|
const qb: SelectQueryBuilder<User> = buildDomainUsersQueryBuilder(domain.id, 'USER')
|
69
69
|
const user: User = await qb
|
70
70
|
.andWhere('LOWER(USER.email) = :email', { email: email?.toLowerCase().trim() || '' })
|
@@ -73,14 +73,16 @@ export class UserMutation {
|
|
73
73
|
.getOne()
|
74
74
|
|
75
75
|
if (patch.roles) {
|
76
|
-
patch.roles = await getRepository(Role).find({
|
76
|
+
patch.roles = await getRepository(Role, tx).find({
|
77
|
+
where: { id: In(patch.roles.map((r: Partial<Role>) => r.id)) }
|
78
|
+
})
|
77
79
|
}
|
78
80
|
|
79
81
|
if (patch.status && patch.status === 'activated') {
|
80
82
|
user.status = UserStatus.ACTIVATED
|
81
83
|
}
|
82
84
|
|
83
|
-
return await getRepository(User).save({
|
85
|
+
return await getRepository(User, tx).save({
|
84
86
|
...user,
|
85
87
|
...patch,
|
86
88
|
updater
|
@@ -92,7 +94,7 @@ export class UserMutation {
|
|
92
94
|
@Mutation(returns => [User], { description: 'To modify multiple users information' })
|
93
95
|
async updateMultipleUser(@Arg('patches', type => [UserPatch]) patches: UserPatch[], @Ctx() context: ResolverContext) {
|
94
96
|
const { domain, user, tx } = context.state
|
95
|
-
const userRepo =
|
97
|
+
const userRepo = getRepository(User, tx)
|
96
98
|
|
97
99
|
let results = []
|
98
100
|
const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
|
@@ -207,8 +209,8 @@ export class UserMutation {
|
|
207
209
|
@Arg('email', type => GraphQLEmailAddress) email: string,
|
208
210
|
@Ctx() context: ResolverContext
|
209
211
|
): Promise<boolean> {
|
210
|
-
const { domain } = context.state
|
211
|
-
const invitee: User = await getRepository(User).findOne({
|
212
|
+
const { domain, tx } = context.state
|
213
|
+
const invitee: User = await getRepository(User, tx).findOne({
|
212
214
|
where: { email: ILike(email) },
|
213
215
|
relations: ['domains']
|
214
216
|
})
|
@@ -222,7 +224,7 @@ export class UserMutation {
|
|
222
224
|
throw new Error(context.t('error.x already exists in y', { x: context.t('field.user'), y: domain.name }))
|
223
225
|
}
|
224
226
|
invitee.domains = [...existingDomains, domain]
|
225
|
-
await getRepository(User).save(invitee)
|
227
|
+
await getRepository(User, tx).save(invitee)
|
226
228
|
|
227
229
|
return true
|
228
230
|
}
|
@@ -236,9 +238,10 @@ export class UserMutation {
|
|
236
238
|
): Promise<boolean> {
|
237
239
|
const { tx, domain } = context.state
|
238
240
|
|
239
|
-
let user: User = await tx
|
240
|
-
|
241
|
-
|
241
|
+
let user: User = await getRepository(User, tx).findOne({
|
242
|
+
where: { email: ILike(email) },
|
243
|
+
relations: ['domains', 'roles', 'roles.domain']
|
244
|
+
})
|
242
245
|
if (!user) {
|
243
246
|
throw new Error(context.t('error.failed to find x', { x: context.t('field.user') }))
|
244
247
|
}
|
@@ -254,7 +257,7 @@ export class UserMutation {
|
|
254
257
|
// Remove domain's roles that user has
|
255
258
|
user.roles = user.roles.filter((role: Role) => role.domain.id !== domain.id)
|
256
259
|
|
257
|
-
await
|
260
|
+
await getRepository(User, tx).save(user)
|
258
261
|
|
259
262
|
return true
|
260
263
|
}
|
@@ -266,12 +269,30 @@ export class UserMutation {
|
|
266
269
|
@Arg('email', type => GraphQLEmailAddress) email: string,
|
267
270
|
@Ctx() context: ResolverContext
|
268
271
|
): Promise<boolean> {
|
269
|
-
const { domain } = context.state
|
270
|
-
const user: User = await getRepository(User).findOne({
|
271
|
-
where: { email: ILike(email) }
|
272
|
+
const { domain, tx } = context.state
|
273
|
+
const user: User = await getRepository(User, tx).findOne({
|
274
|
+
where: { email: ILike(email) },
|
275
|
+
relations: ['domains', 'roles']
|
272
276
|
})
|
277
|
+
|
278
|
+
if (!user) {
|
279
|
+
throw new Error('Failed to find user')
|
280
|
+
}
|
281
|
+
|
282
|
+
if (user.status !== UserStatus.ACTIVATED) {
|
283
|
+
throw new Error('Only activated users are eligible to receive admin privileges.')
|
284
|
+
}
|
285
|
+
|
286
|
+
if (user.domains.map((d: Domain) => d.id).indexOf(domain.id) < 0) {
|
287
|
+
throw new Error(`User is not belongs to current domain`)
|
288
|
+
}
|
289
|
+
|
290
|
+
if (user.roles.filter((r: Role) => r.domainId == domain.id).length == 0) {
|
291
|
+
throw new Error(`Only users with at least one role in this domain are eligible to receive admin privileges.`)
|
292
|
+
}
|
293
|
+
|
273
294
|
domain.owner = user.id
|
274
|
-
await getRepository(Domain).save(domain)
|
295
|
+
await getRepository(Domain, tx).save(domain)
|
275
296
|
|
276
297
|
return true
|
277
298
|
}
|
@@ -282,7 +303,7 @@ export class UserMutation {
|
|
282
303
|
async activateUser(@Arg('userId') userId: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
283
304
|
const { tx, domain } = context.state
|
284
305
|
|
285
|
-
const targetUser: User = await
|
306
|
+
const targetUser: User = await getRepository(User, tx).findOne({
|
286
307
|
where: { id: userId },
|
287
308
|
relations: ['domains']
|
288
309
|
})
|
@@ -297,7 +318,7 @@ export class UserMutation {
|
|
297
318
|
targetUser.failCount = 0
|
298
319
|
targetUser.status = UserStatus.ACTIVATED
|
299
320
|
|
300
|
-
await
|
321
|
+
await getRepository(User, tx).save(targetUser)
|
301
322
|
|
302
323
|
return true
|
303
324
|
}
|
@@ -308,7 +329,7 @@ export class UserMutation {
|
|
308
329
|
async inactivateUser(@Arg('userId') userId: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
309
330
|
const { tx, domain } = context.state
|
310
331
|
|
311
|
-
const targetUser: User = await
|
332
|
+
const targetUser: User = await getRepository(User, tx).findOne({
|
312
333
|
where: { id: userId },
|
313
334
|
relations: ['domains']
|
314
335
|
})
|
@@ -326,7 +347,7 @@ export class UserMutation {
|
|
326
347
|
|
327
348
|
targetUser.status = UserStatus.INACTIVE
|
328
349
|
|
329
|
-
await
|
350
|
+
await getRepository(User, tx).save(targetUser)
|
330
351
|
|
331
352
|
return true
|
332
353
|
}
|
@@ -342,7 +363,7 @@ export class UserMutation {
|
|
342
363
|
throw new Error('No default password found')
|
343
364
|
}
|
344
365
|
|
345
|
-
const targetUser: User = await
|
366
|
+
const targetUser: User = await getRepository(User, tx).findOne({
|
346
367
|
where: { id: userId },
|
347
368
|
relations: ['domains']
|
348
369
|
})
|
@@ -356,7 +377,7 @@ export class UserMutation {
|
|
356
377
|
|
357
378
|
targetUser.salt = User.generateSalt()
|
358
379
|
targetUser.password = User.encode(defaultPassword, targetUser.salt)
|
359
|
-
await
|
380
|
+
await getRepository(User, tx).save(targetUser)
|
360
381
|
|
361
382
|
return true
|
362
383
|
}
|
@@ -371,7 +392,7 @@ export class UserMutation {
|
|
371
392
|
@Ctx() context: ResolverContext
|
372
393
|
) {
|
373
394
|
const { domain, tx } = context.state
|
374
|
-
let user: User = await
|
395
|
+
let user: User = await getRepository(User, tx).findOne({
|
375
396
|
where: { id: userId },
|
376
397
|
relations: ['domains', 'roles']
|
377
398
|
})
|
@@ -387,6 +408,6 @@ export class UserMutation {
|
|
387
408
|
user.roles = user.roles.filter((r: Role) => availableRoleIds.indexOf(r.id) < 0)
|
388
409
|
user.roles = user.roles.concat(selectedRoles as Role[])
|
389
410
|
|
390
|
-
return await
|
411
|
+
return await getRepository(User, tx).save(user)
|
391
412
|
}
|
392
413
|
}
|