initial commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env node
|
||||
// Tiny webhook receiver: validates the shared secret, then shells out to rebuild.sh.
|
||||
// Run on the homeserver (NOT inside docker) on port 4321.
|
||||
//
|
||||
// WEBHOOK_PORT=4321 REPO_DIR=/opt/softvowels REBUILD_TOKEN=change-me node scripts/webhook.js
|
||||
//
|
||||
// Or via the included systemd unit (see scripts/softvowels-webhook.service).
|
||||
|
||||
import { createServer } from 'node:http';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { writeFileSync } from 'node:fs';
|
||||
|
||||
const PORT = Number(process.env.WEBHOOK_PORT || 4321);
|
||||
const TOKEN = process.env.REBUILD_TOKEN || process.env.ASTRO_REVALIDATE_TOKEN;
|
||||
const REPO = process.env.REPO_DIR || '/opt/softvowels';
|
||||
const SCRIPT = process.env.REBUILD_SCRIPT || `${REPO}/scripts/rebuild.sh`;
|
||||
const LOG = process.env.LOG_FILE || '/var/log/softvowels-rebuild.log';
|
||||
|
||||
if (!TOKEN) {
|
||||
console.error('REBUILD_TOKEN is required');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function log(line) {
|
||||
const ts = new Date().toISOString();
|
||||
const msg = `[${ts}] ${line}\n`;
|
||||
try {
|
||||
writeFileSync(LOG, msg, { flag: 'a' });
|
||||
} catch {
|
||||
/* noop */
|
||||
}
|
||||
process.stdout.write(msg);
|
||||
}
|
||||
|
||||
function triggerRebuild(collection, op) {
|
||||
log(`Trigger rebuild for ${collection}.${op}`);
|
||||
const child = spawn('bash', [SCRIPT], { detached: true, stdio: 'ignore' });
|
||||
child.unref();
|
||||
}
|
||||
|
||||
const server = createServer((req, res) => {
|
||||
if (req.method !== 'POST' || req.url === '/') {
|
||||
res.writeHead(405);
|
||||
res.end('Method Not Allowed');
|
||||
return;
|
||||
}
|
||||
const url = new URL(req.url, 'http://x');
|
||||
const secret = url.searchParams.get('secret');
|
||||
const collection = url.searchParams.get('collection') ?? 'unknown';
|
||||
const op = url.searchParams.get('op') ?? 'change';
|
||||
if (secret !== TOKEN) {
|
||||
log(`Bad secret from ${req.socket.remoteAddress}`);
|
||||
res.writeHead(401);
|
||||
res.end('Unauthorized');
|
||||
return;
|
||||
}
|
||||
triggerRebuild(collection, op);
|
||||
res.writeHead(202, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ ok: true, queued: true }));
|
||||
});
|
||||
|
||||
server.listen(PORT, '127.0.0.1', () => {
|
||||
log(`Webhook listening on http://127.0.0.1:${PORT}/__revalidate`);
|
||||
});
|
||||
Reference in New Issue
Block a user