11import { auth } from "@databuddy/auth" ;
2+ import { and , db , eq , member } from "@databuddy/db" ;
23import { Elysia } from "elysia" ;
34import {
45 getApiKeyFromHeader ,
@@ -95,7 +96,7 @@ function checkNoWebsiteAuth(
9596
9697async function checkWebsiteAuth (
9798 websiteId : string ,
98- sessionUser : unknown ,
99+ sessionUser : { id : string ; name : string ; email : string } | unknown ,
99100 apiKey : Parameters < typeof hasWebsiteScope > [ 0 ] | null ,
100101 apiKeyPresent : boolean
101102) : Promise < Response | null > {
@@ -110,9 +111,42 @@ async function checkWebsiteAuth(
110111 if ( website . isPublic ) {
111112 return null ;
112113 }
113- if ( sessionUser ) {
114- return null ;
114+
115+ // Check session-based authentication
116+ if ( sessionUser && typeof sessionUser === "object" && "id" in sessionUser ) {
117+ const userId = ( sessionUser as { id : string } ) . id ;
118+
119+ // Check if user owns the website directly (personal website)
120+ if ( website . userId === userId && ! website . organizationId ) {
121+ return null ;
122+ }
123+
124+ // Check if user has access through organization membership
125+ if ( website . organizationId ) {
126+ const membership = await db . query . member . findFirst ( {
127+ where : and (
128+ eq ( member . userId , userId ) ,
129+ eq ( member . organizationId , website . organizationId )
130+ ) ,
131+ columns : {
132+ id : true ,
133+ } ,
134+ } ) ;
135+
136+ if ( membership ) {
137+ return null ;
138+ }
139+ }
140+
141+ // User is authenticated but doesn't have access to this website
142+ return json ( 403 , {
143+ success : false ,
144+ error : "Access denied to this website" ,
145+ code : "FORBIDDEN" ,
146+ } ) ;
115147 }
148+
149+ // No session user, check API key
116150 if ( ! apiKeyPresent ) {
117151 return json ( 401 , {
118152 success : false ,
0 commit comments