diff --git a/app/api/upstash/[action]/[...key]/route.ts b/app/api/upstash/[action]/[...key]/route.ts new file mode 100644 index 000000000..bcbdeef9d --- /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 5f5b9fc79..1739b5a05 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(); }, }; }