Files
susan-scripts/decrypt_bookmarks.js
Caine c7956ae9b2 Initial commit: susan automation scripts
Overnight transcoding, music discovery/import, system health reports,
stats page generator, and bookmark management.

Secrets stored in /etc/automation/ — not in repo.
2026-02-15 09:41:49 +00:00

35 lines
1.2 KiB
JavaScript

#!/usr/bin/env node
// Decrypt Floccus bookmarks
// Usage: node decrypt_bookmarks.js [password]
const crypto = require('crypto');
const fs = require('fs');
const BOOKMARKS_PATH = '/var/www/webdav/bookmarks.xbel';
const password = process.argv[2] || process.env.BOOKMARKS_PASSWORD || JSON.parse(require('fs').readFileSync('/etc/automation/bookmarks.json', 'utf8')).password;
const data = JSON.parse(fs.readFileSync(BOOKMARKS_PATH, 'utf8'));
const ciphertext = Buffer.from(data.ciphertext, 'base64');
const salt = data.salt; // Floccus uses salt as UTF-8 string, not hex-decoded
// Floccus encryption: PBKDF2-SHA256, 250000 iterations
const key = crypto.pbkdf2Sync(password, salt, 250000, 32, 'sha256');
// 16-byte IV at start, then ciphertext, then 16-byte GCM tag at end
const iv = ciphertext.slice(0, 16);
const encrypted = ciphertext.slice(16, -16);
const tag = ciphertext.slice(-16);
try {
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
decipher.setAuthTag(tag);
let decrypted = decipher.update(encrypted);
decrypted = Buffer.concat([decrypted, decipher.final()]);
console.log(decrypted.toString('utf8'));
} catch (e) {
console.error('Decryption failed:', e.message);
process.exit(1);
}