import type { Actions, PageServerLoad } from '$types'; import { type inquiryTokenPayload, Sender } from '$lib/types/inquiries'; import jwt from 'jsonwebtoken'; import { error } from '@sveltejs/kit'; import sql from '$lib/db/db.server'; import { getRequiredFormString } from '$lib/shared'; import { sendInquiryMessageEmail } from '$lib/email/sender.server'; import type { Item } from '$lib/types/item'; export const load: PageServerLoad = async ({ url, locals, params }) => { const token: string | undefined = url.searchParams.get('token'); const inquiryId: string = params.inquiryId; if (token) { try { jwt.verify(token, process.env.JWT_SECRET!); } catch { throw error(403, 'Your response token does not match this inquiry!'); } } else if (!locals || !locals.user) { throw error( 403, 'You must be either signed in, or have a respond token to access this inquiry!' ); } const [item]: Item[] = await sql` SELECT i.*, json_agg( jsonb_build_object( 'id', t.id, 'item_id', t.item_id, 'created_at', t.created_at, 'messages', m.messages ) ) FILTER ( WHERE t.id = ${inquiryId} ) AS threads FROM items i LEFT JOIN inquiry_threads t ON t.item_id = i.id LEFT JOIN LATERAL ( SELECT json_agg(im.* ORDER BY im.created_at) AS messages FROM inquiry_messages im WHERE im.thread_id = t.id ) m ON TRUE WHERE i.id = (SELECT item_id FROM inquiry_threads WHERE id = ${inquiryId}) GROUP BY i.id;`; console.log(item); return { item }; }; export const actions: Actions = { reply: async ({ request, url, locals, params }) => { const token: string | undefined = url.searchParams.get('token'); const inquiryId: number = params.inquiryId; let sender: Sender | undefined; if (locals && locals.user) { sender = Sender.ADMIN; } else if (token) { let decoded: inquiryTokenPayload; try { decoded = jwt.verify(token, process.env.JWT_SECRET!) as inquiryTokenPayload; sender = decoded.sender; } catch { throw error(403, 'Your response token does not match this inquiry!'); } if (decoded.threadId.toString() !== inquiryId.toString()) { throw error(403, 'Your response token does not match this inquiry!'); } } else { throw error( 403, 'You must be either signed in, or have a respond token to access this inquiry!' ); } const data = await request.formData(); const body = getRequiredFormString(data, 'message'); const response = await sql` INSERT INTO inquiry_messages (thread_id, sender, body) VALUES (${inquiryId}, ${sender}, ${body}) RETURNING id; `; let nextReplySender: Sender; if (sender === Sender.ADMIN || sender === Sender.FINDER) { nextReplySender = Sender.INQUIRER; } else { nextReplySender = Sender.FINDER; } await sendInquiryMessageEmail(inquiryId, nextReplySender); return { success: true }; } } satisfies Actions;