41170d9155
- 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>
28 lines
1.1 KiB
TypeScript
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 });
|
|
}
|