add shared computer feature
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
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');
|
||||
}
|
||||
Reference in New Issue
Block a user