diff --git a/apps/backend/.env b/apps/backend/.env index 1cb85405d..fc0277d58 100644 --- a/apps/backend/.env +++ b/apps/backend/.env @@ -115,3 +115,6 @@ STACK_STRIPE_SECRET_KEY=# enter your stripe api key STACK_STRIPE_WEBHOOK_SECRET=# enter your stripe webhook secret STACK_TELEGRAM_BOT_TOKEN= # enter you telegram bot token STACK_TELEGRAM_CHAT_ID=# enter your telegram chat id + +# Docs AI tool bundle +STACK_DOCS_INTERNAL_BASE_URL=# override the docs origin used by the backend's AI tool bundle to call the docs app's `/api/internal/docs-tools` endpoint. Defaults to http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}04 in dev, https://mcp.stack-auth.com in prod diff --git a/apps/backend/.env.development b/apps/backend/.env.development index 2ba52ced0..b2f69f312 100644 --- a/apps/backend/.env.development +++ b/apps/backend/.env.development @@ -77,10 +77,7 @@ STACK_OPENAI_API_KEY=mock_openai_api_key STACK_STRIPE_SECRET_KEY=sk_test_mockstripekey STACK_STRIPE_WEBHOOK_SECRET=mock_stripe_webhook_secret STACK_OPENROUTER_API_KEY=FORWARD_TO_PRODUCTION -# Optional: override docs origin for the `docs` AI tool bundle (defaults to http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}04 in dev, https://mcp.stack-auth.com in prod) # STACK_DOCS_INTERNAL_BASE_URL=http://localhost:8104 -# Optional: shared secret; when set, backend sends it and docs `/api/internal/docs-tools` requires it -# STACK_INTERNAL_DOCS_TOOLS_SECRET= # Email monitor configuration for tests STACK_EMAIL_MONITOR_VERIFICATION_CALLBACK_URL=http://localhost:8101/handler/email-verification STACK_EMAIL_MONITOR_PROJECT_ID=internal diff --git a/apps/backend/src/lib/ai/tools/docs.ts b/apps/backend/src/lib/ai/tools/docs.ts index 3975e400a..91f45ea10 100644 --- a/apps/backend/src/lib/ai/tools/docs.ts +++ b/apps/backend/src/lib/ai/tools/docs.ts @@ -22,15 +22,10 @@ function getDocsToolsBaseUrl(): string { async function postDocsToolAction(action: Record): Promise { const base = getDocsToolsBaseUrl(); - const secret = getEnvVariable("STACK_INTERNAL_DOCS_TOOLS_SECRET", ""); - const headers = new Headers({ "Content-Type": "application/json" }); - if (secret !== "") { - headers.set("x-stack-internal-docs-tools-secret", secret); - } const res = await fetch(`${base}/api/internal/docs-tools`, { method: "POST", - headers, + headers: { "Content-Type": "application/json" }, body: JSON.stringify(action), }); diff --git a/docs/.env b/docs/.env new file mode 100644 index 000000000..2102f16e4 --- /dev/null +++ b/docs/.env @@ -0,0 +1,6 @@ +# Basic +NEXT_PUBLIC_STACK_API_URL=# the base URL of Stack's backend/API +NEXT_PUBLIC_STACK_PROJECT_ID=# the project ID to use +NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=# publishable client key for the project +STACK_SECRET_SERVER_KEY=# secret server key for the project +STACK_OPENROUTER_API_KEY=# OpenRouter API key for AI-enabled chat \ No newline at end of file diff --git a/docs/.env.development b/docs/.env.development index cd0ca772f..7f67d50ea 100644 --- a/docs/.env.development +++ b/docs/.env.development @@ -5,5 +5,3 @@ NEXT_PUBLIC_STACK_PROJECT_ID=internal NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only STACK_OPENROUTER_API_KEY=your-open-router-api-key-for-ai-enabled-chat -# Optional: require this header value for POST /api/internal/docs-tools (must match backend STACK_INTERNAL_DOCS_TOOLS_SECRET) -# STACK_INTERNAL_DOCS_TOOLS_SECRET= diff --git a/docs/src/app/api/internal/docs-tools/route.ts b/docs/src/app/api/internal/docs-tools/route.ts index 22a5594b1..783ba1f67 100644 --- a/docs/src/app/api/internal/docs-tools/route.ts +++ b/docs/src/app/api/internal/docs-tools/route.ts @@ -15,19 +15,7 @@ const bodySchema: z.ZodType = z.discriminatedUnion("action", [ z.object({ action: z.literal("fetch"), id: z.string() }), ]); -function validateInternalSecret(req: NextRequest): boolean { - const secret = process.env.STACK_INTERNAL_DOCS_TOOLS_SECRET; - if (secret == null || secret === "") { - return true; - } - return req.headers.get("x-stack-internal-docs-tools-secret") === secret; -} - export async function POST(req: NextRequest) { - if (!validateInternalSecret(req)) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); - } - let json: unknown; try { json = await req.json();