Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shiwoslj patch 1 #5905

Closed
wants to merge 109 commits into from
Closed
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
66e42a0
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Mar 27, 2024
08c2c43
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Mar 28, 2024
6b8230a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Mar 29, 2024
f01685d
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 5, 2024
a901d33
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 9, 2024
05a125b
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 10, 2024
3d610ce
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 11, 2024
46136a9
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 12, 2024
cb7f6fe
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 13, 2024
7c1dc9b
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 15, 2024
abba5c8
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 16, 2024
564fcdc
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 17, 2024
a2083ca
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Apr 26, 2024
1e1c1f3
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 1, 2024
3bac81f
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 7, 2024
460d6af
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 8, 2024
5b2c860
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 14, 2024
7930996
Merge branch 'ChatGPTNextWeb:main' into main
shiwoslj May 14, 2024
5af5aa5
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 16, 2024
215fb94
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 17, 2024
8625d8a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 21, 2024
9cca606
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 23, 2024
1314113
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user May 28, 2024
946b1dd
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jun 8, 2024
a97676a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jun 25, 2024
7035242
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jun 27, 2024
a3964dc
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 2, 2024
471762f
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 4, 2024
e203113
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 5, 2024
f4f4b2a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 6, 2024
8bc3b37
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 7, 2024
a0199a9
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 10, 2024
121e351
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 11, 2024
6d2d0a7
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 12, 2024
9457855
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 13, 2024
dd0d4d1
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 14, 2024
cfd248a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 16, 2024
99cfa5f
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 17, 2024
3357911
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 18, 2024
b6f2223
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 19, 2024
f2ea00a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 20, 2024
733c80c
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 21, 2024
9920834
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 23, 2024
05ddc4a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 26, 2024
41add66
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 27, 2024
9fab531
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 30, 2024
7ac2f69
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Jul 31, 2024
10b5637
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 2, 2024
385db10
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 3, 2024
c576c18
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 4, 2024
1b5d345
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 6, 2024
06444ac
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 7, 2024
25a073e
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 8, 2024
241f5af
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 9, 2024
bd6be12
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 14, 2024
37fe9d6
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 16, 2024
3838c29
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 17, 2024
23a2c67
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 20, 2024
7e623e8
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 21, 2024
a637926
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 22, 2024
5faf537
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 25, 2024
7f3ccf8
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 28, 2024
a50a4fd
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Aug 30, 2024
e4e34c0
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 5, 2024
4f99f4a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 7, 2024
2a81b64
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 8, 2024
dd88585
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 9, 2024
5cc5f16
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 10, 2024
059d4e1
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 13, 2024
c9c2918
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 14, 2024
6d65bda
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 15, 2024
919fdca
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 16, 2024
8813743
Merge branch 'ChatGPTNextWeb:main' into main
shiwoslj Sep 22, 2024
9403aac
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 23, 2024
07846e9
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 24, 2024
ca77458
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Sep 25, 2024
05a96d0
Merge branch 'ChatGPTNextWeb:main' into main
shiwoslj Sep 29, 2024
33942d3
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 1, 2024
09f6a6f
Merge branch 'ChatGPTNextWeb:main' into main
shiwoslj Oct 3, 2024
98d75da
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 7, 2024
f73f66a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 9, 2024
a8ac114
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 10, 2024
e2b3a4d
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 11, 2024
49d1279
Merge branch 'ChatGPTNextWeb:main' into main
shiwoslj Oct 12, 2024
2a5f3e7
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 13, 2024
fe0ba31
Merge branch 'ChatGPTNextWeb:main' into main
shiwoslj Oct 20, 2024
b988711
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 24, 2024
68ffd1f
Merge branch 'ChatGPTNextWeb:main' into main
shiwoslj Oct 24, 2024
1b9bf62
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 26, 2024
4c378ec
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 27, 2024
50fcd3a
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 29, 2024
4efd103
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 30, 2024
8ba2140
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Oct 31, 2024
aaecb12
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 1, 2024
d9cd0bb
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 2, 2024
0842fe3
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 5, 2024
671f6b4
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 6, 2024
add661c
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 7, 2024
4dd92be
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 8, 2024
03ec6bc
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 12, 2024
e6222f2
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 13, 2024
1f1289e
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 14, 2024
eac6dab
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 16, 2024
b4866a5
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 17, 2024
98020c7
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 23, 2024
0c94ab9
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 26, 2024
d1e42f7
Merge branch 'main' of https://github.com/ChatGPTNextWeb/ChatGPT-Next…
actions-user Nov 29, 2024
faeba81
route.ts
shiwoslj Dec 6, 2024
28a4706
Update route.ts
shiwoslj Dec 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
326 changes: 173 additions & 153 deletions app/api/webdav/[...path]/route.ts
Original file line number Diff line number Diff line change
@@ -1,167 +1,187 @@
import { NextRequest, NextResponse } from "next/server";
import { STORAGE_KEY, internalAllowedWebDavEndpoints } from "../../../constant";
import { getServerSideConfig } from "@/app/config/server";

