Files
famdone/frontend/src/routes/[fam]/[username]/preferences/+page.server.ts
T

100 lines
3.6 KiB
TypeScript

import { redirect } from '@sveltejs/kit';
import { hono } from '$lib/server/hono';
import { PROXY_URL } from '$app/env/public';
const HONO_URL = PROXY_URL;
export async function load(event) {
const session = event.locals.session;
const famSlug = event.params.fam;
const username = event.params.username;
// Parent (session auth) — profile lives in fam_admins
if (session) {
const famId = session.famId;
if (session.memberName && session.memberName !== username) {
throw redirect(303, `/${famSlug}/${session.memberName}/preferences`);
}
try {
const me = await hono.admin.getProfile(event, famId);
return {
verified: true, token: '', memberId: me.id, famId,
memberName: me.name, memberColor: me.color, email: me.email || '',
session: true,
};
} catch {
return { verified: false, token: '', memberId: '', famId: '', memberName: '', memberColor: '', email: '' };
}
}
// Child (device token) — profile lives in members
const deviceToken = event.cookies.get('device_token') || event.url.searchParams.get('token') || '';
if (!deviceToken) {
return { verified: false, token: '', memberId: '', famId: '', memberName: '', memberColor: '', email: '' };
}
try {
const res = await fetch(`${HONO_URL}/api/members/verify-token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ deviceToken, famSlug }),
});
const data = await res.json();
if (!res.ok || data.name !== username) {
return { verified: false, token: deviceToken, memberId: '', famId: '', memberName: '', memberColor: '', email: '' };
}
return {
verified: true, token: deviceToken, memberId: data.memberId, famId: data.famId,
memberName: data.name, memberColor: data.color, email: data.email || '', session: false,
};
} catch {
return { verified: false, token: '', memberId: '', famId: '', memberName: '', memberColor: '', email: '' };
}
}
export const actions = {
update: async (event) => {
const session = event.locals.session;
const fd = await event.request.formData();
const name = fd.get('name') as string;
const color = fd.get('color') as string;
const email = fd.get('email') as string;
if (session) {
const famId = session.famId;
try {
const data: Record<string, string> = {};
if (name) data.name = name;
if (color) data.color = color;
data.email = email || '';
const me = await hono.admin.updateProfile(event, famId, data);
return { success: true, name: me.name, color: me.color, email: me.email };
} catch (e) {
return { error: e instanceof Error ? e.message : 'Update failed' };
}
}
const deviceToken = event.cookies.get('device_token') || event.url.searchParams.get('token') || '';
const famSlug = event.params.fam;
if (!deviceToken) return { error: 'Not authenticated' };
try {
const verifyRes = await fetch(`${HONO_URL}/api/members/verify-token`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ deviceToken, famSlug }),
});
const verify = await verifyRes.json();
if (!verifyRes.ok) return { error: 'Verification failed' };
const res = await fetch(`${HONO_URL}/api/members/me`, {
method: 'PATCH', headers: { 'x-device-token': deviceToken, 'x-device-famid': verify.famId, 'Content-Type': 'application/json' },
body: JSON.stringify({ name, color }),
});
const data = await res.json();
if (!res.ok) return { error: data.error || 'Update failed' };
return { success: true, name: data.name, color: data.color };
} catch (e) {
return { error: e instanceof Error ? e.message : 'Update failed' };
}
},
};