Skip to content

Commit fb46a70

Browse files
committed
fix: order of checks for public sites
1 parent 18004b0 commit fb46a70

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

apps/api/src/routes/query.ts

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ async function verifyWebsiteAccess(
9696
ctx: AuthContext,
9797
websiteId: string
9898
): Promise<boolean> {
99-
if (!ctx.isAuthenticated) {
100-
return false;
101-
}
102-
10399
const website = await db.query.websites.findFirst({
104100
where: eq(websites.id, websiteId),
105101
columns: {
@@ -118,6 +114,10 @@ async function verifyWebsiteAccess(
118114
return true;
119115
}
120116

117+
if (!ctx.isAuthenticated) {
118+
return false;
119+
}
120+
121121
if (ctx.apiKey) {
122122
if (hasGlobalAccess(ctx.apiKey)) {
123123
if (ctx.apiKey.organizationId) {
@@ -276,22 +276,27 @@ export const query = new Elysia({ prefix: "/v1/query" })
276276
query: { website_id?: string; timezone?: string };
277277
auth: AuthContext;
278278
}) => {
279-
if (!ctx.isAuthenticated) {
280-
return AUTH_FAILED;
281-
}
282-
279+
// Check website access first (handles public websites)
283280
if (q.website_id) {
284281
const hasAccess = await verifyWebsiteAccess(ctx, q.website_id);
285282
if (!hasAccess) {
286283
return new Response(
287284
JSON.stringify({
288285
success: false,
289-
error: "Access denied to this website",
290-
code: "ACCESS_DENIED",
286+
error: ctx.isAuthenticated
287+
? "Access denied to this website"
288+
: "Authentication required",
289+
code: ctx.isAuthenticated ? "ACCESS_DENIED" : "AUTH_REQUIRED",
291290
}),
292-
{ status: 403, headers: { "Content-Type": "application/json" } }
291+
{
292+
status: ctx.isAuthenticated ? 403 : 401,
293+
headers: { "Content-Type": "application/json" },
294+
}
293295
);
294296
}
297+
} else if (!ctx.isAuthenticated) {
298+
// No website_id and not authenticated
299+
return AUTH_FAILED;
295300
}
296301

297302
try {
@@ -324,19 +329,21 @@ export const query = new Elysia({ prefix: "/v1/query" })
324329
auth: AuthContext;
325330
}) =>
326331
record("executeQuery", async () => {
327-
if (!ctx.isAuthenticated) {
328-
return AUTH_FAILED;
329-
}
330-
332+
// Check website access first (handles public websites)
331333
if (q.website_id) {
332334
const hasAccess = await verifyWebsiteAccess(ctx, q.website_id);
333335
if (!hasAccess) {
334336
return {
335337
success: false,
336-
error: "Access denied to this website",
337-
code: "ACCESS_DENIED",
338+
error: ctx.isAuthenticated
339+
? "Access denied to this website"
340+
: "Authentication required",
341+
code: ctx.isAuthenticated ? "ACCESS_DENIED" : "AUTH_REQUIRED",
338342
};
339343
}
344+
} else if (!ctx.isAuthenticated) {
345+
// No website_id and not authenticated
346+
return AUTH_FAILED;
340347
}
341348

342349
const tz = q.timezone || "UTC";

apps/dashboard/app/demo/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { AutumnProvider } from "autumn-js/react";
22
import { Sidebar } from "@/components/layout/sidebar";
33
import { BillingProvider } from "@/components/providers/billing-provider";
44

5-
export default function DemoLayout({
5+
export default async function DemoLayout({
66
children,
77
}: {
88
children: React.ReactNode;

packages/rpc/src/routers/websites.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,8 @@ export const websitesRouter = {
520520
});
521521
}
522522

523+
await invalidateWebsiteCaches(input.id, context.user.id);
524+
523525
logger.info(
524526
{
525527
websiteId: input.id,

packages/rpc/src/utils/cache-invalidation.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ export const invalidateWebsiteCaches = async (
4141
// The cacheable function creates keys with format: "cacheable:{prefix}:{args}"
4242
redisCache.del(`cacheable:website_by_id:${websiteId}`),
4343

44+
redisCache.del(`cacheable:website-cache:${websiteId}`),
45+
redisCache.del(`cacheable:website-domain:${websiteId}`),
46+
4447
createDrizzleCache({ redis, namespace: "auth" }).invalidateByKey(
4548
`auth:${userId}:${websiteId}`
4649
),

0 commit comments

Comments
 (0)