Make sure returnTo is correct URL (#6189)
* make sure returno is safe * More fixes
This commit is contained in:
@@ -18,7 +18,7 @@ function Teams() {
|
||||
size="fab"
|
||||
StartIcon={Icon.FiPlus}
|
||||
type="button"
|
||||
href={`${WEBAPP_URL}/settings/teams/new?returnTo=/teams`}>
|
||||
href={`${WEBAPP_URL}/settings/teams/new?returnTo=${WEBAPP_URL}/teams`}>
|
||||
{t("new")}
|
||||
</Button>
|
||||
}>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useRouter } from "next/router";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
@@ -19,7 +20,9 @@ export const CreateANewTeamForm = () => {
|
||||
|
||||
const returnToParsed = querySchema.safeParse(router.query);
|
||||
|
||||
const returnToParam = returnToParsed.success ? returnToParsed.data.returnTo : "/settings/teams";
|
||||
const returnToParam =
|
||||
(returnToParsed.success ? getSafeRedirectUrl(returnToParsed.data.returnTo) : "/settings/teams") ||
|
||||
"/settings/teams";
|
||||
|
||||
const newTeamFormMethods = useForm<NewTeamFormValues>();
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ export const getSafeRedirectUrl = (url = "") => {
|
||||
if (!url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//It is important that this fn is given absolute URL because urls that don't start with HTTP can still deceive browser into redirecting to another domain
|
||||
if (url.search(/^https?:\/\//) === -1) {
|
||||
throw new Error("Pass an absolute URL");
|
||||
}
|
||||
|
||||
@@ -397,8 +397,23 @@ const loggedInViewerRouter = router({
|
||||
|
||||
let where;
|
||||
|
||||
if (eventTypeId) where = { eventTypeId };
|
||||
else where = { userId: user.id };
|
||||
if (eventTypeId) {
|
||||
if (
|
||||
!(await prisma.eventType.findFirst({
|
||||
where: {
|
||||
id: eventTypeId,
|
||||
userId: user.id,
|
||||
},
|
||||
}))
|
||||
) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: `You don't have access to event type ${eventTypeId}`,
|
||||
});
|
||||
}
|
||||
|
||||
where = { eventTypeId };
|
||||
} else where = { userId: user.id };
|
||||
|
||||
await ctx.prisma.destinationCalendar.upsert({
|
||||
where,
|
||||
@@ -726,42 +741,7 @@ const loggedInViewerRouter = router({
|
||||
})
|
||||
);
|
||||
}),
|
||||
eventTypePosition: authedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
eventType: z.number(),
|
||||
action: z.string(),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
// This mutation is for the user to be able to order their event types by incrementing or decrementing the position number
|
||||
const { prisma } = ctx;
|
||||
if (input.eventType && input.action == "increment") {
|
||||
await prisma.eventType.update({
|
||||
where: {
|
||||
id: input.eventType,
|
||||
},
|
||||
data: {
|
||||
position: {
|
||||
increment: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (input.eventType && input.action == "decrement") {
|
||||
await prisma.eventType.update({
|
||||
where: {
|
||||
id: input.eventType,
|
||||
},
|
||||
data: {
|
||||
position: {
|
||||
decrement: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}),
|
||||
//Comment for PR: eventTypePosition is not used anywhere
|
||||
submitFeedback: authedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
|
||||
@@ -173,7 +173,6 @@ export const availabilityRouter = router({
|
||||
.input(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
copyScheduleId: z.number().optional(),
|
||||
schedule: z
|
||||
.array(
|
||||
z.array(
|
||||
@@ -189,6 +188,22 @@ export const availabilityRouter = router({
|
||||
)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { user, prisma } = ctx;
|
||||
if (input.eventTypeId) {
|
||||
const eventType = await prisma.eventType.findUnique({
|
||||
where: {
|
||||
id: input.eventTypeId,
|
||||
},
|
||||
select: {
|
||||
userId: true,
|
||||
},
|
||||
});
|
||||
if (!eventType || eventType.userId !== user.id) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to create a schedule for this event type",
|
||||
});
|
||||
}
|
||||
}
|
||||
const data: Prisma.ScheduleCreateInput = {
|
||||
name: input.name,
|
||||
user: {
|
||||
|
||||
@@ -818,6 +818,22 @@ export const bookingsRouter = router({
|
||||
};
|
||||
|
||||
const recurringEvent = parseRecurringEvent(booking.eventType?.recurringEvent);
|
||||
if (recurringEventId) {
|
||||
if (
|
||||
!(await prisma.booking.findFirst({
|
||||
where: {
|
||||
recurringEventId,
|
||||
id: booking.id,
|
||||
},
|
||||
}))
|
||||
) {
|
||||
// FIXME: It might be best to retrieve recurringEventId from the booking itself.
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "Recurring event id doesn't belong to the booking",
|
||||
});
|
||||
}
|
||||
}
|
||||
if (recurringEventId && recurringEvent) {
|
||||
const groupedRecurringBookings = await prisma.booking.groupBy({
|
||||
where: {
|
||||
|
||||
Reference in New Issue
Block a user