Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/web/src/app/s/[sessionId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import { OpenInCliButton } from '@/app/share/[shareId]/open-in-cli-button';
import { OpenInEditorButton } from '@/app/share/[shareId]/open-in-editor-button';
import { Card, CardContent, CardHeader } from '@/components/ui/card';

export const revalidate = 86400;
export const dynamic = 'force-dynamic';

export default async function SharedSessionPage({
params,
}: {
params: Promise<{ sessionId: string }>;
}) {
notFound();

const { sessionId } = await params;

// Validate sessionId is a valid UUID before querying the database
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/app/share/[shareId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { cookies } from 'next/headers';
import { getExtensionUrl } from '@/components/auth/getExtensionUrl';
import { validate as isValidUUID } from 'uuid';

export const revalidate = 86400;
export const dynamic = 'force-dynamic';

/**
* Extracts text content from a blob message based on its type.
Expand Down Expand Up @@ -85,6 +85,8 @@ export default async function SharePage({
params: Promise<{ shareId: string }>;
searchParams: Promise<NextAppSearchParams>;
}) {
notFound();

const { shareId } = await params;
const resolvedSearchParams = await searchParams;
const cookieStore = await cookies();
Expand Down
5 changes: 5 additions & 0 deletions services/session-ingest/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { getSessionExport } from './services/session-export';
import { withDORetry } from '@kilocode/worker-utils';

const sessionIdSchema = z.string().startsWith('ses_').length(30);
const publicSessionAccessEnabled: boolean = false;
const invalidateSessionAccessSchema = z.object({
kiloUserId: z.string().min(1),
organizationId: z.uuid(),
Expand Down Expand Up @@ -80,6 +81,10 @@ app.get('/session/:sessionId', async c => {
);
}

if (!publicSessionAccessEnabled) {
return c.json({ success: false, error: 'session_not_found' }, 404);
}

const db = getWorkerDb(c.env.HYPERDRIVE.connectionString);
const rows = await db
.select({
Expand Down
29 changes: 2 additions & 27 deletions services/session-ingest/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ vi.mock('./dos/SessionAccessCacheDO', () => ({

import { app } from './index';
import { getWorkerDb } from '@kilocode/db/client';
import { getSessionIngestDO } from './dos/SessionIngestDO';
import { getSessionAccessCacheDO } from './dos/SessionAccessCacheDO';

type TestBindings = {
Expand Down Expand Up @@ -169,37 +168,13 @@ describe('public session route', () => {
expect(res.status).toBe(400);
});

it('returns 404 when public_id not found', async () => {
it('returns 404 without looking up the public_id', async () => {
const { db, selectResult } = makeDbFakes();
vi.mocked(getWorkerDb).mockReturnValue(db as never);
selectResult.mockResolvedValueOnce([]);

const res = await app.request('/session/11111111-1111-4111-8111-111111111111', {}, defaultEnv);

expect(res.status).toBe(404);
});

it('returns DO snapshot json with content-type', async () => {
const { db, selectResult } = makeDbFakes();
vi.mocked(getWorkerDb).mockReturnValue(db as never);
selectResult.mockResolvedValueOnce([
{
session_id: 'ses_12345678901234567890123456',
kilo_user_id: 'usr_123',
},
]);

const stub = {
getAllStream: vi.fn(async () => new Response('{"ok":true}').body!),
};
vi.mocked(getSessionIngestDO).mockReturnValue(
stub as unknown as ReturnType<typeof getSessionIngestDO>
);

const res = await app.request('/session/11111111-1111-4111-8111-111111111111', {}, defaultEnv);

expect(res.status).toBe(200);
expect(res.headers.get('content-type')).toBe('application/json; charset=utf-8');
expect(await res.text()).toBe('{"ok":true}');
expect(selectResult).not.toHaveBeenCalled();
});
});
Loading