Files
Grow/src/app/api/invite/redeem/route.ts
T
arnaudne 41170d9155 feat: UX improvements, webhooks, invite management
- Photo lightbox: ArrowLeft/Right/Escape keyboard navigation
- Growth chart: persistent WHO percentile legend (not hover-only)
- Sleep stats: configurable window selector (18h/19h/20h/21h)
- Quick-add FAB: now visible on desktop (bottom-right corner)
- Invite code reset button in settings (non-admin, PARENT role only)
- Pending email invites: tracked per-token with 7-day expiry, revocable
  from settings UI; new /auth/invite/t/[token] accept page
- Webhooks: Prisma model, CRUD API, HMAC-SHA256 dispatcher wired into
  event.created / growth.created / doctor_note.created; settings UI
- Docker cron service: medication reminders every 15min, milk-expiry
  and daily-digest daily; secured with CRON_SECRET
- Photo uploads persist across redeploys via Docker named volume

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 23:14:28 +02:00

28 lines
1.1 KiB
TypeScript

import { NextResponse } from "next/server";
import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";
export async function POST(req: Request) {
const { name, email, password, token } = await req.json();
if (!name || !email || !password || !token) {
return NextResponse.json({ error: "Champs requis manquants" }, { status: 400 });
}
const invite = await prisma.pendingInvite.findUnique({ where: { token } });
if (!invite) return NextResponse.json({ error: "Lien d'invitation invalide" }, { status: 404 });
if (invite.expiresAt < new Date()) return NextResponse.json({ error: "Lien d'invitation expiré" }, { status: 410 });
const existing = await prisma.user.findUnique({ where: { email } });
if (existing) return NextResponse.json({ error: "Email déjà utilisé" }, { status: 409 });
const hashed = await bcrypt.hash(password, 12);
const user = await prisma.user.create({
data: { name, email, password: hashed, familyId: invite.familyId, role: invite.role },
});
await prisma.pendingInvite.delete({ where: { token } });
return NextResponse.json({ id: user.id, email: user.email, name: user.name, role: user.role });
}