summaryrefslogtreecommitdiff
path: root/src/util/validation.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/validation.ts')
-rw-r--r--src/util/validation.ts191
1 files changed, 191 insertions, 0 deletions
diff --git a/src/util/validation.ts b/src/util/validation.ts
new file mode 100644
index 0000000..f51769e
--- /dev/null
+++ b/src/util/validation.ts
@@ -0,0 +1,191 @@
+import moment from "moment-timezone";
+
+type Error = {
+ message?: string;
+ field?: string;
+};
+
+type ValidationResponse = {
+ data?: ValidatedEventData;
+ errors?: Error[];
+};
+
+interface EventData {
+ eventName: string;
+ eventLocation: string;
+ eventStart: string;
+ eventEnd: string;
+ timezone: string;
+ eventDescription: string;
+ eventURL: string;
+ imagePath: string;
+ hostName: string;
+ creatorEmail: string;
+ eventGroupCheckbox: string;
+ eventGroupID: string;
+ eventGroupEditToken: string;
+ interactionCheckbox: string;
+ joinCheckbox: string;
+ maxAttendeesCheckbox: string;
+ maxAttendees: number;
+}
+
+// EventData without the 'checkbox' fields
+export type ValidatedEventData = Omit<
+ EventData,
+ | "eventGroupCheckbox"
+ | "interactionCheckbox"
+ | "joinCheckbox"
+ | "maxAttendeesCheckbox"
+> & {
+ eventGroupBoolean: boolean;
+ interactionBoolean: boolean;
+ joinBoolean: boolean;
+ maxAttendeesBoolean: boolean;
+};
+
+const validateEmail = (email: string) => {
+ if (!email || email.length === 0 || typeof email !== "string") {
+ return false;
+ }
+ var re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ return re.test(email);
+};
+
+export const validateEventTime = (start: Date, end: Date): Error | boolean => {
+ if (moment(start).isAfter(moment(end))) {
+ return {
+ message: "Start time must be before end time.",
+ field: "eventStart",
+ };
+ }
+ if (moment(start).isBefore(moment())) {
+ return {
+ message: "Start time must be in the future.",
+ field: "eventStart",
+ };
+ }
+ if (moment(end).isBefore(moment())) {
+ return {
+ message: "End time must be in the future.",
+ field: "eventEnd",
+ };
+ }
+ // Duration cannot be longer than 1 year
+ if (moment(end).diff(moment(start), "years") > 1) {
+ return {
+ message: "Event duration cannot be longer than 1 year.",
+ field: "eventEnd",
+ };
+ }
+ return true;
+};
+
+export const validateEventData = (eventData: EventData): ValidationResponse => {
+ const validatedData: ValidatedEventData = {
+ eventName: eventData.eventName,
+ eventLocation: eventData.eventLocation,
+ eventStart: eventData.eventStart,
+ eventEnd: eventData.eventEnd,
+ timezone: eventData.timezone,
+ eventDescription: eventData.eventDescription,
+ eventURL: eventData.eventURL,
+ imagePath: eventData.imagePath,
+ hostName: eventData.hostName,
+ creatorEmail: eventData.creatorEmail,
+ eventGroupBoolean: eventData.eventGroupCheckbox === "true",
+ interactionBoolean: eventData.interactionCheckbox === "true",
+ joinBoolean: eventData.joinCheckbox === "true",
+ maxAttendeesBoolean: eventData.maxAttendeesCheckbox === "true",
+ eventGroupID: eventData.eventGroupID,
+ eventGroupEditToken: eventData.eventGroupEditToken,
+ maxAttendees: eventData.maxAttendees,
+ };
+ const errors: Error[] = [];
+ if (!validatedData.eventName) {
+ errors.push({
+ message: "Event name is required.",
+ field: "eventName",
+ });
+ }
+ if (!validatedData.eventLocation) {
+ errors.push({
+ message: "Event location is required.",
+ field: "eventLocation",
+ });
+ }
+ if (!validatedData.eventStart) {
+ errors.push({
+ message: "Event start time is required.",
+ field: "eventStart",
+ });
+ }
+ if (!validatedData.eventEnd) {
+ errors.push({
+ message: "Event end time is required.",
+ field: "eventEnd",
+ });
+ }
+ const timeValidation = validateEventTime(
+ new Date(validatedData.eventStart),
+ new Date(validatedData.eventEnd),
+ );
+ if (timeValidation !== true && timeValidation !== false) {
+ errors.push({
+ message: timeValidation.message,
+ });
+ }
+ if (!validatedData.timezone) {
+ errors.push({
+ message: "Event timezone is required.",
+ field: "timezone",
+ });
+ }
+ if (!validatedData.eventDescription) {
+ errors.push({
+ message: "Event description is required.",
+ field: "eventDescription",
+ });
+ }
+ if (validatedData.eventGroupBoolean) {
+ if (!validatedData.eventGroupID) {
+ errors.push({
+ message: "Event group ID is required.",
+ field: "eventGroupID",
+ });
+ }
+ if (!validatedData.eventGroupEditToken) {
+ errors.push({
+ message: "Event group edit token is required.",
+ field: "eventGroupEditToken",
+ });
+ }
+ }
+ if (validatedData.maxAttendeesBoolean) {
+ if (!validatedData.maxAttendees) {
+ errors.push({
+ message: "Max number of attendees is required.",
+ field: "maxAttendees",
+ });
+ }
+ if (isNaN(validatedData.maxAttendees)) {
+ errors.push({
+ message: "Max number of attendees must be a number.",
+ field: "maxAttendees",
+ });
+ }
+ }
+ if (validatedData.creatorEmail) {
+ if (!validateEmail(validatedData.creatorEmail)) {
+ errors.push({
+ message: "Email address is invalid.",
+ field: "creatorEmail",
+ });
+ }
+ }
+
+ return {
+ data: validatedData,
+ errors: errors,
+ };
+};