#!/usr/bin/env node /* Sync Vault configs to local confs/ mirror */ process.env.SHELL = process.env.SHELL || '/usr/bin/sh'; const fs = require('fs'); const path = require('path'); // Load env from vault/.env if dotenv is available (function loadEnv() { const dotenvPaths = [ '/home/debian/4NK_env/vault/node_modules/dotenv', '/home/debian/4NK_env/vault/sdk-client/node_modules/dotenv', ]; for (const p of dotenvPaths) { try { require(p).config({ path: path.resolve('/home/debian/4NK_env/vault/.env') }); break; } catch (_) { /* ignore */ } } })(); // Load SDK client (prefer root dist, fallback to sdk-client dist) let sdk; try { sdk = require('/home/debian/4NK_env/vault/dist/index.js'); } catch (e1) { try { sdk = require('/home/debian/4NK_env/vault/sdk-client/dist/index.js'); } catch (e2) { console.error('[fatal] Vault SDK not built. Build it in vault/ or vault/sdk-client first.'); process.exit(2); } } const { createSecureVaultClient } = sdk; const BASE_URL = process.env.VAULT_BASE_URL || 'https://vault.4nkweb.com:6666'; const USER_ID = process.env.VAULT_USER_ID || process.env.VAULT_USER || 'demo_user_001'; const VAULT_ENV = process.env.VAULT_ENV || 'dev'; const ROOT_DIR = '/home/debian/4NK_env'; const OUTPUT_DIR = path.join(ROOT_DIR, 'confs'); const ENCRYPTED_MIRROR_DIR = path.join(ROOT_DIR, 'confs_encrypted_mirror'); function ensureDirSync(dir) { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } } function looksEncryptedPlaceholder(content) { return typeof content === 'string' && content.startsWith('[CONTENU CHIFFRÉ - DÉCHIFFREMENT NÉCESSAIRE]'); } async function main() { console.log(`[vault-sync] base=${BASE_URL} user=${USER_ID} env=${VAULT_ENV}`); const client = createSecureVaultClient(BASE_URL, USER_ID); const routes = await client.getRoutes(); console.log(`[vault-sync] routes: ${routes.total_routes}`); const argFiles = process.argv.slice(2); let files = argFiles.length > 0 ? argFiles : [ 'bitcoin/bitcoin.conf', 'blindbit-oracle/blindbit.toml', 'grafana/grafana.ini', 'loki/loki-config.yaml', 'promtail/promtail.yml', 'relay/sdk_relay.conf' ]; for (const relPath of files) { try { const file = await client.getFile(VAULT_ENV, relPath); const outPath = path.join(OUTPUT_DIR, relPath); const encPath = path.join(ENCRYPTED_MIRROR_DIR, relPath); ensureDirSync(path.dirname(outPath)); ensureDirSync(path.dirname(encPath)); if (looksEncryptedPlaceholder(file.content)) { fs.writeFileSync(encPath, file.content, { encoding: 'utf-8' }); console.warn(`[skip-write] ${outPath} content appears encrypted; saved to ${encPath}`); } else { fs.writeFileSync(outPath, file.content, { encoding: 'utf-8' }); console.log(`[write] ${outPath} (${file.size} bytes)`); } } catch (e) { console.error(`[error] ${relPath}: ${e.message}`); } } console.log('[vault-sync] done'); } main().catch(err => { console.error(err); process.exit(1); });