@things-factory/auth-base 6.0.49 → 6.0.53

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": "6.0.49",
3
+ "version": "6.0.53",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -41,5 +41,5 @@
41
41
  "passport-jwt": "^4.0.0",
42
42
  "passport-local": "^1.0.0"
43
43
  },
44
- "gitHead": "e107d6f692d008add950e000d2653bcbbd711a24"
44
+ "gitHead": "1b60f52b7e043286423881b8fb41f1fa08f9ba6d"
45
45
  }
package/server/index.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { getRepository } from '@things-factory/shell'
2
+ import { Privilege } from './service/privilege/privilege'
3
+
1
4
  import './routes'
2
5
 
3
6
  export * from './service'
@@ -15,3 +18,16 @@ export * from './utils/access-token-cookie'
15
18
  export * from './errors'
16
19
 
17
20
  export * from './types'
21
+
22
+ process.on('bootstrap-module-start' as any, async ({ app, config, client }: any) => {
23
+ const privileges = process['PRIVILEGES']
24
+ const privilegeRepository = getRepository(Privilege)
25
+
26
+ for (const [category, name] of Object.values(privileges as [string, string])) {
27
+ if (0 == (await privilegeRepository.count({ where: { category, name } }))) {
28
+ await privilegeRepository.save({ category, name })
29
+ }
30
+ }
31
+
32
+ console.log('[auth-base:bootstrap] Synchronization for privilege master has just done.')
33
+ })
@@ -2,8 +2,6 @@ import { defaultFieldResolver, GraphQLSchema } from 'graphql'
2
2
  import gql from 'graphql-tag'
3
3
 
4
4
  import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils'
5
- import { getRepository } from '@things-factory/shell'
6
-
7
5
  import { User } from '../user/user'
8
6
 
9
7
  process['PRIVILEGES'] = {}
@@ -47,40 +45,7 @@ export const privilegeDirectiveResolver = (schema: GraphQLSchema) =>
47
45
 
48
46
  if (!category || !privilege) throw new Error(`Unauthorized!`)
49
47
 
