Implement URL validation on default videos links (#7087)
This commit is contained in:
@@ -196,6 +196,12 @@ export const EventSetupTab = (
|
||||
if (!eventLocationType) {
|
||||
return null;
|
||||
}
|
||||
// We dont want to translate the string link - it doesnt exist in common.json and it gets prefixed/suffixed with __ or //
|
||||
const eventLabel =
|
||||
eventLocationType.defaultValueVariable === "link"
|
||||
? location[eventLocationType.defaultValueVariable]
|
||||
: t(location[eventLocationType.defaultValueVariable] || eventLocationType.label);
|
||||
|
||||
return (
|
||||
<li
|
||||
key={`${location.type}${index}`}
|
||||
@@ -207,9 +213,7 @@ export const EventSetupTab = (
|
||||
className="h-4 w-4"
|
||||
alt={`${eventLocationType.label} logo`}
|
||||
/>
|
||||
<span className="truncate text-sm ltr:ml-1 rtl:mr-1">
|
||||
{t(location[eventLocationType.defaultValueVariable] || eventLocationType.label)}
|
||||
</span>
|
||||
<span className="truncate text-sm ltr:ml-1 rtl:mr-1">{eventLabel}</span>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<button
|
||||
|
||||
@@ -121,6 +121,9 @@ const IntegrationsList = ({ data, handleDisconnect, variant }: IntegrationsListP
|
||||
showToast("Default app updated successfully", "success");
|
||||
utils.viewer.getUsersDefaultConferencingApp.invalidate();
|
||||
},
|
||||
onError: (error) => {
|
||||
showToast(`Error: ${error.message}`, "error");
|
||||
},
|
||||
});
|
||||
|
||||
const { t } = useLocale();
|
||||
|
||||
@@ -66,6 +66,9 @@ const ConferencingLayout = () => {
|
||||
showToast("Default app updated successfully", "success");
|
||||
utils.viewer.getUsersDefaultConferencingApp.invalidate();
|
||||
},
|
||||
onError: (error) => {
|
||||
showToast(`Error: ${error.message}`, "error");
|
||||
},
|
||||
});
|
||||
|
||||
const [deleteAppModal, setDeleteAppModal] = useState(false);
|
||||
|
||||
@@ -15,7 +15,7 @@ export type DefaultEventLocationType = {
|
||||
category: string;
|
||||
|
||||
iconUrl: string;
|
||||
|
||||
urlRegExp?: string;
|
||||
// HACK: `variable` and `defaultValueVariable` are required due to legacy reason where different locations were stored in different places.
|
||||
variable: "locationType" | "locationAddress" | "address" | "locationLink" | "locationPhoneNumber" | "phone";
|
||||
defaultValueVariable: "address" | "attendeeAddress" | "link" | "hostPhoneNumber" | "phone";
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Dispatch, SetStateAction } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { EventLocationType } from "@calcom/app-store/locations";
|
||||
import { EventLocationType, getEventLocationType } from "@calcom/app-store/locations";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import {
|
||||
@@ -31,13 +33,22 @@ export function AppSetDefaultLinkDailog({
|
||||
const utils = trpc.useContext();
|
||||
|
||||
const { t } = useLocale();
|
||||
const form = useForm<LocationTypeSetLinkDialogFormProps>({});
|
||||
const eventLocationTypeOptions = getEventLocationType(locationType.type);
|
||||
|
||||
const form = useForm<LocationTypeSetLinkDialogFormProps>({
|
||||
resolver: zodResolver(
|
||||
z.object({ link: z.string().regex(new RegExp(eventLocationTypeOptions?.urlRegExp ?? "")) })
|
||||
),
|
||||
});
|
||||
|
||||
const updateDefaultAppMutation = trpc.viewer.updateUserDefaultConferencingApp.useMutation({
|
||||
onSuccess: () => {
|
||||
showToast("Default app updated successfully", "success");
|
||||
utils.viewer.getUsersDefaultConferencingApp.invalidate();
|
||||
},
|
||||
onError: () => {
|
||||
showToast(`Invalid App Link Format`, "error");
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -1192,6 +1192,26 @@ const loggedInViewerRouter = router({
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const currentMetadata = userMetadata.parse(ctx.user.metadata);
|
||||
const credentials = ctx.user.credentials;
|
||||
const foundApp = getApps(credentials).filter((app) => app.slug === input.appSlug)[0];
|
||||
const appLocation = foundApp?.appData?.location;
|
||||
|
||||
if (!foundApp || !appLocation)
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "App not installed" });
|
||||
|
||||
if (appLocation.linkType === "static" && !input.appLink) {
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "App link is required" });
|
||||
}
|
||||
|
||||
if (appLocation.linkType === "static" && appLocation.urlRegExp) {
|
||||
const validLink = z
|
||||
.string()
|
||||
.regex(new RegExp(appLocation.urlRegExp), "Invalid App Link")
|
||||
.parse(input.appLink);
|
||||
if (!validLink) {
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "Invalid app link" });
|
||||
}
|
||||
}
|
||||
|
||||
await ctx.prisma.user.update({
|
||||
where: {
|
||||
|
||||
Reference in New Issue
Block a user