mirror of
https://github.com/Hackdex-App/hackdex-website.git
synced 2026-05-08 14:21:35 -05:00
Switch to using patch download proxy url
This commit is contained in:
parent
99f2e05627
commit
efe9ea1c72
|
|
@ -1,5 +1,6 @@
|
||||||
import { NextRequest } from "next/server";
|
import { NextRequest } from "next/server";
|
||||||
import { getMinioClient, PATCHES_BUCKET } from "@/utils/minio/server";
|
import { getMinioClient, PATCHES_BUCKET } from "@/utils/minio/server";
|
||||||
|
import { buildPatchDownloadUrl } from "@/utils/patches/patch-download-url";
|
||||||
import { createClient } from "@/utils/supabase/server";
|
import { createClient } from "@/utils/supabase/server";
|
||||||
|
|
||||||
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||||
|
|
@ -45,6 +46,11 @@ export async function GET(req: NextRequest, { params }: { params: Promise<{ id:
|
||||||
return new Response("Not found", { status: 404 });
|
return new Response("Not found", { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const workerUrl = buildPatchDownloadUrl(patch.filename);
|
||||||
|
if (workerUrl) {
|
||||||
|
return Response.redirect(workerUrl, 302);
|
||||||
|
}
|
||||||
|
|
||||||
const client = getMinioClient();
|
const client = getMinioClient();
|
||||||
const bucket = patch.bucket || PATCHES_BUCKET;
|
const bucket = patch.bucket || PATCHES_BUCKET;
|
||||||
const url = await client.presignedGetObject(bucket, patch.filename, 60 * 5);
|
const url = await client.presignedGetObject(bucket, patch.filename, 60 * 5);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import { createClient, createServiceClient } from "@/utils/supabase/server";
|
import { createClient, createServiceClient } from "@/utils/supabase/server";
|
||||||
import { getMinioClient, PATCHES_BUCKET } from "@/utils/minio/server";
|
import { getMinioClient, PATCHES_BUCKET } from "@/utils/minio/server";
|
||||||
|
import { buildPatchDownloadUrl } from "@/utils/patches/patch-download-url";
|
||||||
import { isInformationalArchiveHack, canEditAsCreator, canEditAsAdmin } from "@/utils/hack";
|
import { isInformationalArchiveHack, canEditAsCreator, canEditAsAdmin } from "@/utils/hack";
|
||||||
import { sendDiscordMessageEmbed } from "@/utils/discord";
|
import { sendDiscordMessageEmbed } from "@/utils/discord";
|
||||||
import { headers } from "next/headers";
|
import { headers } from "next/headers";
|
||||||
|
|
@ -245,8 +246,11 @@ export async function getSignedPatchUrl(slug: string): Promise<{ ok: true; url:
|
||||||
return { ok: false, error: "Patch not found" };
|
return { ok: false, error: "Patch not found" };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign the URL server-side
|
|
||||||
try {
|
try {
|
||||||
|
const workerUrl = buildPatchDownloadUrl(patch.filename);
|
||||||
|
if (workerUrl) {
|
||||||
|
return { ok: true, url: workerUrl };
|
||||||
|
}
|
||||||
const client = getMinioClient();
|
const client = getMinioClient();
|
||||||
const bucket = patch.bucket || PATCHES_BUCKET;
|
const bucket = patch.bucket || PATCHES_BUCKET;
|
||||||
const signedUrl = await client.presignedGetObject(bucket, patch.filename, 60 * 5);
|
const signedUrl = await client.presignedGetObject(bucket, patch.filename, 60 * 5);
|
||||||
|
|
@ -433,6 +437,10 @@ export async function getPatchDownloadUrl(patchId: number): Promise<{ ok: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const workerUrl = buildPatchDownloadUrl(patch.filename);
|
||||||
|
if (workerUrl) {
|
||||||
|
return { ok: true, url: workerUrl };
|
||||||
|
}
|
||||||
const client = getMinioClient();
|
const client = getMinioClient();
|
||||||
const bucket = patch.bucket || PATCHES_BUCKET;
|
const bucket = patch.bucket || PATCHES_BUCKET;
|
||||||
const signedUrl = await client.presignedGetObject(bucket, patch.filename, 60 * 5);
|
const signedUrl = await client.presignedGetObject(bucket, patch.filename, 60 * 5);
|
||||||
|
|
|
||||||
39
src/utils/patches/patch-download-url.ts
Normal file
39
src/utils/patches/patch-download-url.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { createHmac } from "node:crypto";
|
||||||
|
|
||||||
|
/** Aligned with Cloudflare Worker `patchTokenJsonPayload` (key order f, e). */
|
||||||
|
export function patchTokenJsonPayload(filename: string, expiresAtMs: number): string {
|
||||||
|
return JSON.stringify({ f: filename, e: expiresAtMs });
|
||||||
|
}
|
||||||
|
|
||||||
|
const PATCH_DOWNLOAD_TTL_MS = 5 * 60 * 1000;
|
||||||
|
|
||||||
|
/** Wire: base64url(utf8 JSON payload).hex(32-byte HMAC-SHA256), matching Worker `mintPatchToken`. */
|
||||||
|
export function mintPatchDownloadToken(
|
||||||
|
filename: string,
|
||||||
|
expiresAtMs: number,
|
||||||
|
secret: string
|
||||||
|
): string {
|
||||||
|
const buf = Buffer.from(patchTokenJsonPayload(filename, expiresAtMs), "utf8");
|
||||||
|
const hexMac = createHmac("sha256", secret).update(buf).digest("hex");
|
||||||
|
return `${buf.toString("base64url")}.${hexMac}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function trimTrailingSlash(s: string): string {
|
||||||
|
return s.replace(/\/+$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `PATCH_TOKEN_SECRET` and `PATCHES_DOWNLOAD_BASE_URL` are set, returns a Worker URL with `token`.
|
||||||
|
* Otherwise `null` — caller should use Minio `presignedGetObject`.
|
||||||
|
*/
|
||||||
|
export function buildPatchDownloadUrl(filename: string): string | null {
|
||||||
|
const secret = process.env.PATCH_TOKEN_SECRET?.trim();
|
||||||
|
const base = process.env.PATCHES_DOWNLOAD_BASE_URL?.trim();
|
||||||
|
if (!secret || !base) return null;
|
||||||
|
const expiresAtMs = Date.now() + PATCH_DOWNLOAD_TTL_MS;
|
||||||
|
const token = mintPatchDownloadToken(filename, expiresAtMs, secret);
|
||||||
|
const u = new URL(filename, `${trimTrailingSlash(base)}/`);
|
||||||
|
u.searchParams.set("token", token);
|
||||||
|
console.log("buildPatchDownloadUrl", u.href);
|
||||||
|
return u.href;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user