@contember/engine-tenant-api 1.4.0-alpha.5 → 1.4.0-beta.2

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 (49) hide show
  1. package/dist/src/TenantContainer.d.ts +3 -1
  2. package/dist/src/TenantContainer.d.ts.map +1 -1
  3. package/dist/src/TenantContainer.js +1 -0
  4. package/dist/src/TenantContainer.js.map +1 -1
  5. package/dist/src/model/authorization/PermissionActions.d.ts +5 -0
  6. package/dist/src/model/authorization/PermissionActions.d.ts.map +1 -1
  7. package/dist/src/model/authorization/PermissionActions.js +1 -0
  8. package/dist/src/model/authorization/PermissionActions.js.map +1 -1
  9. package/dist/src/model/authorization/PermissionsFactory.d.ts.map +1 -1
  10. package/dist/src/model/authorization/PermissionsFactory.js +1 -0
  11. package/dist/src/model/authorization/PermissionsFactory.js.map +1 -1
  12. package/dist/src/resolvers/ResolverFactory.d.ts +2 -1
  13. package/dist/src/resolvers/ResolverFactory.d.ts.map +1 -1
  14. package/dist/src/resolvers/ResolverFactory.js +1 -0
  15. package/dist/src/resolvers/ResolverFactory.js.map +1 -1
  16. package/dist/src/resolvers/query/PersonQueryResolver.d.ts +9 -0
  17. package/dist/src/resolvers/query/PersonQueryResolver.d.ts.map +1 -0
  18. package/dist/src/resolvers/query/PersonQueryResolver.js +19 -0
  19. package/dist/src/resolvers/query/PersonQueryResolver.js.map +1 -0
  20. package/dist/src/resolvers/query/index.d.ts +1 -0
  21. package/dist/src/resolvers/query/index.d.ts.map +1 -1
  22. package/dist/src/resolvers/query/index.js +1 -0
  23. package/dist/src/resolvers/query/index.js.map +1 -1
  24. package/dist/src/schema/index.d.ts +5 -0
  25. package/dist/src/schema/index.d.ts.map +1 -1
  26. package/dist/src/schema/tenant.graphql.d.ts.map +1 -1
  27. package/dist/src/schema/tenant.graphql.js +1 -0
  28. package/dist/src/schema/tenant.graphql.js.map +1 -1
  29. package/dist/src/tsconfig.tsbuildinfo +1 -1
  30. package/dist/tests/cases/integration/mocked/personByIdQuery.test.d.ts +2 -0
  31. package/dist/tests/cases/integration/mocked/personByIdQuery.test.d.ts.map +1 -0
  32. package/dist/tests/cases/integration/mocked/personByIdQuery.test.js +48 -0
  33. package/dist/tests/cases/integration/mocked/personByIdQuery.test.js.map +1 -0
  34. package/dist/tests/cases/integration/mocked/sql/getPersonByIdSql.d.ts +1 -0
  35. package/dist/tests/cases/integration/mocked/sql/getPersonByIdSql.d.ts.map +1 -1
  36. package/dist/tests/cases/integration/mocked/sql/getPersonByIdSql.js +2 -1
  37. package/dist/tests/cases/integration/mocked/sql/getPersonByIdSql.js.map +1 -1
  38. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +12 -12
  40. package/src/TenantContainer.ts +3 -0
  41. package/src/model/authorization/PermissionActions.ts +1 -0
  42. package/src/model/authorization/PermissionsFactory.ts +1 -0
  43. package/src/resolvers/ResolverFactory.ts +3 -1
  44. package/src/resolvers/query/PersonQueryResolver.ts +26 -0
  45. package/src/resolvers/query/index.ts +1 -0
  46. package/src/schema/index.ts +7 -0
  47. package/src/schema/tenant.graphql.ts +1 -0
  48. package/tests/cases/integration/mocked/personByIdQuery.test.ts +47 -0
  49. package/tests/cases/integration/mocked/sql/getPersonByIdSql.ts +3 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-tenant-api",
3
- "version": "1.4.0-alpha.5",
3
+ "version": "1.4.0-beta.2",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/src/index.js",
6
6
  "typings": "dist/src/index.d.ts",
@@ -13,16 +13,16 @@
13
13
  "test": "vitest --dir ./tests/cases --no-threads"