const config = getServerSideConfig();

const mergedAllowedWebDavEndpoints = [
...internalAllowedWebDavEndpoints,
...config.allowedWebDavEndpoints,
].filter((domain) => Boolean(domain.trim()));

const normalizeUrl = (url: string) => {
try {
return new URL(url);
} catch (err) {
return null;
}
// 配置常量
const ALLOWED_METHODS = ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PROPFIND", "MKCOL"];
const ALLOWED_HEADERS = [
"authorization",
"content-type",
"accept",
"depth",
"destination",
"overwrite",
"content-length"
];
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": ALLOWED_METHODS.join(","),
"Access-Control-Allow-Headers": ALLOWED_HEADERS.join(", "),
"Access-Control-Max-Age": "86400",
Comment on lines +14 to +18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Restrict CORS configuration for production environments

The current CORS configuration allows requests from any origin ("*"), which could expose your WebDAV endpoint to unauthorized access.

Consider implementing environment-specific CORS:

 const CORS_HEADERS = {
-  "Access-Control-Allow-Origin": "*",
+  "Access-Control-Allow-Origin": process.env.ALLOWED_ORIGINS || "*",
   "Access-Control-Allow-Methods": ALLOWED_METHODS.join(","),
   "Access-Control-Allow-Headers": ALLOWED_HEADERS.join(", "),
   "Access-Control-Max-Age": "86400",
 };

Committable suggestion skipped: line range outside the PR's diff.

};
const TIMEOUT = 30000; // 30 seconds

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);
let endpoint = requestUrl.searchParams.get("endpoint");
let proxy_method = requestUrl.searchParams.get("proxy_method") || req.method;

// Validate the endpoint to prevent potential SSRF attacks
if (
!endpoint ||
!mergedAllowedWebDavEndpoints.some((allowedEndpoint) => {
const normalizedAllowedEndpoint = normalizeUrl(allowedEndpoint);
const normalizedEndpoint = normalizeUrl(endpoint as string);

return (
normalizedEndpoint &&
normalizedEndpoint.hostname === normalizedAllowedEndpoint?.hostname &&
normalizedEndpoint.pathname.startsWith(
normalizedAllowedEndpoint.pathname,
)
);
})
) {
return NextResponse.json(
{
error: true,
msg: "Invalid endpoint",
},
{
status: 400,
},
);
}
// WebDAV 服务器端点配置
const ENDPOINT = process.env.WEBDAV_ENDPOINT || "http://localhost:8080";

if (!endpoint?.endsWith("/")) {
endpoint += "/";
}

const endpointPath = params.path.join("/");
const targetPath = `${endpoint}${endpointPath}`;

// only allow MKCOL, GET, PUT
if (
proxy_method !== "MKCOL" &&
proxy_method !== "GET" &&
proxy_method !== "PUT"
) {
return NextResponse.json(
{
error: true,
msg: "you are not allowed to request " + targetPath,
},
{
status: 403,
},
);
}

// for MKCOL request, only allow request ${folder}
if (proxy_method === "MKCOL" && !targetPath.endsWith(folder)) {
return NextResponse.json(
{
error: true,
msg: "you are not allowed to request " + targetPath,
},
{
status: 403,
},
);
}
export const runtime = "edge";

