import { db } from '$lib/server/db'; import type { User } from '$lib/server/db/types/user.js'; import { fail, redirect, type Actions } from '@sveltejs/kit'; import bcrypt from 'bcryptjs'; import { nanoid } from 'nanoid'; export const load = async ({ locals: { guard }, params }) => { guard.requiresAdmin().orRedirects(); let user = db.data.users.find((u) => u.id === params.slug) as Partial; if (!user && params.slug !== 'new') { redirect(302, '/dashboard/users'); } if (user) { user = structuredClone(user); delete user['password']; } return { user, groups: db.data.groups, devices: db.data.devices, }; }; export const actions: Actions = { update: async ({ request, locals: { guard }, params }) => { if (guard.requiresAdmin().isFailed()) { return fail(403); } const form = await request.formData(); const name = form.get('name')?.toString(); const admin = form.get('admin')?.toString() === 'on'; const password = form.get('password')?.toString() ?? ''; const groups = form.getAll('groups').map((g) => g.toString()); const devices = form.getAll('devices').map((d) => d.toString()); if (!name) { // TODO better validation return { error: 'MISSING_FIELDS', }; } if (params.slug === 'new') { if (password.length < 4) { return { error: 'PASSWORD_TOO_WEAK', }; } await db.update(({ users }) => { users.push({ id: nanoid(), name, admin, groups, devices, password: bcrypt.hashSync(password, 10), }); }); } else { await db.update(({ users }) => { let user = users.find((u) => u.id === params.slug); if (!user) { return; } user.name = name; user.admin = admin; user.groups = groups; user.devices = devices; if (password.length > 0) { user.password = bcrypt.hashSync(password, 10); } }); } }, delete: async ({ locals: { guard }, params }) => { if (guard.requiresAdmin().isFailed()) { return fail(403); } db.data.users = db.data.users.filter((u) => u.id !== params.slug); db.write(); }, };