Initial commit
This commit is contained in:
122
functions/_middleware.ts
Normal file
122
functions/_middleware.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import { renderPage } from "vite-plugin-ssr";
|
||||
|
||||
async function constructHTML(context: RequestContext) {
|
||||
const { pathname } = new URL(context.request.url);
|
||||
|
||||
if (pathname.startsWith("/api/")) return await context.next();
|
||||
|
||||
if (
|
||||
pathname.startsWith("/assets/") ||
|
||||
["/app.webmanifest", "/favicon.ico", "/robots.txt"].includes(pathname) ||
|
||||
pathname.startsWith("/files/")
|
||||
)
|
||||
return await context.env.ASSETS.fetch(context.request);
|
||||
|
||||
const { httpResponse, status } = await renderPage({
|
||||
current_user: context.data.current_user,
|
||||
kv: context.env.DATA,
|
||||
status: 200,
|
||||
urlOriginal: context.request.url,
|
||||
});
|
||||
|
||||
return new Response(httpResponse?.getReadableWebStream(), {
|
||||
headers: {
|
||||
"content-type": httpResponse?.contentType ?? "text/html;charset=utf-8",
|
||||
},
|
||||
status: [200, 404, 500].includes(status)
|
||||
? httpResponse?.statusCode
|
||||
: status,
|
||||
});
|
||||
}
|
||||
|
||||
async function generateTokenHash(token: string) {
|
||||
const hash = await crypto.subtle.digest(
|
||||
"SHA-512",
|
||||
new TextEncoder().encode(token)
|
||||
);
|
||||
return btoa(String.fromCharCode(...new Uint8Array(hash)))
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=/g, "");
|
||||
}
|
||||
|
||||
async function setAuth(context: RequestContext) {
|
||||
const cookies = context.request.headers.get("cookie");
|
||||
|
||||
if (!cookies) return await context.next();
|
||||
|
||||
const cookieList = cookies.split(/; /);
|
||||
|
||||
for (const c of cookieList) {
|
||||
const [name, value] = c.split("=");
|
||||
|
||||
if (name !== "_s") continue;
|
||||
|
||||
const userData = await context.env.DATA.get(
|
||||
`auth_${await generateTokenHash(value)}`
|
||||
);
|
||||
|
||||
if (userData) context.data.current_user = JSON.parse(userData);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return await context.next();
|
||||
}
|
||||
|
||||
async function setBody(context: RequestContext) {
|
||||
if (context.request.method === "POST") {
|
||||
if (context.request.headers.get("content-type") !== "application/json")
|
||||
return new Response('{"error":"Invalid content-type"}', {
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
status: 400,
|
||||
});
|
||||
|
||||
let body: { [k: string]: any };
|
||||
|
||||
try {
|
||||
body = await context.request.json();
|
||||
} catch {
|
||||
return new Response('{"error":"Invalid JSON"}', {
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
context.data.body = body;
|
||||
}
|
||||
|
||||
return await context.next();
|
||||
}
|
||||
|
||||
async function setHeaders(context: RequestContext) {
|
||||
const response = await context.next();
|
||||
|
||||
const rtvValues = [
|
||||
"Aldaria",
|
||||
"Altadena",
|
||||
"DEMA",
|
||||
"Dragonborn",
|
||||
"Hollywood",
|
||||
"Parkway East",
|
||||
"Parkway North",
|
||||
"Parkway West",
|
||||
"Tokyo",
|
||||
"Wintervale",
|
||||
];
|
||||
|
||||
response.headers.set(
|
||||
"RTV",
|
||||
rtvValues[Math.round(Math.random() * (rtvValues.length - 1))]
|
||||
);
|
||||
response.headers.set("X-Frame-Options", "DENY");
|
||||
response.headers.set("X-XSS-Protection", "1; mode=block");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const onRequest = [setAuth, constructHTML, setBody, setHeaders];
|
Reference in New Issue
Block a user