units,lesson as standalone

This commit is contained in:
2026-07-10 11:44:46 +08:00
parent 86fba50b95
commit e1ffdab190
46 changed files with 1463 additions and 197 deletions
+11 -10
View File
@@ -159,18 +159,18 @@ async function deleteFile(key) {
// For server-side reads only (e.g. media.controller.js streamAsset piping
// bytes to the browser itself) — never hand this URL to a browser directly.
//
// Must NOT be signed against S3_PUBLIC_URL: that host is fronted by
// garage-anon-proxy, which re-signs every request itself (header-based SigV4,
// real credentials) regardless of any query-string signature already present.
// A presigned URL arriving there collides with the proxy's own signature and
// Garage rejects the request (400 "Header `x-amz-date` should be signed").
// See getPublicUrl() below for the browser-facing equivalent.
// TEMPORARY:
// The problem is this line do not tell for each of development machines
// which ones should be called whether it's for PUBLIC_URL or LOCAL_ENDPOINT itself.
// Must NOT be signed against S3_PUBLIC_URL when Garage is in use: that host is
// fronted by garage-anon-proxy, which re-signs every request itself (header-based
// SigV4, real credentials) regardless of any query-string signature already
// present. A presigned URL arriving there collides with the proxy's own
// signature and Garage rejects the request (400 "Header `x-amz-date` should
// be signed").
//
// Uses the internal `s3` client (always S3_ENDPOINT) when available; falls back
// to getPublicClient() for external S3-compatible services without Garage.
//
async function getSignedDownloadUrl(key, expiresInSeconds = 3600) {
const client = getPublicClient();
const client = process.env.S3_ENDPOINT ? s3 : getPublicClient();
return getSignedUrl(
client,
@@ -183,6 +183,7 @@ async function getSignedDownloadUrl(key, expiresInSeconds = 3600) {
}
);
}
// ─── getPublicUrl ─────────────────────────────────────────────────────────────
//
// Browser-facing pre-signed GET URL, signed against S3_PUBLIC_URL. Safe again