diff --git a/alist-proxy.js b/alist-proxy.js new file mode 100644 index 00000000..78e48a8d --- /dev/null +++ b/alist-proxy.js @@ -0,0 +1,133 @@ +// We support the GET, POST, HEAD, and OPTIONS methods from any origin, +// and allow any header on requests. These headers must be present +// on all responses to all CORS preflight requests. In practice, this means +// all responses to OPTIONS requests. + +const HOST = "YOUR_HOST"; +const TOKEN = "YOUR_TOKEN"; + +const corsHeaders = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS", + "Access-Control-Max-Age": "86400", +}; + +!function(a){"use strict";function b(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c}function c(a,b){return a<>>32-b}function d(a,d,e,f,g,h){return b(c(b(b(d,a),b(f,h)),g),e)}function e(a,b,c,e,f,g,h){return d(b&c|~b&e,a,b,f,g,h)}function f(a,b,c,e,f,g,h){return d(b&e|c&~e,a,b,f,g,h)}function g(a,b,c,e,f,g,h){return d(b^c^e,a,b,f,g,h)}function h(a,b,c,e,f,g,h){return d(c^(b|~e),a,b,f,g,h)}function i(a,c){a[c>>5]|=128<>>9<<4)+14]=c;var d,i,j,k,l,m=1732584193,n=-271733879,o=-1732584194,p=271733878;for(d=0;d>5]>>>b%32&255);return c}function k(a){var b,c=[];for(c[(a.length>>2)-1]=void 0,b=0;b>5]|=(255&a.charCodeAt(b/8))<16&&(e=i(e,8*a.length)),c=0;16>c;c+=1)f[c]=909522486^e[c],g[c]=1549556828^e[c];return d=i(f.concat(k(b)),512+8*b.length),j(i(g.concat(d),640))}function n(a){var b,c,d="0123456789abcdef",e="";for(c=0;c>>4&15)+d.charAt(15&b);return e}function o(a){return unescape(encodeURIComponent(a))}function p(a){return l(o(a))}function q(a){return n(p(a))}function r(a,b){return m(o(a),o(b))}function s(a,b){return n(r(a,b))}function t(a,b,c){return b?c?r(b,a):s(b,a):c?p(a):q(a)}"function"==typeof define&&define.amd?define(function(){return t}):a.md5=t}(this); + +async function handleRequest(request) { + const origin = request.headers.get("origin"); + const url = new URL(request.url); + const path = url.pathname; + const sign = url.searchParams.get("sign"); + const name = path.split("/").pop(); + const right = md5(`alist-${TOKEN}-${name}`).slice(8, 24); + if (sign !== right){ + const resp = new Response( + JSON.stringify({ + code: 401, + message: `sign mismatch`, + you: sign, + right: right, + }), + { + headers: { + "content-type": "application/json;charset=UTF-8", + }, + } + ); + resp.headers.set("Access-Control-Allow-Origin", origin); + return resp; + } + + let resp = await fetch(`${HOST}/api/admin/link`, { + method: "POST", + headers: { + "content-type": "application/json;charset=UTF-8", + Authorization: TOKEN, + }, + body: JSON.stringify({ + path: decodeURI(path), + }), + }); + let data = await resp.json(); + if (data.code != 200) { + return new Response(JSON.stringify(data)); + } + let headers = {}; + if (data.data.header) { + headers[data.data.header.name] = data.data.header.value; + } + let response = await fetch(data.data.url, { + method: "GET", + headers: headers, + }); + + // Recreate the response so we can modify the headers + response = new Response(response.body, response); + + // Set CORS headers + response.headers.set("Access-Control-Allow-Origin", origin); + + // Append to/Add Vary header so browser will cache response correctly + response.headers.append("Vary", "Origin"); + + return response; +} + +function handleOptions(request) { + // Make sure the necessary headers are present + // for this to be a valid pre-flight request + let headers = request.headers; + if ( + headers.get("Origin") !== null && + headers.get("Access-Control-Request-Method") !== null + // && headers.get("Access-Control-Request-Headers") !== null + ) { + // Handle CORS pre-flight request. + // If you want to check or reject the requested method + headers + // you can do that here. + let respHeaders = { + ...corsHeaders, + // Allow all future content Request headers to go back to browser + // such as Authorization (Bearer) or X-Client-Name-Version + "Access-Control-Allow-Headers": request.headers.get( + "Access-Control-Request-Headers" + ), + }; + + return new Response(null, { + headers: respHeaders, + }); + } else { + // Handle standard OPTIONS request. + // If you want to allow other HTTP Methods, you can do that here. + return new Response(null, { + headers: { + Allow: "GET, HEAD, POST, OPTIONS", + }, + }); + } +} + +addEventListener("fetch", (event) => { + const request = event.request; + // const url = new URL(request.url) + if (request.method === "OPTIONS") { + // Handle CORS preflight requests + event.respondWith(handleOptions(request)); + } else if ( + request.method === "GET" || + request.method === "HEAD" || + request.method === "POST" + ) { + // Handle requests to the API server + event.respondWith(handleRequest(request)); + } else { + event.respondWith( + new Response(null, { + status: 405, + statusText: "Method Not Allowed", + }) + ); + } +});