@things-factory/shell 6.2.44 → 6.2.50

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.
Files changed (31) hide show
  1. package/dist-server/middlewares/domain-middleware.js +45 -9
  2. package/dist-server/middlewares/domain-middleware.js.map +1 -1
  3. package/dist-server/server-dev.js +0 -12
  4. package/dist-server/server-dev.js.map +1 -1
  5. package/dist-server/server.js +0 -12
  6. package/dist-server/server.js.map +1 -1
  7. package/dist-server/service/domain/{domain-resolver.d.ts → domain-Mutation.d.ts} +4 -7
  8. package/dist-server/service/domain/{domain-resolver.js → domain-Mutation.js} +25 -61
  9. package/dist-server/service/domain/domain-Mutation.js.map +1 -0
  10. package/dist-server/service/domain/domain-query.d.ts +9 -0
  11. package/dist-server/service/domain/domain-query.js +74 -0
  12. package/dist-server/service/domain/domain-query.js.map +1 -0
  13. package/dist-server/service/domain/domain-types.js.map +1 -1
  14. package/dist-server/service/domain/domain.d.ts +11 -0
  15. package/dist-server/service/domain/domain.js +14 -1
  16. package/dist-server/service/domain/domain.js.map +1 -1
  17. package/dist-server/service/domain/index.d.ts +3 -2
  18. package/dist-server/service/domain/index.js +3 -2
  19. package/dist-server/service/domain/index.js.map +1 -1
  20. package/dist-server/service/index.d.ts +1 -1
  21. package/dist-server/tsconfig.tsbuildinfo +1 -1
  22. package/package.json +3 -3
  23. package/server/middlewares/domain-middleware.ts +52 -9
  24. package/server/server-dev.ts +0 -16
  25. package/server/server.ts +0 -16
  26. package/server/service/domain/{domain-resolver.ts → domain-mutation.ts} +24 -45
  27. package/server/service/domain/domain-query.ts +52 -0
  28. package/server/service/domain/domain-types.ts +1 -1
  29. package/server/service/domain/domain.ts +33 -2
  30. package/server/service/domain/index.ts +3 -2
  31. package/dist-server/service/domain/domain-resolver.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/shell",
3
- "version": "6.2.44",
3
+ "version": "6.2.50",
4
4
  "description": "Core module for framework",
5
5
  "bin": {
6
6
  "things-factory": "bin/things-factory",
@@ -63,7 +63,7 @@
63
63
  "@things-factory/env": "^6.2.33",
64
64
  "@things-factory/operato-license-checker": "^4.0.4",
65
65
  "@things-factory/styles": "^6.2.33",
66
- "@things-factory/utils": "^6.2.33",
66
+ "@things-factory/utils": "^6.2.48",
67
67
  "@webcomponents/webcomponentsjs": "^2.6.0",
68
68
  "args": "^5.0.0",
69
69
  "broadcastchannel-polyfill": "^1.0.1",
@@ -133,5 +133,5 @@
133
133
  "pg": "^8.7.3",
134
134
  "sqlite3": "^5.0.8"
135
135
  },
136
- "gitHead": "a2a1ebf823f6b1315e751b12a01372e9a867d7af"
136
+ "gitHead": "4dc51db04b745ac434d2bb874038ac4c3b47989b"
137
137
  }
@@ -1,17 +1,60 @@
1
+ import requestIp from 'request-ip'
1
2
  import { getDomainFromURL } from '../utils'
2
3
 
