diff options
| author | Fuwn <[email protected]> | 2026-03-27 05:54:01 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-03-27 05:54:01 +0000 |
| commit | 94213976262eab9b7a68a9d580587a5fbb9248cc (patch) | |
| tree | 92e72ae66d2ebf9bb5393afd5edffb9709c4d10d /apps/proxy/src/index.js | |
| parent | fix(actions): resolve quality and trigger deploy drift (diff) | |
| download | due.moe-94213976262eab9b7a68a9d580587a5fbb9248cc.tar.xz due.moe-94213976262eab9b7a68a9d580587a5fbb9248cc.zip | |
chore(apps): Add proxy
Diffstat (limited to 'apps/proxy/src/index.js')
| -rw-r--r-- | apps/proxy/src/index.js | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/apps/proxy/src/index.js b/apps/proxy/src/index.js new file mode 100644 index 00000000..f2a37111 --- /dev/null +++ b/apps/proxy/src/index.js @@ -0,0 +1,113 @@ +const handleRequest = async (request) => { + try { + const url = new URL(request.url); + let query; + let dropHeaders = false; + + if (url.search.includes('&dh')) { + url.search = url.search.replace('&dh', ''); + dropHeaders = true; + } + + if (url.search.includes('?q=')) { + query = url.search.split('?q=')[1]; + } else if (url.search.includes('?d=')) { + query = atob(url.search.split('?d=')[1]); + } else if (url.search.includes('?d2=')) { + const fullEncodedURL = url.search.split('?d2=')[1]; + const key = parseInt(fullEncodedURL.slice(-2)); + + query = atob(fullEncodedURL.slice(0, -2)) + .split(':') + .map((char) => String.fromCharCode(char - key)) + .join(''); + } else { + return new Response(null, { + status: 400, + statusText: 'Bad Request', + }); + } + + request = new Request(query, request); + + request.headers.set('Host', new URL(query).origin); + request.headers.set('Referrer', new URL(query)); + request.headers.set('Origin', new URL(query)); + request.headers.set('Access-Control-Allow-Credentials', 'true'); + request.headers.delete('X-Content-Type-Options'); + + let response = await fetch(request); + + response = new Response(response.body, response); + + if (dropHeaders) response.headers.forEach((_, key) => response.headers.delete(key)); + + response.headers.set('Access-Control-Allow-Origin', 'https://due.moe'); + response.headers.append('Vary', 'Origin'); + response.headers.set('Cache-Control', 'max-age=300'); + + return response; + } catch { + return new Response(null, { + status: 400, + statusText: 'Bad Request', + }); + } +}; + +const handleOptions = async (request) => { + if ( + request.headers.get('Origin') !== null && + request.headers.get('Access-Control-Request-Method') !== null && + request.headers.get('Access-Control-Request-Headers') !== null + ) { + return new Response(null, { + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS', + 'Access-Control-Allow-Headers': '*', + }, + }); + } else { + return new Response(null, { + headers: { + Allow: 'GET, HEAD, POST, OPTIONS', + }, + }); + } +}; + +addEventListener('fetch', (event) => { + const request = event.request; + + try { + switch (request.method) { + case 'OPTIONS': + event.respondWith(handleOptions(request)); + + break; + + case 'GET': + case 'HEAD': + case 'POST': + event.respondWith(handleRequest(request)); + + break; + + default: + event.respondWith(async () => { + return new Response(null, { + status: 405, + statusText: 'Method Not Allowed', + }); + }); + + break; + } + } catch { + return new Response(null, { + status: 400, + statusText: 'Bad Request', + }); + } +}); |