diff --git a/innungsapp/apps/admin/Dockerfile b/innungsapp/apps/admin/Dockerfile index 7262d0b..91f2744 100644 --- a/innungsapp/apps/admin/Dockerfile +++ b/innungsapp/apps/admin/Dockerfile @@ -33,6 +33,7 @@ RUN pnpm --filter @innungsapp/shared prisma:generate # Build the admin app ENV NEXT_TELEMETRY_DISABLED=1 +ENV DOCKER_BUILD=1 RUN pnpm --filter @innungsapp/admin build # ============================================= diff --git a/innungsapp/apps/admin/app/superadmin/actions.ts b/innungsapp/apps/admin/app/superadmin/actions.ts index 4bcaac4..a1554e9 100644 --- a/innungsapp/apps/admin/app/superadmin/actions.ts +++ b/innungsapp/apps/admin/app/superadmin/actions.ts @@ -73,6 +73,7 @@ const createOrgSchema = z.object({ landingPageHeroImage: z.string().optional().nullable(), landingPageHeroOverlayOpacity: z.number().min(0).max(100).optional().default(50), landingPageFeatures: z.string().optional(), + landingPageFooter: z.string().optional(), landingPageSectionTitle: z.string().optional(), landingPageButtonText: z.string().optional(), appStoreUrl: z.string().url('Ungueltige URL').optional().or(z.literal('')), @@ -90,6 +91,7 @@ const updateOrgSchema = z.object({ landingPageText: z.string().optional(), landingPageHeroImage: z.string().optional().nullable(), landingPageFeatures: z.string().optional(), + landingPageFooter: z.string().optional(), landingPageSectionTitle: z.string().optional(), landingPageButtonText: z.string().optional(), appStoreUrl: z.string().url('Ungueltige URL').optional().or(z.literal('')), diff --git a/innungsapp/apps/admin/app/superadmin/landingpages/page.tsx b/innungsapp/apps/admin/app/superadmin/landingpages/page.tsx index 8ab63fc..e02624e 100644 --- a/innungsapp/apps/admin/app/superadmin/landingpages/page.tsx +++ b/innungsapp/apps/admin/app/superadmin/landingpages/page.tsx @@ -12,8 +12,8 @@ export default async function LandingPagesOverview({ const organizations = await prisma.organization.findMany({ where: q ? { OR: [ - { name: { contains: q, mode: 'insensitive' } }, - { slug: { contains: q, mode: 'insensitive' } }, + { name: { contains: q } }, + { slug: { contains: q } }, ] } : {}, orderBy: { name: 'asc' }, diff --git a/innungsapp/apps/admin/app/superadmin/page.tsx b/innungsapp/apps/admin/app/superadmin/page.tsx index e845597..674d805 100644 --- a/innungsapp/apps/admin/app/superadmin/page.tsx +++ b/innungsapp/apps/admin/app/superadmin/page.tsx @@ -32,9 +32,9 @@ export default async function SuperAdminPage({ const where = q ? { OR: [ - { name: { contains: q, mode: 'insensitive' } }, - { slug: { contains: q, mode: 'insensitive' } }, - { contactEmail: { contains: q, mode: 'insensitive' } }, + { name: { contains: q } }, + { slug: { contains: q } }, + { contactEmail: { contains: q } }, ], } : {} diff --git a/innungsapp/apps/admin/next.config.ts b/innungsapp/apps/admin/next.config.ts index a319358..6e978b2 100644 --- a/innungsapp/apps/admin/next.config.ts +++ b/innungsapp/apps/admin/next.config.ts @@ -2,7 +2,7 @@ import type { NextConfig } from 'next' const nextConfig: NextConfig = { transpilePackages: ['@innungsapp/shared'], - output: 'standalone', + output: process.env.DOCKER_BUILD ? 'standalone' : undefined, experimental: {}, webpack: (config, { dev }) => { if (dev) { diff --git a/innungsapp/apps/admin/server/routers/members.ts b/innungsapp/apps/admin/server/routers/members.ts index ec1313b..93eb3cc 100644 --- a/innungsapp/apps/admin/server/routers/members.ts +++ b/innungsapp/apps/admin/server/routers/members.ts @@ -41,17 +41,7 @@ async function createUserDirectly(opts: { email: string; name: string; password: mustChangePassword: opts.mustChangePassword ?? false, }, }) - // Try better-auth API first (guaranteed correct hash format). - // Falls back to direct DB write if API fails (e.g. admin permissions not available). - try { - const authHeaders = await getSanitizedHeaders() - await auth.api.updateUser({ - body: { userId, password: opts.password }, - headers: authHeaders, - }) - } catch { - await createCredentialAccount(userId, opts.password) - } + await createCredentialAccount(userId, opts.password) return { id: userId } } @@ -148,8 +138,8 @@ export const membersRouter = router({ if (callerHasAccess) { const ur = memberAnyOrg.userId ? await ctx.prisma.userRole.findUnique({ - where: { orgId_userId: { orgId: memberAnyOrg.orgId, userId: memberAnyOrg.userId } } - }) + where: { orgId_userId: { orgId: memberAnyOrg.orgId, userId: memberAnyOrg.userId } } + }) : null return { ...memberAnyOrg, role: ur?.role ?? 'member' } } @@ -226,7 +216,7 @@ export const membersRouter = router({ // 1. Create the member record const member = await ctx.prisma.member.create({ - data: { ...rest, orgId: ctx.orgId }, + data: { ...rest, orgId: ctx.orgId } as any, }) // 2. Create a User account if a password was provided OR role is 'admin', @@ -256,8 +246,9 @@ export const membersRouter = router({ where: { userId, providerId: 'credential' } }) if (credAccount) { - // Credential account exists — update the password via Better Auth - await auth.api.updateUser({ body: { userId, password, name: input.name }, headers: authHeaders }) + // Credential account exists — update the password hash directly + const newHash = await hashPassword(password) + await ctx.prisma.account.update({ where: { id: credAccount.id }, data: { password: newHash } }) } else { // No credential account yet — create one directly in the DB await createCredentialAccount(userId, password) @@ -292,7 +283,7 @@ export const membersRouter = router({ // 1. Create member record const member = await ctx.prisma.member.create({ - data: { ...memberData, orgId: ctx.orgId }, + data: { ...memberData, orgId: ctx.orgId } as any, }) const org = await ctx.prisma.organization.findUniqueOrThrow({ @@ -350,7 +341,7 @@ export const membersRouter = router({ where: { id: member.id }, data: { userId: targetUserId } }) - + if (role === 'admin') { await ctx.prisma.userRole.upsert({ where: { orgId_userId: { orgId: ctx.orgId, userId: targetUserId } },