3
4
  export async function domainMiddleware(context: any, next: any) {
4
- const { domain } = context.state
5
+ var { domain } = context.state
6
+ if (!domain) {
7
+ /*
8
+ * The domainType should be checked only when signin and checkin.
9
+ * For purposes such as API calls, the target domainType may be different from the system domainType.
10
+ * So, we don't check domainType here.
11
+ */
12
+ domain = await getDomainFromURL(context)
13
+ }
14
+
5
15
  if (domain) {
6
- return await next()
16
+ const ip = context.ip || requestIp.getClientIp(context.req)
17
+ const { whitelist = [], blacklist = [], protectedlist = [], privileges = [] } = domain.iplist || {}
18
+
19
+ if (Array.isArray(whitelist) && whitelist.length > 0) {
20
+ /* whitelist 우선 */
21
+ const whitelisted =
22
+ Array.isArray(whitelist) &&
23
+ whitelist.some(item => {
24
+ return new RegExp(item).test(ip)
25
+ })
26
+
27
+ if (!whitelisted) {
28
+ context.status = 403
29
+ return
30
+ }
31
+ } else {
32
+ const blacklisted =
33
+ Array.isArray(blacklist) &&
34
+ blacklist.some(item => {
35
+ return new RegExp(item).test(ip)
36
+ })
37
+
38
+ if (blacklisted) {
39
+ context.status = 403
40
+ return
41
+ }
42
+ }
43
+
44
+ if (Array.isArray(protectedlist) && protectedlist.length > 0) {
45
+ const protectedIP = protectedlist.some(item => {
46
+ return new RegExp(item).test(ip)
47
+ })
48
+
49
+ context.state.unsafeIP = !protectedIP
50
+
51
+ if (!protectedIP) {
52
+ context.state.prohibitedPrivileges = privileges
53
+ }
54
+ }
7
55
  }
8
56
 
9
- /*
10
- * The domainType should be checked only when signin and checkin.
11
- * For purposes such as API calls, the target domainType may be different from the system domainType.
12
- * So, we don't check domainType here.
13
- */
14
- context.state.domain = await getDomainFromURL(context)
57
+ context.state.domain = domain
15
58
 
16
- await next()
59
+ return next()
17
60
  }
@@ -15,7 +15,6 @@ import { useServer } from 'graphql-ws/lib/use/ws'
15
15
  import { createServer } from 'http'
16
16
  import Koa from 'koa'
17
17
  import koaBodyParser from 'koa-bodyparser'
18
- import ip from 'koa-ip'
19
18
  import koaStatic from 'koa-static'
20
19
  import compose from 'koa-compose'
21
20
  import { historyApiFallback } from 'koa2-connect-history-api-fallback'
@@ -115,21 +114,6 @@ const bootstrap = async () => {
115
114
  })
116
115
  )
117
116
 
118
- const whitelist = config.get('whitelist')
119
- const blacklist = config.get('blacklist')
120
-
121
- if (whitelist || blacklist) {
122
- app.use(
123
- ip({
124
- whitelist,
125
- blacklist,
126
- handler: async (ctx, next) => {
127
- ctx.status = 403
128
- }
129
- })
130
- )
131
- }
132
-
133
117
  var subscriptionMiddleware = []
134
118
  process.emit('bootstrap-module-subscription' as any, app, subscriptionMiddleware)
135
119
 
package/server/server.ts CHANGED
@@ -15,7 +15,6 @@ import { useServer } from 'graphql-ws/lib/use/ws'
15
15
  import { createServer } from 'http'
16
16
  import Koa from 'koa'
17
17
  import koaBodyParser from 'koa-bodyparser'
18
- import ip from 'koa-ip'
19
18
  import koaStatic from 'koa-static'
20
19
  import compose from 'koa-compose'
21
20
  import { historyApiFallback } from 'koa2-connect-history-api-fallback'
@@ -90,21 +89,6 @@ const bootstrap = async () => {
90
89
  })
91
90
  )
92
91
 
93
- const whitelist = config.get('whitelist')
94
- const blacklist = config.get('blacklist')
95
-
96
- if (whitelist || blacklist) {
97
- app.use(
98
- ip({
99
- whitelist,
100
- blacklist,
101
- handler: async (ctx, next) => {
102
- ctx.status = 403
103
- }
104
- })
105
- )
106
- }
107
-
108
92
  var subscriptionMiddleware = []
109
93
  process.emit('bootstrap-module-subscription' as any, app, subscriptionMiddleware)
110
94
 
@@ -1,53 +1,16 @@
1
- import { Arg, Args, Ctx, Directive, Mutation, Query, Resolver, FieldResolver, Root } from 'type-graphql'
1
+ import { Arg, Args, Ctx, Directive, Mutation, Query, Resolver, Root } from 'type-graphql'
2
2
  import { In, Repository } from 'typeorm'
3
3
 
4
4
  import { slugger } from '@things-factory/utils'
5
5
 
6
6
  import { getRepository } from '../../initializers/database'
7
- import { getQueryBuilderFromListParams } from '../../utils/get-query-builder-from-list-params'
8
7
 
9
- import { ListParam } from '../common-types/list-param'
10
- import { Domain } from './domain'
11
- import { DomainList, DomainPatch } from './domain-types'
8
+ import { Domain, IPList } from './domain'
9
+ import { DomainPatch } from './domain-types'
10
+ import { ScalarObject } from '../common-types'
12
11
 
13
12
  @Resolver(Domain)
