Return to Builder to finish connecting OpenRouter.
+`, + { + headers: { + 'Content-Type': 'text/html; charset=utf-8', + 'Cache-Control': 'no-store', + 'Referrer-Policy': 'no-referrer', + 'Content-Security-Policy': `default-src 'none'; script-src 'nonce-${nonce}'; base-uri 'none'; frame-ancestors 'none'; form-action 'none'`, + 'X-Content-Type-Options': 'nosniff', + 'Cross-Origin-Opener-Policy': 'same-origin', + }, + }, + ) +} +export const handlers = { GET: () => openRouterCallbackResponse() } diff --git a/src/chat/server/routes/plugins.ts b/src/chat/server/routes/plugins.ts new file mode 100644 index 000000000..c8f539ced --- /dev/null +++ b/src/chat/server/routes/plugins.ts @@ -0,0 +1,54 @@ +import { hasChatAccess } from '~/chat/access.server' +import { z } from 'zod' +import { getAuthService } from '~/auth/index.server' +import { + jsonError, + validateSameOriginRequest, +} from '~/utils/api-boundary.server' +import { + readWorkspacePolicy, + WorkspacePolicyError, +} from '~/chat/workspace-policy.server' +import { + getKodyEnvironment, + KodyEnvironmentError, +} from '~/chat/server/kody-environment.server' +import { pluginApi } from '~/chat/server/plugin-api' +export async function handlePlugins(request: Request, id?: string) { + if (request.method === 'POST') { + const error = validateSameOriginRequest(request) + if (error) return jsonError(error.message, error.status) + } + const user = await getAuthService().getCurrentUser(request) + if (!user) return jsonError('Sign in to continue.', 401) + if (!(await hasChatAccess(user))) + return jsonError('Chat access is unavailable.', 403) + const url = new URL(request.url) + const parsed = z + .string() + .min(1) + .max(1000) + .safeParse(url.searchParams.get('workspaceId')) + if (url.searchParams.getAll('workspaceId').length !== 1 || !parsed.success) + return jsonError('Choose a workspace.', 400) + try { + await readWorkspacePolicy(parsed.data, user.userId) + return await pluginApi( + request, + await getKodyEnvironment(), + { workspaceId: parsed.data, userId: user.userId }, + id ?? url.searchParams.get('id') ?? undefined, + ) + } catch (error) { + if ( + error instanceof WorkspacePolicyError || + error instanceof KodyEnvironmentError + ) + return jsonError(error.message, error.status) + throw error + } +} +export const handlers = { + GET: ({ request }: { request: Request }) => handlePlugins(request), + POST: ({ request }: { request: Request }) => handlePlugins(request), +} diff --git a/src/chat/server/routes/project-snapshots.$hash.quarantine.ts b/src/chat/server/routes/project-snapshots.$hash.quarantine.ts new file mode 100644 index 000000000..4367eb5ad --- /dev/null +++ b/src/chat/server/routes/project-snapshots.$hash.quarantine.ts @@ -0,0 +1,163 @@ +import { + jsonError, + jsonResponse, + validateSameOriginRequest, +} from '~/utils/api-boundary.server' +import { + purgeHostingCacheTags, + type PurgeResult, +} from '~/utils/hosting-cache.server' +import { + getBuilderProjectSnapshotCacheTag, + isBuilderProjectSnapshotHash, + isBuilderProjectSnapshotQuarantined, + BuilderProjectSnapshotStorageUnavailableError, + quarantineBuilderProjectSnapshot, +} from '~/utils/builder-project-snapshot-storage.server' +import { + BuilderProjectStorageUnavailableError, + quarantineStoredBuilderProjectsBySnapshotHash, +} from '~/utils/builder-project-storage.server' +import { quarantineBuilderProjectsBySnapshotHash } from '~/utils/builder-project-events.server' + +type BuilderProjectQuarantineOperations = { + quarantineSnapshot: (hash: string, userId: string) => PromiseReturn to Builder to finish connecting OpenRouter.
-`, { - headers: { - 'Content-Type': 'text/html; charset=utf-8', - 'Cache-Control': 'no-store', - 'Referrer-Policy': 'no-referrer', - 'Content-Security-Policy': `default-src 'none'; script-src 'nonce-${nonce}'; base-uri 'none'; frame-ancestors 'none'; form-action 'none'`, - 'X-Content-Type-Options': 'nosniff', - 'Cross-Origin-Opener-Policy': 'same-origin', + server: { + handlers: { + GET: ({ request }) => forwardWorkerRequest('CHAT', request), }, - }) -} + }, +}) diff --git a/src/routes/api/chat/plugins.ts b/src/routes/api/chat/plugins.ts index 7a3d81254..9b30c22c2 100644 --- a/src/routes/api/chat/plugins.ts +++ b/src/routes/api/chat/plugins.ts @@ -1,28 +1,11 @@ -import { hasChatAccess } from '~/chat/access.server' -import { z } from 'zod' import { createFileRoute } from '@tanstack/react-router' -import { getAuthService } from '~/auth/index.server' -import { jsonError,validateSameOriginRequest } from '~/utils/api-boundary.server' -import { readWorkspacePolicy,WorkspacePolicyError } from '~/chat/workspace-policy.server' -import { getKodyEnvironment,KodyEnvironmentError } from '~/chat/server/kody-environment.server' -import { pluginApi } from '~/chat/server/plugin-api' -export async function handlePlugins(request:Request, id?:string) { - if(request.method==='POST') { - const error=validateSameOriginRequest(request) - if(error) return jsonError(error.message,error.status) - } - const user=await getAuthService().getCurrentUser(request) - if(!user) return jsonError('Sign in to continue.',401) - if(!await hasChatAccess(user)) return jsonError('Chat access is unavailable.',403) - const url=new URL(request.url) - const parsed=z.string().min(1).max(1000).safeParse(url.searchParams.get('workspaceId')) - if(url.searchParams.getAll('workspaceId').length!==1||!parsed.success) return jsonError('Choose a workspace.',400) - try { - await readWorkspacePolicy(parsed.data,user.userId) - return await pluginApi(request,await getKodyEnvironment(),{workspaceId:parsed.data,userId:user.userId},id??url.searchParams.get('id')??undefined) - } catch(error) { - if(error instanceof WorkspacePolicyError||error instanceof KodyEnvironmentError) return jsonError(error.message,error.status) - throw error - } -} -export const Route=createFileRoute('/api/chat/plugins')({server:{handlers:{GET:({request})=>handlePlugins(request),POST:({request})=>handlePlugins(request)}}}) +import { forwardWorkerRequest } from '~/server/runtime/worker-service.server' + +export const Route = createFileRoute('/api/chat/plugins')({ + server: { + handlers: { + GET: ({ request }) => forwardWorkerRequest('CHAT', request), + POST: ({ request }) => forwardWorkerRequest('CHAT', request), + }, + }, +}) diff --git a/src/routes/api/chat/plugins/$id.ts b/src/routes/api/chat/plugins/$id.ts index 8846d3468..5223a7704 100644 --- a/src/routes/api/chat/plugins/$id.ts +++ b/src/routes/api/chat/plugins/$id.ts @@ -1,11 +1,11 @@ import { createFileRoute } from '@tanstack/react-router' -import { handlePlugins } from '../plugins' +import { forwardWorkerRequest } from '~/server/runtime/worker-service.server' export const Route = createFileRoute('/api/chat/plugins/$id')({ server: { handlers: { - GET: ({ request, params }) => handlePlugins(request, params.id), - POST: ({ request, params }) => handlePlugins(request, params.id), + GET: ({ request }) => forwardWorkerRequest('CHAT', request), + POST: ({ request }) => forwardWorkerRequest('CHAT', request), }, }, }) diff --git a/src/routes/api/chat/policy.ts b/src/routes/api/chat/policy.ts index bac151812..4007290da 100644 --- a/src/routes/api/chat/policy.ts +++ b/src/routes/api/chat/policy.ts @@ -1,3 +1,10 @@ -import {createFileRoute} from '@tanstack/react-router' -import {handleWorkspacePolicy} from '~/chat/server/workspace-policy-http.server' -export const Route=createFileRoute('/api/chat/policy')({server:{handlers:{POST:({request})=>handleWorkspacePolicy(request)}}}) +import { createFileRoute } from '@tanstack/react-router' +import { forwardWorkerRequest } from '~/server/runtime/worker-service.server' + +export const Route = createFileRoute('/api/chat/policy')({ + server: { + handlers: { + POST: ({ request }) => forwardWorkerRequest('CHAT', request), + }, + }, +}) diff --git a/src/routes/api/chat/project-snapshots.$hash.quarantine.ts b/src/routes/api/chat/project-snapshots.$hash.quarantine.ts index f7ce51c99..dd1509d61 100644 --- a/src/routes/api/chat/project-snapshots.$hash.quarantine.ts +++ b/src/routes/api/chat/project-snapshots.$hash.quarantine.ts @@ -1,172 +1,12 @@ import { createFileRoute } from '@tanstack/react-router' -import { - jsonError, - jsonResponse, - validateSameOriginRequest, -} from '~/utils/api-boundary.server' -import { - purgeHostingCacheTags, - type PurgeResult, -} from '~/utils/hosting-cache.server' -import { - getBuilderProjectSnapshotCacheTag, - isBuilderProjectSnapshotHash, - isBuilderProjectSnapshotQuarantined, - BuilderProjectSnapshotStorageUnavailableError, - quarantineBuilderProjectSnapshot, -} from '~/utils/builder-project-snapshot-storage.server' -import { - BuilderProjectStorageUnavailableError, - quarantineStoredBuilderProjectsBySnapshotHash, -} from '~/utils/builder-project-storage.server' -import { quarantineBuilderProjectsBySnapshotHash } from '~/utils/builder-project-events.server' - -type BuilderProjectQuarantineOperations = { - quarantineSnapshot: (hash: string, userId: string) => Promise