mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
Merge branch '3030-feature-role-administration-backend' of github.com:gradido/gradido into 3030-feature-role-administration-backend
This commit is contained in:
commit
ff08e410e4
@ -1,26 +1,22 @@
|
|||||||
|
import { RoleNames } from '@/graphql/enum/RoleNames'
|
||||||
|
|
||||||
import { ADMIN_RIGHTS } from './ADMIN_RIGHTS'
|
import { ADMIN_RIGHTS } from './ADMIN_RIGHTS'
|
||||||
import { INALIENABLE_RIGHTS } from './INALIENABLE_RIGHTS'
|
import { INALIENABLE_RIGHTS } from './INALIENABLE_RIGHTS'
|
||||||
import { MODERATOR_RIGHTS } from './MODERATOR_RIGHTS'
|
import { MODERATOR_RIGHTS } from './MODERATOR_RIGHTS'
|
||||||
import { Role } from './Role'
|
import { Role } from './Role'
|
||||||
import { USER_RIGHTS } from './USER_RIGHTS'
|
import { USER_RIGHTS } from './USER_RIGHTS'
|
||||||
|
|
||||||
export enum ROLE_NAMES {
|
export const ROLE_UNAUTHORIZED = new Role(RoleNames.ROLE_NAME_UNAUTHORIZED, INALIENABLE_RIGHTS)
|
||||||
ROLE_NAME_UNAUTHORIZED = 'unauthorized',
|
export const ROLE_USER = new Role(RoleNames.ROLE_NAME_USER, [
|
||||||
ROLE_NAME_USER = 'user',
|
|
||||||
ROLE_NAME_MODERATOR = 'moderator',
|
|
||||||
ROLE_NAME_ADMIN = 'admin',
|
|
||||||
}
|
|
||||||
export const ROLE_UNAUTHORIZED = new Role(ROLE_NAMES.ROLE_NAME_UNAUTHORIZED, INALIENABLE_RIGHTS)
|
|
||||||
export const ROLE_USER = new Role(ROLE_NAMES.ROLE_NAME_USER, [
|
|
||||||
...INALIENABLE_RIGHTS,
|
...INALIENABLE_RIGHTS,
|
||||||
...USER_RIGHTS,
|
...USER_RIGHTS,
|
||||||
])
|
])
|
||||||
export const ROLE_MODERATOR = new Role(ROLE_NAMES.ROLE_NAME_MODERATOR, [
|
export const ROLE_MODERATOR = new Role(RoleNames.ROLE_NAME_MODERATOR, [
|
||||||
...INALIENABLE_RIGHTS,
|
...INALIENABLE_RIGHTS,
|
||||||
...USER_RIGHTS,
|
...USER_RIGHTS,
|
||||||
...MODERATOR_RIGHTS,
|
...MODERATOR_RIGHTS,
|
||||||
])
|
])
|
||||||
export const ROLE_ADMIN = new Role(ROLE_NAMES.ROLE_NAME_ADMIN, [
|
export const ROLE_ADMIN = new Role(RoleNames.ROLE_NAME_ADMIN, [
|
||||||
...INALIENABLE_RIGHTS,
|
...INALIENABLE_RIGHTS,
|
||||||
...USER_RIGHTS,
|
...USER_RIGHTS,
|
||||||
...MODERATOR_RIGHTS,
|
...MODERATOR_RIGHTS,
|
||||||
|
|||||||
13
backend/src/graphql/arg/SetUserRoleArgs.ts
Normal file
13
backend/src/graphql/arg/SetUserRoleArgs.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { ArgsType, Field, Int, InputType } from 'type-graphql'
|
||||||
|
|
||||||
|
import { RoleNames } from '@enum/RoleNames'
|
||||||
|
|
||||||
|
@InputType()
|
||||||
|
@ArgsType()
|
||||||
|
export class SetUserRoleArgs {
|
||||||
|
@Field(() => Int)
|
||||||
|
userId: number
|
||||||
|
|
||||||
|
@Field(() => RoleNames, { nullable: true } )
|
||||||
|
role: RoleNames | null
|
||||||
|
}
|
||||||
@ -4,9 +4,10 @@ import { AuthChecker } from 'type-graphql'
|
|||||||
import { INALIENABLE_RIGHTS } from '@/auth/INALIENABLE_RIGHTS'
|
import { INALIENABLE_RIGHTS } from '@/auth/INALIENABLE_RIGHTS'
|
||||||
import { decode, encode } from '@/auth/JWT'
|
import { decode, encode } from '@/auth/JWT'
|
||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { ROLE_UNAUTHORIZED, ROLE_USER, ROLE_ADMIN, ROLE_NAMES, ROLE_MODERATOR } from '@/auth/ROLES'
|
import { ROLE_UNAUTHORIZED, ROLE_USER, ROLE_ADMIN, ROLE_MODERATOR } from '@/auth/ROLES'
|
||||||
import { Context } from '@/server/context'
|
import { Context } from '@/server/context'
|
||||||
import { LogError } from '@/server/LogError'
|
import { LogError } from '@/server/LogError'
|
||||||
|
import { RoleNames } from '@enum/RoleNames'
|
||||||
|
|
||||||
export const isAuthorized: AuthChecker<Context> = async ({ context }, rights) => {
|
export const isAuthorized: AuthChecker<Context> = async ({ context }, rights) => {
|
||||||
context.role = ROLE_UNAUTHORIZED // unauthorized user
|
context.role = ROLE_UNAUTHORIZED // unauthorized user
|
||||||
@ -40,10 +41,10 @@ export const isAuthorized: AuthChecker<Context> = async ({ context }, rights) =>
|
|||||||
context.role = ROLE_USER
|
context.role = ROLE_USER
|
||||||
if (user.userRoles?.length > 0) {
|
if (user.userRoles?.length > 0) {
|
||||||
switch (user.userRoles[0].role) {
|
switch (user.userRoles[0].role) {
|
||||||
case ROLE_NAMES.ROLE_NAME_ADMIN:
|
case RoleNames.ROLE_NAME_ADMIN:
|
||||||
context.role = ROLE_ADMIN
|
context.role = ROLE_ADMIN
|
||||||
break
|
break
|
||||||
case ROLE_NAMES.ROLE_NAME_MODERATOR:
|
case RoleNames.ROLE_NAME_MODERATOR:
|
||||||
context.role = ROLE_MODERATOR
|
context.role = ROLE_MODERATOR
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
|
|||||||
13
backend/src/graphql/enum/RoleNames.ts
Normal file
13
backend/src/graphql/enum/RoleNames.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { registerEnumType } from 'type-graphql'
|
||||||
|
|
||||||
|
export enum RoleNames {
|
||||||
|
ROLE_NAME_ADMIN = 'admin',
|
||||||
|
ROLE_NAME_UNAUTHORIZED = 'unauthorized',
|
||||||
|
ROLE_NAME_USER = 'user',
|
||||||
|
ROLE_NAME_MODERATOR = 'moderator',
|
||||||
|
}
|
||||||
|
|
||||||
|
registerEnumType(RoleNames, {
|
||||||
|
name: 'RoleNames', // this one is mandatory
|
||||||
|
description: 'Possible role names', // this one is optional
|
||||||
|
})
|
||||||
@ -1,8 +1,6 @@
|
|||||||
import { User as dbUser } from '@entity/User'
|
import { User as dbUser } from '@entity/User'
|
||||||
import { ObjectType, Field, Int } from 'type-graphql'
|
import { ObjectType, Field, Int } from 'type-graphql'
|
||||||
|
|
||||||
import { ROLE_NAMES } from '@/auth/ROLES'
|
|
||||||
|
|
||||||
import { KlickTipp } from './KlickTipp'
|
import { KlickTipp } from './KlickTipp'
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
@ -72,14 +70,4 @@ export class User {
|
|||||||
|
|
||||||
@Field(() => [String])
|
@Field(() => [String])
|
||||||
roles: string[]
|
roles: string[]
|
||||||
|
|
||||||
@Field(() => Boolean)
|
|
||||||
isAdmin(): boolean {
|
|
||||||
return this.roles.includes(ROLE_NAMES.ROLE_NAME_ADMIN)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Field(() => Boolean)
|
|
||||||
isModerator(): boolean {
|
|
||||||
return this.roles.includes(ROLE_NAMES.ROLE_NAME_MODERATOR)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,6 @@ import { User } from '@entity/User'
|
|||||||
import { Decimal } from 'decimal.js-light'
|
import { Decimal } from 'decimal.js-light'
|
||||||
import { ObjectType, Field, Int } from 'type-graphql'
|
import { ObjectType, Field, Int } from 'type-graphql'
|
||||||
|
|
||||||
import { ROLE_NAMES } from '@/auth/ROLES'
|
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
export class UserAdmin {
|
export class UserAdmin {
|
||||||
constructor(user: User, creation: Decimal[], hasElopage: boolean, emailConfirmationSend: string) {
|
constructor(user: User, creation: Decimal[], hasElopage: boolean, emailConfirmationSend: string) {
|
||||||
@ -48,16 +46,6 @@ export class UserAdmin {
|
|||||||
|
|
||||||
@Field(() => [String])
|
@Field(() => [String])
|
||||||
roles: string[]
|
roles: string[]
|
||||||
|
|
||||||
@Field(() => Boolean)
|
|
||||||
isAdmin(): boolean {
|
|
||||||
return this.roles.includes(ROLE_NAMES.ROLE_NAME_ADMIN)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Field(() => Boolean)
|
|
||||||
isModerator(): boolean {
|
|
||||||
return this.roles.includes(ROLE_NAMES.ROLE_NAME_MODERATOR)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/help
|
|||||||
import { logger, i18n as localization } from '@test/testSetup'
|
import { logger, i18n as localization } from '@test/testSetup'
|
||||||
|
|
||||||
import { subscribe } from '@/apis/KlicktippController'
|
import { subscribe } from '@/apis/KlicktippController'
|
||||||
import { ROLE_NAMES } from '@/auth/ROLES'
|
import { RoleNames } from '@enum/RoleNames'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
import {
|
import {
|
||||||
sendAccountActivationEmail,
|
sendAccountActivationEmail,
|
||||||
@ -56,7 +56,6 @@ import {
|
|||||||
searchUsers,
|
searchUsers,
|
||||||
user as userQuery,
|
user as userQuery,
|
||||||
checkUsername,
|
checkUsername,
|
||||||
userContact,
|
|
||||||
} from '@/seeds/graphql/queries'
|
} from '@/seeds/graphql/queries'
|
||||||
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
|
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
|
||||||
import { bobBaumeister } from '@/seeds/users/bob-baumeister'
|
import { bobBaumeister } from '@/seeds/users/bob-baumeister'
|
||||||
@ -339,18 +338,17 @@ describe('UserResolver', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// make Peter Lustig Admin
|
// make Peter Lustig Admin
|
||||||
let peter = await User.findOneOrFail({
|
const peter = await User.findOneOrFail({
|
||||||
where: { id: user[0].id },
|
where: { id: user[0].id },
|
||||||
relations: ['userRoles'],
|
relations: ['userRoles'],
|
||||||
})
|
})
|
||||||
peter.userRoles = [] as UserRole[]
|
peter.userRoles = [] as UserRole[]
|
||||||
peter.userRoles[0] = UserRole.create()
|
peter.userRoles[0] = UserRole.create()
|
||||||
peter.userRoles[0].createdAt = new Date()
|
peter.userRoles[0].createdAt = new Date()
|
||||||
peter.userRoles[0].role = ROLE_NAMES.ROLE_NAME_ADMIN
|
peter.userRoles[0].role = RoleNames.ROLE_NAME_ADMIN
|
||||||
peter.userRoles[0].userId = peter.id
|
peter.userRoles[0].userId = peter.id
|
||||||
await peter.userRoles[0].save()
|
await peter.userRoles[0].save()
|
||||||
|
|
||||||
|
|
||||||
// date statement
|
// date statement
|
||||||
const actualDate = new Date()
|
const actualDate = new Date()
|
||||||
const futureDate = new Date() // Create a future day from the executed day
|
const futureDate = new Date() // Create a future day from the executed day
|
||||||
@ -364,7 +362,6 @@ describe('UserResolver', () => {
|
|||||||
validFrom: actualDate,
|
validFrom: actualDate,
|
||||||
validTo: futureDate,
|
validTo: futureDate,
|
||||||
})
|
})
|
||||||
|
|
||||||
resetToken()
|
resetToken()
|
||||||
result = await mutate({
|
result = await mutate({
|
||||||
mutation: createUser,
|
mutation: createUser,
|
||||||
@ -703,8 +700,6 @@ describe('UserResolver', () => {
|
|||||||
lastName: 'Bloxberg',
|
lastName: 'Bloxberg',
|
||||||
publisherId: 1234,
|
publisherId: 1234,
|
||||||
roles: [],
|
roles: [],
|
||||||
isAdmin: false,
|
|
||||||
isModerator: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -976,8 +971,6 @@ describe('UserResolver', () => {
|
|||||||
hasElopage: false,
|
hasElopage: false,
|
||||||
publisherId: 1234,
|
publisherId: 1234,
|
||||||
roles: [],
|
roles: [],
|
||||||
isAdmin: false,
|
|
||||||
isModerator: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -993,34 +986,6 @@ describe('UserResolver', () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns usercontact object', async () => {
|
|
||||||
await expect(
|
|
||||||
query({
|
|
||||||
query: userContact,
|
|
||||||
variables: {
|
|
||||||
userId: user[0].id,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
).resolves.toMatchObject({
|
|
||||||
// expect.objectContaining({
|
|
||||||
data: {
|
|
||||||
userContact: {
|
|
||||||
id: expect.any(Number),
|
|
||||||
type: UserContactType.USER_CONTACT_EMAIL,
|
|
||||||
userId: user[0].id,
|
|
||||||
email: 'bibi@bloxberg.de',
|
|
||||||
emailOptInTypeId: expect.any(Number),
|
|
||||||
emailResendCount: expect.any(Number),
|
|
||||||
emailChecked: expect.any(Boolean),
|
|
||||||
phone: null,
|
|
||||||
createdAt: expect.any(String),
|
|
||||||
updatedAt: expect.any(String),
|
|
||||||
deletedAt: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1446,7 +1411,7 @@ describe('UserResolver', () => {
|
|||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
firstName: 'Peter',
|
firstName: 'Peter',
|
||||||
lastName: 'Lustig',
|
lastName: 'Lustig',
|
||||||
role: ROLE_NAMES.ROLE_NAME_ADMIN,
|
role: RoleNames.ROLE_NAME_ADMIN,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
@ -1535,8 +1500,6 @@ describe('UserResolver', () => {
|
|||||||
lastName: 'Bloxberg',
|
lastName: 'Bloxberg',
|
||||||
publisherId: 1234,
|
publisherId: 1234,
|
||||||
roles: [],
|
roles: [],
|
||||||
isAdmin: false,
|
|
||||||
isModerator: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -1557,7 +1520,7 @@ describe('UserResolver', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
mutate({
|
mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: 1, role: ROLE_NAMES.ROLE_NAME_ADMIN },
|
variables: { userId: 1, role: RoleNames.ROLE_NAME_ADMIN },
|
||||||
}),
|
}),
|
||||||
).resolves.toEqual(
|
).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@ -1586,7 +1549,7 @@ describe('UserResolver', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
mutate({
|
mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id + 1, role: ROLE_NAMES.ROLE_NAME_ADMIN },
|
variables: { userId: user.id + 1, role: RoleNames.ROLE_NAME_ADMIN },
|
||||||
}),
|
}),
|
||||||
).resolves.toEqual(
|
).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@ -1603,7 +1566,7 @@ describe('UserResolver', () => {
|
|||||||
|
|
||||||
// set Moderator-Role for Peter
|
// set Moderator-Role for Peter
|
||||||
const userRole = await UserRole.findOneOrFail({ where: { userId: admin.id } })
|
const userRole = await UserRole.findOneOrFail({ where: { userId: admin.id } })
|
||||||
userRole.role = ROLE_NAMES.ROLE_NAME_MODERATOR
|
userRole.role = RoleNames.ROLE_NAME_MODERATOR
|
||||||
userRole.userId = admin.id
|
userRole.userId = admin.id
|
||||||
await UserRole.save(userRole)
|
await UserRole.save(userRole)
|
||||||
|
|
||||||
@ -1622,7 +1585,7 @@ describe('UserResolver', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
mutate({
|
mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_ADMIN },
|
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
|
||||||
}),
|
}),
|
||||||
).resolves.toEqual(
|
).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@ -1650,12 +1613,12 @@ describe('UserResolver', () => {
|
|||||||
it('returns user with new moderator-role', async () => {
|
it('returns user with new moderator-role', async () => {
|
||||||
const result = await mutate({
|
const result = await mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_MODERATOR },
|
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
|
||||||
})
|
})
|
||||||
expect(result).toEqual(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
data: {
|
data: {
|
||||||
setUserRole: ROLE_NAMES.ROLE_NAME_MODERATOR,
|
setUserRole: RoleNames.ROLE_NAME_MODERATOR,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -1672,7 +1635,7 @@ describe('UserResolver', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
mutate({
|
mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: admin.id + 1, role: ROLE_NAMES.ROLE_NAME_ADMIN },
|
variables: { userId: admin.id + 1, role: RoleNames.ROLE_NAME_ADMIN },
|
||||||
}),
|
}),
|
||||||
).resolves.toEqual(
|
).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@ -1706,12 +1669,12 @@ describe('UserResolver', () => {
|
|||||||
it('returns admin-rolename', async () => {
|
it('returns admin-rolename', async () => {
|
||||||
const result = await mutate({
|
const result = await mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_ADMIN },
|
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
|
||||||
})
|
})
|
||||||
expect(result).toEqual(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
data: {
|
data: {
|
||||||
setUserRole: ROLE_NAMES.ROLE_NAME_ADMIN,
|
setUserRole: RoleNames.ROLE_NAME_ADMIN,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -1740,12 +1703,12 @@ describe('UserResolver', () => {
|
|||||||
it('returns date string', async () => {
|
it('returns date string', async () => {
|
||||||
const result = await mutate({
|
const result = await mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_MODERATOR },
|
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
|
||||||
})
|
})
|
||||||
expect(result).toEqual(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
data: {
|
data: {
|
||||||
setUserRole: ROLE_NAMES.ROLE_NAME_MODERATOR,
|
setUserRole: RoleNames.ROLE_NAME_MODERATOR,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -1847,12 +1810,12 @@ describe('UserResolver', () => {
|
|||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
await mutate({
|
await mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_ADMIN },
|
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
|
||||||
})
|
})
|
||||||
await expect(
|
await expect(
|
||||||
mutate({
|
mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_ADMIN },
|
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
|
||||||
}),
|
}),
|
||||||
).resolves.toEqual(
|
).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@ -1864,7 +1827,7 @@ describe('UserResolver', () => {
|
|||||||
it('logs the error thrown', () => {
|
it('logs the error thrown', () => {
|
||||||
expect(logger.error).toBeCalledWith(
|
expect(logger.error).toBeCalledWith(
|
||||||
'User already has role=',
|
'User already has role=',
|
||||||
ROLE_NAMES.ROLE_NAME_ADMIN,
|
RoleNames.ROLE_NAME_ADMIN,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1874,12 +1837,12 @@ describe('UserResolver', () => {
|
|||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
await mutate({
|
await mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_MODERATOR },
|
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
|
||||||
})
|
})
|
||||||
await expect(
|
await expect(
|
||||||
mutate({
|
mutate({
|
||||||
mutation: setUserRole,
|
mutation: setUserRole,
|
||||||
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_MODERATOR },
|
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
|
||||||
}),
|
}),
|
||||||
).resolves.toEqual(
|
).resolves.toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@ -1891,7 +1854,7 @@ describe('UserResolver', () => {
|
|||||||
it('logs the error thrown', () => {
|
it('logs the error thrown', () => {
|
||||||
expect(logger.error).toBeCalledWith(
|
expect(logger.error).toBeCalledWith(
|
||||||
'User already has role=',
|
'User already has role=',
|
||||||
ROLE_NAMES.ROLE_NAME_MODERATOR,
|
RoleNames.ROLE_NAME_MODERATOR,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -24,12 +24,10 @@ import { UserContactType } from '@enum/UserContactType'
|
|||||||
import { SearchAdminUsersResult } from '@model/AdminUser'
|
import { SearchAdminUsersResult } from '@model/AdminUser'
|
||||||
import { User } from '@model/User'
|
import { User } from '@model/User'
|
||||||
import { UserAdmin, SearchUsersResult } from '@model/UserAdmin'
|
import { UserAdmin, SearchUsersResult } from '@model/UserAdmin'
|
||||||
import { UserContact } from '@model/UserContact'
|
|
||||||
|
|
||||||
import { subscribe } from '@/apis/KlicktippController'
|
import { subscribe } from '@/apis/KlicktippController'
|
||||||
import { encode } from '@/auth/JWT'
|
import { encode } from '@/auth/JWT'
|
||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { ROLE_NAMES } from '@/auth/ROLES'
|
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
import {
|
import {
|
||||||
sendAccountActivationEmail,
|
sendAccountActivationEmail,
|
||||||
@ -72,6 +70,9 @@ import { getKlicktippState } from './util/getKlicktippState'
|
|||||||
import { setUserRole, deleteUserRole } from './util/modifyUserRole'
|
import { setUserRole, deleteUserRole } from './util/modifyUserRole'
|
||||||
import { validateAlias } from './util/validateAlias'
|
import { validateAlias } from './util/validateAlias'
|
||||||
|
|
||||||
|
import { RoleNames } from '@enum/RoleNames'
|
||||||
|
import { SetUserRoleArgs } from '@arg/SetUserRoleArgs'
|
||||||
|
|
||||||
const LANGUAGES = ['de', 'en', 'es', 'fr', 'nl']
|
const LANGUAGES = ['de', 'en', 'es', 'fr', 'nl']
|
||||||
const DEFAULT_LANGUAGE = 'de'
|
const DEFAULT_LANGUAGE = 'de'
|
||||||
const isLanguage = (language: string): boolean => {
|
const isLanguage = (language: string): boolean => {
|
||||||
@ -707,22 +708,10 @@ export class UserResolver {
|
|||||||
@Authorized([RIGHTS.SET_USER_ROLE])
|
@Authorized([RIGHTS.SET_USER_ROLE])
|
||||||
@Mutation(() => String, { nullable: true })
|
@Mutation(() => String, { nullable: true })
|
||||||
async setUserRole(
|
async setUserRole(
|
||||||
@Arg('userId', () => Int)
|
@Args() { userId, role }: SetUserRoleArgs,
|
||||||
userId: number,
|
|
||||||
@Arg('role', () => String, { nullable: true })
|
|
||||||
role: string | null | undefined,
|
|
||||||
@Ctx()
|
@Ctx()
|
||||||
context: Context,
|
context: Context,
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
switch (role) {
|
|
||||||
case null:
|
|
||||||
case ROLE_NAMES.ROLE_NAME_ADMIN:
|
|
||||||
case ROLE_NAMES.ROLE_NAME_MODERATOR:
|
|
||||||
logger.debug('setUserRole=', role)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new LogError('Not allowed to set user role=', role)
|
|
||||||
}
|
|
||||||
const user = await DbUser.findOne({
|
const user = await DbUser.findOne({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
relations: ['userRoles'],
|
relations: ['userRoles'],
|
||||||
@ -827,18 +816,6 @@ export class UserResolver {
|
|||||||
async user(@Arg('identifier') identifier: string): Promise<User> {
|
async user(@Arg('identifier') identifier: string): Promise<User> {
|
||||||
return new User(await findUserByIdentifier(identifier))
|
return new User(await findUserByIdentifier(identifier))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Authorized([RIGHTS.USER])
|
|
||||||
@Query(() => UserContact)
|
|
||||||
async userContact(@Arg('userId', () => Int) userId: number): Promise<UserContact> {
|
|
||||||
return new UserContact(
|
|
||||||
await DbUserContact.findOneOrFail({
|
|
||||||
where: { userId },
|
|
||||||
withDeleted: true,
|
|
||||||
relations: ['user'],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function findUserByEmail(email: string): Promise<DbUser> {
|
export async function findUserByEmail(email: string): Promise<DbUser> {
|
||||||
|
|||||||
@ -20,6 +20,7 @@ export const contributionLinkFactory = async (
|
|||||||
mutation: login,
|
mutation: login,
|
||||||
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
|
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
|
||||||
})
|
})
|
||||||
|
console.log('user=', user)
|
||||||
const variables = {
|
const variables = {
|
||||||
amount: contributionLink.amount,
|
amount: contributionLink.amount,
|
||||||
memo: contributionLink.memo,
|
memo: contributionLink.memo,
|
||||||
@ -32,5 +33,6 @@ export const contributionLinkFactory = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await mutate({ mutation: createContributionLink, variables })
|
const result = await mutate({ mutation: createContributionLink, variables })
|
||||||
|
console.log('link...', result)
|
||||||
return result.data.createContributionLink
|
return result.data.createContributionLink
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
import { User } from '@entity/User'
|
import { User } from '@entity/User'
|
||||||
import { ApolloServerTestClient } from 'apollo-server-testing'
|
import { ApolloServerTestClient } from 'apollo-server-testing'
|
||||||
|
|
||||||
import { ROLE_NAMES } from '@/auth/ROLES'
|
import { RoleNames } from '@enum/RoleNames'
|
||||||
import { setUserRole } from '@/graphql/resolver/util/modifyUserRole'
|
import { setUserRole } from '@/graphql/resolver/util/modifyUserRole'
|
||||||
import { createUser, setPassword } from '@/seeds/graphql/mutations'
|
import { createUser, setPassword } from '@/seeds/graphql/mutations'
|
||||||
import { UserInterface } from '@/seeds/users/UserInterface'
|
import { UserInterface } from '@/seeds/users/UserInterface'
|
||||||
@ -39,7 +39,7 @@ export const userFactory = async (
|
|||||||
if (user.deletedAt) dbUser.deletedAt = user.deletedAt
|
if (user.deletedAt) dbUser.deletedAt = user.deletedAt
|
||||||
if (
|
if (
|
||||||
user.role &&
|
user.role &&
|
||||||
(user.role === ROLE_NAMES.ROLE_NAME_ADMIN || user.role === ROLE_NAMES.ROLE_NAME_MODERATOR)
|
(user.role === RoleNames.ROLE_NAME_ADMIN || user.role === RoleNames.ROLE_NAME_MODERATOR)
|
||||||
) {
|
) {
|
||||||
await setUserRole(dbUser, user.role)
|
await setUserRole(dbUser, user.role)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -119,7 +119,7 @@ export const confirmContribution = gql`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export const setUserRole = gql`
|
export const setUserRole = gql`
|
||||||
mutation ($userId: Int!, $role: String) {
|
mutation ($userId: Int!, $role: RoleNames) {
|
||||||
setUserRole(userId: $userId, role: $role)
|
setUserRole(userId: $userId, role: $role)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@ -322,8 +322,6 @@ export const login = gql`
|
|||||||
hasElopage
|
hasElopage
|
||||||
publisherId
|
publisherId
|
||||||
roles
|
roles
|
||||||
isAdmin
|
|
||||||
isModerator
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@ -12,8 +12,6 @@ export const verifyLogin = gql`
|
|||||||
hasElopage
|
hasElopage
|
||||||
publisherId
|
publisherId
|
||||||
roles
|
roles
|
||||||
isAdmin
|
|
||||||
isModerator
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@ -387,20 +385,3 @@ export const user = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
export const userContact = gql`
|
|
||||||
query ($userId: Int!) {
|
|
||||||
userContact(userId: $userId) {
|
|
||||||
id
|
|
||||||
type
|
|
||||||
userId
|
|
||||||
email
|
|
||||||
emailOptInTypeId
|
|
||||||
emailResendCount
|
|
||||||
emailChecked
|
|
||||||
phone
|
|
||||||
createdAt
|
|
||||||
updatedAt
|
|
||||||
deletedAt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ROLE_NAMES } from '@/auth/ROLES'
|
import { RoleNames } from '@enum/RoleNames'
|
||||||
|
|
||||||
import { UserInterface } from './UserInterface'
|
import { UserInterface } from './UserInterface'
|
||||||
|
|
||||||
@ -10,5 +10,5 @@ export const peterLustig: UserInterface = {
|
|||||||
createdAt: new Date('2020-11-25T10:48:43'),
|
createdAt: new Date('2020-11-25T10:48:43'),
|
||||||
emailChecked: true,
|
emailChecked: true,
|
||||||
language: 'de',
|
language: 'de',
|
||||||
role: ROLE_NAMES.ROLE_NAME_ADMIN,
|
role: RoleNames.ROLE_NAME_ADMIN,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user