14
14
  },
15
15
  "dependencies": {
16
- "@contember/authorization": "1.4.0-alpha.5",
17
- "@contember/config-loader": "1.4.0-alpha.5",
18
- "@contember/database": "1.4.0-alpha.5",
19
- "@contember/database-migrations": "1.4.0-alpha.5",
20
- "@contember/dic": "1.4.0-alpha.5",
21
- "@contember/graphql-utils": "1.4.0-alpha.5",
22
- "@contember/logger": "1.4.0-alpha.5",
23
- "@contember/schema": "1.4.0-alpha.5",
24
- "@contember/schema-utils": "1.4.0-alpha.5",
25
- "@contember/typesafe": "1.4.0-alpha.5",
16
+ "@contember/authorization": "1.4.0-beta.2",
17
+ "@contember/config-loader": "1.4.0-beta.2",
18
+ "@contember/database": "1.4.0-beta.2",
19
+ "@contember/database-migrations": "1.4.0-beta.2",
20
+ "@contember/dic": "1.4.0-beta.2",
21
+ "@contember/graphql-utils": "1.4.0-beta.2",
22
+ "@contember/logger": "1.4.0-beta.2",
23
+ "@contember/schema": "1.4.0-beta.2",
24
+ "@contember/schema-utils": "1.4.0-beta.2",
25
+ "@contember/typesafe": "1.4.0-beta.2",
26
26
  "@graphql-tools/utils": "^10.0.8",
27
27
  "graphql-tag": "^2.12.6",
28
28
  "jose": "^5.1.1",
@@ -32,7 +32,7 @@
32
32
  "otpauth": "^9.1.5"
33
33
  },