50
- const result = await getRepository(User).query(
51
- `
52
- SELECT
53
- COUNT(1) AS has_privilege
54
- FROM
55
- privileges
56
- WHERE
57
- category = '${category}'
58
- AND
59
- name = '${privilege}'
60
- AND
61
- id
62
- IN (
63
- SELECT
64
- RP.privileges_id
65
- FROM
66
- users_roles UR
67
- INNER JOIN
68
- roles_privileges RP
69
- ON
70
- UR.roles_id = RP.roles_id
71
- LEFT JOIN
72
- roles R
73
- ON
74
- R.id = UR.roles_id
75
- WHERE
76
- UR.users_id = '${user?.id}'
77
- AND
78
- R.domain_id = '${domain?.id}'
79
- )
80
- `
81
- )
82
-
83
- if (result[0].has_privilege > 0) {
48
+ if (await User.hasPrivilege(privilege, category, domain, user)) {
84
49
  return await resolve.call(this, source, args, context, info)
85
50
  } else {
86
51
  throw new Error(`Unauthorized!`)
@@ -1,4 +1,4 @@
1
- import { Arg, Ctx, Mutation, Resolver } from 'type-graphql'
1
+ import { Arg, Ctx, Mutation, Resolver, Directive } from 'type-graphql'
2
2
  import { In } from 'typeorm'
3
3
 
4
4
  import { getRepository } from '@things-factory/shell'
@@ -9,14 +9,35 @@ import { NewPrivilege, PrivilegePatch } from './privilege-types'
9
9
 
10
10
  @Resolver(Privilege)
11
11
  export class PrivilegeMutation {
12
+ @Directive('@privilege(superUserGranted:true)')
13
+ @Mutation(returns => Boolean, {
14
+ description: 'To synchronize privilege master from API schema.'
15
+ })
16
+ async synchronizePrivilegeMaster(
17
+ @Arg('privilege') privilege: NewPrivilege,
18
+ @Ctx() context: ResolverContext
19
+ ): Promise<Boolean> {
20
+ const privileges = process['PRIVILEGES']
21
+ const privilegeRepository = getRepository(Privilege)
22
+
23
+ for (const [category, name] of Object.values(privileges as [string, string])) {
24
+ if (0 == (await privilegeRepository.count({ where: { category, name } }))) {
25
+ await privilegeRepository.save({ category, name })
26
+ }
27
+ }
28
+
29
+ return true
30
+ }
31
+
32
+ @Directive('@privilege(superUserGranted:true)')
12
33
  @Mutation(returns => Privilege, { description: 'To create new privilege' })
13
34
  async createPrivilege(
14
35
  @Arg('privilege') privilege: NewPrivilege,
15
36
  @Ctx() context: ResolverContext
16
37
  ): Promise<Privilege> {
17
38
  if (privilege.roles && privilege.roles.length) {
18
- privilege.roles = await getRepository(Role).findBy({
19
- id: In(privilege.roles.map((role: Partial<Role>) => role.id))
39
+ privilege.roles = await getRepository(Role).findBy({
40
+ id: In(privilege.roles.map((role: Partial<Role>) => role.id))
20
41
  })
21
42
  }
22
43
 
@@ -27,6 +48,7 @@ export class PrivilegeMutation {
27
48
  })
28
49
  }
29
50
 
51
+ @Directive('@privilege(superUserGranted:true)')
30
52
  @Mutation(returns => Privilege, { description: 'To modify privilege information' })
31
53
  async updatePrivilege(
32
54
  @Arg('name') name: string,
@@ -57,6 +79,7 @@ export class PrivilegeMutation {
57
79
  })
58
80
  }
59
81
 
82
+ @Directive('@privilege(superUserGranted:true)')
60
83
  @Mutation(returns => Boolean, { description: 'To delete privilege' })
61
84
  async deletePrivilege(
62
85
  @Arg('name') name: string,
@@ -1,6 +1,5 @@
1
- import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
-
3
- import { buildQuery, getRepository, ListParam } from '@things-factory/shell'
1
+ import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+ import { getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
4
3
 
5
4
  import { Role } from '../role/role'
6
5
  import { User } from '../user/user'
@@ -9,6 +8,7 @@ import { PrivilegeList } from './privilege-types'
9
8
 
10
9
  @Resolver(Privilege)
11
10
  export class PrivilegeQuery {
11
+ @Directive('@privilege(category: "privilege", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
12
12
  @Query(returns => Privilege, { description: 'To fetch privilege' })
13
13
  async privilege(@Arg('name') name: string, @Arg('category') category: string): Promise<Privilege> {
14
14
  return await getRepository(Privilege).findOne({
@@ -16,16 +16,28 @@ export class PrivilegeQuery {
16
16
  })
17
17
  }
18
18
 
19
+ @Directive('@privilege(category: "privilege", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
19
20
  @Query(returns => PrivilegeList, { description: 'To fetch multiple privileges' })
20
21
  async privileges(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<PrivilegeList> {
21
- const queryBuilder = getRepository(Privilege).createQueryBuilder()
22
- buildQuery(queryBuilder, params, context, { domainRef: false })
23
-
24
- const [items, total] = await queryBuilder.getManyAndCount()
22
+ const [items, total] = await getQueryBuilderFromListParams({
23
+ params,
24
+ repository: getRepository(Privilege),
25
+ searchables: ['name', 'category']
26
+ }).getManyAndCount()
25
27
 
26
28
  return { items, total }
27
29
  }
28
30
 
31
+ @Query(returns => Boolean, { description: 'To query whether I have the given permission' })
32
+ async hasPrivilege(
33
+ @Arg('name') name: string,
34
+ @Arg('category') category: string,
35
+ @Ctx() context: ResolverContext
36
+ ): Promise<Boolean> {
37
+ const { domain, user } = context.state
38
+ return await User.hasPrivilege(name, category, domain, user)
39
+ }
40
+
29
41
  @FieldResolver(type => String)
30
42
  async description(@Root() privilege: Privilege, @Ctx() context: ResolverContext) {
31
43
  const { t } = context
@@ -5,7 +5,6 @@ import {
5
5
  Column,
6
6
  CreateDateColumn,
7
7
  Entity,
8
- getRepository,
9
8
  Index,
10
9
  JoinTable,
11
10
  ManyToMany,
@@ -16,7 +15,7 @@ import {
16
15
  } from 'typeorm'
17
16
 
18
17
  import { config } from '@things-factory/env'
19
- import { Domain } from '@things-factory/shell'
18
+ import { Domain, getRepository } from '@things-factory/shell'
20
19
 
21
20
  import { validatePasswordByRule } from '../../controllers/utils/password-rule'
22
21
  import { AuthError } from '../../errors/auth-error'
@@ -248,4 +247,23 @@ export class User {
248
247
  return user
249
248
  }
250
249
  }
250
+
251
+ static async hasPrivilege(name: string, category: string, domain: Domain, user: User) {
252
+ const result = await getRepository(User).query(
253
+ `SELECT COUNT(1) AS has_privilege FROM privileges
254
+ WHERE category = '${category}'
255
+ AND name = '${name}'
256
+ AND id IN (
257
+ SELECT RP.privileges_id
258
+ FROM users_roles UR
259
+ INNER JOIN roles_privileges RP ON UR.roles_id = RP.roles_id
260
+ LEFT JOIN roles R ON R.id = UR.roles_id
261
+ WHERE UR.users_id = '${user?.id}'
262
+ AND R.domain_id = '${domain?.id}'
263
+ )
264
+ `
265
+ )
266
+
267
+ return result[0].has_privilege > 0
268
+ }
251
269
  }