pure Verzweiflung...

This commit is contained in:
Claus-Peter Huebner 2023-07-13 21:10:56 +02:00
parent 928091029a
commit 46151006b9
13 changed files with 69 additions and 153 deletions

View File

@ -1,26 +1,22 @@
import { RoleNames } from '@/graphql/enum/RoleNames'
import { ADMIN_RIGHTS } from './ADMIN_RIGHTS'
import { INALIENABLE_RIGHTS } from './INALIENABLE_RIGHTS'
import { MODERATOR_RIGHTS } from './MODERATOR_RIGHTS'
import { Role } from './Role'
import { USER_RIGHTS } from './USER_RIGHTS'
export enum ROLE_NAMES {
ROLE_NAME_UNAUTHORIZED = 'unauthorized',
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, [
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(ROLE_NAMES.ROLE_NAME_MODERATOR, [
export const ROLE_MODERATOR = new Role(RoleNames.ROLE_NAME_MODERATOR, [
...INALIENABLE_RIGHTS,
...USER_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,
...USER_RIGHTS,
...MODERATOR_RIGHTS,

View 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
}

View File

@ -4,9 +4,10 @@ import { AuthChecker } from 'type-graphql'
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_NAMES, ROLE_MODERATOR } from '@/auth/ROLES'
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
@ -40,10 +41,10 @@ export const isAuthorized: AuthChecker<Context> = async ({ context }, rights) =>
context.role = ROLE_USER
if (user.userRoles && user.userRoles.length > 0) {
switch (user.userRoles[0].role) {
case ROLE_NAMES.ROLE_NAME_ADMIN:
case RoleNames.ROLE_NAME_ADMIN:
context.role = ROLE_ADMIN
break
case ROLE_NAMES.ROLE_NAME_MODERATOR:
case RoleNames.ROLE_NAME_MODERATOR:
context.role = ROLE_MODERATOR
break
default:

View 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
})

View File

@ -1,8 +1,6 @@
import { User as dbUser } from '@entity/User'
import { ObjectType, Field, Int } from 'type-graphql'
import { ROLE_NAMES } from '@/auth/ROLES'
import { KlickTipp } from './KlickTipp'
@ObjectType()
@ -72,14 +70,4 @@ export class User {
@Field(() => [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)
}
}

View File

@ -2,8 +2,6 @@ import { User } from '@entity/User'
import { Decimal } from 'decimal.js-light'
import { ObjectType, Field, Int } from 'type-graphql'
import { ROLE_NAMES } from '@/auth/ROLES'
@ObjectType()
export class UserAdmin {
constructor(user: User, creation: Decimal[], hasElopage: boolean, emailConfirmationSend: string) {
@ -48,16 +46,6 @@ export class UserAdmin {
@Field(() => [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()

View File

@ -22,7 +22,7 @@ import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/help
import { logger, i18n as localization } from '@test/testSetup'
import { subscribe } from '@/apis/KlicktippController'
import { ROLE_NAMES } from '@/auth/ROLES'
import { RoleNames } from '@enum/RoleNames'
import { CONFIG } from '@/config'
import {
sendAccountActivationEmail,
@ -56,7 +56,6 @@ import {
searchUsers,
user as userQuery,
checkUsername,
userContact,
} from '@/seeds/graphql/queries'
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
import { bobBaumeister } from '@/seeds/users/bob-baumeister'
@ -165,7 +164,7 @@ describe('UserResolver', () => {
createdAt: expect.any(Date),
// emailChecked: false,
language: 'de',
userRoles: [], // expect.any(Array),
userRoles: [],
deletedAt: null,
publisherId: 1234,
referrerId: null,
@ -339,22 +338,17 @@ describe('UserResolver', () => {
})
// make Peter Lustig Admin
let peter = await User.findOneOrFail({
const peter = await User.findOneOrFail({
where: { id: user[0].id },
relations: ['userRoles'],
})
peter.userRoles = [] as UserRole[]
peter.userRoles[0] = UserRole.create()
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
await peter.userRoles[0].save()
peter = await User.findOneOrFail({
where: { id: user[0].id },
relations: ['userRoles'],
})
// date statement
const actualDate = new Date()
const futureDate = new Date() // Create a future day from the executed day
@ -368,7 +362,6 @@ describe('UserResolver', () => {
validFrom: actualDate,
validTo: futureDate,
})
resetToken()
result = await mutate({
mutation: createUser,
@ -707,8 +700,6 @@ describe('UserResolver', () => {
lastName: 'Bloxberg',
publisherId: 1234,
roles: [],
isAdmin: false,
isModerator: false,
},
},
}),
@ -980,8 +971,6 @@ describe('UserResolver', () => {
hasElopage: false,
publisherId: 1234,
roles: [],
isAdmin: false,
isModerator: false,
},
},
}),
@ -997,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,
},
},
})
})
})
})
})
@ -1450,7 +1411,7 @@ describe('UserResolver', () => {
expect.objectContaining({
firstName: 'Peter',
lastName: 'Lustig',
role: ROLE_NAMES.ROLE_NAME_ADMIN,
role: RoleNames.ROLE_NAME_ADMIN,
}),
]),
},
@ -1539,8 +1500,6 @@ describe('UserResolver', () => {
lastName: 'Bloxberg',
publisherId: 1234,
roles: [],
isAdmin: false,
isModerator: false,
},
},
}),
@ -1561,7 +1520,7 @@ describe('UserResolver', () => {
await expect(
mutate({
mutation: setUserRole,
variables: { userId: 1, role: ROLE_NAMES.ROLE_NAME_ADMIN },
variables: { userId: 1, role: RoleNames.ROLE_NAME_ADMIN },
}),
).resolves.toEqual(
expect.objectContaining({
@ -1590,7 +1549,7 @@ describe('UserResolver', () => {
await expect(
mutate({
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(
expect.objectContaining({
@ -1607,7 +1566,7 @@ describe('UserResolver', () => {
// set Moderator-Role for Peter
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
await UserRole.save(userRole)
@ -1626,7 +1585,7 @@ describe('UserResolver', () => {
await expect(
mutate({
mutation: setUserRole,
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_ADMIN },
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
}),
).resolves.toEqual(
expect.objectContaining({
@ -1654,12 +1613,12 @@ describe('UserResolver', () => {
it('returns user with new moderator-role', async () => {
const result = await mutate({
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.objectContaining({
data: {
setUserRole: ROLE_NAMES.ROLE_NAME_MODERATOR,
setUserRole: RoleNames.ROLE_NAME_MODERATOR,
},
}),
)
@ -1676,7 +1635,7 @@ describe('UserResolver', () => {
await expect(
mutate({
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(
expect.objectContaining({
@ -1710,12 +1669,12 @@ describe('UserResolver', () => {
it('returns admin-rolename', async () => {
const result = await mutate({
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.objectContaining({
data: {
setUserRole: ROLE_NAMES.ROLE_NAME_ADMIN,
setUserRole: RoleNames.ROLE_NAME_ADMIN,
},
}),
)
@ -1744,12 +1703,12 @@ describe('UserResolver', () => {
it('returns date string', async () => {
const result = await mutate({
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.objectContaining({
data: {
setUserRole: ROLE_NAMES.ROLE_NAME_MODERATOR,
setUserRole: RoleNames.ROLE_NAME_MODERATOR,
},
}),
)
@ -1851,12 +1810,12 @@ describe('UserResolver', () => {
jest.clearAllMocks()
await mutate({
mutation: setUserRole,
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_ADMIN },
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
})
await expect(
mutate({
mutation: setUserRole,
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_ADMIN },
variables: { userId: user.id, role: RoleNames.ROLE_NAME_ADMIN },
}),
).resolves.toEqual(
expect.objectContaining({
@ -1868,7 +1827,7 @@ describe('UserResolver', () => {
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'User already has role=',
ROLE_NAMES.ROLE_NAME_ADMIN,
RoleNames.ROLE_NAME_ADMIN,
)
})
})
@ -1878,12 +1837,12 @@ describe('UserResolver', () => {
jest.clearAllMocks()
await mutate({
mutation: setUserRole,
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_MODERATOR },
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
})
await expect(
mutate({
mutation: setUserRole,
variables: { userId: user.id, role: ROLE_NAMES.ROLE_NAME_MODERATOR },
variables: { userId: user.id, role: RoleNames.ROLE_NAME_MODERATOR },
}),
).resolves.toEqual(
expect.objectContaining({
@ -1895,7 +1854,7 @@ describe('UserResolver', () => {
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'User already has role=',
ROLE_NAMES.ROLE_NAME_MODERATOR,
RoleNames.ROLE_NAME_MODERATOR,
)
})
})

View File

@ -24,12 +24,10 @@ import { UserContactType } from '@enum/UserContactType'
import { SearchAdminUsersResult } from '@model/AdminUser'
import { User } from '@model/User'
import { UserAdmin, SearchUsersResult } from '@model/UserAdmin'
import { UserContact } from '@model/UserContact'
import { subscribe } from '@/apis/KlicktippController'
import { encode } from '@/auth/JWT'
import { RIGHTS } from '@/auth/RIGHTS'
import { ROLE_NAMES } from '@/auth/ROLES'
import { CONFIG } from '@/config'
import {
sendAccountActivationEmail,
@ -72,6 +70,9 @@ 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 => {
@ -707,22 +708,10 @@ export class UserResolver {
@Authorized([RIGHTS.SET_USER_ROLE])
@Mutation(() => String, { nullable: true })
async setUserRole(
@Arg('userId', () => Int)
userId: number,
@Arg('role', () => String, { nullable: true })
role: string | null | undefined,
@Args() { userId, role }: SetUserRoleArgs,
@Ctx()
context: Context,
): 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({
where: { id: userId },
relations: ['userRoles'],
@ -827,18 +816,6 @@ export class UserResolver {
async user(@Arg('identifier') identifier: string): Promise<User> {
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> {

View File

@ -20,6 +20,7 @@ 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,
@ -32,5 +33,6 @@ export const contributionLinkFactory = async (
}
const result = await mutate({ mutation: createContributionLink, variables })
console.log('link...', result)
return result.data.createContributionLink
}

View File

@ -3,7 +3,7 @@
import { User } from '@entity/User'
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 { createUser, setPassword } from '@/seeds/graphql/mutations'
import { UserInterface } from '@/seeds/users/UserInterface'
@ -39,7 +39,7 @@ export const userFactory = async (
if (user.deletedAt) dbUser.deletedAt = user.deletedAt
if (
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)
}

View File

@ -119,7 +119,7 @@ export const confirmContribution = gql`
`
export const setUserRole = gql`
mutation ($userId: Int!, $role: String) {
mutation ($userId: Int!, $role: RoleNames) {
setUserRole(userId: $userId, role: $role)
}
`
@ -322,8 +322,6 @@ export const login = gql`
hasElopage
publisherId
roles
isAdmin
isModerator
}
}
`

View File

@ -12,8 +12,6 @@ export const verifyLogin = gql`
hasElopage
publisherId
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
}
}
`

View File

@ -1,4 +1,4 @@
import { ROLE_NAMES } from '@/auth/ROLES'
import { RoleNames } from '@enum/RoleNames'
import { UserInterface } from './UserInterface'
@ -10,5 +10,5 @@ export const peterLustig: UserInterface = {
createdAt: new Date('2020-11-25T10:48:43'),
emailChecked: true,
language: 'de',
role: ROLE_NAMES.ROLE_NAME_ADMIN,
role: RoleNames.ROLE_NAME_ADMIN,
}