34
34
  "devDependencies": {
35
- "@contember/database-tester": "1.4.0-alpha.5",
35
+ "@contember/database-tester": "1.4.0-beta.2",
36
36
  "@graphql-codegen/cli": "^5.0.0",
37
37
  "@graphql-codegen/typescript": "^4.0.1",
38
38
  "@graphql-codegen/typescript-operations": "^4.0.1",
@@ -55,6 +55,7 @@ import {
55
55
  MailTemplateMutationResolver,
56
56
  MeQueryResolver,
57
57
  OtpMutationResolver,
58
+ PersonQueryResolver,
58
59
  ProjectMembersQueryResolver,
59
60
  ProjectQueryResolver,
60
61
  ProjectTypeResolver,
@@ -208,6 +209,8 @@ export class TenantContainerFactory {
208
209
  new SignInResponseFactory(permissionContextFactory, identityTypeResolver))
209
210
  .addService('meQueryResolver', () =>
210
211
  new MeQueryResolver())
212
+ .addService('personQueryResolver', ({ personManager }) =>
213
+ new PersonQueryResolver(personManager))
211
214
  .addService('idpQueryResolver', ({ idpManager }) =>
212
215
  new IDPQueryResolver(idpManager))
213
216
  .addService('projectQueryResolver', ({ projectManager }) =>
@@ -19,6 +19,7 @@ namespace PermissionActions {
19
19
 
20
20
  export const PERSON_DISABLE = (roles?: readonly string[]) => Authorizator.createAction(Resources.person, 'disable', { roles })
21
21
 
22
+ export const PERSON_VIEW = Authorizator.createAction(Resources.person, 'view')
22
23
  export const PERSON_SIGN_IN = Authorizator.createAction(Resources.person, 'signIn')
23
24
  export const PERSON_SIGN_UP = (roles?: readonly string[]) => Authorizator.createAction(Resources.person, 'signUp', { roles })
24
25
  export const PERSON_SIGN_OUT = Authorizator.createAction(Resources.person, 'signOut')
@@ -25,6 +25,7 @@ class PermissionsFactory {
25
25
  permissions.allow(TenantRole.LOGIN, PermissionActions.PERSON_CREATE_IDP_URL)
26
26
  permissions.allow(TenantRole.LOGIN, PermissionActions.PERSON_SIGN_IN_IDP)
27
27
 
28
+ permissions.allow(TenantRole.PERSON, PermissionActions.PERSON_VIEW)
28
29
  permissions.allow(TenantRole.PERSON, PermissionActions.PERSON_CHANGE_MY_PASSWORD)
29
30
  permissions.allow(TenantRole.PERSON, PermissionActions.PERSON_CHANGE_MY_PROFILE)
30
31
  permissions.allow(TenantRole.PERSON, PermissionActions.PERSON_SIGN_OUT)
@@ -20,7 +20,7 @@ import {
20
20
  } from './mutation'
21
21
 
22
22
  import { Resolvers } from '../schema'
23
- import { MeQueryResolver, ProjectMembersQueryResolver, ProjectQueryResolver } from './query'
23
+ import { MeQueryResolver, PersonQueryResolver, ProjectMembersQueryResolver, ProjectQueryResolver } from './query'
24
24
  import { IdentityTypeResolver, ProjectTypeResolver } from './types'
25
25
  import { DateTimeType, JSONType } from '@contember/graphql-utils'
26
26
  import { IDPQueryResolver } from './query/IDPQueryResolver'
@@ -32,6 +32,7 @@ class ResolverFactory {
32
32
  public constructor(
33
33
  private readonly resolvers: {
34
34
  meQueryResolver: MeQueryResolver
35
+ personQueryResolver: PersonQueryResolver
35
36
  projectQueryResolver: ProjectQueryResolver
36
37
  projectMembersQueryResolver: ProjectMembersQueryResolver
37
38
  idpQueryResolver: IDPQueryResolver
@@ -90,6 +91,7 @@ class ResolverFactory {
90
91
  },
91
92
  Query: {
92
93
  me: this.resolvers.meQueryResolver.me.bind(this.resolvers.meQueryResolver),
94
+ personById: this.resolvers.personQueryResolver.personById.bind(this.resolvers.personQueryResolver),
93
95
  projectBySlug: this.resolvers.projectQueryResolver.projectBySlug.bind(this.resolvers.projectQueryResolver),
94
96
  projects: this.resolvers.projectQueryResolver.projects.bind(this.resolvers.projectQueryResolver),
95
97
  projectMemberships: this.resolvers.projectMembersQueryResolver.projectMemberships.bind(this.resolvers.projectMembersQueryResolver),
@@ -0,0 +1,26 @@
1
+ import {
2
+ Maybe,
3
+ Person,
4
+ QueryPersonByIdArgs,
5
+ QueryResolvers,
6
+ } from '../../schema'
7
+ import { TenantResolverContext } from '../TenantResolverContext'
8
+ import { PermissionActions, PersonManager } from '../../model'
9
+ import { PersonResponseFactory } from '../responseHelpers/PersonResponseFactory'
10
+
11
+ export class PersonQueryResolver implements QueryResolvers {
12
+ constructor(private readonly personManager: PersonManager) {}
13
+
14
+ async personById(
15
+ parent: unknown,
16
+ args: QueryPersonByIdArgs,
17
+ context: TenantResolverContext,
18
+ ): Promise<Maybe<Person>> {
19
+ const person = await this.personManager.findPersonById(context.db, args.id)
20
+ if (!person || !(await context.isAllowed({ action: PermissionActions.PERSON_VIEW }))) {
21
+ return null
22
+ }
23
+
24
+ return await PersonResponseFactory.createPersonResponse(person)
25
+ }
26
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './MeQueryResolver'
2
2
  export * from './ProjectMembersQueryResolver'
3
3
  export * from './ProjectQueryResolver'
4
+ export * from './PersonQueryResolver'
@@ -905,6 +905,7 @@ export type Query = {
905
905
  readonly checkResetPasswordToken: CheckResetPasswordTokenCode
906
906
  readonly identityProviders: ReadonlyArray<IdentityProvider>
907
907
  readonly me: Identity
908
+ readonly personById?: Maybe<Person>
908
909
  readonly projectBySlug?: Maybe<Project>
909
910
  readonly projectMemberships: ReadonlyArray<Membership>
910
911
  readonly projects: ReadonlyArray<Project>
@@ -917,6 +918,11 @@ export type QueryCheckResetPasswordTokenArgs = {
917
918
  }
918
919
 
919
920
 
921
+ export type QueryPersonByIdArgs = {
922
+ id: Scalars['String']['input']
923
+ }
924
+
925
+
920
926
  export type QueryProjectBySlugArgs = {
921
927
  slug: Scalars['String']['input']
922
928
  }
@@ -2032,6 +2038,7 @@ export type QueryResolvers<ContextType = any, ParentType extends ResolversParent
2032
2038
  checkResetPasswordToken?: Resolver<ResolversTypes['CheckResetPasswordTokenCode'], ParentType, ContextType, RequireFields<QueryCheckResetPasswordTokenArgs, 'requestId' | 'token'>>
2033
2039
  identityProviders?: Resolver<ReadonlyArray<ResolversTypes['IdentityProvider']>, ParentType, ContextType>
2034
2040
  me?: Resolver<ResolversTypes['Identity'], ParentType, ContextType>
2041
+ personById?: Resolver<Maybe<ResolversTypes['Person']>, ParentType, ContextType, RequireFields<QueryPersonByIdArgs, 'id'>>
2035
2042
  projectBySlug?: Resolver<Maybe<ResolversTypes['Project']>, ParentType, ContextType, RequireFields<QueryProjectBySlugArgs, 'slug'>>
2036
2043
  projectMemberships?: Resolver<ReadonlyArray<ResolversTypes['Membership']>, ParentType, ContextType, RequireFields<QueryProjectMembershipsArgs, 'identityId' | 'projectSlug'>>
2037
2044
  projects?: Resolver<ReadonlyArray<ResolversTypes['Project']>, ParentType, ContextType>
@@ -12,6 +12,7 @@ const schema: DocumentNode = gql`
12
12
 
13
13
  type Query {
14
14
  me: Identity!
15
+ personById(id: String!): Person
15
16
  projects: [Project!]!
16
17
  projectBySlug(slug: String!): Project
17
18
  projectMemberships(projectSlug: String!, identityId: String!): [Membership!]!
@@ -0,0 +1,47 @@
1
+ import { executeTenantTest } from '../../../src/testTenant'
2
+ import { GQL } from '../../../src/tags'
3
+ import { testUuid } from '../../../src/testUuid'
4
+ import { test } from 'vitest'
5
+ import { getPersonByIdSql } from './sql/getPersonByIdSql'
6
+
7
+ test('get person by id query', async () => {
8
+ const name = 'John Doe'
9
+ const email = 'john@doe.com'
10
+ const personId = testUuid(1)
11
+ const identityId = testUuid(2)
12
+
13
+ await executeTenantTest({
14
+ query: {
15
+ query: GQL`
16
+ query personById($id: String!) {
17
+ personById(id: $id) {
18
+ id
19
+ name
20
+ email
21
+ identity {
22
+ id
23
+ }
24
+ }
25
+ }`,
26
+ variables: { id: personId },
27
+ },
28
+ executes: [
29
+ getPersonByIdSql({
30
+ personId,
31
+ response: { personId, email, roles: [], password: '123', identityId, name },
32
+ }),
33
+ ],
34
+ return: {
35
+ data: {
36
+ personById: {
37
+ id: personId,
38
+ name,
39
+ email,
40
+ identity: {
41
+ id: identityId,
42
+ },
43
+ },
44
+ },
45
+ },
46
+ })
47
+ })
@@ -3,7 +3,7 @@ import { SQL } from '../../../../src/tags'
3
3
 
4
4
  export const getPersonByIdSql = (args: {
5
5
  personId: string
6
- response: { personId: string; password: string; identityId: string; roles: string[]; email: string }
6
+ response: { personId: string; password: string; identityId: string; roles: string[]; email: string; name?: string }
7
7
  }): ExpectedQuery => ({
8
8
  sql: SQL`SELECT "person"."id", "person"."password_hash", "person"."otp_uri", "person"."otp_activated_at", "person"."identity_id", "person"."email", "person"."name", "person"."disabled_at", "identity"."roles"
9
9
  FROM "tenant"."person"
@@ -17,7 +17,8 @@ export const getPersonByIdSql = (args: {
17
17
  password_hash: `BCRYPTED-${args.response.password}`,
18
18
  identity_id: args.response.identityId,
19
19
  roles: args.response.roles,
20
- mail: args.response.email,
20
+ email: args.response.email,
21
+ name: args.response.name,
21
22
  },
22
23
  ],
23
24
  },