Fix SendouForm date validation (#2808)

This commit is contained in:
Kalle 2026-02-15 21:10:27 +02:00 committed by GitHub
parent d1da074428
commit 49062284f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 66 additions and 36 deletions

View File

@ -222,8 +222,8 @@ export const scrimsNewFormSchema = z
at: datetimeRequired({
label: "labels.start",
bottomText: "bottomTexts.scrimStart",
min: sub(new Date(), { days: 1 }),
max: add(new Date(), { days: 15 }),
min: () => sub(new Date(), { days: 1 }),
max: () => add(new Date(), { days: 15 }),
minMessage: "errors.dateInPast",
maxMessage: "errors.dateTooFarInFuture",
}),

View File

@ -95,7 +95,7 @@ export const banUserActionSchema = z.object({
expiresAt: datetimeOptional({
label: "labels.banUserExpiresAt",
bottomText: "bottomTexts.banUserExpiresAtHelp",
min: new Date(),
min: () => new Date(),
minMessage: "errors.dateInPast",
}),
});

View File

@ -153,7 +153,7 @@ export const vodFormBaseSchema = z.object({
}),
date: dayMonthYearRequired({
label: "labels.vodDate",
max: add(new Date(), { days: 1 }),
max: () => add(new Date(), { days: 1 }),
maxMessage: "errors.dateMustNotBeFuture",
minMessage: "errors.dateTooOld",
}),

View File

@ -389,22 +389,20 @@ type DateTimeArgs = WithTypedTranslationKeys<
};
export function datetimeRequired(args: DateTimeArgs) {
const minDate = args.min ?? new Date(Date.UTC(2015, 4, 28));
const maxDate = args.max ?? new Date(Date.UTC(2030, 4, 28));
const resolveMin = args.min ?? (() => new Date(Date.UTC(2015, 4, 28)));
const resolveMax = args.max ?? (() => new Date(Date.UTC(2030, 4, 28)));
return z
.preprocess(
date,
z
.date({ message: "forms:errors.required" })
.min(
minDate,
args.minMessage ? { message: `forms:${args.minMessage}` } : undefined,
)
.max(
maxDate,
args.maxMessage ? { message: `forms:${args.maxMessage}` } : undefined,
),
.refine((d) => d >= resolveMin(), {
message: `forms:${args.minMessage ?? "errors.dateTooEarly"}`,
})
.refine((d) => d <= resolveMax(), {
message: `forms:${args.maxMessage ?? "errors.dateTooLate"}`,
}),
)
.register(formRegistry, {
...args,
@ -417,22 +415,20 @@ export function datetimeRequired(args: DateTimeArgs) {
}
export function datetimeOptional(args: DateTimeArgs) {
const minDate = args.min ?? new Date(Date.UTC(2015, 4, 28));
const maxDate = args.max ?? new Date(Date.UTC(2030, 4, 28));
const resolveMin = args.min ?? (() => new Date(Date.UTC(2015, 4, 28)));
const resolveMax = args.max ?? (() => new Date(Date.UTC(2030, 4, 28)));
return z
.preprocess(
date,
z
.date()
.min(
minDate,
args.minMessage ? { message: `forms:${args.minMessage}` } : undefined,
)
.max(
maxDate,
args.maxMessage ? { message: `forms:${args.maxMessage}` } : undefined,
)
.refine((d) => d >= resolveMin(), {
message: `forms:${args.minMessage ?? "errors.dateTooEarly"}`,
})
.refine((d) => d <= resolveMax(), {
message: `forms:${args.maxMessage ?? "errors.dateTooLate"}`,
})
.nullish(),
)
.register(formRegistry, {
@ -446,22 +442,20 @@ export function datetimeOptional(args: DateTimeArgs) {
}
export function dayMonthYearRequired(args: DateTimeArgs) {
const minDate = args.min ?? new Date(Date.UTC(2015, 4, 28));
const maxDate = args.max ?? new Date(Date.UTC(2030, 4, 28));
const resolveMin = args.min ?? (() => new Date(Date.UTC(2015, 4, 28)));
const resolveMax = args.max ?? (() => new Date(Date.UTC(2030, 4, 28)));
return z
.preprocess(
date,
z
.date({ message: "forms:errors.required" })
.min(
minDate,
args.minMessage ? { message: `forms:${args.minMessage}` } : undefined,
)
.max(
maxDate,
args.maxMessage ? { message: `forms:${args.maxMessage}` } : undefined,
),
.refine((d) => d >= resolveMin(), {
message: `forms:${args.minMessage ?? "errors.dateTooEarly"}`,
})
.refine((d) => d <= resolveMax(), {
message: `forms:${args.maxMessage ?? "errors.dateTooLate"}`,
}),
)
.transform((d) => ({
day: d.getDate(),

View File

@ -87,8 +87,8 @@ export interface FormFieldInputGroup<T extends string, V extends string>
}
export interface FormFieldDatetime<T extends string> extends FormFieldBase<T> {
min?: Date;
max?: Date;
min?: () => Date;
max?: () => Date;
required: boolean;
}

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "Start time",
"bottomTexts.scrimRequestStartTime": "Select a time within the post's time range",
"errors.dateInPast": "Date can not be in the past",
"errors.dateTooEarly": "Date is too early",
"errors.dateTooLate": "Date is too late",
"errors.dateTooFarInFuture": "Date can not be more than 2 weeks in the future",
"errors.minUsersExcludingYourself": "Must have at least {{min}} users excluding yourself",
"errors.usersMustBeUnique": "Users must be unique",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -163,6 +163,7 @@
"dmgHtdExplanation": "נזק = פגיעה | פ'ל = פגיעות להרוס",
"noDmgData": "אין נתונים על נזק של הנשק הזה. בדקו מאוחר יותר!",
"perInkTankGrid.header_one": "יריות של {{weapon}} לאחר ×{{count}} שימוש בנשק משני",
"perInkTankGrid.header_two": "",
"perInkTankGrid.header_other": "יריות של {{weapon}} לאחר ×{{count}} שימוש בנשקים משניים",
"bigBubblerExplanation": "משך הזמן של {{weapon}} גדל גם ככל שהעמידות גדלה",
"button.showChart": "הצג תרשים",
@ -183,6 +184,7 @@
"comp.showWeaponGrid": "הצג בורר נשק",
"comp.hideWeaponGrid": "הסתר בורר נשק",
"comp.hits_one": "{{count}} פגיעה",
"comp.hits_two": "",
"comp.hits_other": "{{count}} פגיעות",
"comp.enemyRes": "Ink Resistance Up של היריב",
"comp.enemySubDef": "Sub Defense Up של היריב",

View File

@ -1,5 +1,6 @@
{
"pendingApproval_one": "יש לכם תמונה {{count}} שממתינה לאישור מנחה",
"pendingApproval_two": "",
"pendingApproval_other": "יש לכם {{count}} תמונות שממתינות לאישור מנחה",
"madeBy": "מאת",
"radios.all": "הכל",

View File

@ -3,6 +3,7 @@
"patreon+": "תומך+ של sendou.ink ב-Patreon",
"xp": "מוענק עבור הגעה ל-{{xpText}}",
"tournament_one": "מוענק עבור ניצחון {{tournament}}",
"tournament_two": "",
"tournament_other": "מוענק עבור ניצחון {{tournament}} (×{{count}})",
"forYourEvent": "תג לאירוע שלכם?",
"managedBy": "מנוהל על ידי <0></0>",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",

View File

@ -69,6 +69,8 @@
"labels.scrimRequestStartTime": "",
"bottomTexts.scrimRequestStartTime": "",
"errors.dateInPast": "",
"errors.dateTooEarly": "",
"errors.dateTooLate": "",
"errors.dateTooFarInFuture": "",
"errors.minUsersExcludingYourself": "",
"errors.usersMustBeUnique": "",