push
This commit is contained in:
72
innungsapp/apps/admin/app/api/registrierung/[slug]/route.ts
Normal file
72
innungsapp/apps/admin/app/api/registrierung/[slug]/route.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@innungsapp/shared'
|
||||
import { sendInviteEmail } from '@/lib/email'
|
||||
import { auth } from '@/lib/auth'
|
||||
|
||||
export async function POST(req: NextRequest, { params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params
|
||||
const body = await req.json().catch(() => null)
|
||||
|
||||
if (!body?.name || !body?.email) {
|
||||
return NextResponse.json({ error: 'Name und E-Mail sind erforderlich.' }, { status: 400 })
|
||||
}
|
||||
|
||||
const name: string = String(body.name).trim()
|
||||
const email: string = String(body.email).trim().toLowerCase()
|
||||
|
||||
const org = await prisma.organization.findUnique({
|
||||
where: { slug },
|
||||
select: { id: true, name: true },
|
||||
})
|
||||
|
||||
if (!org) {
|
||||
return NextResponse.json({ error: 'Organisation nicht gefunden.' }, { status: 404 })
|
||||
}
|
||||
|
||||
// Check if email already registered in this org
|
||||
const existing = await prisma.member.findFirst({
|
||||
where: { orgId: org.id, email },
|
||||
})
|
||||
|
||||
if (existing) {
|
||||
// Still send invite so user can log in — don't reveal whether they exist
|
||||
await sendInviteEmail({
|
||||
to: email,
|
||||
memberName: existing.name,
|
||||
orgName: org.name,
|
||||
apiUrl: process.env.BETTER_AUTH_URL!,
|
||||
})
|
||||
return NextResponse.json({ success: true })
|
||||
}
|
||||
|
||||
// Create member record
|
||||
await prisma.member.create({
|
||||
data: {
|
||||
name,
|
||||
email,
|
||||
orgId: org.id,
|
||||
betrieb: '-',
|
||||
sparte: '-',
|
||||
ort: '-',
|
||||
status: 'aktiv',
|
||||
},
|
||||
})
|
||||
|
||||
// Create auth user (may already exist)
|
||||
try {
|
||||
await auth.api.createUser({
|
||||
body: { name, email, role: 'user', password: undefined },
|
||||
})
|
||||
} catch {
|
||||
// User may already exist in auth system
|
||||
}
|
||||
|
||||
await sendInviteEmail({
|
||||
to: email,
|
||||
memberName: name,
|
||||
orgName: org.name,
|
||||
apiUrl: process.env.BETTER_AUTH_URL!,
|
||||
})
|
||||
|
||||
return NextResponse.json({ success: true })
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@innungsapp/shared'
|
||||
|
||||
export async function POST(req: NextRequest, { params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params
|
||||
const body = await req.json().catch(() => null)
|
||||
|
||||
if (!body?.email) {
|
||||
return NextResponse.json({ error: 'E-Mail ist erforderlich.' }, { status: 400 })
|
||||
}
|
||||
|
||||
const email: string = String(body.email).trim().toLowerCase()
|
||||
const name: string = String(body.name ?? '').trim() || email.split('@')[0]
|
||||
|
||||
const org = await prisma.organization.findUnique({
|
||||
where: { slug },
|
||||
select: { id: true },
|
||||
})
|
||||
|
||||
if (!org) {
|
||||
return NextResponse.json({ error: 'Organisation nicht gefunden.' }, { status: 404 })
|
||||
}
|
||||
|
||||
// Look up the auth user that better-auth just created
|
||||
const authUser = await prisma.user.findUnique({
|
||||
where: { email },
|
||||
select: { id: true },
|
||||
})
|
||||
|
||||
if (!authUser) {
|
||||
return NextResponse.json({ error: 'Benutzer nicht gefunden. Bitte zuerst registrieren.' }, { status: 400 })
|
||||
}
|
||||
|
||||
// Idempotent: skip if member already exists (linked to this user)
|
||||
const existingMember = await prisma.member.findFirst({
|
||||
where: { orgId: org.id, userId: authUser.id },
|
||||
})
|
||||
|
||||
if (!existingMember) {
|
||||
// Member may exist without userId (created by admin before user registered)
|
||||
const unlinkedMember = await prisma.member.findFirst({
|
||||
where: { orgId: org.id, email, userId: null },
|
||||
})
|
||||
|
||||
if (unlinkedMember) {
|
||||
await prisma.member.update({
|
||||
where: { id: unlinkedMember.id },
|
||||
data: { userId: authUser.id },
|
||||
})
|
||||
} else {
|
||||
await prisma.member.create({
|
||||
data: {
|
||||
name,
|
||||
email,
|
||||
orgId: org.id,
|
||||
userId: authUser.id,
|
||||
betrieb: '-',
|
||||
sparte: '-',
|
||||
ort: '-',
|
||||
status: 'aktiv',
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Idempotent: skip if role already exists
|
||||
const existingRole = await prisma.userRole.findFirst({
|
||||
where: { userId: authUser.id, orgId: org.id },
|
||||
})
|
||||
|
||||
if (!existingRole) {
|
||||
await prisma.userRole.create({
|
||||
data: {
|
||||
userId: authUser.id,
|
||||
orgId: org.id,
|
||||
role: 'member',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true })
|
||||
}
|
||||
Reference in New Issue
Block a user