owltide/server/api/auth/account.patch.ts
Hornwitser f4f23e6c18
All checks were successful
/ build (push) Successful in 1m29s
/ deploy (push) Successful in 16s
Validate timezone with normalizeZone
Instead of constructing a new DateTime object and seeing if it
succeeded, validate the client's timezone selection using the
Info.normalizeZone utility function.  This prevents throwing an
unexpected error creating the DateTime object after the change
in e100555 to throw on invalid dates.
2025-06-14 19:26:58 +02:00

73 lines
2.1 KiB
TypeScript

import { readAccounts, writeAccounts } from "~/server/database";
import { DateTime, Info } from "~/shared/utils/luxon";
import { apiAccountPatchSchema } from "~/shared/types/api";
import { z } from "zod/v4-mini";
export default defineEventHandler(async (event) => {
const session = await requireServerSession(event);
const { success, error, data: patch } = apiAccountPatchSchema.safeParse(await readBody(event));
if (!success) {
throw createError({
status: 400,
statusText: "Bad Request",
message: z.prettifyError(error),
});
}
if (patch.timezone?.length) {
const zone = Info.normalizeZone(patch.timezone);
if (!zone.isValid) {
throw createError({
status: 400,
message: `Invalid timezone: the zone "${patch.timezone} is not supported`,
});
}
}
if (patch.locale?.length) {
const locale = DateTime.local({ locale: patch.locale }).resolvedLocaleOptions().locale;
if (locale !== patch.locale) {
throw createError({
status: 400,
message: `Invalid locale: the locale "${patch.locale}" is not supported (was treated as "${locale}")`
});
}
}
const accounts = await readAccounts();
const sessionAccount = accounts.find(account => account.id === session.accountId);
if (!sessionAccount) {
throw Error("Account does not exist");
}
if (patch.interestedEventIds !== undefined) {
if (patch.interestedEventIds.length) {
sessionAccount.interestedEventIds = patch.interestedEventIds;
} else {
delete sessionAccount.interestedEventIds;
}
}
if (patch.interestedEventSlotIds !== undefined) {
if (patch.interestedEventSlotIds.length) {
sessionAccount.interestedEventSlotIds = patch.interestedEventSlotIds;
} else {
delete sessionAccount.interestedEventSlotIds;
}
}
if (patch.timezone !== undefined) {
if (patch.timezone)
sessionAccount.timezone = patch.timezone;
else
delete sessionAccount.timezone;
}
if (patch.locale !== undefined) {
if (patch.locale)
sessionAccount.locale = patch.locale;
else
delete sessionAccount.locale;
}
await writeAccounts(accounts);
// Update Schedule counts.
await updateScheduleInterestedCounts(accounts);
})