@things-factory/auth-base 8.0.0-beta.1 → 8.0.0-beta.4
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 +6 -6
- package/client/actions/auth.ts +0 -24
- package/client/auth.ts +0 -272
- package/client/bootstrap.ts +0 -47
- package/client/directive/privileged.ts +0 -28
- package/client/index.ts +0 -4
- package/client/profiled.ts +0 -83
- package/client/reducers/auth.ts +0 -31
- package/client/verify-webauthn.ts +0 -86
- package/server/constants/error-code.ts +0 -22
- package/server/constants/error-message.ts +0 -0
- package/server/constants/max-age.ts +0 -1
- package/server/controllers/auth.ts +0 -5
- package/server/controllers/change-pwd.ts +0 -100
- package/server/controllers/checkin.ts +0 -21
- package/server/controllers/delete-user.ts +0 -71
- package/server/controllers/invitation.ts +0 -163
- package/server/controllers/profile.ts +0 -55
- package/server/controllers/reset-password.ts +0 -126
- package/server/controllers/signin.ts +0 -98
- package/server/controllers/signup.ts +0 -72
- package/server/controllers/unlock-user.ts +0 -62
- package/server/controllers/utils/make-invitation-token.ts +0 -5
- package/server/controllers/utils/make-verification-token.ts +0 -4
- package/server/controllers/utils/password-rule.ts +0 -120
- package/server/controllers/utils/save-invitation-token.ts +0 -10
- package/server/controllers/utils/save-verification-token.ts +0 -12
- package/server/controllers/verification.ts +0 -84
- package/server/errors/auth-error.ts +0 -24
- package/server/errors/index.ts +0 -2
- package/server/errors/user-domain-not-match-error.ts +0 -29
- package/server/index.ts +0 -37
- package/server/middlewares/authenticate-401-middleware.ts +0 -114
- package/server/middlewares/domain-authenticate-middleware.ts +0 -78
- package/server/middlewares/graphql-authenticate-middleware.ts +0 -13
- package/server/middlewares/index.ts +0 -67
- package/server/middlewares/jwt-authenticate-middleware.ts +0 -84
- package/server/middlewares/signin-middleware.ts +0 -55
- package/server/middlewares/webauthn-middleware.ts +0 -126
- package/server/migrations/1548206416130-SeedUser.ts +0 -60
- package/server/migrations/1566805283882-SeedPrivilege.ts +0 -28
- package/server/migrations/index.ts +0 -9
- package/server/router/auth-checkin-router.ts +0 -113
- package/server/router/auth-private-process-router.ts +0 -114
- package/server/router/auth-public-process-router.ts +0 -314
- package/server/router/auth-signin-router.ts +0 -55
- package/server/router/auth-signup-router.ts +0 -95
- package/server/router/index.ts +0 -9
- package/server/router/oauth2/index.ts +0 -2
- package/server/router/oauth2/oauth2-authorize-router.ts +0 -81
- package/server/router/oauth2/oauth2-router.ts +0 -165
- package/server/router/oauth2/oauth2-server.ts +0 -262
- package/server/router/oauth2/passport-oauth2-client-password.ts +0 -87
- package/server/router/oauth2/passport-refresh-token.ts +0 -87
- package/server/router/path-base-domain-router.ts +0 -8
- package/server/router/site-root-router.ts +0 -48
- package/server/router/webauthn-router.ts +0 -149
- package/server/routes.ts +0 -80
- package/server/service/app-binding/app-binding-mutation.ts +0 -22
- package/server/service/app-binding/app-binding-query.ts +0 -92
- package/server/service/app-binding/app-binding-types.ts +0 -11
- package/server/service/app-binding/app-binding.ts +0 -17
- package/server/service/app-binding/index.ts +0 -4
- package/server/service/appliance/appliance-mutation.ts +0 -113
- package/server/service/appliance/appliance-query.ts +0 -76
- package/server/service/appliance/appliance-types.ts +0 -56
- package/server/service/appliance/appliance.ts +0 -133
- package/server/service/appliance/index.ts +0 -6
- package/server/service/application/application-mutation.ts +0 -104
- package/server/service/application/application-query.ts +0 -98
- package/server/service/application/application-types.ts +0 -76
- package/server/service/application/application.ts +0 -216
- package/server/service/application/index.ts +0 -6
- package/server/service/auth-provider/auth-provider-mutation.ts +0 -159
- package/server/service/auth-provider/auth-provider-parameter-spec.ts +0 -24
- package/server/service/auth-provider/auth-provider-query.ts +0 -88
- package/server/service/auth-provider/auth-provider-type.ts +0 -67
- package/server/service/auth-provider/auth-provider.ts +0 -155
- package/server/service/auth-provider/index.ts +0 -7
- package/server/service/domain-generator/domain-generator-mutation.ts +0 -117
- package/server/service/domain-generator/domain-generator-types.ts +0 -46
- package/server/service/domain-generator/index.ts +0 -3
- package/server/service/granted-role/granted-role-mutation.ts +0 -156
- package/server/service/granted-role/granted-role-query.ts +0 -60
- package/server/service/granted-role/granted-role.ts +0 -27
- package/server/service/granted-role/index.ts +0 -6
- package/server/service/index.ts +0 -90
- package/server/service/invitation/index.ts +0 -6
- package/server/service/invitation/invitation-mutation.ts +0 -78
- package/server/service/invitation/invitation-query.ts +0 -33
- package/server/service/invitation/invitation-types.ts +0 -11
- package/server/service/invitation/invitation.ts +0 -63
- package/server/service/login-history/index.ts +0 -5
- package/server/service/login-history/login-history-query.ts +0 -51
- package/server/service/login-history/login-history-type.ts +0 -12
- package/server/service/login-history/login-history.ts +0 -45
- package/server/service/partner/index.ts +0 -6
- package/server/service/partner/partner-mutation.ts +0 -61
- package/server/service/partner/partner-query.ts +0 -102
- package/server/service/partner/partner-types.ts +0 -11
- package/server/service/partner/partner.ts +0 -57
- package/server/service/password-history/index.ts +0 -3
- package/server/service/password-history/password-history.ts +0 -16
- package/server/service/privilege/index.ts +0 -6
- package/server/service/privilege/privilege-directive.ts +0 -77
- package/server/service/privilege/privilege-mutation.ts +0 -92
- package/server/service/privilege/privilege-query.ts +0 -94
- package/server/service/privilege/privilege-types.ts +0 -60
- package/server/service/privilege/privilege.ts +0 -102
- package/server/service/role/index.ts +0 -6
- package/server/service/role/role-mutation.ts +0 -109
- package/server/service/role/role-query.ts +0 -155
- package/server/service/role/role-types.ts +0 -81
- package/server/service/role/role.ts +0 -72
- package/server/service/user/domain-query.ts +0 -24
- package/server/service/user/index.ts +0 -7
- package/server/service/user/user-mutation.ts +0 -482
- package/server/service/user/user-query.ts +0 -145
- package/server/service/user/user-types.ts +0 -100
- package/server/service/user/user.ts +0 -381
- package/server/service/users-auth-providers/index.ts +0 -5
- package/server/service/users-auth-providers/users-auth-providers.ts +0 -71
- package/server/service/verification-token/index.ts +0 -3
- package/server/service/verification-token/verification-token.ts +0 -60
- package/server/service/web-auth-credential/index.ts +0 -3
- package/server/service/web-auth-credential/web-auth-credential.ts +0 -67
- package/server/templates/account-unlock-email.ts +0 -65
- package/server/templates/invitation-email.ts +0 -66
- package/server/templates/reset-password-email.ts +0 -65
- package/server/templates/verification-email.ts +0 -66
- package/server/types.ts +0 -21
- package/server/utils/accepts.ts +0 -11
- package/server/utils/access-token-cookie.ts +0 -61
- package/server/utils/check-permission.ts +0 -52
- package/server/utils/check-user-belongs-domain.ts +0 -19
- package/server/utils/check-user-has-role.ts +0 -29
- package/server/utils/encrypt-state.ts +0 -22
- package/server/utils/get-aes-256-key.ts +0 -13
- package/server/utils/get-domain-from-hostname.ts +0 -7
- package/server/utils/get-domain-users.ts +0 -38
- package/server/utils/get-secret.ts +0 -13
- package/server/utils/get-user-domains.ts +0 -112
@@ -1,61 +0,0 @@
|
|
1
|
-
import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
|
2
|
-
|
3
|
-
import { Domain, getRepository } from '@things-factory/shell'
|
4
|
-
|
5
|
-
import { terminateGrantedRoles } from '../granted-role/granted-role-mutation'
|
6
|
-
import { Partner } from './partner'
|
7
|
-
|
8
|
-
@Resolver(Partner)
|
9
|
-
export class PartnerMutation {
|
10
|
-
@Directive('@privilege(category: "partner", privilege: "mutation")')
|
11
|
-
@Mutation(returns => Boolean)
|
12
|
-
async inviteCustomer(@Arg('customerDomainName') customerDomainName: string, @Ctx() context: ResolverContext) {
|
13
|
-
// 1. Try to find existing customer
|
14
|
-
const { domain, user } = context.state
|
15
|
-
const customerDomain: Domain = await getRepository(Domain).findOne({ where: { name: customerDomainName } })
|
16
|
-
if (!customerDomain) throw new Error(`There's no customer which has ${customerDomainName} as name`)
|
17
|
-
|
18
|
-
const isExistingCustomer: boolean = Boolean(
|
19
|
-
await getRepository(Partner).count({
|
20
|
-
where: { domain: { id: domain.id }, partnerDomain: { id: customerDomain.id } }
|
21
|
-
})
|
22
|
-
)
|
23
|
-
if (isExistingCustomer) throw new Error('Partner is registered as customer already')
|
24
|
-
|
25
|
-
await getRepository(Partner).save({
|
26
|
-
domain,
|
27
|
-
partnerDomain: customerDomain,
|
28
|
-
requester: user,
|
29
|
-
approver: user
|
30
|
-
})
|
31
|
-
|
32
|
-
return true
|
33
|
-
}
|
34
|
-
|
35
|
-
@Directive('@privilege(category: "partner", privilege: "mutation")')
|
36
|
-
@Directive('@transaction')
|
37
|
-
@Mutation(returns => Boolean)
|
38
|
-
async terminateContract(@Arg('partnerName') partnerName: string, @Ctx() context: ResolverContext) {
|
39
|
-
const { tx, domain } = context.state
|
40
|
-
|
41
|
-
// Find partnerDomain
|
42
|
-
const partnerDomain: Domain = await tx.getRepository(Domain).findOne({
|
43
|
-
where: { name: partnerName }
|
44
|
-
})
|
45
|
-
if (!partnerDomain) throw new Error(context.t('error.failed to find x', { x: context.t('label.partner') }))
|
46
|
-
|
47
|
-
// Find partner
|
48
|
-
const partner: Partner = await tx.getRepository(Partner).findOne({
|
49
|
-
where: { domain: { id: domain.id }, partnerDomain: { id: partnerDomain.id } }
|
50
|
-
})
|
51
|
-
if (!partner) throw new Error(context.t('error.failed to find x', { x: context.t('label.partner') }))
|
52
|
-
|
53
|
-
// Remove record from partner
|
54
|
-
await tx.getRepository(Partner).delete(partner.id)
|
55
|
-
|
56
|
-
// Remove granted roles
|
57
|
-
await terminateGrantedRoles(domain, partnerDomain, tx)
|
58
|
-
|
59
|
-
return true
|
60
|
-
}
|
61
|
-
}
|
@@ -1,102 +0,0 @@
|
|
1
|
-
import { Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
|
2
|
-
import { SelectQueryBuilder } from 'typeorm'
|
3
|
-
|
4
|
-
import { Domain, DomainList, getRepository, ListParam, getQueryBuilderFromListParams } from '@things-factory/shell'
|
5
|
-
|
6
|
-
import { checkUserBelongsDomain } from '../../utils/check-user-belongs-domain'
|
7
|
-
import { User } from '../user/user'
|
8
|
-
import { Partner } from './partner'
|
9
|
-
import { PartnerList } from './partner-types'
|
10
|
-
|
11
|
-
@Resolver(Partner)
|
12
|
-
export class PartnerQuery {
|
13
|
-
@Directive('@privilege(category: "partner", privilege: "query", domainOwnerGranted: true)')
|
14
|
-
@Query(returns => PartnerList)
|
15
|
-
async partners(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<PartnerList> {
|
16
|
-
if (await checkUserBelongsDomain(context.state.domain, context.state.user)) {
|
17
|
-
const { domain } = context.state
|
18
|
-
|
19
|
-
const queryBuilder = getQueryBuilderFromListParams({
|
20
|
-
domain,
|
21
|
-
params,
|
22
|
-
repository: getRepository(Partner),
|
23
|
-
alias: 'partner'
|
24
|
-
})
|
25
|
-
|
26
|
-
const [items, total] = await queryBuilder.getManyAndCount()
|
27
|
-
|
28
|
-
return { items, total }
|
29
|
-
} else {
|
30
|
-
throw new Error(`User doesn't belong in current domain`)
|
31
|
-
}
|
32
|
-
}
|
33
|
-
|
34
|
-
@Directive('@privilege(category: "partner", privilege: "query", domainOwnerGranted: true)')
|
35
|
-
@Query(returns => [Domain])
|
36
|
-
async customers(@Ctx() context: ResolverContext): Promise<Domain[]> {
|
37
|
-
const { domain } = context.state
|
38
|
-
const partners: Partner[] = await getRepository(Partner).find({
|
39
|
-
where: { domain: { id: domain.id } },
|
40
|
-
relations: ['partnerDomain']
|
41
|
-
})
|
42
|
-
|
43
|
-
return partners.map((p: Partner) => p.partnerDomain)
|
44
|
-
}
|
45
|
-
|
46
|
-
@Directive('@privilege(category: "partner", privilege: "query")')
|
47
|
-
@Query(returns => DomainList)
|
48
|
-
async searchCustomers(
|
49
|
-
@Args(type => ListParam) params: ListParam,
|
50
|
-
@Ctx() context: ResolverContext
|
51
|
-
): Promise<DomainList> {
|
52
|
-
const { domain } = context.state
|
53
|
-
const partners: Partner[] = await getRepository(Partner).find({
|
54
|
-
where: { domain: { id: domain.id } },
|
55
|
-
relations: ['partnerDomain']
|
56
|
-
})
|
57
|
-
|
58
|
-
const qb: SelectQueryBuilder<Domain> = await getQueryBuilderFromListParams({
|
59
|
-
repository: getRepository(Domain),
|
60
|
-
params,
|
61
|
-
searchables: ['name', 'description']
|
62
|
-
})
|
63
|
-
|
64
|
-
qb.andWhereInIds(partners.map((p: Partner) => p.partnerDomain.id))
|
65
|
-
const [items, total] = await qb.getManyAndCount()
|
66
|
-
return { items, total }
|
67
|
-
}
|
68
|
-
|
69
|
-
@Directive('@privilege(category: "partner", privilege: "query", domainOwnerGranted: true)')
|
70
|
-
@Query(returns => [Domain])
|
71
|
-
async vendors(@Ctx() context: ResolverContext): Promise<Domain[]> {
|
72
|
-
const { domain } = context.state
|
73
|
-
const qb: SelectQueryBuilder<Partner> = getRepository(Partner).createQueryBuilder('PARTNER')
|
74
|
-
const partners: Partner[] = await qb
|
75
|
-
.leftJoinAndSelect('PARTNER.domain', 'DOMAIN')
|
76
|
-
.leftJoinAndSelect('PARTNER.partnerDomain', 'P_DOMAIN')
|
77
|
-
.where('P_DOMAIN.id = :domainId', { domainId: domain.id })
|
78
|
-
.getMany()
|
79
|
-
|
80
|
-
return partners.map((p: Partner) => p.domain)
|
81
|
-
}
|
82
|
-
|
83
|
-
@FieldResolver()
|
84
|
-
async domain(@Root() partner: Partner) {
|
85
|
-
return await getRepository(Domain).findOneBy({ id: partner.domainId })
|
86
|
-
}
|
87
|
-
|
88
|
-
@FieldResolver()
|
89
|
-
async partnerDomain(@Root() partner: Partner) {
|
90
|
-
return await getRepository(Domain).findOneBy({ id: partner.partnerDomainId })
|
91
|
-
}
|
92
|
-
|
93
|
-
@FieldResolver()
|
94
|
-
async requester(@Root() partner: Partner) {
|
95
|
-
return await getRepository(User).findOneBy({ id: partner.requesterId })
|
96
|
-
}
|
97
|
-
|
98
|
-
@FieldResolver()
|
99
|
-
async approver(@Root() partner: Partner) {
|
100
|
-
return await getRepository(User).findOneBy({ id: partner.approverId })
|
101
|
-
}
|
102
|
-
}
|
@@ -1,11 +0,0 @@
|
|
1
|
-
import { Field, Int, ObjectType } from 'type-graphql'
|
2
|
-
import { Partner } from './partner'
|
3
|
-
|
4
|
-
@ObjectType()
|
5
|
-
export class PartnerList {
|
6
|
-
@Field(type => [Partner], { nullable: true })
|
7
|
-
items: Partner[]
|
8
|
-
|
9
|
-
@Field(type => Int, { nullable: true })
|
10
|
-
total: number
|
11
|
-
}
|
@@ -1,57 +0,0 @@
|
|
1
|
-
import { Domain } from '@things-factory/shell'
|
2
|
-
import {
|
3
|
-
CreateDateColumn,
|
4
|
-
Entity,
|
5
|
-
Index,
|
6
|
-
ManyToOne,
|
7
|
-
PrimaryGeneratedColumn,
|
8
|
-
UpdateDateColumn,
|
9
|
-
RelationId
|
10
|
-
} from 'typeorm'
|
11
|
-
import { ObjectType, Field, ID } from 'type-graphql'
|
12
|
-
import { User } from '../user/user'
|
13
|
-
|
14
|
-
@Entity()
|
15
|
-
@Index('ix_partner_0', (partner: Partner) => [partner.domain, partner.partnerDomain], { unique: true })
|
16
|
-
@ObjectType()
|
17
|
-
export class Partner {
|
18
|
-
@PrimaryGeneratedColumn('uuid')
|
19
|
-
@Field(type => ID)
|
20
|
-
readonly id: string
|
21
|
-
|
22
|
-
@ManyToOne(type => Domain)
|
23
|
-
@Field(type => Domain)
|
24
|
-
domain?: Domain
|
25
|
-
|
26
|
-
@RelationId((partner: Partner) => partner.domain)
|
27
|
-
domainId: string
|
28
|
-
|
29
|
-
@ManyToOne(type => Domain)
|
30
|
-
@Field(type => Domain)
|
31
|
-
partnerDomain?: Domain
|
32
|
-
|
33
|
-
@RelationId((partner: Partner) => partner.partnerDomain)
|
34
|
-
partnerDomainId: string
|
35
|
-
|
36
|
-
@CreateDateColumn()
|
37
|
-
@Field({ nullable: true })
|
38
|
-
requestedAt: Date
|
39
|
-
|
40
|
-
@UpdateDateColumn()
|
41
|
-
@Field({ nullable: true })
|
42
|
-
approvedAt: Date
|
43
|
-
|
44
|
-
@ManyToOne(type => User, { nullable: true })
|
45
|
-
@Field({ nullable: true })
|
46
|
-
requester: User
|
47
|
-
|
48
|
-
@RelationId((partner: Partner) => partner.requester)
|
49
|
-
requesterId: string
|
50
|
-
|
51
|
-
@ManyToOne(type => User, { nullable: true })
|
52
|
-
@Field({ nullable: true })
|
53
|
-
approver: User
|
54
|
-
|
55
|
-
@RelationId((partner: Partner) => partner.approver)
|
56
|
-
approverId: string
|
57
|
-
}
|
@@ -1,16 +0,0 @@
|
|
1
|
-
import { Entity, Column, PrimaryColumn } from 'typeorm'
|
2
|
-
import { ObjectType, Field, ID } from 'type-graphql'
|
3
|
-
|
4
|
-
@Entity()
|
5
|
-
@ObjectType()
|
6
|
-
export class PasswordHistory {
|
7
|
-
@PrimaryColumn()
|
8
|
-
@Field(type => ID)
|
9
|
-
userId: string
|
10
|
-
|
11
|
-
@Column({
|
12
|
-
nullable: true
|
13
|
-
})
|
14
|
-
@Field({ nullable: true })
|
15
|
-
history: string
|
16
|
-
}
|
@@ -1,77 +0,0 @@
|
|
1
|
-
import { defaultFieldResolver, GraphQLSchema } from 'graphql'
|
2
|
-
import gql from 'graphql-tag'
|
3
|
-
|
4
|
-
import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils'
|
5
|
-
import { checkPermission } from '../../utils/check-permission'
|
6
|
-
|
7
|
-
process['PRIVILEGES'] = {}
|
8
|
-
|
9
|
-
const DIRECTIVE = 'privilege'
|
10
|
-
|
11
|
-
export const privilegeDirectiveTypeDefs = gql`
|
12
|
-
directive @privilege(
|
13
|
-
category: String
|
14
|
-
privilege: String
|
15
|
-
domainOwnerGranted: Boolean
|
16
|
-
superUserGranted: Boolean
|
17
|
-
) on FIELD_DEFINITION
|
18
|
-
`
|
19
|
-
export const privilegeDirectiveResolver = (schema: GraphQLSchema) =>
|
20
|
-
mapSchema(schema, {
|
21
|
-
[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName, schema) => {
|
22
|
-
const privilegeDirective = getDirective(schema, fieldConfig, DIRECTIVE)?.[0]
|
23
|
-
if (privilegeDirective) {
|
24
|
-
const { resolve = defaultFieldResolver, args } = fieldConfig
|
25
|
-
|
26
|
-
if (!args) {
|
27
|
-
throw new Error(`Unexpected Error. args should be defined in @privilege directive for field ${fieldName}.`)
|
28
|
-
}
|
29
|
-
|
30
|
-
const { domainOwnerGranted, superUserGranted, category, privilege } = privilegeDirective
|
31
|
-
if (category && privilege) {
|
32
|
-
process['PRIVILEGES'][`${category} ${privilege}`] = [category, privilege]
|
33
|
-
}
|
34
|
-
|
35
|
-
// 필드의 기존 description 가져오기
|
36
|
-
const existingDescription = fieldConfig.description || ''
|
37
|
-
|
38
|
-
// 권한 정보를 포함한 새로운 description 생성
|
39
|
-
const privilegeDescription =
|
40
|
-
`\n\n🔒 Requires privilege: ${category}:${privilege}` +
|
41
|
-
(domainOwnerGranted ? ', Domain ownership' : '') +
|
42
|
-
(superUserGranted ? ', System ownership' : '')
|
43
|
-
|
44
|
-
// 기존 description과 결합
|
45
|
-
fieldConfig.description = `${existingDescription} ${privilegeDescription}`.trim()
|
46
|
-
|
47
|
-
fieldConfig.resolve = async function (source, args, context, info) {
|
48
|
-
const { domain, user, unsafeIP, prohibitedPrivileges } = context.state
|
49
|
-
|
50
|
-
if (
|
51
|
-
await checkPermission(
|
52
|
-
{
|
53
|
-
category,
|
54
|
-
privilege,
|
55
|
-
owner: domainOwnerGranted,
|
56
|
-
super: superUserGranted
|
57
|
-
},
|
58
|
-
user,
|
59
|
-
domain,
|
60
|
-
unsafeIP,
|
61
|
-
prohibitedPrivileges
|
62
|
-
)
|
63
|
-
) {
|
64
|
-
return await resolve.call(this, source, args, context, info)
|
65
|
-
} else {
|
66
|
-
throw new Error(
|
67
|
-
`Unauthorized! ${
|
68
|
-
category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'
|
69
|
-
} required`
|
70
|
-
)
|
71
|
-
}
|
72
|
-
}
|
73
|
-
|
74
|
-
return fieldConfig
|
75
|
-
}
|
76
|
-
}
|
77
|
-
})
|
@@ -1,92 +0,0 @@
|
|
1
|
-
import { Arg, Ctx, Mutation, Resolver, Directive } from 'type-graphql'
|
2
|
-
import { In } from 'typeorm'
|
3
|
-
|
4
|
-
import { getRepository } from '@things-factory/shell'
|
5
|
-
|
6
|
-
import { Role } from '../role/role'
|
7
|
-
import { Privilege } from './privilege'
|
8
|
-
import { NewPrivilege, PrivilegePatch } from './privilege-types'
|
9
|
-
|
10
|
-
@Resolver(Privilege)
|
11
|
-
export class PrivilegeMutation {
|
12
|
-
@Directive('@privilege(superUserGranted:true)')
|
13
|
-
@Mutation(returns => Boolean, {
|
14
|
-
description: 'To synchronize privilege master from graphql directives. Only superuser is permitted.'
|
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)')
|
33
|
-
@Mutation(returns => Privilege, { description: 'To create new privilege' })
|
34
|
-
async createPrivilege(
|
35
|
-
@Arg('privilege') privilege: NewPrivilege,
|
36
|
-
@Ctx() context: ResolverContext
|
37
|
-
): Promise<Privilege> {
|
38
|
-
if (privilege.roles && privilege.roles.length) {
|
39
|
-
privilege.roles = await getRepository(Role).findBy({
|
40
|
-
id: In(privilege.roles.map((role: Partial<Role>) => role.id))
|
41
|
-
})
|
42
|
-
}
|
43
|
-
|
44
|
-
return await getRepository(Privilege).save({
|
45
|
-
creator: context.state.user,
|
46
|
-
updater: context.state.user,
|
47
|
-
...privilege
|
48
|
-
})
|
49
|
-
}
|
50
|
-
|
51
|
-
@Directive('@privilege(superUserGranted:true)')
|
52
|
-
@Mutation(returns => Privilege, { description: 'To modify privilege information' })
|
53
|
-
async updatePrivilege(
|
54
|
-
@Arg('name') name: string,
|
55
|
-
@Arg('category') category: string,
|
56
|
-
@Arg('patch') patch: PrivilegePatch,
|
57
|
-
@Ctx() context: ResolverContext
|
58
|
-
): Promise<Privilege> {
|
59
|
-
const repository = getRepository(Privilege)
|
60
|
-
const privilege = await repository.findOne({
|
61
|
-
where: { name, category },
|
62
|
-
relations: ['roles', 'creator', 'updater']
|
63
|
-
})
|
64
|
-
|
65
|
-
const roleIds = privilege.roles.map(role => role.id)
|
66
|
-
if (patch.roles && patch.roles.length) {
|
67
|
-
patch.roles.forEach(({ id }) => {
|
68
|
-
if (!roleIds.includes(id)) {
|
69
|
-
roleIds.push(id)
|
70
|
-
}
|
71
|
-
})
|
72
|
-
}
|
73
|
-
|
74
|
-
return await repository.save({
|
75
|
-
...privilege,
|
76
|
-
...patch,
|
77
|
-
roles: await getRepository(Role).findByIds(roleIds),
|
78
|
-
updater: context.state.user
|
79
|
-
})
|
80
|
-
}
|
81
|
-
|
82
|
-
@Directive('@privilege(superUserGranted:true)')
|
83
|
-
@Mutation(returns => Boolean, { description: 'To delete privilege' })
|
84
|
-
async deletePrivilege(
|
85
|
-
@Arg('name') name: string,
|
86
|
-
@Arg('category') category: string,
|
87
|
-
@Ctx() context: ResolverContext
|
88
|
-
): Promise<boolean> {
|
89
|
-
await getRepository(Privilege).delete({ name, category })
|
90
|
-
return true
|
91
|
-
}
|
92
|
-
}
|
@@ -1,94 +0,0 @@
|
|
1
|
-
import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
|
2
|
-
import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
|
3
|
-
|
4
|
-
import { Role } from '../role/role'
|
5
|
-
import { User } from '../user/user'
|
6
|
-
import { Privilege } from './privilege'
|
7
|
-
import { PrivilegeList } from './privilege-types'
|
8
|
-
|
9
|
-
@Resolver(Privilege)
|
10
|
-
export class PrivilegeQuery {
|
11
|
-
@Directive('@privilege(category: "privilege", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
|
12
|
-
@Query(returns => PrivilegeList, { description: 'To fetch multiple privileges' })
|
13
|
-
async privileges(
|
14
|
-
@Args(type => ListParam) params: ListParam,
|
15
|
-
@Ctx() context: ResolverContext
|
16
|
-
): Promise<PrivilegeList> {
|
17
|
-
const [items, total] = await getQueryBuilderFromListParams({
|
18
|
-
params,
|
19
|
-
repository: getRepository(Privilege),
|
20
|
-
alias: 'p',
|
21
|
-
searchables: ['privilege', 'category'],
|
22
|
-
filtersMap: {
|
23
|
-
privilege: {
|
24
|
-
columnName: 'name'
|
25
|
-
}
|
26
|
-
}
|
27
|
-
})
|
28
|
-
.orderBy('p.category', 'ASC')
|
29
|
-
.getManyAndCount()
|
30
|
-
|
31
|
-
return { items, total }
|
32
|
-
}
|
33
|
-
|
34
|
-
@Query(returns => Boolean, { description: 'To query whether I have the given permission' })
|
35
|
-
async hasPrivilege(
|
36
|
-
@Arg('privilege') privilege: string,
|
37
|
-
@Arg('category') category: string,
|
38
|
-
@Ctx() context: ResolverContext
|
39
|
-
): Promise<Boolean> {
|
40
|
-
const { domain, user } = context.state
|
41
|
-
return await User.hasPrivilege(privilege, category, domain, user)
|
42
|
-
}
|
43
|
-
|
44
|
-
@Query(returns => [Domain], { description: 'To fetch domains with given privilege for user' })
|
45
|
-
async domainsWithPrivilege(
|
46
|
-
@Arg('privilege') privilege: string,
|
47
|
-
@Arg('category') category: string,
|
48
|
-
@Ctx() context: ResolverContext
|
49
|
-
): Promise<Partial<Domain>[]> {
|
50
|
-
const { user } = context.state
|
51
|
-
return await User.getDomainsWithPrivilege(privilege, category, user)
|
52
|
-
}
|
53
|
-
|
54
|
-
@FieldResolver(type => String)
|
55
|
-
async description(@Root() privilege: Privilege, @Ctx() context: ResolverContext) {
|
56
|
-
const { t } = context
|
57
|
-
const { name, category } = privilege
|
58
|
-
|
59
|
-
const keyname = `privilege.name.${name}`
|
60
|
-
const keycategory = `privilege.category.${category}`
|
61
|
-
const tname = t(keyname)
|
62
|
-
const tcategory = t(keycategory)
|
63
|
-
|
64
|
-
return t('privilege.description', {
|
65
|
-
name: tname === keyname ? name : tname,
|
66
|
-
category: tcategory === keycategory ? category : tcategory
|
67
|
-
})
|
68
|
-
}
|
69
|
-
|
70
|
-
@FieldResolver(type => String)
|
71
|
-
async privilege(@Root() privilege: Privilege, @Ctx() context: ResolverContext) {
|
72
|
-
return privilege.name
|
73
|
-
}
|
74
|
-
|
75
|
-
@FieldResolver(type => [Role])
|
76
|
-
async roles(@Root() privilege: Privilege) {
|
77
|
-
return (
|
78
|
-
await getRepository(Privilege).findOne({
|
79
|
-
where: { id: privilege.id },
|
80
|
-
relations: ['roles']
|
81
|
-
})
|
82
|
-
).roles
|
83
|
-
}
|
84
|
-
|
85
|
-
@FieldResolver(type => User)
|
86
|
-
async updater(@Root() privilege: Privilege): Promise<User> {
|
87
|
-
return await getRepository(User).findOneBy({ id: privilege.updaterId })
|
88
|
-
}
|
89
|
-
|
90
|
-
@FieldResolver(type => User)
|
91
|
-
async creator(@Root() privilege: Privilege): Promise<User> {
|
92
|
-
return await getRepository(User).findOneBy({ id: privilege.creatorId })
|
93
|
-
}
|
94
|
-
}
|
@@ -1,60 +0,0 @@
|
|
1
|
-
import { ObjectType, InputType, Field, Int } from 'type-graphql'
|
2
|
-
import { ObjectRef } from '@things-factory/shell'
|
3
|
-
import { Privilege } from './privilege'
|
4
|
-
|
5
|
-
@InputType()
|
6
|
-
export class NewPrivilege {
|
7
|
-
@Field()
|
8
|
-
name: string
|
9
|
-
|
10
|
-
@Field()
|
11
|
-
category: string
|
12
|
-
|
13
|
-
@Field({ nullable: true })
|
14
|
-
description?: string
|
15
|
-
|
16
|
-
@Field(type => [ObjectRef], { nullable: true })
|
17
|
-
roles: ObjectRef[]
|
18
|
-
}
|
19
|
-
|
20
|
-
@InputType()
|
21
|
-
export class PrivilegePatch {
|
22
|
-
@Field({ nullable: true })
|
23
|
-
id?: string
|
24
|
-
|
25
|
-
@Field({ nullable: true })
|
26
|
-
name?: string
|
27
|
-
|
28
|
-
@Field({ nullable: true })
|
29
|
-
category?: string
|
30
|
-
|
31
|
-
@Field({ nullable: true })
|
32
|
-
description?: string
|
33
|
-
|
34
|
-
@Field(type => [ObjectRef], { nullable: true })
|
35
|
-
roles?: ObjectRef[]
|
36
|
-
}
|
37
|
-
|
38
|
-
@ObjectType()
|
39
|
-
export class PrivilegeList {
|
40
|
-
@Field(type => [Privilege], { nullable: true })
|
41
|
-
items: Privilege[]
|
42
|
-
|
43
|
-
@Field(type => Int, { nullable: true })
|
44
|
-
total: number
|
45
|
-
}
|
46
|
-
|
47
|
-
@ObjectType()
|
48
|
-
export class UserPrivilege {
|
49
|
-
@Field({ nullable: true })
|
50
|
-
id: String
|
51
|
-
|
52
|
-
@Field({ nullable: true })
|
53
|
-
name: String
|
54
|
-
|
55
|
-
@Field({ nullable: true })
|
56
|
-
description: String
|
57
|
-
|
58
|
-
@Field({ nullable: true })
|
59
|
-
assigned: Boolean
|
60
|
-
}
|
@@ -1,102 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
Column,
|
3
|
-
CreateDateColumn,
|
4
|
-
Entity,
|
5
|
-
Index,
|
6
|
-
ManyToMany,
|
7
|
-
ManyToOne,
|
8
|
-
JoinTable,
|
9
|
-
RelationId,
|
10
|
-
PrimaryGeneratedColumn,
|
11
|
-
UpdateDateColumn
|
12
|
-
} from 'typeorm'
|
13
|
-
import { ObjectType, InputType, Field, ID } from 'type-graphql'
|
14
|
-
import { Role } from '../role/role'
|
15
|
-
import { User } from '../user/user'
|
16
|
-
|
17
|
-
@ObjectType()
|
18
|
-
export class PrivilegeObject {
|
19
|
-
@Field({ nullable: true })
|
20
|
-
privilege?: string
|
21
|
-
|
22
|
-
@Field({ nullable: true })
|
23
|
-
category?: string
|
24
|
-
|
25
|
-
@Field({ nullable: true })
|
26
|
-
owner?: boolean
|
27
|
-
|
28
|
-
@Field({ nullable: true })
|
29
|
-
super?: boolean
|
30
|
-
}
|
31
|
-
|
32
|
-
@InputType()
|
33
|
-
export class PrivilegeInput {
|
34
|
-
@Field({ nullable: true })
|
35
|
-
privilege?: string
|
36
|
-
|
37
|
-
@Field({ nullable: true })
|
38
|
-
category?: string
|
39
|
-
|
40
|
-
@Field({ nullable: true })
|
41
|
-
owner?: boolean
|
42
|
-
|
43
|
-
@Field({ nullable: true })
|
44
|
-
super?: boolean
|
45
|
-
}
|
46
|
-
|
47
|
-
@Entity()
|
48
|
-
@Index('ix_privilege_0', (privilege: Privilege) => [privilege.name, privilege.category], {
|
49
|
-
unique: false
|
50
|
-
})
|
51
|
-
@ObjectType()
|
52
|
-
export class Privilege {
|
53
|
-
@PrimaryGeneratedColumn('uuid')
|
54
|
-
@Field(type => ID)
|
55
|
-
id: string
|
56
|
-
|
57
|
-
@Column()
|
58
|
-
@Field()
|
59
|
-
name: string
|
60
|
-
|
61
|
-
@Column()
|
62
|
-
@Field({ nullable: true })
|
63
|
-
category: string
|
64
|
-
|
65
|
-
@Column({
|
66
|
-
nullable: true
|
67
|
-
})
|
68
|
-
@Field({ nullable: true })
|
69
|
-
description: string
|
70
|
-
|
71
|
-
@ManyToMany(type => Role, role => role.privileges)
|
72
|
-
@JoinTable({
|
73
|
-
/* case M2M, JoinTable setting should be defined only one side (never set both side) */
|
74
|
-
name: 'roles_privileges',
|
75
|
-
joinColumns: [{ name: 'privileges_id', referencedColumnName: 'id' }],
|
76
|
-
inverseJoinColumns: [{ name: 'roles_id', referencedColumnName: 'id' }]
|
77
|
-
})
|
78
|
-
@Field(type => [Role], { nullable: true })
|
79
|
-
roles: Role[]
|
80
|
-
|
81
|
-
@ManyToOne(type => User, { nullable: true })
|
82
|
-
@Field(type => User, { nullable: true })
|
83
|
-
creator: User
|
84
|
-
|
85
|
-
@RelationId((privilege: Privilege) => privilege.creator)
|
86
|
-
creatorId: string
|
87
|
-
|
88
|
-
@ManyToOne(type => User, { nullable: true })
|
89
|
-
@Field(type => User, { nullable: true })
|
90
|
-
updater: User
|
91
|
-
|
92
|
-
@RelationId((privilege: Privilege) => privilege.updater)
|
93
|
-
updaterId: string
|
94
|
-
|
95
|
-
@CreateDateColumn()
|
96
|
-
@Field({ nullable: true })
|
97
|
-
createdAt: Date
|
98
|
-
|
99
|
-
@UpdateDateColumn()
|
100
|
-
@Field({ nullable: true })
|
101
|
-
updatedAt: Date
|
102
|
-
}
|