From e62f141fc1b355bc517654b0158ebc36da84b96e Mon Sep 17 00:00:00 2001 From: Xenc5 Date: Tue, 30 Jun 2026 00:35:49 +0100 Subject: [PATCH 1/2] Add caution around endpoint security, update fetch code snippet --- docs/capabilities/server/http-fetch.mdx | 8 ++++++-- .../version-0.12/capabilities/server/http-fetch.mdx | 8 ++++++-- .../version-0.13/capabilities/server/http-fetch.mdx | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/docs/capabilities/server/http-fetch.mdx b/docs/capabilities/server/http-fetch.mdx index 16284f81..1d3b25d9 100644 --- a/docs/capabilities/server/http-fetch.mdx +++ b/docs/capabilities/server/http-fetch.mdx @@ -70,10 +70,14 @@ Client-side fetch has different restrictions and can only make requests to your **Client-side restrictions:** - **Domain limitation**: Can only make requests to your own webview domain -- **Endpoint requirement**: All requests must target endpoints that end with `/api` +- **Endpoint requirement**: Client-side fetches to your app server must target paths that start with `/api/` - **Authentication**: Handled automatically - no need to manage auth tokens - **No external domains**: Cannot make requests to external domains from client-side code +:::caution +Do not treat `/api/` endpoints as private. Any user who can load your app will be able to call them directly. When changing Redis, content, settings, moderator state, or other persistent data, first check that the user has permission in your server logic. Apps with unprotected endpoints will be rejected during review. +::: + ```tsx title="client/index.ts" const handleFetchData = async () => { // Correct: fetching your own webview's API endpoint @@ -91,7 +95,7 @@ const handleFetchData = async () => { // Incorrect: cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: endpoint must end with /api +// Incorrect: client fetch endpoint must start with /api/ // const response = await fetch('/user-data'); ``` diff --git a/versioned_docs/version-0.12/capabilities/server/http-fetch.mdx b/versioned_docs/version-0.12/capabilities/server/http-fetch.mdx index 16284f81..1d3b25d9 100644 --- a/versioned_docs/version-0.12/capabilities/server/http-fetch.mdx +++ b/versioned_docs/version-0.12/capabilities/server/http-fetch.mdx @@ -70,10 +70,14 @@ Client-side fetch has different restrictions and can only make requests to your **Client-side restrictions:** - **Domain limitation**: Can only make requests to your own webview domain -- **Endpoint requirement**: All requests must target endpoints that end with `/api` +- **Endpoint requirement**: Client-side fetches to your app server must target paths that start with `/api/` - **Authentication**: Handled automatically - no need to manage auth tokens - **No external domains**: Cannot make requests to external domains from client-side code +:::caution +Do not treat `/api/` endpoints as private. Any user who can load your app will be able to call them directly. When changing Redis, content, settings, moderator state, or other persistent data, first check that the user has permission in your server logic. Apps with unprotected endpoints will be rejected during review. +::: + ```tsx title="client/index.ts" const handleFetchData = async () => { // Correct: fetching your own webview's API endpoint @@ -91,7 +95,7 @@ const handleFetchData = async () => { // Incorrect: cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: endpoint must end with /api +// Incorrect: client fetch endpoint must start with /api/ // const response = await fetch('/user-data'); ``` diff --git a/versioned_docs/version-0.13/capabilities/server/http-fetch.mdx b/versioned_docs/version-0.13/capabilities/server/http-fetch.mdx index 16284f81..1d3b25d9 100644 --- a/versioned_docs/version-0.13/capabilities/server/http-fetch.mdx +++ b/versioned_docs/version-0.13/capabilities/server/http-fetch.mdx @@ -70,10 +70,14 @@ Client-side fetch has different restrictions and can only make requests to your **Client-side restrictions:** - **Domain limitation**: Can only make requests to your own webview domain -- **Endpoint requirement**: All requests must target endpoints that end with `/api` +- **Endpoint requirement**: Client-side fetches to your app server must target paths that start with `/api/` - **Authentication**: Handled automatically - no need to manage auth tokens - **No external domains**: Cannot make requests to external domains from client-side code +:::caution +Do not treat `/api/` endpoints as private. Any user who can load your app will be able to call them directly. When changing Redis, content, settings, moderator state, or other persistent data, first check that the user has permission in your server logic. Apps with unprotected endpoints will be rejected during review. +::: + ```tsx title="client/index.ts" const handleFetchData = async () => { // Correct: fetching your own webview's API endpoint @@ -91,7 +95,7 @@ const handleFetchData = async () => { // Incorrect: cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: endpoint must end with /api +// Incorrect: client fetch endpoint must start with /api/ // const response = await fetch('/user-data'); ``` From 349ac48726ad71a134b252cea746dedfef3aba8c Mon Sep 17 00:00:00 2001 From: Xenc5 Date: Tue, 30 Jun 2026 01:28:52 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Restore=20emoji=20in=20code=20snippets=20?= =?UTF-8?q?=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/capabilities/http-fetch.md | 8 ++++---- docs/capabilities/server/http-fetch.mdx | 6 +++--- versioned_docs/version-0.12/capabilities/http-fetch.md | 8 ++++---- .../version-0.12/capabilities/server/http-fetch.mdx | 6 +++--- versioned_docs/version-0.13/capabilities/http-fetch.md | 8 ++++---- .../version-0.13/capabilities/server/http-fetch.mdx | 6 +++--- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/capabilities/http-fetch.md b/docs/capabilities/http-fetch.md index b6388dbb..a62722ca 100644 --- a/docs/capabilities/http-fetch.md +++ b/docs/capabilities/http-fetch.md @@ -76,7 +76,7 @@ console.log('External API response:', data); Client-side fetch has different restrictions: - **Domain limitation**: Can only make requests to your own webview domain -- **Endpoint requirement**: All requests must target endpoints that start with /api +- **Endpoint requirement**: All requests must target endpoints that start with /api/ - **Authentication**: Handled automatically \- no need to manage auth tokens - **No external domains**: Cannot make requests to external domains from client-side code client/index.ts @@ -84,7 +84,7 @@ Client-side fetch has different restrictions: ``` const handleFetchData = async () => { - // Correct: fetching your own webview's API endpoint + // ✅ Correct: Fetching your own webview's API endpoint const response = await fetch("/api/user-data", { method: "GET", headers: { @@ -96,10 +96,10 @@ const handleFetchData = async () => { console.log("API response:", data); }; -// Incorrect: cannot fetch external domains from client-side +// ❌ Incorrect: Cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: endpoint must start with /api +// ❌ Incorrect: Endpoint must start with /api/ // const response = await fetch('/user-data'); ``` diff --git a/docs/capabilities/server/http-fetch.mdx b/docs/capabilities/server/http-fetch.mdx index 1d3b25d9..769617ee 100644 --- a/docs/capabilities/server/http-fetch.mdx +++ b/docs/capabilities/server/http-fetch.mdx @@ -80,7 +80,7 @@ Do not treat `/api/` endpoints as private. Any user who can load your app will b ```tsx title="client/index.ts" const handleFetchData = async () => { - // Correct: fetching your own webview's API endpoint + // ✅ Correct: Fetching your own webview's API endpoint const response = await fetch("/api/user-data", { method: "GET", headers: { @@ -92,10 +92,10 @@ const handleFetchData = async () => { console.log("API response:", data); }; -// Incorrect: cannot fetch external domains from client-side +// ❌ Incorrect: Cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: client fetch endpoint must start with /api/ +// ❌ Incorrect: Endpoint must start with /api/ // const response = await fetch('/user-data'); ``` diff --git a/versioned_docs/version-0.12/capabilities/http-fetch.md b/versioned_docs/version-0.12/capabilities/http-fetch.md index f9d8c253..4931820c 100644 --- a/versioned_docs/version-0.12/capabilities/http-fetch.md +++ b/versioned_docs/version-0.12/capabilities/http-fetch.md @@ -76,7 +76,7 @@ console.log('External API response:', data); Client-side fetch has different restrictions: - **Domain limitation**: Can only make requests to your own webview domain -- **Endpoint requirement**: All requests must target endpoints that start with /api +- **Endpoint requirement**: All requests must target endpoints that start with /api/ - **Authentication**: Handled automatically \- no need to manage auth tokens - **No external domains**: Cannot make requests to external domains from client-side code client/index.ts @@ -84,7 +84,7 @@ Client-side fetch has different restrictions: ``` const handleFetchData = async () => { - // Correct: fetching your own webview's API endpoint + // ✅ Correct: Fetching your own webview's API endpoint const response = await fetch("/api/user-data", { method: "GET", headers: { @@ -96,10 +96,10 @@ const handleFetchData = async () => { console.log("API response:", data); }; -// Incorrect: cannot fetch external domains from client-side +// ❌ Incorrect: Cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: endpoint must start with /api +// ❌ Incorrect: Endpoint must start with /api/ // const response = await fetch('/user-data'); ``` diff --git a/versioned_docs/version-0.12/capabilities/server/http-fetch.mdx b/versioned_docs/version-0.12/capabilities/server/http-fetch.mdx index 1d3b25d9..769617ee 100644 --- a/versioned_docs/version-0.12/capabilities/server/http-fetch.mdx +++ b/versioned_docs/version-0.12/capabilities/server/http-fetch.mdx @@ -80,7 +80,7 @@ Do not treat `/api/` endpoints as private. Any user who can load your app will b ```tsx title="client/index.ts" const handleFetchData = async () => { - // Correct: fetching your own webview's API endpoint + // ✅ Correct: Fetching your own webview's API endpoint const response = await fetch("/api/user-data", { method: "GET", headers: { @@ -92,10 +92,10 @@ const handleFetchData = async () => { console.log("API response:", data); }; -// Incorrect: cannot fetch external domains from client-side +// ❌ Incorrect: Cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: client fetch endpoint must start with /api/ +// ❌ Incorrect: Endpoint must start with /api/ // const response = await fetch('/user-data'); ``` diff --git a/versioned_docs/version-0.13/capabilities/http-fetch.md b/versioned_docs/version-0.13/capabilities/http-fetch.md index 4dc1fdf9..d7eaf7fd 100644 --- a/versioned_docs/version-0.13/capabilities/http-fetch.md +++ b/versioned_docs/version-0.13/capabilities/http-fetch.md @@ -76,7 +76,7 @@ console.log('External API response:', data); Client-side fetch has different restrictions: - **Domain limitation**: Can only make requests to your own webview domain -- **Endpoint requirement**: All requests must target endpoints that start with /api +- **Endpoint requirement**: All requests must target endpoints that start with /api/ - **Authentication**: Handled automatically \- no need to manage auth tokens - **No external domains**: Cannot make requests to external domains from client-side code client/index.ts @@ -84,7 +84,7 @@ Client-side fetch has different restrictions: ``` const handleFetchData = async () => { - // Correct: fetching your own webview's API endpoint + // ✅ Correct: Fetching your own webview's API endpoint const response = await fetch("/api/user-data", { method: "GET", headers: { @@ -96,10 +96,10 @@ const handleFetchData = async () => { console.log("API response:", data); }; -// Incorrect: cannot fetch external domains from client-side +// ❌ Incorrect: Cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: endpoint must start with /api +// ❌ Incorrect: Endpoint must start with /api/ // const response = await fetch('/user-data'); ``` diff --git a/versioned_docs/version-0.13/capabilities/server/http-fetch.mdx b/versioned_docs/version-0.13/capabilities/server/http-fetch.mdx index 1d3b25d9..769617ee 100644 --- a/versioned_docs/version-0.13/capabilities/server/http-fetch.mdx +++ b/versioned_docs/version-0.13/capabilities/server/http-fetch.mdx @@ -80,7 +80,7 @@ Do not treat `/api/` endpoints as private. Any user who can load your app will b ```tsx title="client/index.ts" const handleFetchData = async () => { - // Correct: fetching your own webview's API endpoint + // ✅ Correct: Fetching your own webview's API endpoint const response = await fetch("/api/user-data", { method: "GET", headers: { @@ -92,10 +92,10 @@ const handleFetchData = async () => { console.log("API response:", data); }; -// Incorrect: cannot fetch external domains from client-side +// ❌ Incorrect: Cannot fetch external domains from client-side // const response = await fetch('https://external-api.com/data'); -// Incorrect: client fetch endpoint must start with /api/ +// ❌ Incorrect: Endpoint must start with /api/ // const response = await fetch('/user-data'); ```