11import { db } from "@cap/database" ;
2- import { eq , desc , sql , count } from "drizzle-orm" ;
2+ import { eq , desc , sql , count , InferSelectModel } from "drizzle-orm" ;
33import { Logo } from "@cap/ui" ;
44import {
55 videos ,
@@ -24,8 +24,8 @@ import { isAiGenerationEnabled, isAiUiEnabled } from "@/utils/flags";
2424import { Share } from "./Share" ;
2525import { PasswordOverlay } from "./_components/PasswordOverlay" ;
2626import { ImageViewer } from "./_components/ImageViewer" ;
27- import { decrypt } from "@cap/database/crypto" ;
2827import { ShareHeader } from "./_components/ShareHeader" ;
28+ import { userHasAccessToVideo } from "@/utils/auth" ;
2929
3030export const dynamic = "auto" ;
3131export const dynamicParams = true ;
@@ -245,7 +245,7 @@ export default async function ShareVideoPage(props: Props) {
245245 const videoId = params . videoId as string ;
246246 console . log ( "[ShareVideoPage] Starting page load for videoId:" , videoId ) ;
247247
248- const user = ( await getCurrentUser ( ) ) as typeof userSelectProps | null ;
248+ const user = await getCurrentUser ( ) ;
249249 const userId = user ?. id as string | undefined ;
250250 console . log ( "[ShareVideoPage] Current user:" , userId ) ;
251251
@@ -287,6 +287,35 @@ export default async function ShareVideoPage(props: Props) {
287287 return < p > No video found</ p > ;
288288 }
289289
290+ const userAccess = await userHasAccessToVideo ( user , video ) ;
291+
292+ if ( userAccess === "private" ) return < p > This video is private</ p > ;
293+
294+ return (
295+ < div className = "min-h-screen flex flex-col bg-[#F7F8FA]" >
296+ < PasswordOverlay
297+ isOpen = { userAccess === "needs-password" }
298+ videoId = { video . id }
299+ />
300+ { userAccess === "has-access" && (
301+ < AuthorizedContent video = { video } user = { user } />
302+ ) }
303+ </ div >
304+ ) ;
305+ }
306+
307+ async function AuthorizedContent ( {
308+ video,
309+ user,
310+ } : {
311+ video : InferSelectModel < typeof videos > & {
312+ sharedOrganization : { organizationId : string } | null ;
313+ } ;
314+ user : InferSelectModel < typeof users > | null ;
315+ } ) {
316+ const videoId = video . id ;
317+ const userId = user ?. id ;
318+
290319 let aiGenerationEnabled = false ;
291320 const videoOwnerQuery = await db ( )
292321 . select ( {
@@ -423,10 +452,6 @@ export default async function ShareVideoPage(props: Props) {
423452 }
424453 }
425454
426- if ( video . public === false && userId !== video . ownerId ) {
427- return < p > This video is private</ p > ;
428- }
429-
430455 const commentsQuery : CommentWithAuthor [ ] = await db ( )
431456 . select ( {
432457 id : comments . id ,
@@ -593,69 +618,48 @@ export default async function ShareVideoPage(props: Props) {
593618 ) ;
594619 }
595620
596- const authorized =
597- ! videoWithOrganizationInfo . hasPassword ||
598- user ?. id === videoWithOrganizationInfo . ownerId ||
599- ( await verifyPasswordCookie ( video . password ?? "" ) ) ;
600-
601621 return (
602- < div className = "min-h-screen flex flex-col bg-[#F7F8FA]" >
603- < PasswordOverlay
604- isOpen = { ! authorized }
605- videoId = { videoWithOrganizationInfo . id }
606- />
607- { authorized && (
608- < >
609- < div className = "container flex-1 px-4 py-4 mx-auto" >
610- < ShareHeader
611- data = { {
612- ...videoWithOrganizationInfo ,
613- createdAt : video . metadata ?. customCreatedAt
614- ? new Date ( video . metadata . customCreatedAt )
615- : video . createdAt ,
616- } }
617- user = { user }
618- customDomain = { customDomain }
619- domainVerified = { domainVerified }
620- sharedOrganizations = {
621- videoWithOrganizationInfo . sharedOrganizations || [ ]
622- }
623- userOrganizations = { userOrganizations }
624- />
625-
626- < Share
627- data = { videoWithOrganizationInfo }
628- user = { user }
629- comments = { commentsQuery }
630- initialAnalytics = { initialAnalytics }
631- customDomain = { customDomain }
632- domainVerified = { domainVerified }
633- userOrganizations = { userOrganizations }
634- initialAiData = { initialAiData }
635- aiGenerationEnabled = { aiGenerationEnabled }
636- aiUiEnabled = { aiUiEnabled }
637- />
638- </ div >
639- < div className = "py-4 mt-auto" >
640- < a
641- target = "_blank"
642- href = { `/?ref=video_${ video . id } ` }
643- className = "flex justify-center items-center px-4 py-2 mx-auto space-x-2 bg-gray-1 rounded-full new-card-style w-fit"
644- >
645- < span className = "text-sm" > Recorded with</ span >
646- < Logo className = "w-14 h-auto" />
647- </ a >
648- </ div >
649- </ >
650- ) }
651- </ div >
652- ) ;
653- }
654-
655- async function verifyPasswordCookie ( videoPassword : string ) {
656- const password = cookies ( ) . get ( "x-cap-password" ) ?. value ;
657- if ( ! password ) return false ;
622+ < >
623+ < div className = "container flex-1 px-4 py-4 mx-auto" >
624+ < ShareHeader
625+ data = { {
626+ ...videoWithOrganizationInfo ,
627+ createdAt : video . metadata ?. customCreatedAt
628+ ? new Date ( video . metadata . customCreatedAt )
629+ : video . createdAt ,
630+ } }
631+ user = { user }
632+ customDomain = { customDomain }
633+ domainVerified = { domainVerified }
634+ sharedOrganizations = {
635+ videoWithOrganizationInfo . sharedOrganizations || [ ]
636+ }
637+ userOrganizations = { userOrganizations }
638+ />
658639
659- const decrypted = await decrypt ( password ) . catch ( ( ) => "" ) ;
660- return decrypted === videoPassword ;
640+ < Share
641+ data = { videoWithOrganizationInfo }
642+ user = { user }
643+ comments = { commentsQuery }
644+ initialAnalytics = { initialAnalytics }
645+ customDomain = { customDomain }
646+ domainVerified = { domainVerified }
647+ userOrganizations = { userOrganizations }
648+ initialAiData = { initialAiData }
649+ aiGenerationEnabled = { aiGenerationEnabled }
650+ aiUiEnabled = { aiUiEnabled }
651+ />
652+ </ div >
653+ < div className = "py-4 mt-auto" >
654+ < a
655+ target = "_blank"
656+ href = { `/?ref=video_${ video . id } ` }
657+ className = "flex justify-center items-center px-4 py-2 mx-auto space-x-2 bg-gray-1 rounded-full new-card-style w-fit"
658+ >
659+ < span className = "text-sm" > Recorded with</ span >
660+ < Logo className = "w-14 h-auto" />
661+ </ a >
662+ </ div >
663+ </ >
664+ ) ;
661665}
0 commit comments