import { json, error } from '@sveltejs/kit'; import type { RequestEvent } from '@sveltejs/kit'; import { getPin, setPin, verifyPin, hasPin, PIN_RE } from '$lib/server/pins'; import { createPbClient } from '$lib/server/pocketbase'; // PIN status for the shared-device toggle reminders. Never reveals values: // - child → whether THEIR OWN pin is set (about self only); // - parent → per-child set/unset roster (names + booleans, no PIN values; // actual values stay behind the settings revealPin action). export async function GET(event: RequestEvent) { const u = event.locals.user; if (!u || !event.locals.pbToken) throw error(401, 'Unauthorized'); if (u.role === 'child') { return json({ hasPin: await hasPin(u.id) }); } if (u.role !== 'parent') throw error(403, 'Forbidden'); const pb = createPbClient(event.locals.pbToken); const kids: any[] = await pb .collection('users') .getFullList({ filter: `famId = '${u.famId}' && role = 'child'` }) .catch(() => []); const children = await Promise.all( kids.map(async (k: any) => ({ userId: k.id, name: k.name || '?', hasPin: await hasPin(k.id) })) ); return json({ children }); } // Child PIN management. Session-role checked here (PB rules are superuser-only // on `pins`): only the child themselves can set/change their own PIN. export async function POST(event: RequestEvent) { const u = event.locals.user; if (!u) throw error(401, 'Unauthorized'); if (u.role !== 'child') throw error(403, 'Only children use PINs'); const body = await event.request.json().catch(() => ({})); const { action, pin, currentPin } = body as { action?: string; pin?: string; currentPin?: string; }; if (!action || !pin || !PIN_RE.test(pin)) { throw error(400, 'PIN must be exactly 3 digits'); } if (action === 'set') { if (await getPin(u.id)) throw error(400, 'PIN already set'); await setPin(u.famId, u.id, pin); return json({ ok: true }); } // Join wizard: assign the PIN on THIS device without touching an existing // one (a kid joining a second shared device already has a PIN — their pin // works everywhere; nobody can silently reassign it). if (action === 'ensure') { if (!(await getPin(u.id))) await setPin(u.famId, u.id, pin); return json({ ok: true }); } if (action === 'change') { const existing = await getPin(u.id); if (!existing) throw error(400, 'No PIN set yet'); if (!currentPin || !(await verifyPin(u.id, currentPin))) { throw error(401, 'Current PIN is wrong'); } await setPin(u.famId, u.id, pin); return json({ ok: true }); } throw error(400, 'Unknown action'); }