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.
73 lines
2.1 KiB
TypeScript
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);
|
|
})
|