// for GET request, only allow request ending with fileName
if (proxy_method === "GET" && !targetPath.endsWith(fileName)) {
return NextResponse.json(
{
error: true,
msg: "you are not allowed to request " + targetPath,
},
{
status: 403,
},
);
}
// 路径拼接函数
function joinPaths(...parts: string[]): string {
return parts
.map(part => part.replace(/^\/+|\/+$/g, ''))
.filter(Boolean)
.join('/');
}
Comment on lines +28 to +33
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add path traversal protection to joinPaths function

The current implementation doesn't prevent directory traversal attacks using ../ sequences.

Add path normalization:

 function joinPaths(...parts: string[]): string {
+  // Normalize and validate path segments
+  const normalizedParts = parts.map(part => {
+    const cleaned = part.replace(/^\/+|\/+$/g, '');
+    if (cleaned.includes('../') || cleaned === '..') {
+      throw new Error('Path traversal not allowed');
+    }
+    return cleaned;
+  });
+
   return parts
-    .map(part => part.replace(/^\/+|\/+$/g, ''))
     .filter(Boolean)
     .join('/');
 }

Committable suggestion skipped: line range outside the PR's diff.


// for PUT request, only allow request ending with fileName
if (proxy_method === "PUT" && !targetPath.endsWith(fileName)) {
return NextResponse.json(
{
error: true,
msg: "you are not allowed to request " + targetPath,
},
{
status: 403,
},
);
// 重试机制
async function makeRequest(url: string, options: RequestInit, retries = 3) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT);

