Skip to content
Draft
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
1 change: 1 addition & 0 deletions apps/cloud/src/edge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export { marketingMiddleware } from "./marketing";
export { sentryTunnelMiddleware } from "./sentry-tunnel";
export { posthogProxyMiddleware } from "./posthog";
export { docsProxyMiddleware } from "./docs";
export { openAiAppsChallengeMiddleware } from "./openai-apps-challenge";
29 changes: 29 additions & 0 deletions apps/cloud/src/edge/openai-apps-challenge.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { describe, expect, it } from "@effect/vitest";

import {
OPENAI_APPS_CHALLENGE_PATH,
OPENAI_APPS_CHALLENGE_TOKEN,
isOpenAiAppsChallengePath,
openAiAppsChallengeResponse,
} from "./openai-apps-challenge";

describe("isOpenAiAppsChallengePath", () => {
it("claims the OpenAI Apps verification challenge path", () => {
expect(isOpenAiAppsChallengePath(OPENAI_APPS_CHALLENGE_PATH)).toBe(true);
});

it("does not claim sibling well-known paths", () => {
expect(isOpenAiAppsChallengePath("/.well-known/openai-apps-challenge/extra")).toBe(false);
expect(isOpenAiAppsChallengePath("/.well-known/oauth-protected-resource/mcp")).toBe(false);
});
});

describe("openAiAppsChallengeResponse", () => {
it("serves the exact verification token as plain text", async () => {
const response = openAiAppsChallengeResponse();

expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("text/plain; charset=utf-8");
expect(await response.text()).toBe(OPENAI_APPS_CHALLENGE_TOKEN);
});
});
23 changes: 23 additions & 0 deletions apps/cloud/src/edge/openai-apps-challenge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createMiddleware } from "@tanstack/react-start";

export const OPENAI_APPS_CHALLENGE_PATH = "/.well-known/openai-apps-challenge";
export const OPENAI_APPS_CHALLENGE_TOKEN =
"P_fW7WgF8HkXXQkP85B7aDZD_RuZv8YmQA2Zq9JoIfc";

export const isOpenAiAppsChallengePath = (pathname: string) =>
pathname === OPENAI_APPS_CHALLENGE_PATH;

export const openAiAppsChallengeResponse = () =>
new Response(OPENAI_APPS_CHALLENGE_TOKEN, {
headers: {
"cache-control": "public, max-age=300",
"content-type": "text/plain; charset=utf-8",
},
});

export const openAiAppsChallengeMiddleware = createMiddleware({ type: "request" }).server(
({ pathname, next }) => {
if (!isOpenAiAppsChallengePath(pathname)) return next();
return openAiAppsChallengeResponse();
},
);
2 changes: 2 additions & 0 deletions apps/cloud/src/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { prepareMcpOrgScope } from "./mcp/mount";
import {
docsProxyMiddleware,
marketingMiddleware,
openAiAppsChallengeMiddleware,
posthogProxyMiddleware,
sentryTunnelMiddleware,
} from "./edge";
Expand Down Expand Up @@ -100,6 +101,7 @@ const appRequestMiddleware = createMiddleware({ type: "request" }).server(
// load-bearing.
export const startInstance = createStart(() => ({
requestMiddleware: [
openAiAppsChallengeMiddleware,
marketingMiddleware,
docsProxyMiddleware,
sentryTunnelMiddleware,
Expand Down
Loading