feat: udpates

This commit is contained in:
2025-01-19 01:23:14 +08:00
parent ab9edbb4fd
commit 3218e1f491
4 changed files with 61 additions and 39 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env -S deno run --allow-env --allow-net #!/usr/bin/env -S deno run --allow-env --allow-net
import {Mutex} from "https://deno.land/x/async@v2.1.0/mutex.ts"; import { Mutex } from "https://deno.land/x/async@v2.1.0/mutex.ts";
// Reference: // Reference:
// * https://docs.deno.com/runtime/reference/env_variables/ // * https://docs.deno.com/runtime/reference/env_variables/
@@ -14,7 +14,7 @@ const listen = {
const startTime = new Date().getTime(); const startTime = new Date().getTime();
// IP: Add time // IP: Add time
let globalIpAddressMap = {}; const globalIpAddressMap = {};
const globalIpAddressMapMutex = new Mutex(); const globalIpAddressMapMutex = new Mutex();
async function addIpAddress(ip: string): Promise<void> { async function addIpAddress(ip: string): Promise<void> {
@@ -29,9 +29,9 @@ async function addIpAddress(ip: string): Promise<void> {
async function cleanAndGetIpAddresses(): Promise<Array<string>> { async function cleanAndGetIpAddresses(): Promise<Array<string>> {
await globalIpAddressMapMutex.acquire(); await globalIpAddressMapMutex.acquire();
try { try {
let currentTimeMillis = new Date().getTime(); const currentTimeMillis = new Date().getTime();
let invalidKeys = []; const invalidKeys = [];
let validKeys = []; const validKeys = [];
for (let k in globalIpAddressMap) { for (let k in globalIpAddressMap) {
const t = globalIpAddressMap[k]; const t = globalIpAddressMap[k];
if ((currentTimeMillis - t) > 60 * 60 * 1000) { if ((currentTimeMillis - t) > 60 * 60 * 1000) {
@@ -49,17 +49,20 @@ async function cleanAndGetIpAddresses(): Promise<Array<string>> {
} }
} }
let globalFilters = []; const globalFilters: any[] = [];
let globalHandlerMap = {}; const globalHandlerMap = {};
type RequestHandler = (url: URL, req: any) => Promise<Response>; type RequestHandler = (url: URL, req: any) => Promise<Response>;
function registerFilter(handler: RequestHandler) { function registerFilter(handler: RequestHandler) {
globalFilters.push(handler); globalFilters.push(handler);
} }
function registerHandler(method: string, path: string, handler: RequestHandler) { function registerHandler(
method: string,
path: string,
handler: RequestHandler,
) {
const requestIdent = `${method}::${path}`; const requestIdent = `${method}::${path}`;
if (globalHandlerMap[requestIdent] != null) { if (globalHandlerMap[requestIdent] != null) {
throw `Handler for ${method} ${path} exists.`; throw `Handler for ${method} ${path} exists.`;
@@ -81,7 +84,10 @@ function buildOkJsonResponse(body: any): Response {
} }
function notFoundHandler(url: URL, req: any): Response { function notFoundHandler(url: URL, req: any): Response {
return buildJsonResponse(404, {"error": "not_found", "message": "Resource not found.",}); return buildJsonResponse(404, {
"error": "not_found",
"message": "Resource not found.",
});
} }
registerFilter(async (url: URL, req: any) => { registerFilter(async (url: URL, req: any) => {
@@ -89,41 +95,47 @@ registerFilter(async (url: URL, req: any) => {
return null; return null;
} }
if (TOKEN == null) { if (TOKEN == null) {
return buildJsonResponse(500, {"error": "bad_token", "message": "Bad token."}); return buildJsonResponse(500, {
"error": "bad_token",
"message": "Bad token.",
});
} }
const token = url.searchParams.get('__token'); const token = url.searchParams.get("__token");
if (TOKEN !== token) { if (TOKEN !== token) {
return buildJsonResponse(401, {"error": "invalid_token", "message": "Invalid token."}) return buildJsonResponse(401, {
"error": "invalid_token",
"message": "Invalid token.",
});
} }
return null; return null;
}); });
function formatHumanTime(time: number): string { function formatHumanTime(time: number): string {
let t = []; const t = [];
let leftMs = time % 1000; const leftMs = time % 1000;
if (leftMs > 0) { if (leftMs > 0) {
t.push(`${leftMs}ms`); t.push(`${leftMs}ms`);
} }
let secs = Math.floor(time / 1000); const secs = Math.floor(time / 1000);
let leftSecs = secs % 60; const leftSecs = secs % 60;
if (leftSecs > 0) { if (leftSecs > 0) {
t.push(`${leftSecs}s`); t.push(`${leftSecs}s`);
} }
let mins = Math.floor(secs / 60); const mins = Math.floor(secs / 60);
let leftMins = mins % 60; const leftMins = mins % 60;
if (leftMins > 0) { if (leftMins > 0) {
t.push(`${leftMins}min`); t.push(`${leftMins}min`);
} }
let hours = Math.floor(mins / 60); const hours = Math.floor(mins / 60);
let leftHours = hours % 24; const leftHours = hours % 24;
if (leftHours > 0) { if (leftHours > 0) {
t.push(`${leftHours}hour`); t.push(`${leftHours}hour`);
} }
let days = Math.floor(hours / 24); const days = Math.floor(hours / 24);
if (days > 0) { if (days > 0) {
t.push(`${days}day`); t.push(`${days}day`);
} }
return t.reverse().join(' '); return t.reverse().join(" ");
} }
registerHandler("GET", "/version", async (url, req) => { registerHandler("GET", "/version", async (url, req) => {
@@ -142,7 +154,10 @@ registerHandler("POST", "/ip_addresses", async (url, req) => {
try { try {
addIpAddressRequest = await req.json(); addIpAddressRequest = await req.json();
} catch (e) { } catch (e) {
return buildJsonResponse(400, {"error": "bad_request", "message": "Bad request."}); return buildJsonResponse(400, {
"error": "bad_request",
"message": "Bad request.",
});
} }
await addIpAddress(addIpAddressRequest.ip); await addIpAddress(addIpAddressRequest.ip);
return buildOkJsonResponse({}); return buildOkJsonResponse({});
@@ -156,15 +171,21 @@ registerHandler("GET", "/ip_addresses", async (url, req) => {
}); });
registerHandler("*", "/check_ip_address", async (url, req) => { registerHandler("*", "/check_ip_address", async (url, req) => {
const clientIp = req.headers.get('x-real-ip'); const clientIp = req.headers.get("x-real-ip");
if (clientIp == null) { if (clientIp == null) {
return buildJsonResponse(400, {"error": "bad_request", "message": "Bad request: no client IP"}); return buildJsonResponse(400, {
"error": "bad_request",
"message": "Bad request: no client IP",
});
} }
const ipAddresses = await cleanAndGetIpAddresses(); const ipAddresses = await cleanAndGetIpAddresses();
if (ipAddresses.indexOf(clientIp) >= 0) { if (ipAddresses.indexOf(clientIp) >= 0) {
return buildOkJsonResponse({}); return buildOkJsonResponse({});
} }
return buildJsonResponse(401, {"error": "access_denied", "message": "Access denied: not allowed IP"}); return buildJsonResponse(401, {
"error": "access_denied",
"message": "Access denied: not allowed IP",
});
}); });
Deno.serve(listen, async (req) => { Deno.serve(listen, async (req) => {
@@ -178,6 +199,7 @@ Deno.serve(listen, async (req) => {
console.log("Handler request:", req.method, url.pathname); console.log("Handler request:", req.method, url.pathname);
const req1 = `${req.method}::${url.pathname}`; const req1 = `${req.method}::${url.pathname}`;
const req2 = `*::${url.pathname}`; const req2 = `*::${url.pathname}`;
const req_handler = globalHandlerMap[req1] || globalHandlerMap[req2] || notFoundHandler; const req_handler = globalHandlerMap[req1] || globalHandlerMap[req2] ||
notFoundHandler;
return await req_handler(url, req); return await req_handler(url, req);
}); });

View File

@@ -1,8 +1,8 @@
{ {
"access-guard.ts": { "access-guard.ts": {
"script_name": "access-guard.ts", "script_name": "access-guard.ts",
"script_length": 5508, "script_length": 5756,
"script_sha256": "608fb5987c04b9bcfcb7006cb75eac7c8f81346906d3aed7ffd368357e6fa5cb", "script_sha256": "ecd11481f6182a5db14008c981a2ebba42a4851d656043c79498e83c95521c7b",
"script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/access-guard-ts/main.ts" "script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/access-guard-ts/main.ts"
}, },
"helloworld.ts": { "helloworld.ts": {
@@ -27,8 +27,8 @@
}, },
"sigstore-verify.ts": { "sigstore-verify.ts": {
"script_name": "sigstore-verify.ts", "script_name": "sigstore-verify.ts",
"script_length": 3511, "script_length": 3515,
"script_sha256": "5d3987d9f838158ab89ca098cd4b142147ab2157b693e48f042d080be4928ff7", "script_sha256": "0371be7620d5aa2607a5ed1a9b45e2664b5c27ee163966a681e630d568c4a445",
"script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/sigstore-verify-ts/main.ts" "script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/sigstore-verify-ts/main.ts"
} }
} }

View File

@@ -1,8 +1,8 @@
{ {
"access-guard-ts": { "access-guard-ts": {
"script_name": "access-guard-ts", "script_name": "access-guard-ts",
"script_length": 5508, "script_length": 5756,
"script_sha256": "608fb5987c04b9bcfcb7006cb75eac7c8f81346906d3aed7ffd368357e6fa5cb" "script_sha256": "ecd11481f6182a5db14008c981a2ebba42a4851d656043c79498e83c95521c7b"
}, },
"helloworld-ts": { "helloworld-ts": {
"script_name": "helloworld-ts", "script_name": "helloworld-ts",
@@ -11,7 +11,7 @@
}, },
"sigstore-verify-ts": { "sigstore-verify-ts": {
"script_name": "sigstore-verify-ts", "script_name": "sigstore-verify-ts",
"script_length": 3511, "script_length": 3515,
"script_sha256": "5d3987d9f838158ab89ca098cd4b142147ab2157b693e48f042d080be4928ff7" "script_sha256": "0371be7620d5aa2607a5ed1a9b45e2664b5c27ee163966a681e630d568c4a445"
} }
} }

View File

@@ -130,8 +130,8 @@ sigstore-verify.ts [--attest sigstore-attest.json]
`); `);
return; return;
} }
let attestFileName = args.attest || "sigstore-attest.json"; const attestFileName = args.attest || "sigstore-attest.json";
let attest = await loadAttest(attestFileName); const attest = await loadAttest(attestFileName);
if (attest.format !== "rekor-attest-v1") { if (attest.format !== "rekor-attest-v1") {
throw `Bad rekor attest file format: ${attest.format}`; throw `Bad rekor attest file format: ${attest.format}`;
} }