From 0b914bef79c195648e76193b45f5a1b2d0b5f6a2 Mon Sep 17 00:00:00 2001 From: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:11:18 +0530 Subject: [PATCH] fix: update meeting token if expired (#17096) --- .../web/lib/video/[uid]/getServerSideProps.ts | 16 +++++++- .../dailyvideo/lib/VideoApiAdapter.ts | 40 +++++++++++++++++++ packages/app-store/dailyvideo/lib/types.ts | 2 +- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/apps/web/lib/video/[uid]/getServerSideProps.ts b/apps/web/lib/video/[uid]/getServerSideProps.ts index 2b0581983d..c0cbc2c39c 100644 --- a/apps/web/lib/video/[uid]/getServerSideProps.ts +++ b/apps/web/lib/video/[uid]/getServerSideProps.ts @@ -4,6 +4,7 @@ import type { GetServerSidePropsContext } from "next"; import { generateGuestMeetingTokenFromOwnerMeetingToken, setEnableRecordingUIAndUserIdForOrganizer, + updateMeetingTokenIfExpired, } from "@calcom/app-store/dailyvideo/lib/VideoApiAdapter"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import { getCalVideoReference } from "@calcom/features/get-cal-video-reference"; @@ -78,10 +79,21 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { const oldVideoReference = getCalVideoReference(bookingObj.references); + const endTime = new Date(booking.endTime); + const fourteenDaysAfter = new Date(endTime.getTime() + 14 * 24 * 60 * 60 * 1000); + const epochTimeFourteenDaysAfter = Math.floor(fourteenDaysAfter.getTime() / 1000); + + const videoReferencePassword = await updateMeetingTokenIfExpired({ + bookingReferenceId: oldVideoReference.id, + roomName: oldVideoReference.uid, + meetingToken: oldVideoReference.meetingPassword, + exp: epochTimeFourteenDaysAfter, + }); + // set meetingPassword for guests if (session?.user.id !== bookingObj.user?.id) { const guestMeetingPassword = await generateGuestMeetingTokenFromOwnerMeetingToken( - oldVideoReference.meetingPassword, + videoReferencePassword, session?.user.id ); @@ -93,7 +105,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { else { const meetingPassword = await setEnableRecordingUIAndUserIdForOrganizer( oldVideoReference.id, - oldVideoReference.meetingPassword, + videoReferencePassword, session?.user.id ); if (!!meetingPassword) { diff --git a/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts b/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts index 4a120b6539..4d694c640b 100644 --- a/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts +++ b/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts @@ -98,6 +98,46 @@ async function processTranscriptsInBatches(transcriptIds: Array) { return allTranscriptsAccessLinks; } +export const updateMeetingTokenIfExpired = async ({ + bookingReferenceId, + meetingToken, + roomName, + exp, +}: { + bookingReferenceId: number; + meetingToken: string | null; + roomName: string; + exp: number; +}) => { + if (!meetingToken) return null; + + try { + await fetcher(`/meeting-tokens/${meetingToken}`).then(ZGetMeetingTokenResponseSchema.parse); + } catch (err) { + const organizerMeetingToken = await postToDailyAPI("/meeting-tokens", { + properties: { + room_name: roomName, + exp: exp, + enable_recording_ui: false, + is_owner: true, + }, + }).then(meetingTokenSchema.parse); + + await prisma.bookingReference.update({ + where: { + id: bookingReferenceId, + }, + data: { + meetingPassword: organizerMeetingToken.token, + }, + }); + + return organizerMeetingToken.token; + } + + return meetingToken; +}; + export const generateGuestMeetingTokenFromOwnerMeetingToken = async ( meetingToken: string | null, userId?: number diff --git a/packages/app-store/dailyvideo/lib/types.ts b/packages/app-store/dailyvideo/lib/types.ts index 6a167a5c6e..8031a34535 100644 --- a/packages/app-store/dailyvideo/lib/types.ts +++ b/packages/app-store/dailyvideo/lib/types.ts @@ -65,6 +65,6 @@ export const ZGetMeetingTokenResponseSchema = z room_name: z.string(), exp: z.number(), enable_recording_ui: z.boolean().optional(), - user_id: z.number().optional(), + user_id: z.number().nullable().optional(), }) .passthrough();