for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(timeoutId);
return response;
} catch (error) {
console.error(`Attempt ${i + 1} failed:`, error);
if (error.name === 'AbortError') {
throw new Error('Request Timeout');
}
if (i === retries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
throw new Error('Max retries reached');
}

const targetUrl = targetPath;

const method = proxy_method || req.method;
const shouldNotHaveBody = ["get", "head"].includes(
method?.toLowerCase() ?? "",
);

const fetchOptions: RequestInit = {
headers: {
authorization: req.headers.get("authorization") ?? "",
},
body: shouldNotHaveBody ? null : req.body,
redirect: "manual",
method,
// @ts-ignore
duplex: "half",
};

let fetchResult;

export async function handler(
req: NextRequest,
{ params }: { params: { path: string[] } }
) {
try {
fetchResult = await fetch(targetUrl, fetchOptions);
} finally {
console.log(
"[Any Proxy]",
targetUrl,
{
method: method,
},
{
status: fetchResult?.status,
statusText: fetchResult?.statusText,
},
const method = req.method;

console.log(`[Proxy Request] ${method} ${req.url}`);
console.log("Request Headers:", Object.fromEntries(req.headers));
Comment on lines +67 to +68
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid logging full request headers to prevent sensitive data exposure

Logging complete request headers may inadvertently expose sensitive information such as authentication tokens or personal data. It's important to sanitize or omit sensitive headers to enhance security.

Apply this diff to sanitize or remove sensitive headers from logs:

     // Log request method and URL
     console.log(`[Proxy Request] ${method} ${req.url}`);
-    console.log("Request Headers:", Object.fromEntries(req.headers));
+    // Optionally, log non-sensitive headers if necessary
+    // const loggedHeaders = { ... };
+    // console.log("Request Headers:", loggedHeaders);

Committable suggestion skipped: line range outside the PR's diff.


if (method === "OPTIONS") {
return new NextResponse(null, {
status: 204,
headers: CORS_HEADERS,
});
}

if (!ALLOWED_METHODS.includes(method)) {
return NextResponse.json(
{ error: "Method Not Allowed" },
{ status: 405, headers: CORS_HEADERS }
);
}

// 构建目标 URL(使用自定义的 joinPaths 函数替代 path.join)
const targetUrlObj = new URL(ENDPOINT);
const pathSegments = params.path || [];
targetUrlObj.pathname = joinPaths(targetUrlObj.pathname, ...pathSegments);
const targetUrl = targetUrlObj.toString();

// 其余代码保持不变...
const headers = new Headers();
req.headers.forEach((value, key) => {
if (ALLOWED_HEADERS.includes(key.toLowerCase())) {
headers.set(key, value);
}
});

const depth = req.headers.get('depth');
if (depth) {
headers.set('depth', depth);
}

const authHeader = req.headers.get('authorization');
if (authHeader) {
headers.set('authorization', authHeader);
}

let requestBody: BodyInit | null = null;
if (["POST", "PUT"].includes(method)) {
try {
const contentLength = req.headers.get('content-length');
if (contentLength && parseInt(contentLength) > 10 * 1024 * 1024) {
requestBody = req.body;
headers.set('transfer-encoding', 'chunked');
} else {
Comment on lines +114 to +115
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid manually setting 'transfer-encoding' header

Manually setting the transfer-encoding header can lead to unexpected behavior, as the underlying fetch implementation manages this automatically when streaming. It's better to let the system handle encoding.

Apply this diff to remove the manual header setting:

           requestBody = req.body;
-          headers.set('transfer-encoding', 'chunked');

Committable suggestion skipped: line range outside the PR's diff.

requestBody = await req.blob();
}
Comment on lines +111 to +117
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve large file handling configuration

The large file threshold is hardcoded and the handling logic could be improved.

Consider these improvements:

+const MAX_MEMORY_FILE_SIZE = 10 * 1024 * 1024; // 10MB
+
 const contentLength = req.headers.get('content-length');
-if (contentLength && parseInt(contentLength) > 10 * 1024 * 1024) {
+const size = contentLength ? parseInt(contentLength) : 0;
+if (size > MAX_MEMORY_FILE_SIZE) {
   requestBody = req.body;
-  headers.set('transfer-encoding', 'chunked');
+  // Let the underlying fetch implementation handle transfer encoding
 } else {
-  requestBody = await req.blob();
+  // For smaller files, use ArrayBuffer for better memory efficiency
+  requestBody = await req.arrayBuffer();
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const contentLength = req.headers.get('content-length');
if (contentLength && parseInt(contentLength) > 10 * 1024 * 1024) {
requestBody = req.body;
headers.set('transfer-encoding', 'chunked');
} else {
requestBody = await req.blob();
}
const MAX_MEMORY_FILE_SIZE = 10 * 1024 * 1024; // 10MB
const contentLength = req.headers.get('content-length');
const size = contentLength ? parseInt(contentLength) : 0;
if (size > MAX_MEMORY_FILE_SIZE) {
requestBody = req.body;
// Let the underlying fetch implementation handle transfer encoding
} else {
// For smaller files, use ArrayBuffer for better memory efficiency
requestBody = await req.arrayBuffer();
}

} catch (error) {
console.error("[Request Body Error]", error);
return NextResponse.json(
{ error: "Invalid Request Body" },
{ status: 400, headers: CORS_HEADERS }
);
}
}
Comment on lines +108 to +125
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add content type validation for uploads

The current implementation doesn't validate content types for uploaded files.

Add content type validation:

 let requestBody: BodyInit | null = null;
 if (["POST", "PUT"].includes(method)) {
   try {
+    const contentType = req.headers.get('content-type');
+    if (contentType) {
+      // Add your allowed content types
+      const allowedTypes = ['application/octet-stream', 'text/plain'];
+      if (!allowedTypes.some(type => contentType.includes(type))) {
+        return NextResponse.json(
+          { error: "Unsupported content type" },
+          { status: 415, headers: CORS_HEADERS }
+        );
+      }
+    }
     const contentLength = req.headers.get('content-length');

Committable suggestion skipped: line range outside the PR's diff.


const fetchOptions: RequestInit = {
method,
headers,
body: requestBody,
redirect: "manual",
cache: 'no-store',
next: {
revalidate: 0
}
};

let response: Response;
try {
console.log(`[Proxy Forward] ${method} ${targetUrl}`);
response = await makeRequest(targetUrl, fetchOptions);
} catch (error) {
console.error("[Proxy Error]", error);
const status = error.message === 'Request Timeout' ? 504 : 500;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use error types instead of messages for error handling logic

Relying on error messages for control flow is fragile and can lead to bugs if messages change. Using custom error classes or properties provides a more reliable way to handle specific errors.

Consider defining a custom error class for timeouts and updating the error handling:

+// Define a custom error class
+class RequestTimeoutError extends Error {
+  constructor(message: string) {
+    super(message);
+    this.name = 'RequestTimeoutError';
+  }
+}

 // In makeRequest function
 if (error.name === 'AbortError') {
-  throw new Error('Request Timeout');
+  throw new RequestTimeoutError('Request Timeout');
 }

 // In the handler function
 try {
   // ...
 } catch (error) {
   console.error("[Proxy Error]", error);
-  const status = error.message === 'Request Timeout' ? 504 : 500;
+  const status = error instanceof RequestTimeoutError ? 504 : 500;
   return NextResponse.json(
     { error: "Internal Server Error" },
     { status, headers: CORS_HEADERS }
   );
 }

Committable suggestion skipped: line range outside the PR's diff.

return NextResponse.json(
{ error: error.message || "Internal Server Error" },
{ status, headers: CORS_HEADERS }
);
Comment on lines +146 to +148
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Prevent exposure of internal error messages in responses

Returning internal error messages to clients can expose sensitive information. It's safer to return a generic error message and log the detailed error server-side.

Apply this diff to use a generic error message:

 return NextResponse.json(
-  { error: error.message || "Internal Server Error" },
+  { error: "Internal Server Error" },
   { status, headers: CORS_HEADERS }
 );

Ensure that detailed errors are logged internally:

 console.error("[Proxy Error]", error);
+// Detailed error logged above
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{ error: error.message || "Internal Server Error" },
{ status, headers: CORS_HEADERS }
);
{ error: "Internal Server Error" },
{ status, headers: CORS_HEADERS }
);

}

const responseHeaders = new Headers(response.headers);
["set-cookie", "server"].forEach((header) => {
responseHeaders.delete(header);
});

Object.entries({
...CORS_HEADERS,
"Content-Security-Policy": "upgrade-insecure-requests",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains"
}).forEach(([key, value]) => {
responseHeaders.set(key, value);
});

console.log(`[Proxy Response] ${response.status} ${response.statusText}`);
console.log("Response Headers:", Object.fromEntries(responseHeaders));
Comment on lines +164 to +165
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid logging full response headers to prevent sensitive data exposure

Logging all response headers could expose sensitive information. It's advisable to sanitize or avoid logging headers that may contain confidential data.

Apply this diff to sanitize or remove sensitive headers from logs:

     // Log response status
     console.log(`[Proxy Response] ${response.status} ${response.statusText}`);
-    console.log("Response Headers:", Object.fromEntries(responseHeaders));
+    // Optionally, log non-sensitive headers if necessary
+    // const loggedHeaders = { ... };
+    // console.log("Response Headers:", loggedHeaders);

Committable suggestion skipped: line range outside the PR's diff.


return new NextResponse(response.body, {
status: response.status,
statusText: response.statusText,
headers: responseHeaders,
});
} catch (error) {
console.error("[Global Error]", error);
return NextResponse.json(
{ error: "Internal Server Error", details: error.message },
{ status: 500, headers: CORS_HEADERS }
Comment on lines +175 to +176
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Prevent exposure of internal error details in responses

Including error.message in the API response may leak internal details. Return a generic message instead.

Apply this diff to remove internal error details from the response:

 return NextResponse.json(
-  { error: "Internal Server Error", details: error.message },
+  { error: "Internal Server Error" },
   { status: 500, headers: CORS_HEADERS }
 );

Ensure that the error is logged for debugging purposes:

 console.error("[Global Error]", error);
+// Detailed error logged above

Committable suggestion skipped: line range outside the PR's diff.

);
}

return fetchResult;
}

export const PUT = handle;
export const GET = handle;
export const OPTIONS = handle;

export const runtime = "edge";
export const GET = handler;
export const POST = handler;
export const PUT = handler;
export const DELETE = handler;
export const OPTIONS = handler;
export const PROPFIND = handler;
export const MKCOL = handler;
Loading