feat: content engine
This commit is contained in:
@@ -2,65 +2,115 @@
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# Define potential container names
|
||||
CONTAINERS=("cms-infra-infra-cms-1" "at-mintel-directus-1")
|
||||
|
||||
echo "🔧 Checking for Directus containers to patch..."
|
||||
|
||||
for CONTAINER in "${CONTAINERS[@]}"; do
|
||||
# Check if container exists and is running
|
||||
if [ "$(docker ps -q -f name=^/${CONTAINER}$)" ]; then
|
||||
echo "🔧 Applying core patch to Directus container: $CONTAINER..."
|
||||
docker exec "$CONTAINER" node -e '
|
||||
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");
|
||||
// Try multiple potential paths for the node_modules location
|
||||
const searchPaths = [
|
||||
"/directus/node_modules/.pnpm/@directus+extensions@file+packages+extensions_deep-diff@1.0.2_express@4.21.2_graphql@16_244b87fbecd929c2d2240e7b3abc1fe4/node_modules/@directus/extensions/dist/node.js",
|
||||
"/directus/node_modules/@directus/extensions/dist/node.js"
|
||||
];
|
||||
|
||||
let targetPath = null;
|
||||
for (const p of searchPaths) {
|
||||
if (fs.existsSync(p)) {
|
||||
targetPath = p;
|
||||
break;
|
||||
}
|
||||
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 (targetPath) {
|
||||
let content = fs.readFileSync(targetPath, "utf8");
|
||||
|
||||
// Patch the filter: allow string entrypoints for modules
|
||||
const filterPatch = "extension.host === \"app\" && (extension.entrypoint.app || extension.entrypoint)";
|
||||
if (!content.includes(filterPatch)) {
|
||||
content = content.replace(
|
||||
/extension\.host === \"app\" && !!extension\.entrypoint\.app/g,
|
||||
filterPatch
|
||||
);
|
||||
}
|
||||
|
||||
// Patch all imports: handle string entrypoints
|
||||
if (!content.includes("(extension.entrypoint.app || extension.entrypoint)")) {
|
||||
content = content.replace(
|
||||
/extension\.entrypoint\.app/g,
|
||||
"(extension.entrypoint.app || extension.entrypoint)"
|
||||
);
|
||||
}
|
||||
|
||||
fs.writeFileSync(targetPath, content);
|
||||
console.log(`✅ Core patched successfully at ${targetPath}.`);
|
||||
} else {
|
||||
console.error("⚠️ Could not find @directus/extensions node.js to patch!");
|
||||
}
|
||||
'
|
||||
|
||||
echo "🔄 Restarting Directus container: $CONTAINER..."
|
||||
docker restart "$CONTAINER"
|
||||
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 is not running or not found. Skipping patch."
|
||||
echo "ℹ️ Container $CONTAINER not found. Skipping."
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✨ Patching process finished."
|
||||
echo "✨ All patches check complete."
|
||||
|
||||
Reference in New Issue
Block a user