mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
enum solution and graphql-schema-validation
This commit is contained in:
parent
03f60fa4d4
commit
abc7128e5f
@ -6,17 +6,14 @@ import { MODERATOR_RIGHTS } from './MODERATOR_RIGHTS'
|
||||
import { Role } from './Role'
|
||||
import { USER_RIGHTS } from './USER_RIGHTS'
|
||||
|
||||
export const ROLE_UNAUTHORIZED = new Role(RoleNames.ROLE_NAME_UNAUTHORIZED, INALIENABLE_RIGHTS)
|
||||
export const ROLE_USER = new Role(RoleNames.ROLE_NAME_USER, [
|
||||
...INALIENABLE_RIGHTS,
|
||||
...USER_RIGHTS,
|
||||
])
|
||||
export const ROLE_MODERATOR = new Role(RoleNames.ROLE_NAME_MODERATOR, [
|
||||
export const ROLE_UNAUTHORIZED = new Role(RoleNames.MODERATOR, INALIENABLE_RIGHTS)
|
||||
export const ROLE_USER = new Role(RoleNames.USER, [...INALIENABLE_RIGHTS, ...USER_RIGHTS])
|
||||
export const ROLE_MODERATOR = new Role(RoleNames.MODERATOR, [
|
||||
...INALIENABLE_RIGHTS,
|
||||
...USER_RIGHTS,
|
||||
...MODERATOR_RIGHTS,
|
||||
])
|
||||
export const ROLE_ADMIN = new Role(RoleNames.ROLE_NAME_ADMIN, [
|
||||
export const ROLE_ADMIN = new Role(RoleNames.ADMIN, [
|
||||
...INALIENABLE_RIGHTS,
|
||||
...USER_RIGHTS,
|
||||
...MODERATOR_RIGHTS,
|
||||
|
||||
@ -8,6 +8,6 @@ export class SetUserRoleArgs {
|
||||
@Field(() => Int)
|
||||
userId: number
|
||||
|
||||
@Field(() => RoleNames, { nullable: true } )
|
||||
role: RoleNames | null
|
||||
@Field(() => RoleNames, { nullable: true })
|
||||
role: RoleNames | null | undefined
|
||||
}
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
import { User } from '@entity/User'
|
||||
import { AuthChecker } from 'type-graphql'
|
||||
|
||||
import { RoleNames } from '@enum/RoleNames'
|
||||
|
||||
import { INALIENABLE_RIGHTS } from '@/auth/INALIENABLE_RIGHTS'
|
||||
import { decode, encode } from '@/auth/JWT'
|
||||
import { RIGHTS } from '@/auth/RIGHTS'
|
||||
import { ROLE_UNAUTHORIZED, ROLE_USER, ROLE_ADMIN, ROLE_MODERATOR } from '@/auth/ROLES'
|
||||
import { Context } from '@/server/context'
|
||||
import { LogError } from '@/server/LogError'
|
||||
import { RoleNames } from '@enum/RoleNames'
|
||||
|
||||
export const isAuthorized: AuthChecker<Context> = async ({ context }, rights) => {
|
||||
context.role = ROLE_UNAUTHORIZED // unauthorized user
|
||||
@ -41,10 +42,10 @@ export const isAuthorized: AuthChecker<Context> = async ({ context }, rights) =>
|
||||
context.role = ROLE_USER
|
||||
if (user.userRoles?.length > 0) {
|
||||
switch (user.userRoles[0].role) {
|
||||
case RoleNames.ROLE_NAME_ADMIN:
|
||||
case RoleNames.ADMIN:
|
||||
context.role = ROLE_ADMIN
|
||||
break
|
||||
case RoleNames.ROLE_NAME_MODERATOR:
|
||||
case RoleNames.MODERATOR:
|
||||
context.role = ROLE_MODERATOR
|
||||
break
|
||||
default:
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { registerEnumType } from 'type-graphql'
|
||||
|
||||
export enum RoleNames {
|
||||
ROLE_NAME_ADMIN = 'admin',
|
||||
ROLE_NAME_UNAUTHORIZED = 'unauthorized',
|
||||
ROLE_NAME_USER = 'user',
|
||||
ROLE_NAME_MODERATOR = 'moderator',
|
||||
UNAUTHORIZED = 'UNAUTHORIZED',
|
||||
USER = 'USER',
|
||||
MODERATOR = 'MODERATOR',
|
||||
ADMIN = 'ADMIN',
|
||||
}
|
||||
|
||||
registerEnumType(RoleNames, {
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
import { UserContact as dbUserContact } from '@entity/UserContact'
|
||||
import { ObjectType, Field, Int } from 'type-graphql'
|
||||
|
||||
@ObjectType()
|
||||
export class UserContact {
|
||||
constructor(userContact: dbUserContact) {
|
||||
this.id = userContact.id
|
||||
this.type = userContact.type
|
||||
this.userId = userContact.userId
|
||||
this.email = userContact.email
|
||||
// this.emailVerificationCode = userContact.emailVerificationCode
|
||||
this.emailOptInTypeId = userContact.emailOptInTypeId
|
||||
this.emailResendCount = userContact.emailResendCount
|
||||
this.emailChecked = userContact.emailChecked
|
||||
this.phone = userContact.phone
|
||||
this.createdAt = userContact.createdAt
|
||||
this.updatedAt = userContact.updatedAt
|
||||
this.deletedAt = userContact.deletedAt
|
||||
}
|
||||
|
||||
@Field(() => Int)
|
||||
id: number
|
||||
|
||||
@Field(() => String)
|
||||
type: string
|
||||
|
||||
@Field(() => Int)
|
||||
userId: number
|
||||
|
||||
@Field(() => String)
|
||||
email: string
|
||||
|
||||
// @Field(() => BigInt, { nullable: true })
|
||||
// emailVerificationCode: BigInt | null
|
||||
|
||||
@Field(() => Int, { nullable: true })
|
||||
emailOptInTypeId: number | null
|
||||
|
||||
@Field(() => Int, { nullable: true })
|
||||
emailResendCount: number | null
|
||||
|
||||
@Field(() => Boolean)
|
||||
emailChecked: boolean
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
phone: string | null
|
||||
|
||||
@Field(() => Date)
|
||||
createdAt: Date
|
||||
|
||||
@Field(() => Date, { nullable: true })
|
||||
updatedAt: Date | null
|
||||
|
||||
@Field(() => Date, { nullable: true })
|
||||
deletedAt: Date | null
|
||||
}
|
||||
@ -10,19 +10,20 @@ import { TransactionLink } from '@entity/TransactionLink'
|
||||
import { User } from '@entity/User'
|
||||
import { UserContact } from '@entity/UserContact'
|
||||
import { UserRole } from '@entity/UserRole'
|
||||
import { UserInputError } from 'apollo-server-express'
|
||||
import { ApolloServerTestClient } from 'apollo-server-testing'
|
||||
import { GraphQLError } from 'graphql'
|
||||
import { v4 as uuidv4, validate as validateUUID, version as versionUUID } from 'uuid'
|
||||
|
||||
import { OptInType } from '@enum/OptInType'
|
||||
import { PasswordEncryptionType } from '@enum/PasswordEncryptionType'
|
||||
import { RoleNames } from '@enum/RoleNames'
|
||||
import { UserContactType } from '@enum/UserContactType'
|
||||
import { ContributionLink } from '@model/ContributionLink'
|
||||
import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/helpers'
|
||||
import { logger, i18n as localization } from '@test/testSetup'
|
||||
|
||||
import { subscribe } from '@/apis/KlicktippController'
|
||||
import { RoleNames } from '@enum/RoleNames'
|
||||
import { CONFIG } from '@/config'
|
||||
import {
|
||||
sendAccountActivationEmail,
|
||||
@ -345,7 +346,7 @@ describe('UserResolver', () => {
|
||||
peter.userRoles = [] as UserRole[]
|
||||
peter.userRoles[0] = UserRole.create()
|
||||
peter.userRoles[0].createdAt = new Date()
|
||||
peter.userRoles[0].role = RoleNames.ROLE_NAME_ADMIN
|
||||
peter.userRoles[0].role = RoleNames.ADMIN
|
||||
peter.userRoles[0].userId = peter.id
|
||||
await peter.userRoles[0].save()
|
||||
|
||||
@ -1411,7 +1412,7 @@ describe('UserResolver', () => {
|
||||
expect.objectContaining({
|
||||
firstName: 'Peter',
|
||||
lastName: 'Lustig',
|
||||
role: RoleNames.ROLE_NAME_ADMIN,
|
||||
role: RoleNames.ADMIN,
|
||||
}),
|
||||
]),
|
||||
},
|
||||
@ -1520,7 +1521,7 @@ describe('UserResolver', () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: 1, role: RoleNames.ROLE_NAME_ADMIN },
|
||||
variables: { userId: 1, role: RoleNames.ADMIN },
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
@ -1549,7 +1550,7 @@ describe('UserResolver', () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id + 1, role: RoleNames.ROLE_NAME_ADMIN },
|
||||
variables: { userId: user.id + 1, role: RoleNames.ADMIN },
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
@ -1566,7 +1567,7 @@ describe('UserResolver', () => {
|
||||
|
||||
// set Moderator-Role for Peter
|
||||
const userRole = await UserRole.findOneOrFail({ where: { userId: admin.id } })
|
||||
userRole.role = RoleNames.ROLE_NAME_MODERATOR
|
||||
userRole.role = RoleNames.MODERATOR
|
||||
userRole.userId = admin.id
|
||||
await UserRole.save(userRole)
|
||||
|
||||
@ -1585,7 +1586,7 @@ describe('UserResolver', () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
|
||||
variables: { userId: user.id, role: RoleNames.ADMIN },
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
@ -1613,12 +1614,12 @@ describe('UserResolver', () => {
|
||||
it('returns user with new moderator-role', async () => {
|
||||
const result = await mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
|
||||
variables: { userId: user.id, role: RoleNames.MODERATOR },
|
||||
})
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
setUserRole: RoleNames.ROLE_NAME_MODERATOR,
|
||||
setUserRole: RoleNames.MODERATOR,
|
||||
},
|
||||
}),
|
||||
)
|
||||
@ -1635,7 +1636,7 @@ describe('UserResolver', () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: admin.id + 1, role: RoleNames.ROLE_NAME_ADMIN },
|
||||
variables: { userId: admin.id + 1, role: RoleNames.ADMIN },
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
@ -1669,31 +1670,23 @@ describe('UserResolver', () => {
|
||||
it('returns admin-rolename', async () => {
|
||||
const result = await mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
|
||||
variables: { userId: user.id, role: RoleNames.ADMIN },
|
||||
})
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
setUserRole: RoleNames.ROLE_NAME_ADMIN,
|
||||
setUserRole: RoleNames.ADMIN,
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('stores the ADMIN_USER_ROLE_SET event in the database', async () => {
|
||||
const userContact = await UserContact.findOneOrFail({
|
||||
where: { email: 'bibi@bloxberg.de' },
|
||||
relations: ['user'],
|
||||
})
|
||||
const adminContact = await UserContact.findOneOrFail({
|
||||
where: { email: 'peter@lustig.de' },
|
||||
relations: ['user'],
|
||||
})
|
||||
await expect(DbEvent.find()).resolves.toContainEqual(
|
||||
expect.objectContaining({
|
||||
type: EventType.ADMIN_USER_ROLE_SET,
|
||||
affectedUserId: userContact.user.id,
|
||||
actingUserId: adminContact.user.id,
|
||||
affectedUserId: user.id,
|
||||
actingUserId: admin.id,
|
||||
}),
|
||||
)
|
||||
})
|
||||
@ -1703,12 +1696,12 @@ describe('UserResolver', () => {
|
||||
it('returns date string', async () => {
|
||||
const result = await mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
|
||||
variables: { userId: user.id, role: RoleNames.MODERATOR },
|
||||
})
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
setUserRole: RoleNames.ROLE_NAME_MODERATOR,
|
||||
setUserRole: RoleNames.MODERATOR,
|
||||
},
|
||||
}),
|
||||
)
|
||||
@ -1716,19 +1709,11 @@ describe('UserResolver', () => {
|
||||
})
|
||||
|
||||
it('stores the ADMIN_USER_ROLE_SET event in the database', async () => {
|
||||
const userContact = await UserContact.findOneOrFail({
|
||||
where: { email: 'bibi@bloxberg.de' },
|
||||
relations: ['user'],
|
||||
})
|
||||
const adminContact = await UserContact.findOneOrFail({
|
||||
where: { email: 'peter@lustig.de' },
|
||||
relations: ['user'],
|
||||
})
|
||||
await expect(DbEvent.find()).resolves.toContainEqual(
|
||||
expect.objectContaining({
|
||||
type: EventType.ADMIN_USER_ROLE_SET,
|
||||
affectedUserId: userContact.user.id,
|
||||
actingUserId: adminContact.user.id,
|
||||
affectedUserId: user.id,
|
||||
actingUserId: admin.id,
|
||||
}),
|
||||
)
|
||||
})
|
||||
@ -1791,17 +1776,14 @@ describe('UserResolver', () => {
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
errors: [new GraphQLError('Not allowed to set user role=')],
|
||||
errors: [
|
||||
new UserInputError(
|
||||
'Variable "$role" got invalid value "unknown rolename"; Value "unknown rolename" does not exist in "RoleNames" enum.',
|
||||
),
|
||||
],
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('logs the error thrown', () => {
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'Not allowed to set user role=',
|
||||
'unknown rolename',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('user has already role to be set', () => {
|
||||
@ -1810,12 +1792,12 @@ describe('UserResolver', () => {
|
||||
jest.clearAllMocks()
|
||||
await mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
|
||||
variables: { userId: user.id, role: RoleNames.ADMIN },
|
||||
})
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
|
||||
variables: { userId: user.id, role: RoleNames.ADMIN },
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
@ -1825,10 +1807,7 @@ describe('UserResolver', () => {
|
||||
})
|
||||
|
||||
it('logs the error thrown', () => {
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'User already has role=',
|
||||
RoleNames.ROLE_NAME_ADMIN,
|
||||
)
|
||||
expect(logger.error).toBeCalledWith('User already has role=', RoleNames.ADMIN)
|
||||
})
|
||||
})
|
||||
|
||||
@ -1837,12 +1816,12 @@ describe('UserResolver', () => {
|
||||
jest.clearAllMocks()
|
||||
await mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
|
||||
variables: { userId: user.id, role: RoleNames.MODERATOR },
|
||||
})
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: setUserRole,
|
||||
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
|
||||
variables: { userId: user.id, role: RoleNames.MODERATOR },
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
@ -1852,10 +1831,7 @@ describe('UserResolver', () => {
|
||||
})
|
||||
|
||||
it('logs the error thrown', () => {
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'User already has role=',
|
||||
RoleNames.ROLE_NAME_MODERATOR,
|
||||
)
|
||||
expect(logger.error).toBeCalledWith('User already has role=', RoleNames.MODERATOR)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ import { v4 as uuidv4 } from 'uuid'
|
||||
import { CreateUserArgs } from '@arg/CreateUserArgs'
|
||||
import { Paginated } from '@arg/Paginated'
|
||||
import { SearchUsersFilters } from '@arg/SearchUsersFilters'
|
||||
import { SetUserRoleArgs } from '@arg/SetUserRoleArgs'
|
||||
import { UnsecureLoginArgs } from '@arg/UnsecureLoginArgs'
|
||||
import { UpdateUserInfosArgs } from '@arg/UpdateUserInfosArgs'
|
||||
import { OptInType } from '@enum/OptInType'
|
||||
@ -70,9 +71,6 @@ import { getKlicktippState } from './util/getKlicktippState'
|
||||
import { setUserRole, deleteUserRole } from './util/modifyUserRole'
|
||||
import { validateAlias } from './util/validateAlias'
|
||||
|
||||
import { RoleNames } from '@enum/RoleNames'
|
||||
import { SetUserRoleArgs } from '@arg/SetUserRoleArgs'
|
||||
|
||||
const LANGUAGES = ['de', 'en', 'es', 'fr', 'nl']
|
||||
const DEFAULT_LANGUAGE = 'de'
|
||||
const isLanguage = (language: string): boolean => {
|
||||
|
||||
@ -3,7 +3,7 @@ import { UserRole } from '@entity/UserRole'
|
||||
|
||||
import { LogError } from '@/server/LogError'
|
||||
|
||||
export async function setUserRole(user: DbUser, role: string | null): Promise<void> {
|
||||
export async function setUserRole(user: DbUser, role: string | null | undefined): Promise<void> {
|
||||
// if role should be set
|
||||
if (role) {
|
||||
// in case user has still no associated userRole
|
||||
|
||||
@ -20,7 +20,6 @@ export const contributionLinkFactory = async (
|
||||
mutation: login,
|
||||
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
|
||||
})
|
||||
console.log('user=', user)
|
||||
const variables = {
|
||||
amount: contributionLink.amount,
|
||||
memo: contributionLink.memo,
|
||||
@ -33,6 +32,5 @@ export const contributionLinkFactory = async (
|
||||
}
|
||||
|
||||
const result = await mutate({ mutation: createContributionLink, variables })
|
||||
console.log('link...', result)
|
||||
return result.data.createContributionLink
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import { User } from '@entity/User'
|
||||
import { ApolloServerTestClient } from 'apollo-server-testing'
|
||||
|
||||
import { RoleNames } from '@enum/RoleNames'
|
||||
|
||||
import { setUserRole } from '@/graphql/resolver/util/modifyUserRole'
|
||||
import { createUser, setPassword } from '@/seeds/graphql/mutations'
|
||||
import { UserInterface } from '@/seeds/users/UserInterface'
|
||||
@ -37,10 +38,7 @@ export const userFactory = async (
|
||||
if (user.createdAt || user.deletedAt || user.role) {
|
||||
if (user.createdAt) dbUser.createdAt = user.createdAt
|
||||
if (user.deletedAt) dbUser.deletedAt = user.deletedAt
|
||||
if (
|
||||
user.role &&
|
||||
(user.role === RoleNames.ROLE_NAME_ADMIN || user.role === RoleNames.ROLE_NAME_MODERATOR)
|
||||
) {
|
||||
if (user.role && (user.role === RoleNames.ADMIN || user.role === RoleNames.MODERATOR)) {
|
||||
await setUserRole(dbUser, user.role)
|
||||
}
|
||||
await dbUser.save()
|
||||
|
||||
@ -95,8 +95,6 @@ export const searchUsers = gql`
|
||||
emailConfirmationSend
|
||||
deletedAt
|
||||
roles
|
||||
isAdmin
|
||||
isModerator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,5 +10,5 @@ export const peterLustig: UserInterface = {
|
||||
createdAt: new Date('2020-11-25T10:48:43'),
|
||||
emailChecked: true,
|
||||
language: 'de',
|
||||
role: RoleNames.ROLE_NAME_ADMIN,
|
||||
role: RoleNames.ADMIN,
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user