sec-001 fixes (#2866) (#2867)

* sec-001 fixes (#2866)

* sec-001 fixes

* Typo

* Fixes paid bookings

# Conflicts:
#	apps/web/ee/components/stripe/Payment.tsx
This commit is contained in:
Omar López 2022-05-24 19:29:29 -06:00 committed by GitHub
parent a48a164e71
commit 7548233a96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 25 deletions

View File

@ -129,6 +129,7 @@ const BookingPage = ({
paymentUid,
date,
name: attendees[0].name,
email: attendees[0].email,
absolute: false,
})
);

View File

@ -47,7 +47,7 @@ type States =
export default function PaymentComponent(props: Props) {
const { t, i18n } = useLocale();
const router = useRouter();
const { name, date } = router.query;
const { email, name, date } = router.query;
const [state, setState] = useState<States>({ status: "idle" });
const stripe = useStripe();
const elements = useElements();
@ -86,6 +86,7 @@ export default function PaymentComponent(props: Props) {
date,
type: props.eventType.id,
user: props.user.username,
email,
name,
bookingId: props.bookingId,
};

View File

@ -80,6 +80,7 @@ export async function handlePayment(
link: createPaymentLink({
paymentUid: payment.uid,
name: booking.user?.name,
email: booking.user?.email,
date: booking.startTime.toISOString(),
}),
},

View File

@ -15,7 +15,7 @@ export default function Custom404() {
const { t } = useLocale();
const router = useRouter();
const username = router.asPath.replace("%20", "-").split(/[?#]/)[0];
const [username] = router.asPath.replace("%20", "-").split(/[?#]/);
const links = [
{
@ -35,10 +35,11 @@ export default function Custom404() {
const [url, setUrl] = useState("https://cal.com/signup?username=");
useEffect(() => {
setUrl(`https://cal.com/signup?username=${username.replace("/", "")}`);
}, [username, router.query]);
}, [username]);
const isSubpage = router.asPath.includes("/", 2);
const isSignup = router.asPath.includes("/signup");
const isSuccessPage = router.asPath.startsWith("/success");
const isSubpage = router.asPath.includes("/", 2) || isSuccessPage;
const isSignup = router.asPath.startsWith("/signup");
const isCalcom = process.env.NEXT_PUBLIC_WEBAPP_URL === "https://app.cal.com";
return (
@ -177,7 +178,7 @@ export default function Custom404() {
<div className="text-center">
<p className="text-sm font-semibold uppercase tracking-wide text-black">{t("error_404")}</p>
<h1 className="font-cal mt-2 text-4xl font-extrabold text-gray-900 sm:text-5xl">
{t("page_doesnt_exist")}
{isSuccessPage ? "Booking not found" : t("page_doesnt_exist")}
</h1>
{isSubpage ? (
<span className="mt-2 inline-block text-lg ">

View File

@ -14,6 +14,7 @@ import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect, useRef, useState } from "react";
import RRule from "rrule";
import { z } from "zod";
import { SpaceBookingSuccessPage } from "@calcom/app-store/spacebooking/components";
import {
@ -29,7 +30,7 @@ import { RecurringEvent } from "@calcom/types/Calendar";
import Button from "@calcom/ui/Button";
import { EmailInput } from "@calcom/ui/form/fields";
import { asStringOrNull, asStringOrThrow } from "@lib/asStringOrNull";
import { asStringOrThrow } from "@lib/asStringOrNull";
import { getEventName } from "@lib/event";
import useTheme from "@lib/hooks/useTheme";
import { isBrandingHidden } from "@lib/isBrandingHidden";
@ -647,10 +648,10 @@ function RecurringBookings({
) : null;
}
const getEventTypesFromDB = async (typeId: number) => {
const getEventTypesFromDB = async (id: number) => {
return await prisma.eventType.findUnique({
where: {
id: typeId,
id,
},
select: {
id: true,
@ -688,22 +689,42 @@ const getEventTypesFromDB = async (typeId: number) => {
});
};
const strToNumber = z.string().transform((val, ctx) => {
const parsed = parseInt(val);
if (isNaN(parsed)) ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Not a number" });
return parsed;
});
const schema = z.object({
type: strToNumber,
date: z.string().optional(),
user: z.string().optional(),
reschedule: z.string().optional(),
name: z.string().optional(),
email: z.string().optional(),
recur: z.string().optional(),
location: z.string().optional(),
eventSlug: z.string().default("15min"),
eventName: z.string().default(""),
bookingId: strToNumber,
});
export async function getServerSideProps(context: GetServerSidePropsContext) {
const ssr = await ssrInit(context);
const typeId = parseInt(asStringOrNull(context.query.type) ?? "");
const recurringEventIdQuery = asStringOrNull(context.query.recur);
const typeSlug = asStringOrNull(context.query.eventSlug) ?? "15min";
const dynamicEventName = asStringOrNull(context.query.eventName) ?? "";
if (typeof context.query.bookingId !== "string") return { notFound: true } as const;
const bookingId = parseInt(context.query.bookingId);
const parsedQuery = schema.safeParse(context.query);
if (!parsedQuery.success) return { notFound: true };
const {
type: eventTypeId,
recur: recurringEventIdQuery,
eventSlug: eventTypeSlug,
eventName: dynamicEventName,
bookingId,
user: username,
name,
email,
} = parsedQuery.data;
if (isNaN(typeId)) {
return {
notFound: true,
};
}
const eventTypeRaw = !typeId ? getDefaultEvent(typeSlug) : await getEventTypesFromDB(typeId);
const eventTypeRaw = !eventTypeId ? getDefaultEvent(eventTypeSlug) : await getEventTypesFromDB(eventTypeId);
if (!eventTypeRaw) {
return {
@ -768,9 +789,12 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
slug: eventType.team?.slug || eventType.users[0]?.username || null,
};
const bookingInfo = await prisma.booking.findUnique({
const bookingInfo = await prisma.booking.findFirst({
where: {
id: bookingId,
eventTypeId: eventType.id,
user: { username },
attendees: { some: { email, name } },
},
select: {
title: true,

View File

@ -25,12 +25,13 @@ export function createPaymentLink(opts: {
paymentUid: string;
name?: Maybe<string>;
date?: Maybe<string>;
email?: Maybe<string>;
absolute?: boolean;
}): string {
const { paymentUid, name, date, absolute = true } = opts;
const { paymentUid, name, email, date, absolute = true } = opts;
let link = "";
if (absolute) link = process.env.NEXT_PUBLIC_WEBSITE_URL!;
const query = stringify({ date, name });
const query = stringify({ date, name, email });
return link + `/payment/${paymentUid}?${query}`;
}