mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
break out code into server-core
This commit is contained in:
@@ -3,59 +3,16 @@ const fs = require("fs");
|
||||
const path = require("path");
|
||||
const archiver = require("archiver");
|
||||
const config = require("../config");
|
||||
const { writeCoalesced, getPending } = require("../write-coalescer");
|
||||
const {
|
||||
writeCoalescer,
|
||||
encodeContentDispositionFilename,
|
||||
resolveVaultPath,
|
||||
} = require("@ignis/server-core");
|
||||
const { writeCoalesced, getPending } = writeCoalescer;
|
||||
const bootstrapRoutes = require("./bootstrap");
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* Encode a filename for use in Content-Disposition header.
|
||||
* Handles non-ASCII characters and special characters to prevent header injection.
|
||||
* Uses RFC 5987 encoding for filename* parameter when needed.
|
||||
*
|
||||
* @param {string} filename - The filename to encode
|
||||
* @returns {string} - Properly formatted Content-Disposition value
|
||||
*/
|
||||
function encodeContentDispositionFilename(filename) {
|
||||
// Check if filename contains non-ASCII characters
|
||||
const hasNonASCII = /[^\x00-\x7F]/.test(filename);
|
||||
|
||||
// Escape quotes and backslashes in ASCII filename by prefixing with backslash
|
||||
const escapedFilename = filename.replace(/["\\ ]/g, function (match) {
|
||||
if (match === '"') return '\\"';
|
||||
if (match === "\\") return "\\\\";
|
||||
return match;
|
||||
});
|
||||
|
||||
// Remove any control characters that could cause header injection
|
||||
const sanitizedFilename = escapedFilename.replace(/[\x00-\x1F\x7F]/g, "");
|
||||
|
||||
if (!hasNonASCII) {
|
||||
// Simple ASCII filename - use standard format
|
||||
return `attachment; filename="${sanitizedFilename}"`;
|
||||
}
|
||||
|
||||
// Non-ASCII filename - use RFC 5987 encoding
|
||||
// Encode using percent-encoding for UTF-8
|
||||
const encodedFilename = encodeURIComponent(filename)
|
||||
.replace(/['()]/g, function (c) {
|
||||
return "%" + c.charCodeAt(0).toString(16).toUpperCase();
|
||||
})
|
||||
.replace(/\*/g, "%2A");
|
||||
|
||||
// Provide both filename (ASCII fallback) and filename* (UTF-8 encoded)
|
||||
// For fallback, replace non-ASCII with underscores
|
||||
const asciiFallback = filename
|
||||
.replace(/[^\x00-\x7F]/g, "_")
|
||||
.replace(/["\\ ]/g, function (match) {
|
||||
if (match === '"') return '\\"';
|
||||
if (match === "\\") return "\\\\";
|
||||
return match;
|
||||
});
|
||||
|
||||
return `attachment; filename="${asciiFallback}"; filename*=UTF-8''${encodedFilename}`;
|
||||
}
|
||||
|
||||
// Resolve the vault root for a request. Reads vault ID from query or body.
|
||||
function getVaultRoot(req, res) {
|
||||
const vaultId = req.query.vault || req.body?.vault || config.defaultVaultId;
|
||||
@@ -76,20 +33,6 @@ function invalidateBootstrap(req) {
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve a client-provided path to an absolute path within a vault.
|
||||
// Strips leading slashes so paths from the client are always treated as relative to the vault root.
|
||||
function resolveVaultPath(vaultRoot, relativePath) {
|
||||
const cleaned = (relativePath || "").replace(/^\/+/, "");
|
||||
const resolved = path.resolve(vaultRoot, cleaned);
|
||||
|
||||
const resolvedRoot = path.resolve(vaultRoot);
|
||||
|
||||
if (resolved !== resolvedRoot && !resolved.startsWith(resolvedRoot + path.sep)) {
|
||||
return null;
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
function guardPath(req, res, source = "query") {
|
||||
const vaultRoot = getVaultRoot(req, res);
|
||||
|
||||
@@ -653,5 +596,3 @@ router.get("/download-zip", async (req, res) => {
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
module.exports.resolveVaultPath = resolveVaultPath;
|
||||
module.exports.encodeContentDispositionFilename = encodeContentDispositionFilename;
|
||||
|
||||
@@ -6,7 +6,7 @@ const require = createRequire(import.meta.url);
|
||||
const {
|
||||
resolveVaultPath,
|
||||
encodeContentDispositionFilename,
|
||||
} = require("./fs.js");
|
||||
} = require("@ignis/server-core");
|
||||
|
||||
// -- encodeContentDispositionFilename --------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user