From 844c2a26bc3528e9a2f6601fa6e2ca0c050f987f Mon Sep 17 00:00:00 2001 From: SukkaW Date: Wed, 13 Mar 2024 13:30:16 +0800 Subject: [PATCH 01/10] chore: specify yarn 1 in package.json --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b31d6a901a05..c92e0a08459d 100644 --- a/package.json +++ b/package.json @@ -63,5 +63,6 @@ }, "resolutions": { "lint-staged/yaml": "^2.2.2" - } -} \ No newline at end of file + }, + "packageManager": "yarn@1.22.19" +} From 9a8497299d11706f096a4fc10ff0ab5af43465c7 Mon Sep 17 00:00:00 2001 From: Fred Date: Wed, 13 Mar 2024 23:58:28 +0800 Subject: [PATCH 02/10] fix: adjust upstash api --- app/api/upstash/[action]/[...key]/route.ts | 72 ++++++++++++++++++++++ app/utils/cloud/upstash.ts | 14 +++-- 2 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 app/api/upstash/[action]/[...key]/route.ts diff --git a/app/api/upstash/[action]/[...key]/route.ts b/app/api/upstash/[action]/[...key]/route.ts new file mode 100644 index 000000000000..bcbdeef9df80 --- /dev/null +++ b/app/api/upstash/[action]/[...key]/route.ts @@ -0,0 +1,72 @@ +import { NextRequest, NextResponse } from "next/server"; + +async function handle( + req: NextRequest, + { params }: { params: { action: string; key: string[] } }, +) { + const requestUrl = new URL(req.url); + const endpoint = requestUrl.searchParams.get("endpoint"); + + if (req.method === "OPTIONS") { + return NextResponse.json({ body: "OK" }, { status: 200 }); + } + const [action, ...key] = params.key; + // only allow to request to *.upstash.io + if (!endpoint || !endpoint.endsWith("upstash.io")) { + return NextResponse.json( + { + error: true, + msg: "you are not allowed to request " + params.key.join("/"), + }, + { + status: 403, + }, + ); + } + + // only allow upstash get and set method + if (action !== "get" && action !== "set") { + return NextResponse.json( + { + error: true, + msg: "you are not allowed to request " + params.action, + }, + { + status: 403, + }, + ); + } + + const [protocol, ...subpath] = params.key; + const targetUrl = `${protocol}://${subpath.join("/")}`; + + const method = req.headers.get("method") ?? undefined; + const shouldNotHaveBody = ["get", "head"].includes( + method?.toLowerCase() ?? "", + ); + + const fetchOptions: RequestInit = { + headers: { + authorization: req.headers.get("authorization") ?? "", + }, + body: shouldNotHaveBody ? null : req.body, + method, + // @ts-ignore + duplex: "half", + }; + + const fetchResult = await fetch(targetUrl, fetchOptions); + + console.log("[Any Proxy]", targetUrl, { + status: fetchResult.status, + statusText: fetchResult.statusText, + }); + + return fetchResult; +} + +export const POST = handle; +export const GET = handle; +export const OPTIONS = handle; + +export const runtime = "edge"; diff --git a/app/utils/cloud/upstash.ts b/app/utils/cloud/upstash.ts index 5f5b9fc79254..1739b5a055be 100644 --- a/app/utils/cloud/upstash.ts +++ b/app/utils/cloud/upstash.ts @@ -85,17 +85,21 @@ export function createUpstashClient(store: SyncStore) { }; }, path(path: string) { - let url = config.endpoint; + // let url = config.endpoint; - if (!url.endsWith("/")) { - url += "/"; + if (!path.endsWith("/")) { + path += "/"; } - if (path.startsWith("/")) { path = path.slice(1); } - return url + path; + let url = new URL("/api/" + path); + + // add query params + url.searchParams.append("endpoint", config.endpoint); + + return url.toString(); }, }; } From 038fa3b301794050ec7e59325aa00f25b3ce3257 Mon Sep 17 00:00:00 2001 From: Fred Date: Thu, 14 Mar 2024 00:33:26 +0800 Subject: [PATCH 03/10] fix: add webdav request filter --- app/api/webdav/[...path]/route.ts | 103 ++++++++++++++++++++++++++++++ app/utils/cloud/upstash.ts | 2 +- app/utils/cloud/webdav.ts | 12 ++-- 3 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 app/api/webdav/[...path]/route.ts diff --git a/app/api/webdav/[...path]/route.ts b/app/api/webdav/[...path]/route.ts new file mode 100644 index 000000000000..1ddd37761b95 --- /dev/null +++ b/app/api/webdav/[...path]/route.ts @@ -0,0 +1,103 @@ +import { NextRequest, NextResponse } from "next/server"; +import { STORAGE_KEY } from "../../../constant"; +async function handle( + req: NextRequest, + { params }: { params: { path: string[] } }, +) { + if (req.method === "OPTIONS") { + return NextResponse.json({ body: "OK" }, { status: 200 }); + } + const folder = STORAGE_KEY; + const fileName = `${folder}/backup.json`; + + const requestUrl = new URL(req.url); + const endpoint = requestUrl.searchParams.get("endpoint"); + + const [protocol, ...subpath] = params.path; + + const endpointPath = subpath.join("/"); + + // only allow MKCOL, GET, PUT + if (req.method !== "MKCOL" && req.method !== "GET" && req.method !== "PUT") { + return NextResponse.json( + { + error: true, + msg: "you are not allowed to request " + params.path.join("/"), + }, + { + status: 403, + }, + ); + } + + // for MKCOL request, only allow request ${folder} + if (req.method == "MKCOL" && !endpointPath.endsWith(folder)) { + return NextResponse.json( + { + error: true, + msg: "you are not allowed to request " + params.path.join("/"), + }, + { + status: 403, + }, + ); + } + + // for GET request, only allow request ending with fileName + if (req.method == "GET" && !endpointPath.endsWith(fileName)) { + return NextResponse.json( + { + error: true, + msg: "you are not allowed to request " + params.path.join("/"), + }, + { + status: 403, + }, + ); + } + + // for PUT request, only allow request ending with fileName + if (req.method == "PUT" && !endpointPath.endsWith(fileName)) { + return NextResponse.json( + { + error: true, + msg: "you are not allowed to request " + params.path.join("/"), + }, + { + status: 403, + }, + ); + } + + const targetUrl = `${protocol}://${endpoint + endpointPath}`; + + const method = req.headers.get("method") ?? undefined; + const shouldNotHaveBody = ["get", "head"].includes( + method?.toLowerCase() ?? "", + ); + + const fetchOptions: RequestInit = { + headers: { + authorization: req.headers.get("authorization") ?? "", + }, + body: shouldNotHaveBody ? null : req.body, + method, + // @ts-ignore + duplex: "half", + }; + + const fetchResult = await fetch(targetUrl, fetchOptions); + + console.log("[Any Proxy]", targetUrl, { + status: fetchResult.status, + statusText: fetchResult.statusText, + }); + + return fetchResult; +} + +export const POST = handle; +export const GET = handle; +export const OPTIONS = handle; + +export const runtime = "edge"; diff --git a/app/utils/cloud/upstash.ts b/app/utils/cloud/upstash.ts index 1739b5a055be..02af7663302b 100644 --- a/app/utils/cloud/upstash.ts +++ b/app/utils/cloud/upstash.ts @@ -94,7 +94,7 @@ export function createUpstashClient(store: SyncStore) { path = path.slice(1); } - let url = new URL("/api/" + path); + let url = new URL("/api/upstash/" + path); // add query params url.searchParams.append("endpoint", config.endpoint); diff --git a/app/utils/cloud/webdav.ts b/app/utils/cloud/webdav.ts index 3a1553c10357..9efa80c690f7 100644 --- a/app/utils/cloud/webdav.ts +++ b/app/utils/cloud/webdav.ts @@ -60,16 +60,18 @@ export function createWebDavClient(store: SyncStore) { }; }, path(path: string) { - let url = config.endpoint; - - if (!url.endsWith("/")) { - url += "/"; + if (!path.endsWith("/")) { + path += "/"; } - if (path.startsWith("/")) { path = path.slice(1); } + let url = new URL("/api/webdav/" + path); + + // add query params + url.searchParams.append("endpoint", config.endpoint); + return url + path; }, }; From eebc334e02e9f5d9f83203c97fbf4622a9141d0a Mon Sep 17 00:00:00 2001 From: Fred Date: Thu, 14 Mar 2024 00:57:54 +0800 Subject: [PATCH 04/10] fix: remove corsFetch --- app/api/cors/[...path]/route.ts | 43 --------------------------------- app/utils/cloud/upstash.ts | 18 +++++++------- app/utils/cloud/webdav.ts | 17 +++++++------ app/utils/cors.ts | 34 -------------------------- 4 files changed, 18 insertions(+), 94 deletions(-) delete mode 100644 app/api/cors/[...path]/route.ts diff --git a/app/api/cors/[...path]/route.ts b/app/api/cors/[...path]/route.ts deleted file mode 100644 index 1f70d6630823..000000000000 --- a/app/api/cors/[...path]/route.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NextRequest, NextResponse } from "next/server"; - -async function handle( - req: NextRequest, - { params }: { params: { path: string[] } }, -) { - if (req.method === "OPTIONS") { - return NextResponse.json({ body: "OK" }, { status: 200 }); - } - - const [protocol, ...subpath] = params.path; - const targetUrl = `${protocol}://${subpath.join("/")}`; - - const method = req.headers.get("method") ?? undefined; - const shouldNotHaveBody = ["get", "head"].includes( - method?.toLowerCase() ?? "", - ); - - const fetchOptions: RequestInit = { - headers: { - authorization: req.headers.get("authorization") ?? "", - }, - body: shouldNotHaveBody ? null : req.body, - method, - // @ts-ignore - duplex: "half", - }; - - const fetchResult = await fetch(targetUrl, fetchOptions); - - console.log("[Any Proxy]", targetUrl, { - status: fetchResult.status, - statusText: fetchResult.statusText, - }); - - return fetchResult; -} - -export const POST = handle; -export const GET = handle; -export const OPTIONS = handle; - -export const runtime = "edge"; diff --git a/app/utils/cloud/upstash.ts b/app/utils/cloud/upstash.ts index 02af7663302b..831aa8902286 100644 --- a/app/utils/cloud/upstash.ts +++ b/app/utils/cloud/upstash.ts @@ -1,6 +1,5 @@ import { STORAGE_KEY } from "@/app/constant"; import { SyncStore } from "@/app/store/sync"; -import { corsFetch } from "../cors"; import { chunks } from "../format"; export type UpstashConfig = SyncStore["upstash"]; @@ -18,10 +17,9 @@ export function createUpstashClient(store: SyncStore) { return { async check() { try { - const res = await corsFetch(this.path(`get/${storeKey}`), { + const res = await fetch(this.path(`get/${storeKey}`, proxyUrl), { method: "GET", headers: this.headers(), - proxyUrl, }); console.log("[Upstash] check", res.status, res.statusText); return [200].includes(res.status); @@ -32,10 +30,9 @@ export function createUpstashClient(store: SyncStore) { }, async redisGet(key: string) { - const res = await corsFetch(this.path(`get/${key}`), { + const res = await fetch(this.path(`get/${key}`, proxyUrl), { method: "GET", headers: this.headers(), - proxyUrl, }); console.log("[Upstash] get key = ", key, res.status, res.statusText); @@ -45,11 +42,10 @@ export function createUpstashClient(store: SyncStore) { }, async redisSet(key: string, value: string) { - const res = await corsFetch(this.path(`set/${key}`), { + const res = await fetch(this.path(`set/${key}`, proxyUrl), { method: "POST", headers: this.headers(), body: value, - proxyUrl, }); console.log("[Upstash] set key = ", key, res.status, res.statusText); @@ -84,7 +80,7 @@ export function createUpstashClient(store: SyncStore) { Authorization: `Bearer ${config.apiKey}`, }; }, - path(path: string) { + path(path: string, proxyUrl: string = "") { // let url = config.endpoint; if (!path.endsWith("/")) { @@ -94,7 +90,11 @@ export function createUpstashClient(store: SyncStore) { path = path.slice(1); } - let url = new URL("/api/upstash/" + path); + if (proxyUrl.length > 0 && !proxyUrl.endsWith("/")) { + proxyUrl += "/"; + } + + let url = new URL(proxyUrl + "/api/upstash/" + path); // add query params url.searchParams.append("endpoint", config.endpoint); diff --git a/app/utils/cloud/webdav.ts b/app/utils/cloud/webdav.ts index 9efa80c690f7..6874302b8125 100644 --- a/app/utils/cloud/webdav.ts +++ b/app/utils/cloud/webdav.ts @@ -15,10 +15,9 @@ export function createWebDavClient(store: SyncStore) { return { async check() { try { - const res = await corsFetch(this.path(folder), { + const res = await fetch(this.path(folder, proxyUrl), { method: "MKCOL", headers: this.headers(), - proxyUrl, }); console.log("[WebDav] check", res.status, res.statusText); return [201, 200, 404, 301, 302, 307, 308].includes(res.status); @@ -30,10 +29,9 @@ export function createWebDavClient(store: SyncStore) { }, async get(key: string) { - const res = await corsFetch(this.path(fileName), { + const res = await fetch(this.path(fileName, proxyUrl), { method: "GET", headers: this.headers(), - proxyUrl, }); console.log("[WebDav] get key = ", key, res.status, res.statusText); @@ -42,11 +40,10 @@ export function createWebDavClient(store: SyncStore) { }, async set(key: string, value: string) { - const res = await corsFetch(this.path(fileName), { + const res = await fetch(this.path(fileName, proxyUrl), { method: "PUT", headers: this.headers(), body: value, - proxyUrl, }); console.log("[WebDav] set key = ", key, res.status, res.statusText); @@ -59,7 +56,7 @@ export function createWebDavClient(store: SyncStore) { authorization: `Basic ${auth}`, }; }, - path(path: string) { + path(path: string, proxyUrl: string = "") { if (!path.endsWith("/")) { path += "/"; } @@ -67,7 +64,11 @@ export function createWebDavClient(store: SyncStore) { path = path.slice(1); } - let url = new URL("/api/webdav/" + path); + if (proxyUrl.length > 0 && !proxyUrl.endsWith("/")) { + proxyUrl += "/"; + } + + let url = new URL(proxyUrl + "/api/webdav/" + path); // add query params url.searchParams.append("endpoint", config.endpoint); diff --git a/app/utils/cors.ts b/app/utils/cors.ts index 20b3e5160177..93956a7b5c75 100644 --- a/app/utils/cors.ts +++ b/app/utils/cors.ts @@ -14,37 +14,3 @@ export function corsPath(path: string) { return `${baseUrl}${path}`; } - -export function corsFetch( - url: string, - options: RequestInit & { - proxyUrl?: string; - }, -) { - if (!url.startsWith("http")) { - throw Error("[CORS Fetch] url must starts with http/https"); - } - - let proxyUrl = options.proxyUrl ?? corsPath(ApiPath.Cors); - if (!proxyUrl.endsWith("/")) { - proxyUrl += "/"; - } - - url = url.replace("://", "/"); - - const corsOptions = { - ...options, - method: "POST", - headers: options.method - ? { - ...options.headers, - method: options.method, - } - : options.headers, - }; - - const corsUrl = proxyUrl + url; - console.info("[CORS] target = ", corsUrl); - - return fetch(corsUrl, corsOptions); -} From 86452146540a224a3242238dd07964a26b8df246 Mon Sep 17 00:00:00 2001 From: Fred Date: Thu, 14 Mar 2024 01:22:50 +0800 Subject: [PATCH 05/10] fix: change matching pattern --- app/api/upstash/[action]/[...key]/route.ts | 2 +- app/api/webdav/[...path]/route.ts | 15 ++++++++++++--- app/utils/cloud/webdav.ts | 1 - 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/api/upstash/[action]/[...key]/route.ts b/app/api/upstash/[action]/[...key]/route.ts index bcbdeef9df80..6be243c92e4b 100644 --- a/app/api/upstash/[action]/[...key]/route.ts +++ b/app/api/upstash/[action]/[...key]/route.ts @@ -12,7 +12,7 @@ async function handle( } const [action, ...key] = params.key; // only allow to request to *.upstash.io - if (!endpoint || !endpoint.endsWith("upstash.io")) { + if (!endpoint || !new URL(endpoint).hostname.endsWith(".upstash.io")) { return NextResponse.json( { error: true, diff --git a/app/api/webdav/[...path]/route.ts b/app/api/webdav/[...path]/route.ts index 1ddd37761b95..cade9ab51069 100644 --- a/app/api/webdav/[...path]/route.ts +++ b/app/api/webdav/[...path]/route.ts @@ -31,7 +31,10 @@ async function handle( } // for MKCOL request, only allow request ${folder} - if (req.method == "MKCOL" && !endpointPath.endsWith(folder)) { + if ( + req.method == "MKCOL" && + !new URL(endpointPath).pathname.endsWith(folder) + ) { return NextResponse.json( { error: true, @@ -44,7 +47,10 @@ async function handle( } // for GET request, only allow request ending with fileName - if (req.method == "GET" && !endpointPath.endsWith(fileName)) { + if ( + req.method == "GET" && + !new URL(endpointPath).pathname.endsWith(fileName) + ) { return NextResponse.json( { error: true, @@ -57,7 +63,10 @@ async function handle( } // for PUT request, only allow request ending with fileName - if (req.method == "PUT" && !endpointPath.endsWith(fileName)) { + if ( + req.method == "PUT" && + !new URL(endpointPath).pathname.endsWith(fileName) + ) { return NextResponse.json( { error: true, diff --git a/app/utils/cloud/webdav.ts b/app/utils/cloud/webdav.ts index 6874302b8125..79fff9472bb4 100644 --- a/app/utils/cloud/webdav.ts +++ b/app/utils/cloud/webdav.ts @@ -1,6 +1,5 @@ import { STORAGE_KEY } from "@/app/constant"; import { SyncStore } from "@/app/store/sync"; -import { corsFetch } from "../cors"; export type WebDAVConfig = SyncStore["webdav"]; export type WebDavClient = ReturnType; From 133ce39a13cb90733bc0aac220ea179e34fd4430 Mon Sep 17 00:00:00 2001 From: Fred Date: Thu, 14 Mar 2024 01:33:41 +0800 Subject: [PATCH 06/10] chore: update cors default path --- app/constant.ts | 2 +- app/utils/cloud/upstash.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/constant.ts b/app/constant.ts index c1f91d31c880..9041706874fe 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -23,7 +23,7 @@ export enum Path { } export enum ApiPath { - Cors = "/api/cors", + Cors = "", OpenAI = "/api/openai", } diff --git a/app/utils/cloud/upstash.ts b/app/utils/cloud/upstash.ts index 831aa8902286..f5579cea0547 100644 --- a/app/utils/cloud/upstash.ts +++ b/app/utils/cloud/upstash.ts @@ -81,8 +81,6 @@ export function createUpstashClient(store: SyncStore) { }; }, path(path: string, proxyUrl: string = "") { - // let url = config.endpoint; - if (!path.endsWith("/")) { path += "/"; } From 6aaf83f3c211b3efea63d20f39a58f0c1ab6fa17 Mon Sep 17 00:00:00 2001 From: Fred Date: Thu, 14 Mar 2024 01:56:36 +0800 Subject: [PATCH 07/10] fix: fix upstash sync issue --- app/api/upstash/[action]/[...key]/route.ts | 11 ++++++----- app/api/webdav/[...path]/route.ts | 2 +- app/utils/cloud/upstash.ts | 16 ++++++++++------ app/utils/cloud/webdav.ts | 16 ++++++++++------ 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/app/api/upstash/[action]/[...key]/route.ts b/app/api/upstash/[action]/[...key]/route.ts index 6be243c92e4b..fcfef471862c 100644 --- a/app/api/upstash/[action]/[...key]/route.ts +++ b/app/api/upstash/[action]/[...key]/route.ts @@ -10,7 +10,7 @@ async function handle( if (req.method === "OPTIONS") { return NextResponse.json({ body: "OK" }, { status: 200 }); } - const [action, ...key] = params.key; + const [...key] = params.key; // only allow to request to *.upstash.io if (!endpoint || !new URL(endpoint).hostname.endsWith(".upstash.io")) { return NextResponse.json( @@ -25,7 +25,8 @@ async function handle( } // only allow upstash get and set method - if (action !== "get" && action !== "set") { + if (params.action !== "get" && params.action !== "set") { + console.log("[Upstash Route] forbidden action ", params.action); return NextResponse.json( { error: true, @@ -37,10 +38,9 @@ async function handle( ); } - const [protocol, ...subpath] = params.key; - const targetUrl = `${protocol}://${subpath.join("/")}`; + const targetUrl = `${endpoint}/${params.action}/${params.key.join("/")}`; - const method = req.headers.get("method") ?? undefined; + const method = req.method; const shouldNotHaveBody = ["get", "head"].includes( method?.toLowerCase() ?? "", ); @@ -55,6 +55,7 @@ async function handle( duplex: "half", }; + console.log("[Upstash Proxy]", targetUrl, fetchOptions); const fetchResult = await fetch(targetUrl, fetchOptions); console.log("[Any Proxy]", targetUrl, { diff --git a/app/api/webdav/[...path]/route.ts b/app/api/webdav/[...path]/route.ts index cade9ab51069..826e2df01602 100644 --- a/app/api/webdav/[...path]/route.ts +++ b/app/api/webdav/[...path]/route.ts @@ -80,7 +80,7 @@ async function handle( const targetUrl = `${protocol}://${endpoint + endpointPath}`; - const method = req.headers.get("method") ?? undefined; + const method = req.method; const shouldNotHaveBody = ["get", "head"].includes( method?.toLowerCase() ?? "", ); diff --git a/app/utils/cloud/upstash.ts b/app/utils/cloud/upstash.ts index f5579cea0547..bf6147bd4672 100644 --- a/app/utils/cloud/upstash.ts +++ b/app/utils/cloud/upstash.ts @@ -92,12 +92,16 @@ export function createUpstashClient(store: SyncStore) { proxyUrl += "/"; } - let url = new URL(proxyUrl + "/api/upstash/" + path); - - // add query params - url.searchParams.append("endpoint", config.endpoint); - - return url.toString(); + let url; + if (proxyUrl.length > 0 || proxyUrl === "/") { + let u = new URL(proxyUrl + "/api/upstash/" + path); + // add query params + u.searchParams.append("endpoint", config.endpoint); + url = u.toString(); + } else { + url = "/api/upstash/" + path + "?endpoint=" + config.endpoint; + } + return url; }, }; } diff --git a/app/utils/cloud/webdav.ts b/app/utils/cloud/webdav.ts index 79fff9472bb4..bc569de0ec41 100644 --- a/app/utils/cloud/webdav.ts +++ b/app/utils/cloud/webdav.ts @@ -67,12 +67,16 @@ export function createWebDavClient(store: SyncStore) { proxyUrl += "/"; } - let url = new URL(proxyUrl + "/api/webdav/" + path); - - // add query params - url.searchParams.append("endpoint", config.endpoint); - - return url + path; + let url; + if (proxyUrl.length > 0 || proxyUrl === "/") { + let u = new URL(proxyUrl + "/api/webdav/" + path); + // add query params + u.searchParams.append("endpoint", config.endpoint); + url = u.toString(); + } else { + url = "/api/upstash/" + path + "?endpoint=" + config.endpoint; + } + return url; }, }; } From 99aa064319991b6ee53eb9c75bcfeb5a6b0188cb Mon Sep 17 00:00:00 2001 From: Fred Date: Thu, 14 Mar 2024 01:58:25 +0800 Subject: [PATCH 08/10] fix: fix webdav sync issue --- app/api/webdav/[...path]/route.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/api/webdav/[...path]/route.ts b/app/api/webdav/[...path]/route.ts index 826e2df01602..c60ca18bb397 100644 --- a/app/api/webdav/[...path]/route.ts +++ b/app/api/webdav/[...path]/route.ts @@ -11,11 +11,11 @@ async function handle( const fileName = `${folder}/backup.json`; const requestUrl = new URL(req.url); - const endpoint = requestUrl.searchParams.get("endpoint"); - - const [protocol, ...subpath] = params.path; - - const endpointPath = subpath.join("/"); + let endpoint = requestUrl.searchParams.get("endpoint"); + if (!endpoint?.endsWith("/")) { + endpoint += "/"; + } + const endpointPath = params.path.join("/"); // only allow MKCOL, GET, PUT if (req.method !== "MKCOL" && req.method !== "GET" && req.method !== "PUT") { @@ -78,7 +78,7 @@ async function handle( ); } - const targetUrl = `${protocol}://${endpoint + endpointPath}`; + const targetUrl = `${endpoint + endpointPath}`; const method = req.method; const shouldNotHaveBody = ["get", "head"].includes( From aec3c5d6cc598282e1f35b9e1de5081190a9c378 Mon Sep 17 00:00:00 2001 From: Fred Date: Thu, 14 Mar 2024 02:29:31 +0800 Subject: [PATCH 09/10] feat: bump version --- src-tauri/tauri.conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 405d267ff654..f03efb0fe49d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -9,7 +9,7 @@ }, "package": { "productName": "NextChat", - "version": "2.11.2" + "version": "2.11.3" }, "tauri": { "allowlist": { From 066ca9e552f5f455bb9456994361c6ac9e08297c Mon Sep 17 00:00:00 2001 From: Fred Date: Thu, 14 Mar 2024 03:03:46 +0800 Subject: [PATCH 10/10] fix: auto migrate proxy config --- app/store/sync.ts | 11 ++++++++++- app/utils/cors.ts | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/store/sync.ts b/app/store/sync.ts index 5ff1cc6e56cc..674ff6744208 100644 --- a/app/store/sync.ts +++ b/app/store/sync.ts @@ -118,7 +118,7 @@ export const useSyncStore = createPersistStore( }), { name: StoreKey.Sync, - version: 1.1, + version: 1.2, migrate(persistedState, version) { const newState = persistedState as typeof DEFAULT_SYNC_STATE; @@ -127,6 +127,15 @@ export const useSyncStore = createPersistStore( newState.upstash.username = STORAGE_KEY; } + if (version < 1.2) { + if ( + (persistedState as typeof DEFAULT_SYNC_STATE).proxyUrl === + "/api/cors/" + ) { + newState.proxyUrl = ""; + } + } + return newState as any; }, }, diff --git a/app/utils/cors.ts b/app/utils/cors.ts index 93956a7b5c75..fa348f9bf5da 100644 --- a/app/utils/cors.ts +++ b/app/utils/cors.ts @@ -4,6 +4,9 @@ import { ApiPath, DEFAULT_API_HOST } from "../constant"; export function corsPath(path: string) { const baseUrl = getClientConfig()?.isApp ? `${DEFAULT_API_HOST}` : ""; + if (baseUrl === "" && path === "") { + return ""; + } if (!path.startsWith("/")) { path = "/" + path; }