fix: persist service media uploads
This commit is contained in:
+51
-9
@@ -3,7 +3,7 @@ import { createServer as createHttpServer } from "node:http";
|
||||
import { randomBytes, randomUUID, createHash, timingSafeEqual } from "node:crypto";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { mkdir, writeFile } from "node:fs/promises";
|
||||
import { dirname, extname, join, resolve } from "node:path";
|
||||
import { dirname, extname, isAbsolute, join, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { createRemoteJWKSet, jwtVerify } from "jose";
|
||||
import { createAuthentikSyncClient, resolveRequiredGroups } from "./authentik-sync.mjs";
|
||||
@@ -31,6 +31,8 @@ const config = readConfig();
|
||||
const app = express();
|
||||
const httpServer = createHttpServer(app);
|
||||
const controlPlaneStore = createControlPlaneStore({ projectRoot });
|
||||
const runtimeStorageRoot = resolveRuntimeStorageRoot(projectRoot);
|
||||
const runtimeUploadsRoot = resolveRuntimeUploadsRoot(projectRoot, runtimeStorageRoot);
|
||||
const authentikSyncClient = createAuthentikSyncClient({ baseUrl: config.authentikBaseUrl, token: config.authentikApiToken });
|
||||
const pendingLogins = new Map();
|
||||
const serviceHandoffs = new Map();
|
||||
@@ -1533,6 +1535,20 @@ app.get("/storage/launcher-data.json", (_req, res) => {
|
||||
res.status(404).json({ error: "not_found" });
|
||||
});
|
||||
|
||||
for (const uploadRoot of getReadableUploadRoots()) {
|
||||
app.use(
|
||||
"/storage/uploads",
|
||||
express.static(uploadRoot, {
|
||||
fallthrough: true,
|
||||
immutable: true,
|
||||
maxAge: "1y",
|
||||
setHeaders(res) {
|
||||
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
let fixFrontendStacktrace = () => {};
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
@@ -2821,10 +2837,9 @@ async function saveUploadedFile(payload) {
|
||||
const fileBuffer = Buffer.from(match[2], "base64");
|
||||
|
||||
await Promise.all(
|
||||
getWritableStorageRoots().map(async (storageRoot) => {
|
||||
const uploadDir = join(storageRoot, "uploads");
|
||||
await mkdir(uploadDir, { recursive: true });
|
||||
await writeFile(join(uploadDir, storedName), fileBuffer);
|
||||
getWritableUploadRoots().map(async (uploadRoot) => {
|
||||
await mkdir(uploadRoot, { recursive: true });
|
||||
await writeFile(join(uploadRoot, storedName), fileBuffer);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -2841,15 +2856,22 @@ async function saveLauncherData(payload) {
|
||||
await controlPlaneStore.writeData(payload);
|
||||
}
|
||||
|
||||
function getWritableStorageRoots() {
|
||||
const roots = [join(projectRoot, "public", "storage")];
|
||||
function getWritableUploadRoots() {
|
||||
return [runtimeUploadsRoot];
|
||||
}
|
||||
|
||||
function getReadableUploadRoots() {
|
||||
const roots = [
|
||||
runtimeUploadsRoot,
|
||||
join(projectRoot, "public", "storage", "uploads"),
|
||||
];
|
||||
const distRoot = join(projectRoot, "dist");
|
||||
|
||||
if (existsSync(distRoot)) {
|
||||
roots.push(join(distRoot, "storage"));
|
||||
roots.push(join(distRoot, "storage", "uploads"));
|
||||
}
|
||||
|
||||
return roots;
|
||||
return [...new Set(roots)];
|
||||
}
|
||||
|
||||
function buildStoredFileName(fileName, mimeType) {
|
||||
@@ -2876,6 +2898,26 @@ function extensionFromMimeType(mimeType) {
|
||||
return "";
|
||||
}
|
||||
|
||||
function resolveRuntimeStorageRoot(root) {
|
||||
const configuredRoot = process.env.NODEDC_LAUNCHER_STORAGE_DIR;
|
||||
|
||||
if (configuredRoot && configuredRoot.trim()) {
|
||||
return isAbsolute(configuredRoot) ? configuredRoot : resolve(root, configuredRoot);
|
||||
}
|
||||
|
||||
return join(root, "server", "storage");
|
||||
}
|
||||
|
||||
function resolveRuntimeUploadsRoot(root, storageRoot) {
|
||||
const configuredRoot = process.env.NODEDC_LAUNCHER_UPLOADS_DIR;
|
||||
|
||||
if (configuredRoot && configuredRoot.trim()) {
|
||||
return isAbsolute(configuredRoot) ? configuredRoot : resolve(root, configuredRoot);
|
||||
}
|
||||
|
||||
return join(storageRoot, "uploads");
|
||||
}
|
||||
|
||||
function isUploadPayload(payload) {
|
||||
return Boolean(
|
||||
payload &&
|
||||
|
||||
Reference in New Issue
Block a user