121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
const express = require('express');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const app = express();
|
|
const PORT = process.env.PORT || 80;
|
|
|
|
// Caminhos dos arquivos
|
|
const SECRETS_PATH = process.env.SECRETS_PATH || '/root/Apps/segredos.md';
|
|
const KEYS_JSON_PATH = path.join(__dirname, 'keys.json');
|
|
const KEYS_HTML_PATH = path.join(__dirname, 'index.html');
|
|
|
|
app.use(express.json());
|
|
|
|
// Rota para servir o app
|
|
app.get('/', (req, res) => {
|
|
res.sendFile(KEYS_HTML_PATH);
|
|
});
|
|
|
|
// Servir o JSON de forma dinâmica (sempre sincronizado)
|
|
app.get('/keys.json', (req, res) => {
|
|
try {
|
|
const data = syncAndGetJson();
|
|
res.json(data);
|
|
} catch (err) {
|
|
console.error('Erro ao sincronizar:', err);
|
|
// Fallback para o arquivo local se a sincronização falhar
|
|
if (fs.existsSync(KEYS_JSON_PATH)) {
|
|
res.sendFile(KEYS_JSON_PATH);
|
|
} else {
|
|
res.status(500).send('Erro ao carregar dados');
|
|
}
|
|
}
|
|
});
|
|
|
|
// Endpoint explícito de sync
|
|
app.get('/api/sync', (req, res) => {
|
|
try {
|
|
const data = syncAndGetJson();
|
|
res.json({ success: true, lastUpdated: data.lastUpdated });
|
|
} catch (err) {
|
|
res.status(500).json({ success: false, error: err.message });
|
|
}
|
|
});
|
|
|
|
// Servir outros arquivos estáticos
|
|
app.use(express.static(__dirname));
|
|
|
|
function syncAndGetJson() {
|
|
let currentData = { version: "1.0", lastUpdated: new Date().toISOString(), credentials: [], metadata: { categories: { destino: [], "tipo-dado": [] } } };
|
|
|
|
// Tenta carregar dados existentes para manter IDs e infos que não estão no segredos.md
|
|
if (fs.existsSync(KEYS_JSON_PATH)) {
|
|
currentData = JSON.parse(fs.readFileSync(KEYS_JSON_PATH, 'utf8'));
|
|
}
|
|
|
|
if (!fs.existsSync(SECRETS_PATH)) return currentData;
|
|
|
|
const markdown = fs.readFileSync(SECRETS_PATH, 'utf8');
|
|
|
|
// 1. Extrair Seções e Linhas de Credenciais
|
|
// Padrão: - **Nome:** `Valor`
|
|
const credentialRegex = /- \*\*([^*]+):\*\* `([^`]+)`/g;
|
|
let match;
|
|
const foundValues = new Map();
|
|
|
|
while ((match = credentialRegex.exec(markdown)) !== null) {
|
|
foundValues.set(match[1].trim(), match[2].trim());
|
|
}
|
|
|
|
// 2. Extrair Tabelas (Resumo e APIs)
|
|
const tableRegex = /\|([^|]+)\|([^|]+)\|([^|]+)\|/g;
|
|
while ((match = tableRegex.exec(markdown)) !== null) {
|
|
const col1 = match[1].trim();
|
|
const col2 = match[2].trim();
|
|
const col3 = match[3].trim();
|
|
|
|
if (col1 && col1 !== 'Recurso' && col1 !== 'Serviço / Site' && col1 !== 'Provedor' && !col1.includes('---')) {
|
|
foundValues.set(col1, { user: col2, pass: col3 });
|
|
}
|
|
}
|
|
|
|
// 3. Atualizar ou Criar Credenciais no JSON
|
|
foundValues.forEach((val, name) => {
|
|
let cred = currentData.credentials.find(c => c.name.includes(name) || name.includes(c.name));
|
|
|
|
const isTableEntry = typeof val === 'object';
|
|
const displayValue = isTableEntry ? val.pass : val;
|
|
const loginUser = isTableEntry ? val.user : null;
|
|
|
|
if (cred) {
|
|
cred.value = displayValue;
|
|
if (loginUser && loginUser !== '-') cred.loginUsername = loginUser;
|
|
cred.updatedAt = new Date().toISOString().split('T')[0];
|
|
} else {
|
|
// Criar nova se não existir (ID simplificado)
|
|
currentData.credentials.push({
|
|
id: `sync-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
|
|
name: name,
|
|
category: "infraestrutura",
|
|
dataType: name.toLowerCase().includes('token') ? 'token' : 'password',
|
|
value: displayValue,
|
|
loginUsername: (loginUser && loginUser !== '-') ? loginUser : null,
|
|
createdAt: new Date().toISOString().split('T')[0],
|
|
updatedAt: new Date().toISOString().split('T')[0],
|
|
tags: ["auto-sync"]
|
|
});
|
|
}
|
|
});
|
|
|
|
currentData.lastUpdated = new Date().toISOString();
|
|
|
|
// Salva o JSON atualizado
|
|
fs.writeFileSync(KEYS_JSON_PATH, JSON.stringify(currentData, null, 2));
|
|
|
|
return currentData;
|
|
}
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`VaultUI Server rodando na porta ${PORT}`);
|
|
});
|