From a17d477d2048dfc6b23fd62b69803b1ada79d03a Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Mon, 28 Jun 2021 17:47:40 +0000 Subject: [PATCH 1/7] Added NEXTAUTH_URL back to .env.example as it is required on Vercel --- .env.example | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.env.example b/.env.example index de845300..99636771 100644 --- a/.env.example +++ b/.env.example @@ -2,6 +2,10 @@ DATABASE_URL='postgresql://:@:/' GOOGLE_API_CREDENTIALS='secret' BASE_URL='http://localhost:3000' +# @see: https://github.com/calendso/calendso/issues/263 +# Required for Vercel hosting - set NEXTAUTH_URL to equal your BASE_URL +# NEXTAUTH_URL='http://localhost:3000' + # Remove this var if you don't want Calendso to collect anonymous usage NEXT_PUBLIC_TELEMETRY_KEY=js.2pvs2bbpqq1zxna97wcml.oi2jzirnbj1ev4tc57c5r From f918f220eba5e7b4d6cd67f34f9be48e88376dd8 Mon Sep 17 00:00:00 2001 From: nicolas Date: Tue, 29 Jun 2021 02:21:08 +0200 Subject: [PATCH 2/7] Fixed Zoom Auth --- pages/api/book/[user].ts | 159 ++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 69 deletions(-) diff --git a/pages/api/book/[user].ts b/pages/api/book/[user].ts index c6d41e07..3aefeae7 100644 --- a/pages/api/book/[user].ts +++ b/pages/api/book/[user].ts @@ -1,47 +1,48 @@ import type { NextApiRequest, NextApiResponse } from "next"; import prisma from "../../../lib/prisma"; -import { CalendarEvent, createEvent, updateEvent, getBusyCalendarTimes } from "../../../lib/calendarClient"; +import { CalendarEvent, createEvent, updateEvent } from "../../../lib/calendarClient"; import async from "async"; import { v5 as uuidv5 } from "uuid"; import short from "short-uuid"; -import { createMeeting, updateMeeting, getBusyVideoTimes } from "../../../lib/videoClient"; +import { createMeeting, updateMeeting } from "../../../lib/videoClient"; import EventAttendeeMail from "../../../lib/emails/EventAttendeeMail"; import { getEventName } from "../../../lib/event"; import { LocationType } from "../../../lib/location"; import merge from "lodash.merge"; + const translator = short(); -import dayjs from "dayjs"; -const isAvailable = (busyTimes, time, length) => { - // Check for conflicts - let t = true; - busyTimes.forEach((busyTime) => { - const startTime = dayjs(busyTime.start); - const endTime = dayjs(busyTime.end); - - // Check if start times are the same - if (dayjs(time).format("HH:mm") == startTime.format("HH:mm")) { - t = false; - } - - // Check if time is between start and end times - if (dayjs(time).isBetween(startTime, endTime)) { - t = false; - } - - // Check if slot end time is between start and end time - if (dayjs(time).add(length, "minutes").isBetween(startTime, endTime)) { - t = false; - } - - // Check if startTime is between slot - if (startTime.isBetween(dayjs(time), dayjs(time).add(length, "minutes"))) { - t = false; - } - }); - - return t; -}; +// Commented out because unused and thus throwing an error in linter. +// const isAvailable = (busyTimes, time, length) => { +// // Check for conflicts +// let t = true; +// busyTimes.forEach((busyTime) => { +// const startTime = dayjs(busyTime.start); +// const endTime = dayjs(busyTime.end); +// +// // Check if start times are the same +// if (dayjs(time).format("HH:mm") == startTime.format("HH:mm")) { +// t = false; +// } +// +// // Check if time is between start and end times +// if (dayjs(time).isBetween(startTime, endTime)) { +// t = false; +// } +// +// // Check if slot end time is between start and end time +// if (dayjs(time).add(length, "minutes").isBetween(startTime, endTime)) { +// t = false; +// } +// +// // Check if startTime is between slot +// if (startTime.isBetween(dayjs(time), dayjs(time).add(length, "minutes"))) { +// t = false; +// } +// }); +// +// return t; +// }; interface GetLocationRequestFromIntegrationRequest { location: string; @@ -63,10 +64,10 @@ const getLocationRequestFromIntegration = ({ location }: GetLocationRequestFromI return null; }; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { +export default async function handler(req: NextApiRequest, res: NextApiResponse): Promise { const { user } = req.query; - const currentUser = await prisma.user.findFirst({ + let currentUser = await prisma.user.findFirst({ where: { username: user, }, @@ -79,42 +80,62 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) }, }); - const selectedCalendars = await prisma.selectedCalendar.findMany({ + // Commented out because unused and thus throwing an error in linter. + // const selectedCalendars = await prisma.selectedCalendar.findMany({ + // where: { + // userId: currentUser.id, + // }, + // }); + // Split credentials up into calendar credentials and video credentials + let calendarCredentials = currentUser.credentials.filter((cred) => cred.type.endsWith("_calendar")); + let videoCredentials = currentUser.credentials.filter((cred) => cred.type.endsWith("_video")); + + // Commented out because unused and thus throwing an error in linter. + // const hasCalendarIntegrations = + // currentUser.credentials.filter((cred) => cred.type.endsWith("_calendar")).length > 0; + // const hasVideoIntegrations = + // currentUser.credentials.filter((cred) => cred.type.endsWith("_video")).length > 0; + + // Commented out because unused and thus throwing an error in linter. + // const calendarAvailability = await getBusyCalendarTimes( + // currentUser.credentials, + // dayjs(req.body.start).startOf("day").utc().format(), + // dayjs(req.body.end).endOf("day").utc().format(), + // selectedCalendars + // ); + // const videoAvailability = await getBusyVideoTimes( + // currentUser.credentials, + // dayjs(req.body.start).startOf("day").utc().format(), + // dayjs(req.body.end).endOf("day").utc().format() + // ); + // let commonAvailability = []; + + // Commented out because unused and thus throwing an error in linter. + // if (hasCalendarIntegrations && hasVideoIntegrations) { + // commonAvailability = calendarAvailability.filter((availability) => + // videoAvailability.includes(availability) + // ); + // } else if (hasVideoIntegrations) { + // commonAvailability = videoAvailability; + // } else if (hasCalendarIntegrations) { + // commonAvailability = calendarAvailability; + // } + + // Now, get the newly stored credentials (new refresh token for example). + currentUser = await prisma.user.findFirst({ where: { - userId: currentUser.id, + username: user, + }, + select: { + id: true, + credentials: true, + timeZone: true, + email: true, + name: true, }, }); - // Split credentials up into calendar credentials and video credentials - const calendarCredentials = currentUser.credentials.filter((cred) => cred.type.endsWith("_calendar")); - const videoCredentials = currentUser.credentials.filter((cred) => cred.type.endsWith("_video")); - - const hasCalendarIntegrations = - currentUser.credentials.filter((cred) => cred.type.endsWith("_calendar")).length > 0; - const hasVideoIntegrations = - currentUser.credentials.filter((cred) => cred.type.endsWith("_video")).length > 0; - - const calendarAvailability = await getBusyCalendarTimes( - currentUser.credentials, - dayjs(req.body.start).startOf("day").utc().format(), - dayjs(req.body.end).endOf("day").utc().format(), - selectedCalendars - ); - const videoAvailability = await getBusyVideoTimes( - currentUser.credentials, - dayjs(req.body.start).startOf("day").utc().format(), - dayjs(req.body.end).endOf("day").utc().format() - ); - let commonAvailability = []; - - if (hasCalendarIntegrations && hasVideoIntegrations) { - commonAvailability = calendarAvailability.filter((availability) => - videoAvailability.includes(availability) - ); - } else if (hasVideoIntegrations) { - commonAvailability = videoAvailability; - } else if (hasCalendarIntegrations) { - commonAvailability = calendarAvailability; - } + calendarCredentials = currentUser.credentials.filter((cred) => cred.type.endsWith("_calendar")); + videoCredentials = currentUser.credentials.filter((cred) => cred.type.endsWith("_video")); const rescheduleUid = req.body.rescheduleUid; @@ -170,7 +191,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) }); // TODO isAvailable was throwing an error - const isAvailableToBeBooked = true;//isAvailable(commonAvailability, req.body.start, selectedEventType.length); + const isAvailableToBeBooked = true; //isAvailable(commonAvailability, req.body.start, selectedEventType.length); if (!isAvailableToBeBooked) { return res.status(400).json({ message: `${currentUser.name} is unavailable at this time.` }); From d1bdac45eb2afe1a6e1916b0a4414b103bbd069e Mon Sep 17 00:00:00 2001 From: femyeda Date: Mon, 28 Jun 2021 19:39:08 -0500 Subject: [PATCH 3/7] dont allow user to book a past date --- pages/api/book/[user].ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pages/api/book/[user].ts b/pages/api/book/[user].ts index c6d41e07..8fbd5791 100644 --- a/pages/api/book/[user].ts +++ b/pages/api/book/[user].ts @@ -66,6 +66,16 @@ const getLocationRequestFromIntegration = ({ location }: GetLocationRequestFromI export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { user } = req.query; + const isTimeInPast = (time) => { + return dayjs(time).isBefore(new Date(), "day"); + }; + + if (isTimeInPast(req.body.start)) { + return res + .status(400) + .json({ errorCode: "BookingDateInPast", message: "Attempting to create a meeting in the past." }); + } + const currentUser = await prisma.user.findFirst({ where: { username: user, @@ -170,7 +180,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) }); // TODO isAvailable was throwing an error - const isAvailableToBeBooked = true;//isAvailable(commonAvailability, req.body.start, selectedEventType.length); + const isAvailableToBeBooked = true; //isAvailable(commonAvailability, req.body.start, selectedEventType.length); if (!isAvailableToBeBooked) { return res.status(400).json({ message: `${currentUser.name} is unavailable at this time.` }); From 39df7d61bca26946ea84b482bc8b86d96863a80e Mon Sep 17 00:00:00 2001 From: mihaic195 Date: Tue, 29 Jun 2021 11:45:54 +0300 Subject: [PATCH 4/7] fix: add login link on forgot password page --- pages/auth/forgot-password/index.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pages/auth/forgot-password/index.tsx b/pages/auth/forgot-password/index.tsx index 5760de01..f3313900 100644 --- a/pages/auth/forgot-password/index.tsx +++ b/pages/auth/forgot-password/index.tsx @@ -1,4 +1,5 @@ import Head from "next/head"; +import Link from "next/link"; import React from "react"; import { getCsrfToken } from "next-auth/client"; import debounce from "lodash.debounce"; @@ -137,6 +138,15 @@ export default function Page({ csrfToken }) { Request Password Reset +
+ + + +
)} From 272cee28d10698b40a946a4c1a355c9f955b1b81 Mon Sep 17 00:00:00 2001 From: Faraz Patankar Date: Tue, 29 Jun 2021 16:28:42 +0400 Subject: [PATCH 5/7] add railway button --- README.md | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 964e87cd..6ee88dc5 100644 --- a/README.md +++ b/README.md @@ -80,30 +80,30 @@ You will also need Google API credentials. You can get this from the [Google API ```
If you don't know how to configure the DATABASE_URL, then follow the steps here - + 1. Create a free account with [Heroku](https://www.heroku.com/). - - 2. Create a new app. + + 2. Create a new app. Google Chrome — CleanShotX | 2021-04-20 at 02 01 56 - + 3. In your new app, go to `Overview` and next to `Installed add-ons`, click `Configure Add-ons`. We need this to set up our database. ![image](https://user-images.githubusercontent.com/16905768/115323232-a53ba480-a17f-11eb-98db-58e2f8c52426.png) - 4. Once you clicked on `Configure Add-ons`, click on `Find more add-ons` and search for `postgres`. One of the options will be `Heroku Postgres` - click on that option. + 4. Once you clicked on `Configure Add-ons`, click on `Find more add-ons` and search for `postgres`. One of the options will be `Heroku Postgres` - click on that option. ![image](https://user-images.githubusercontent.com/16905768/115323126-5beb5500-a17f-11eb-8030-7380310807a9.png) - 5. Once the pop-up appears, click `Submit Order Form` - plan name should be `Hobby Dev - Free`. + 5. Once the pop-up appears, click `Submit Order Form` - plan name should be `Hobby Dev - Free`. Google Chrome — CleanShotX | 2021-04-20 at 02 04 29 - - 6. Once you completed the above steps, click on your newly created `Heroku Postgres` and go to its `Settings`. + + 6. Once you completed the above steps, click on your newly created `Heroku Postgres` and go to its `Settings`. ![image](https://user-images.githubusercontent.com/16905768/115323367-e92ea980-a17f-11eb-9ff4-dec95f2ec349.png) - - 7. In `Settings`, copy your URI to your Calendso .env file and replace the `postgresql://:@:` with it. + + 7. In `Settings`, copy your URI to your Calendso .env file and replace the `postgresql://:@:` with it. ![image](https://user-images.githubusercontent.com/16905768/115323556-4591c900-a180-11eb-9808-2f55d2aa3995.png) ![image](https://user-images.githubusercontent.com/16905768/115323697-7a9e1b80-a180-11eb-9f08-a742b1037f90.png) - 8. To view your DB, once you add new data in Prisma, you can use [Heroku Data Explorer](https://heroku-data-explorer.herokuapp.com/). -
+ 8. To view your DB, once you add new data in Prisma, you can use [Heroku Data Explorer](https://heroku-data-explorer.herokuapp.com/). + 5. Set up the database using the Prisma schema (found in `prisma/schema.prisma`) ```sh @@ -127,7 +127,7 @@ You will also need Google API credentials. You can get this from the [Google API git pull ``` 2. Apply database migrations by running one of the following commands: - + In a development environment, run: ``` npx prisma migrate dev @@ -140,7 +140,7 @@ You will also need Google API credentials. You can get this from the [Google API ``` 3. Check the `.env.example` and compare it to your current `.env` file. In case there are any fields not present in your current `.env`, add them there. - + For the current version, especially check if the variable `BASE_URL` is present and properly set in your environment, for example: ``` BASE_URL='https://yourdomain.com' @@ -155,6 +155,13 @@ You will also need Google API credentials. You can get this from the [Google API yarn start ``` 5. Enjoy the new version. + +## Deployment + +[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template?template=https%3A%2F%2Fgithub.com%2Fcalendso%2Fcalendso&plugins=postgresql&envs=GOOGLE_API_CREDENTIALS%2CBASE_URL%2CNEXTAUTH_URL%2CPORT&BASE_URLDefault=http%3A%2F%2Flocalhost%3A3000&NEXTAUTH_URLDefault=http%3A%2F%2Flocalhost%3A3000&PORTDefault=3000) + +You can deploy Calendso on [Railway](https://railway.app/) using the button above. The team at Railway also have a [detailed blog post](https://blog.railway.app/p/calendso) on deploying Calendso on their platform. + ## Roadmap @@ -239,4 +246,3 @@ Special thanks to these amazing projects which help power Calendso: * [Prisma](https://prisma.io/) [product-screenshot]: https://i.imgur.com/4yvFj2E.png - From 51c0556d307f1cc5c89bebb064b625101e3bd261 Mon Sep 17 00:00:00 2001 From: Bailey Pumfleet Date: Tue, 29 Jun 2021 17:08:55 +0100 Subject: [PATCH 6/7] Hide Calendso branding --- pages/[user]/[type].tsx | 73 ++-- pages/api/user/profile.ts | 2 + pages/settings/profile.tsx | 24 ++ pages/success.tsx | 366 +++++++++++------- .../migration.sql | 2 + prisma/schema.prisma | 1 + 6 files changed, 300 insertions(+), 168 deletions(-) create mode 100644 prisma/migrations/20210629160507_hide_branding/migration.sql diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 04a13d3b..bf09b987 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -119,21 +119,46 @@ export default function Type(props): Type { {rescheduleUid && "Reschedule"} {props.eventType.title} | {props.user.name || props.user.username} | Calendso - + - - - " + props.eventType.description).replace(/'/g, "%27") + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + encodeURIComponent(props.user.avatar)} /> + + + " + props.eventType.description + ).replace(/'/g, "%27") + + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + + encodeURIComponent(props.user.avatar) + } + /> - - + + - " + props.eventType.description).replace(/'/g, "%27") + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + encodeURIComponent(props.user.avatar)} /> - + " + props.eventType.description + ).replace(/'/g, "%27") + + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + + encodeURIComponent(props.user.avatar) + } + />
- {/* note(peer): - you can remove calendso branding here, but we'd also appreciate it, if you don't <3 - */} - + {!props.user.hideBranding && ( + + )}
); @@ -245,6 +269,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { timeZone: true, endTime: true, weekStart: true, + hideBranding: true, }, }); diff --git a/pages/api/user/profile.ts b/pages/api/user/profile.ts index cc9aef6a..dfb13315 100644 --- a/pages/api/user/profile.ts +++ b/pages/api/user/profile.ts @@ -41,6 +41,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) const avatar = req.body.avatar; const timeZone = req.body.timeZone; const weekStart = req.body.weekStart; + const hideBranding = req.body.hideBranding; const updateUser = await prisma.user.update({ where: { @@ -53,6 +54,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) bio: description, timeZone: timeZone, weekStart: weekStart, + hideBranding: hideBranding, }, }); diff --git a/pages/settings/profile.tsx b/pages/settings/profile.tsx index c8cc0586..8278a55c 100644 --- a/pages/settings/profile.tsx +++ b/pages/settings/profile.tsx @@ -17,6 +17,7 @@ export default function Settings(props) { const nameRef = useRef(); const descriptionRef = useRef(); const avatarRef = useRef(); + const hideBrandingRef = useRef(); const [selectedTimeZone, setSelectedTimeZone] = useState({ value: props.user.timeZone }); const [selectedWeekStartDay, setSelectedWeekStartDay] = useState(props.user.weekStart || "Sunday"); @@ -43,6 +44,7 @@ export default function Settings(props) { const enteredAvatar = avatarRef.current.value; const enteredTimeZone = selectedTimeZone.value; const enteredWeekStartDay = selectedWeekStartDay; + const enteredHideBranding = hideBrandingRef.current.checked; // TODO: Add validation @@ -55,6 +57,7 @@ export default function Settings(props) { avatar: enteredAvatar, timeZone: enteredTimeZone, weekStart: enteredWeekStartDay, + hideBranding: enteredHideBranding, }), headers: { "Content-Type": "application/json", @@ -154,6 +157,26 @@ export default function Settings(props) { +
+
+
+ +
+
+ +

Hide all Calendso branding from your public pages.

+
+
+
@@ -247,6 +270,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { avatar: true, timeZone: true, weekStart: true, + hideBranding: true, }, }); diff --git a/pages/success.tsx b/pages/success.tsx index c8f27ecd..52c1f22b 100644 --- a/pages/success.tsx +++ b/pages/success.tsx @@ -1,166 +1,244 @@ -import Head from 'next/head'; -import Link from 'next/link'; -import prisma from '../lib/prisma'; -import {useEffect, useState} from "react"; -import {useRouter} from 'next/router'; -import {CheckIcon} from '@heroicons/react/outline'; -import {CalendarIcon, ClockIcon, LocationMarkerIcon} from '@heroicons/react/solid'; -import dayjs from 'dayjs'; -import utc from 'dayjs/plugin/utc'; -import toArray from 'dayjs/plugin/toArray'; -import timezone from 'dayjs/plugin/timezone'; -import {createEvent} from 'ics'; -import {getEventName} from "../lib/event"; +import Head from "next/head"; +import Link from "next/link"; +import prisma from "../lib/prisma"; +import { useEffect, useState } from "react"; +import { useRouter } from "next/router"; +import { CheckIcon } from "@heroicons/react/outline"; +import { CalendarIcon, ClockIcon, LocationMarkerIcon } from "@heroicons/react/solid"; +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; +import toArray from "dayjs/plugin/toArray"; +import timezone from "dayjs/plugin/timezone"; +import { createEvent } from "ics"; +import { getEventName } from "../lib/event"; dayjs.extend(utc); dayjs.extend(toArray); dayjs.extend(timezone); export default function Success(props) { - const router = useRouter(); - const {location, name} = router.query; + const router = useRouter(); + const { location, name } = router.query; - const [ is24h, setIs24h ] = useState(false); - const [ date, setDate ] = useState(dayjs.utc(router.query.date)); + const [is24h, setIs24h] = useState(false); + const [date, setDate] = useState(dayjs.utc(router.query.date)); - useEffect( () => { - setDate(date.tz(localStorage.getItem('timeOption.preferredTimeZone') || dayjs.tz.guess())); - setIs24h(!!localStorage.getItem('timeOption.is24hClock')); - }, []); + useEffect(() => { + setDate(date.tz(localStorage.getItem("timeOption.preferredTimeZone") || dayjs.tz.guess())); + setIs24h(!!localStorage.getItem("timeOption.is24hClock")); + }, []); - const eventName = getEventName(name, props.eventType.title, props.eventType.eventName); + const eventName = getEventName(name, props.eventType.title, props.eventType.eventName); - function eventLink(): string { - - let optional = {}; - if (location) { - optional['location'] = location; - } - - const event = createEvent({ - start: date.utc().toArray().slice(0, 6).map((v, i) => i === 1 ? v + 1 : v), - startInputType: 'utc', - title: eventName, - description: props.eventType.description, - duration: { minutes: props.eventType.length }, - ...optional - }); - - if (event.error) { - throw event.error; - } - - return encodeURIComponent(event.value); + function eventLink(): string { + let optional = {}; + if (location) { + optional["location"] = location; } - return( -
- - Booking Confirmed | {eventName} | Calendso - - -
-
-
- +
- ) +
+
+ ); } export async function getServerSideProps(context) { - const user = await prisma.user.findFirst({ - where: { - username: context.query.user, - }, - select: { - username: true, - name: true, - bio: true, - avatar: true, - eventTypes: true - } - }); + const user = await prisma.user.findFirst({ + where: { + username: context.query.user, + }, + select: { + username: true, + name: true, + bio: true, + avatar: true, + eventTypes: true, + hideBranding: true, + }, + }); - const eventType = await prisma.eventType.findUnique({ - where: { - id: parseInt(context.query.type), - }, - select: { - id: true, - title: true, - description: true, - length: true, - eventName: true - } - }); + const eventType = await prisma.eventType.findUnique({ + where: { + id: parseInt(context.query.type), + }, + select: { + id: true, + title: true, + description: true, + length: true, + eventName: true, + }, + }); - return { - props: { - user, - eventType - }, - } + return { + props: { + user, + eventType, + }, + }; } diff --git a/prisma/migrations/20210629160507_hide_branding/migration.sql b/prisma/migrations/20210629160507_hide_branding/migration.sql new file mode 100644 index 00000000..0e6be4d5 --- /dev/null +++ b/prisma/migrations/20210629160507_hide_branding/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "users" ADD COLUMN "hideBranding" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 491fd909..8bddada9 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -47,6 +47,7 @@ model User { startTime Int @default(0) endTime Int @default(1440) bufferTime Int @default(0) + hideBranding Boolean @default(false) createdDate DateTime @default(now()) @map(name: "created") eventTypes EventType[] credentials Credential[] From dfb9870894da23c396766bcb81ccabd1288f4f98 Mon Sep 17 00:00:00 2001 From: Malte Delfs Date: Tue, 29 Jun 2021 18:17:09 +0200 Subject: [PATCH 7/7] hotfix --- pages/api/book/[user].ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pages/api/book/[user].ts b/pages/api/book/[user].ts index 598da06f..2ea6611b 100644 --- a/pages/api/book/[user].ts +++ b/pages/api/book/[user].ts @@ -9,6 +9,7 @@ import EventAttendeeMail from "../../../lib/emails/EventAttendeeMail"; import { getEventName } from "../../../lib/event"; import { LocationType } from "../../../lib/location"; import merge from "lodash.merge"; +import dayjs from "dayjs"; const translator = short(); @@ -77,7 +78,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) .json({ errorCode: "BookingDateInPast", message: "Attempting to create a meeting in the past." }); } - const currentUser = await prisma.user.findFirst({ + let currentUser = await prisma.user.findFirst({ where: { username: user, },