14
- export class DomainResolver {
15
- @Directive('@privilege(category: "system", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
16
- @Query(returns => Domain, { description: 'To fetch domain' })
17
- async domain(@Arg('id') id: string, @Ctx() context: any): Promise<Domain> {
18
- const repository = getRepository(Domain)
19
-
20
- return await repository.findOneBy({ id })
21
- }
22
-
23
- @Directive('@privilege(superUserGranted: true)')
24
- @Query(returns => DomainList, { description: 'To fetch all domains (Only superuser is granted this privilege.)' })
25
- async domains(@Args() params: ListParam, @Ctx() context: any): Promise<DomainList> {
26
- const queryBuilder = await getQueryBuilderFromListParams({
27
- repository: getRepository(Domain),
28
- alias: 'ContactPoint',
29
- params,
30
- searchables: ['name', 'description', 'subdomain']
31
- })
32
-
33
- const [items, total] = await queryBuilder.getManyAndCount()
34
-
35
- return { items, total }
36
- }
37
-
38
- // @Query(returns => Boolean, { description: 'To check if given domain is exist' })
39
- // async checkExistsDomain(@Arg('name') name: string) {
40
- // const domainRepository: Repository<Domain> = getRepository(Domain)
41
- // const targetSubdomain: string = slugger(name)
42
-
43
- // const oldDomain = await domainRepository.findOneBy({ subdomain: targetSubdomain })
44
- // if (oldDomain) {
45
- // throw new Error('domain is duplicated')
46
- // }
47
-
48
- // return true
49
- // }
50
-
13
+ export class DomainMutation {
51
14
  @Directive('@transaction')
52
15
  @Directive('@privilege(superUserGranted: true)')
53
16
  @Mutation(returns => Domain, { description: 'To create domain (Only superuser is granted this privilege.)' })
@@ -134,8 +97,24 @@ export class DomainResolver {
134
97
  return true
135
98
  }
136
99
 
137
- @FieldResolver(type => Domain)
138
- async parent(@Root() domain: Domain): Promise<Domain> {
139
- return domain.parentId && (await getRepository(Domain).findOneBy({ id: domain.parentId }))
100
+ @Directive('@transaction')
101
+ @Directive(
102
+ '@privilege(category: "security", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'
103
+ )
104
+ @Mutation(returns => ScalarObject, { nullable: true, description: 'To update secure IP list for domain' })
105
+ async updateSecureIPList(
106
+ @Arg('iplist', type => ScalarObject) iplist: IPList,
107
+ @Ctx() context: any
108
+ ): Promise<IPList | null> {
109
+ const { domain } = context.state
110
+ const repository = getRepository(Domain)
111
+ // const domain: Domain = await repository.findOneBy({ id })
112
+
113
+ const { iplist: result } = await repository.save({
114
+ ...domain,
115
+ iplist
116
+ } as any)
117
+
118
+ return result
140
119
  }
141
120
  }
@@ -0,0 +1,52 @@
1
+ import { Arg, Args, Ctx, Directive, Mutation, Query, Resolver, FieldResolver, Root } from 'type-graphql'
2
+ import { In, Repository } from 'typeorm'
3
+
4
+ import { getRepository } from '../../initializers/database'
5
+ import { getQueryBuilderFromListParams } from '../../utils/get-query-builder-from-list-params'
6
+
7
+ import { ListParam } from '../common-types/list-param'
8
+ import { Domain, IPList } from './domain'
9
+ import { DomainList } from './domain-types'
10
+ import { ScalarObject } from '../common-types'
11
+
12
+ @Resolver(Domain)
13
+ export class DomainQuery {
14
+ @Directive('@privilege(superUserGranted: true)')
15
+ @Query(returns => Domain, { description: 'To fetch domain' })
16
+ async domain(@Arg('id') id: string, @Ctx() context: any): Promise<Domain> {
17
+ const repository = getRepository(Domain)
18
+
19
+ return await repository.findOneBy({ id })
20
+ }
21
+
22
+ @Directive('@privilege(superUserGranted: true)')
23
+ @Query(returns => DomainList, { description: 'To fetch all domains (Only superuser is granted this privilege.)' })
24
+ async domains(@Args() params: ListParam, @Ctx() context: any): Promise<DomainList> {
25
+ const queryBuilder = await getQueryBuilderFromListParams({
26
+ repository: getRepository(Domain),
27
+ alias: 'ContactPoint',
28
+ params,
29
+ searchables: ['name', 'description', 'subdomain']
30
+ })
31
+
32
+ const [items, total] = await queryBuilder.getManyAndCount()
33
+
34
+ return { items, total }
35
+ }
36
+
37
+ @Directive('@privilege(category: "security", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
38
+ @Query(returns => ScalarObject, { nullable: true, description: 'To fetch domain' })
39
+ async secureIPList(@Ctx() context: any): Promise<IPList | null> {
40
+ const { domain } = context.state
41
+ // const repository = getRepository(Domain)
42
+
43
+ // const { iplist } = await repository.findOneBy({ id })
44
+
45
+ return domain.iplist
46
+ }
47
+
48
+ @FieldResolver(type => Domain)
49
+ async parent(@Root() domain: Domain): Promise<Domain> {
50
+ return domain.parentId && (await getRepository(Domain).findOneBy({ id: domain.parentId }))
51
+ }
52
+ }
@@ -1,5 +1,5 @@
1
1
  import { ObjectType, InputType, Field, Int } from 'type-graphql'
2
- import { Domain } from './domain'
2
+ import { Domain, IPList } from './domain'
3
3
  import { ObjectRef, ScalarObject } from '../common-types'
4
4
 
5
5
  @InputType()
@@ -1,4 +1,14 @@
1
- import { Column, CreateDateColumn, ManyToOne, OneToMany, RelationId, Entity, Index, UpdateDateColumn } from 'typeorm'
1
+ import {
2
+ Column,
3
+ CreateDateColumn,
4
+ ManyToOne,
5
+ OneToMany,
6
+ RelationId,
7
+ Entity,
8
+ Index,
9
+ UpdateDateColumn,
10
+ DeleteDateColumn
11
+ } from 'typeorm'
2
12
  import { ObjectType, Directive, Field, ID } from 'type-graphql'
3
13
  import { config } from '@things-factory/env'
4
14
  import { ScalarObject } from '../common-types'
@@ -9,8 +19,21 @@ const domainPrimaryOption = config.get('domainPrimaryOption')
9
19
  const domainPrimaryType = domainPrimaryOption?.type
10
20
  const domainPrimaryStrategy = domainPrimaryOption?.strategy
11
21
 
22
+ export type IPList = {
23
+ whitelist?: string[]
24
+ blacklist?: string[]
25
+ protectedlist?: string[]
26
+ privileges?: {
27
+ category: string
28
+ name: string
29
+ }[]
30
+ }
31
+
12
32
  @Entity()
13
- @Index('ix_domain_0', (domain: Domain) => [domain.subdomain], { unique: true })
33
+ @Index('ix_domain_0', (domain: Domain) => [domain.subdomain, domain.deletedAt], {
34
+ unique: true,
35
+ where: '"deleted_at" IS NULL'
36
+ })
14
37
  @ObjectType()
15
38
  export class Domain {
16
39
  @Field(type => ID)
@@ -102,6 +125,10 @@ export class Domain {
102
125
  @Column({ nullable: true })
103
126
  theme: string
104
127
 
128
+ @Column('simple-json', { nullable: true })
129
+ @Field(type => ScalarObject, { nullable: true })
130
+ iplist?: IPList
131
+
105
132
  @Column('simple-json', { nullable: true })
106
133
  @Field(type => ScalarObject, { nullable: true })
107
134
  attributes?: any
@@ -113,4 +140,8 @@ export class Domain {
113
140
  @Field({ nullable: true })
114
141
  @UpdateDateColumn()
115
142
  updatedAt: Date
143
+
144
+ @DeleteDateColumn()
145
+ @Field({ nullable: true })
146
+ deletedAt?: Date
116
147
  }
@@ -1,5 +1,6 @@
1
1
  import { Domain } from './domain'
2
- import { DomainResolver } from './domain-resolver'
2
+ import { DomainQuery } from './domain-query'
3
+ import { DomainMutation } from './domain-Mutation'
3
4
 
4
5
  export const entities = [Domain]
5
- export const resolvers = [DomainResolver]
6
+ export const resolvers = [DomainQuery, DomainMutation]
@@ -1 +0,0 @@
1
- {"version":3,"file":"domain-resolver.js","sourceRoot":"","sources":["../../../server/service/domain/domain-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Args, Ctx, Directive, Mutation, Query, Resolver, FieldResolver, Root } from 'type-graphql'\nimport { In, Repository } from 'typeorm'\n\nimport { slugger } from '@things-factory/utils'\n\nimport { getRepository } from '../../initializers/database'\nimport { getQueryBuilderFromListParams } from '../../utils/get-query-builder-from-list-params'\n\nimport { ListParam } from '../common-types/list-param'\nimport { Domain } from './domain'\nimport { DomainList, DomainPatch } from './domain-types'\n\n@Resolver(Domain)\nexport class DomainResolver {\n @Directive('@privilege(category: \"system\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => Domain, { description: 'To fetch domain' })\n async domain(@Arg('id') id: string, @Ctx() context: any): Promise<Domain> {\n const repository = getRepository(Domain)\n\n return await repository.findOneBy({ id })\n }\n\n @Directive('@privilege(superUserGranted: true)')\n @Query(returns => DomainList, { description: 'To fetch all domains (Only superuser is granted this privilege.)' })\n async domains(@Args() params: ListParam, @Ctx() context: any): Promise<DomainList> {\n const queryBuilder = await getQueryBuilderFromListParams({\n repository: getRepository(Domain),\n alias: 'ContactPoint',\n params,\n searchables: ['name', 'description', 'subdomain']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n // @Query(returns => Boolean, { description: 'To check if given domain is exist' })\n // async checkExistsDomain(@Arg('name') name: string) {\n // const domainRepository: Repository<Domain> = getRepository(Domain)\n // const targetSubdomain: string = slugger(name)\n\n // const oldDomain = await domainRepository.findOneBy({ subdomain: targetSubdomain })\n // if (oldDomain) {\n // throw new Error('domain is duplicated')\n // }\n\n // return true\n // }\n\n @Directive('@transaction')\n @Directive('@privilege(superUserGranted: true)')\n @Mutation(returns => Domain, { description: 'To create domain (Only superuser is granted this privilege.)' })\n async createDomain(@Arg('domainInput') domainInput: DomainPatch) {\n const { name, description } = domainInput\n const domainRepo: Repository<Domain> = getRepository(Domain)\n const subdomain: string = slugger(name)\n\n const domain: Domain = await domainRepo.findOneBy({ subdomain })\n if (domain) {\n throw new Error('domain is duplicated')\n }\n\n return await domainRepo.save({ name, description, subdomain })\n }\n\n @Directive('@transaction')\n @Directive('@privilege(superUserGranted: true)')\n @Mutation(returns => Domain, { description: 'To delete domain (Only superuser is granted this privilege.)' })\n async deleteDomain(@Arg('name') name: string) {\n return await getRepository(Domain).delete({ name })\n }\n\n @Directive('@transaction')\n @Directive('@privilege(superUserGranted: true)')\n @Mutation(returns => Boolean, {\n description: 'To delete multiple domains (Only superuser is granted this privilege.)'\n })\n async deleteDomains(@Arg('names', () => [String]) names: string[]) {\n const domains: Domain[] = await getRepository(Domain).find({ where: { name: In(names) } })\n const domainIds: string[] = domains.map(domain => domain.id)\n\n await getRepository(Domain).delete({ id: In(domainIds) })\n }\n\n @Directive('@transaction')\n @Directive('@privilege(superUserGranted: true)')\n @Mutation(returns => Domain, {\n description: 'To update domain (Only superuser is granted this privilege.)'\n })\n async updateDomain(@Arg('name') name: string, @Arg('patch', () => DomainPatch) patch: DomainPatch) {\n const repository = getRepository(Domain)\n const domain: Domain = await repository.findOneBy({ name })\n\n if (patch.parent && patch.parent.id == domain.id) {\n delete patch.parent\n }\n\n return await repository.save({\n ...domain,\n ...patch\n } as any)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(superUserGranted: true)')\n @Mutation(returns => Boolean, {\n description: 'To update multiple domains (Only superuser is granted this privilege.)'\n })\n async updateDomains(@Arg('patches', () => [DomainPatch]) patches: DomainPatch[]): Promise<boolean> {\n const domainRepo: Repository<Domain> = getRepository(Domain)\n\n const patchIds = patches.filter((patch: any) => patch.id)\n\n if (patchIds.length > 0) {\n patchIds.forEach(async updateRecord => {\n const domain: Domain = await domainRepo.findOne({ where: { id: updateRecord.id } })\n\n if (updateRecord.name) {\n updateRecord.subdomain = slugger(updateRecord.name)\n }\n\n if (updateRecord.parent && updateRecord.parent.id == domain.id) {\n delete updateRecord.parent\n }\n\n await domainRepo.save({\n ...domain,\n ...updateRecord\n } as any)\n })\n }\n\n return true\n }\n\n @FieldResolver(type => Domain)\n async parent(@Root() domain: Domain): Promise<Domain> {\n return domain.parentId && (await getRepository(Domain).findOneBy({ id: domain.parentId }))\n }\n}\n"]}