|
|
@@ -1,5 +1,14 @@
|
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
|
-import { STORAGE_KEY } from "../../../constant";
|
|
|
+import { STORAGE_KEY, internalWhiteWebDavDomains } from "../../../constant";
|
|
|
+import { getServerSideConfig } from "@/app/config/server";
|
|
|
+
|
|
|
+const config = getServerSideConfig();
|
|
|
+
|
|
|
+const mergedWhiteWebDavDomains = [
|
|
|
+ ...internalWhiteWebDavDomains,
|
|
|
+ ...config.whiteWebDevDomains,
|
|
|
+].filter((domain) => Boolean(domain.trim()));
|
|
|
+
|
|
|
async function handle(
|
|
|
req: NextRequest,
|
|
|
{ params }: { params: { path: string[] } },
|
|
|
@@ -14,7 +23,9 @@ async function handle(
|
|
|
let endpoint = requestUrl.searchParams.get("endpoint");
|
|
|
|
|
|
// Validate the endpoint to prevent potential SSRF attacks
|
|
|
- if (!endpoint || !endpoint.startsWith("/")) {
|
|
|
+ if (
|
|
|
+ !mergedWhiteWebDavDomains.some((domain) => endpoint?.startsWith(domain))
|
|
|
+ ) {
|
|
|
return NextResponse.json(
|
|
|
{
|
|
|
error: true,
|
|
|
@@ -25,6 +36,11 @@ async function handle(
|
|
|
},
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ if (!endpoint?.endsWith("/")) {
|
|
|
+ endpoint += "/";
|
|
|
+ }
|
|
|
+
|
|
|
const endpointPath = params.path.join("/");
|
|
|
const targetPath = `${endpoint}/${endpointPath}`;
|
|
|
|
|
|
@@ -42,10 +58,7 @@ async function handle(
|
|
|
}
|
|
|
|
|
|
// for MKCOL request, only allow request ${folder}
|
|
|
- if (
|
|
|
- req.method === "MKCOL" &&
|
|
|
- !targetPath.endsWith(folder)
|
|
|
- ) {
|
|
|
+ if (req.method === "MKCOL" && !targetPath.endsWith(folder)) {
|
|
|
return NextResponse.json(
|
|
|
{
|
|
|
error: true,
|
|
|
@@ -58,10 +71,7 @@ async function handle(
|
|
|
}
|
|
|
|
|
|
// for GET request, only allow request ending with fileName
|
|
|
- if (
|
|
|
- req.method === "GET" &&
|
|
|
- !targetPath.endsWith(fileName)
|
|
|
- ) {
|
|
|
+ if (req.method === "GET" && !targetPath.endsWith(fileName)) {
|
|
|
return NextResponse.json(
|
|
|
{
|
|
|
error: true,
|
|
|
@@ -74,10 +84,7 @@ async function handle(
|
|
|
}
|
|
|
|
|
|
// for PUT request, only allow request ending with fileName
|
|
|
- if (
|
|
|
- req.method === "PUT" &&
|
|
|
- !targetPath.endsWith(fileName)
|
|
|
- ) {
|
|
|
+ if (req.method === "PUT" && !targetPath.endsWith(fileName)) {
|
|
|
return NextResponse.json(
|
|
|
{
|
|
|
error: true,
|
|
|
@@ -101,7 +108,7 @@ async function handle(
|
|
|
authorization: req.headers.get("authorization") ?? "",
|
|
|
},
|
|
|
body: shouldNotHaveBody ? null : req.body,
|
|
|
- redirect: 'manual',
|
|
|
+ redirect: "manual",
|
|
|
method,
|
|
|
// @ts-ignore
|
|
|
duplex: "half",
|
|
|
@@ -109,15 +116,20 @@ async function handle(
|
|
|
|
|
|
const fetchResult = await fetch(targetUrl, fetchOptions);
|
|
|
|
|
|
- console.log("[Any Proxy]", targetUrl, {
|
|
|
- status: fetchResult.status,
|
|
|
- statusText: fetchResult.statusText,
|
|
|
- });
|
|
|
+ console.log(
|
|
|
+ "[Any Proxy]",
|
|
|
+ targetUrl,
|
|
|
+ {
|
|
|
+ status: fetchResult.status,
|
|
|
+ statusText: fetchResult.statusText,
|
|
|
+ },
|
|
|
+ fetchResult,
|
|
|
+ );
|
|
|
|
|
|
return fetchResult;
|
|
|
}
|
|
|
|
|
|
-export const POST = handle;
|
|
|
+export const PUT = handle;
|
|
|
export const GET = handle;
|
|
|
export const OPTIONS = handle;
|
|
|
|