117 lines
5.0 KiB
Bash
Executable File
117 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# Configuration
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
CONTAINERS=("cms-infra-infra-cms-1" "at-mintel-directus-1")
|
||
|
||
echo "🔧 Checking for Directus containers to patch..."
|
||
|
||
for CONTAINER in "${CONTAINERS[@]}"; do
|
||
if [ "$(docker ps -q -f name=^/${CONTAINER}$)" ]; then
|
||
echo "🔧 Applying core patches to: $CONTAINER..."
|
||
|
||
# Capture output to determine if restart is needed
|
||
OUTPUT=$(docker exec -i "$CONTAINER" node << 'EOF'
|
||
const fs = require("node:fs");
|
||
const { execSync } = require("node:child_process");
|
||
let patched = false;
|
||
|
||
try {
|
||
// 1. Patch @directus/extensions node.js (Entrypoints)
|
||
const findNodeCmd = "find /directus/node_modules -path \"*/@directus/extensions/dist/node.js\"";
|
||
const nodePaths = execSync(findNodeCmd).toString().trim().split("\n").filter(Boolean);
|
||
|
||
nodePaths.forEach(targetPath => {
|
||
let content = fs.readFileSync(targetPath, "utf8");
|
||
let modified = false;
|
||
|
||
const filterPatch = 'extension.host === "app" && (extension.entrypoint.app || extension.entrypoint)';
|
||
|
||
// Only replace if the OLD pattern exists
|
||
if (content.includes('extension.host === "app" && !!extension.entrypoint.app')) {
|
||
content = content.replace(/extension\.host === "app" && !!extension\.entrypoint\.app/g, filterPatch);
|
||
modified = true;
|
||
}
|
||
|
||
// Only replace if the OLD pattern exists for entrypoint
|
||
// We check if "extension.entrypoint.app" is present but NOT part of our patch
|
||
// This is a simple heuristic: if the patch string is NOT present, but the target IS.
|
||
if (!content.includes("(extension.entrypoint.app || extension.entrypoint)")) {
|
||
if (content.includes("extension.entrypoint.app")) {
|
||
content = content.replace(/extension\.entrypoint\.app/g, "(extension.entrypoint.app || extension.entrypoint)");
|
||
modified = true;
|
||
}
|
||
}
|
||
|
||
if (modified) {
|
||
fs.writeFileSync(targetPath, content);
|
||
console.log(`✅ Entrypoint patched.`);
|
||
patched = true;
|
||
}
|
||
});
|
||
|
||
// 2. Patch @directus/api manager.js (HTML Injection)
|
||
const findManagerCmd = "find /directus/node_modules -path \"*/@directus/api/dist/extensions/manager.js\"";
|
||
const managerPaths = execSync(findManagerCmd).toString().trim().split("\n").filter(Boolean);
|
||
|
||
managerPaths.forEach(targetPath => {
|
||
let content = fs.readFileSync(targetPath, "utf8");
|
||
|
||
const original = "head: wrapEmbeds('Custom Embed Head', this.hookEmbedsHead),";
|
||
const injection = "head: '<script type=\"module\" src=\"/extensions/sources/index.js\"></script>\\n' + wrapEmbeds('Custom Embed Head', this.hookEmbedsHead),";
|
||
|
||
if (content.includes(original) && !content.includes("/extensions/sources/index.js")) {
|
||
content = content.replace(original, injection);
|
||
fs.writeFileSync(targetPath, content);
|
||
console.log(`✅ Injection patched.`);
|
||
patched = true;
|
||
}
|
||
});
|
||
|
||
// 3. Patch @directus/api app.js (CSP for unsafe-inline)
|
||
const findAppCmd = "find /directus/node_modules -path \"*/@directus/api/dist/app.js\"";
|
||
const appPaths = execSync(findAppCmd).toString().trim().split("\n").filter(Boolean);
|
||
|
||
appPaths.forEach(targetPath => {
|
||
let content = fs.readFileSync(targetPath, "utf8");
|
||
let modified = false;
|
||
|
||
const original = "scriptSrc: [\"'self'\", \"'unsafe-eval'\"],";
|
||
const patchedStr = "scriptSrc: [\"'self'\", \"'unsafe-eval'\", \"'unsafe-inline'\"],";
|
||
|
||
if (content.includes(original)) {
|
||
content = content.replace(original, patchedStr);
|
||
modified = true;
|
||
}
|
||
|
||
if (modified) {
|
||
fs.writeFileSync(targetPath, content);
|
||
console.log(`✅ CSP patched in app.js.`);
|
||
patched = true;
|
||
}
|
||
});
|
||
|
||
if (patched) process.exit(100); // Signal restart needed
|
||
|
||
} catch (error) {
|
||
console.error("❌ Error applying patch:", error.message);
|
||
process.exit(1);
|
||
}
|
||
EOF
|
||
)
|
||
EXIT_CODE=$?
|
||
echo "$OUTPUT"
|
||
|
||
if [ $EXIT_CODE -eq 100 ]; then
|
||
echo "🔄 Patches applied. Restarting Directus container: $CONTAINER..."
|
||
docker restart "$CONTAINER"
|
||
else
|
||
echo "✅ Container $CONTAINER is already patched. No restart needed."
|
||
fi
|
||
else
|
||
echo "ℹ️ Container $CONTAINER not found. Skipping."
|
||
fi
|
||
done
|
||
|
||
echo "✨ All patches check complete."
|