diff --git a/backend/src/graphql/resolver/ProjectBrandingResolver.ts b/backend/src/graphql/resolver/ProjectBrandingResolver.ts index edfe3eef2..2c3b5a08d 100644 --- a/backend/src/graphql/resolver/ProjectBrandingResolver.ts +++ b/backend/src/graphql/resolver/ProjectBrandingResolver.ts @@ -11,6 +11,7 @@ import { projectBrandingsTable, } from 'database' import { getLogger } from 'log4js' +import { projectBrandingSchema } from 'shared' import { Arg, Authorized, ID, Int, Mutation, Query, Resolver } from 'type-graphql' import { HumHubClient } from '@/apis/humhub/HumHubClient' import { RIGHTS } from '@/auth/RIGHTS' @@ -50,7 +51,7 @@ export class ProjectBrandingResolver { async upsertProjectBranding( @Arg('input') input: ProjectBrandingInput, ): Promise { - return new ProjectBranding(await dbUpsertProjectBranding(input)) + return new ProjectBranding(await dbUpsertProjectBranding(projectBrandingSchema.parse(input))) } @Mutation(() => Boolean) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 061498207..fb2481446 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -30,9 +30,11 @@ import { TransactionLink as DbTransactionLink, User as DbUser, UserContact as DbUserContact, + dbFindProjectBrandingByAlias, + dbFindProjectSpaceId, findUserByIdentifier, getHomeCommunity, - ProjectBranding, + ProjectBrandingSelect, UserLoggingView, } from 'database' import { GraphQLResolveInfo } from 'graphql' @@ -202,7 +204,7 @@ export class UserResolver { // request to humhub and klicktipp run in parallel let humhubUserPromise: Promise> | undefined - let projectBrandingPromise: Promise | undefined + let projectBrandingSpaceIdPromise: Promise | undefined const klicktippStatePromise = getKlicktippState(dbUser.emailContact.email) if (CONFIG.HUMHUB_ACTIVE && dbUser.humhubAllowed) { const getHumhubUser = new PostUser(dbUser) @@ -211,10 +213,7 @@ export class UserResolver { ) } if (project) { - projectBrandingPromise = ProjectBranding.findOne({ - where: { alias: project }, - select: { spaceId: true }, - }) + projectBrandingSpaceIdPromise = dbFindProjectSpaceId(project) } if ( @@ -244,19 +243,15 @@ export class UserResolver { }) await EVENT_USER_LOGIN(dbUser) - const projectBranding = await projectBrandingPromise - logger.debug('project branding: ', projectBranding?.id) + const projectBrandingSpaceId = await projectBrandingSpaceIdPromise + logger.debug('project branding: ', projectBrandingSpaceId) // load humhub state if (humhubUserPromise) { try { const result = await humhubUserPromise user.humhubAllowed = result?.result?.account.status === 1 if (user.humhubAllowed && result?.result?.account?.username) { - let spaceId = null - if (projectBranding) { - spaceId = projectBranding.spaceId - } - await syncHumhub(null, dbUser, result.result.account.username, spaceId) + await syncHumhub(null, dbUser, result.result.account.username, projectBrandingSpaceId) } } catch (e) { logger.error("couldn't reach out to humhub, disable for now", e) @@ -359,12 +354,9 @@ export class UserResolver { return user } } - let projectBrandingPromise: Promise | undefined + let projectBrandingPromise: Promise | undefined if (project) { - projectBrandingPromise = ProjectBranding.findOne({ - where: { alias: project }, - select: { logoUrl: true, spaceId: true }, - }) + projectBrandingPromise = dbFindProjectBrandingByAlias(project) } const gradidoID = await newGradidoID(logger) @@ -423,7 +415,7 @@ export class UserResolver { const queryRunner = db.getDataSource().createQueryRunner() await queryRunner.connect() await queryRunner.startTransaction('REPEATABLE READ') - let projectBranding: ProjectBranding | null | undefined + let projectBranding: ProjectBrandingSelect | undefined try { dbUser = await queryRunner.manager.save(dbUser).catch((error) => { throw new LogError('Error while saving dbUser', error) @@ -924,7 +916,9 @@ export class UserResolver { } // should rarely happen, so we don't optimize for parallel processing if (!dbUser.humhubAllowed && project) { - await ProjectBranding.findOneOrFail({ where: { alias: project } }) + if (!(await dbFindProjectBrandingByAlias(project))) { + throw new LogError(`project branding with alias: ${project} not found`) + } dbUser.humhubAllowed = true await dbUser.save() } diff --git a/backend/src/graphql/resolver/util/syncHumhub.ts b/backend/src/graphql/resolver/util/syncHumhub.ts index 7fbca18ce..9f1556ce5 100644 --- a/backend/src/graphql/resolver/util/syncHumhub.ts +++ b/backend/src/graphql/resolver/util/syncHumhub.ts @@ -22,7 +22,7 @@ export async function syncHumhub( updateUserInfosArg: UpdateUserInfosArgs | null, user: User, oldHumhubUsername: string, - spaceId?: number | null, + spaceId?: number | null | undefined, ): Promise { const logger = createLogger() logger.addContext('user', user.id) diff --git a/database/src/queries/projectBranding.ts b/database/src/queries/projectBranding.ts index 3583c7e1e..4ea33a84f 100644 --- a/database/src/queries/projectBranding.ts +++ b/database/src/queries/projectBranding.ts @@ -56,6 +56,15 @@ export async function dbFindProjectSpaceUrl(alias: string): Promise { + const result = await drizzleDb() + .select({ spaceId: projectBrandingsTable.spaceId }) + .from(projectBrandingsTable) + .where(eq(projectBrandingsTable.alias, alias)) + .limit(1) + return result.at(0)?.spaceId +} /** * * @param alias throw if project not found @@ -91,6 +100,17 @@ export async function dbFindProjectBrandingById( return result.at(0) } +export async function dbFindProjectBrandingByAlias( + alias: string, +): Promise { + const result = await drizzleDb() + .select() + .from(projectBrandingsTable) + .where(eq(projectBrandingsTable.alias, alias)) + .limit(1) + return result.at(0) +} + export async function dbDeleteProjectBranding(id: number): Promise { await drizzleDb().delete(projectBrandingsTable).where(eq(projectBrandingsTable.id, id)) }