Files
sloth-manager/backend/src/secrets.js
T
2026-06-02 01:00:27 +02:00

98 lines
2.7 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const SECRETS_PATH = process.env.SECRETS_PATH || path.join(__dirname, '..', 'secrets.json');
const SECRET_TYPES = ['api_token', 'ssl_certificate', 'password', 'generic'];
function load() {
try {
return JSON.parse(fs.readFileSync(SECRETS_PATH, 'utf8'));
} catch {
return [];
}
}
function save(secrets) {
fs.writeFileSync(SECRETS_PATH, JSON.stringify(secrets, null, 2), 'utf8');
}
function getAll() {
return load();
}
function getById(id) {
return load().find(s => s.id === id) ?? null;
}
function create(data) {
const secrets = load();
const secret = {
id: Date.now().toString(),
name: data.name,
type: data.type || 'generic',
description: data.description || '',
expires_at: data.expires_at,
warning_days: Number(data.warning_days) || 30,
notes: data.notes || '',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
};
secrets.push(secret);
save(secrets);
return secret;
}
function update(id, data) {
const secrets = load();
const idx = secrets.findIndex(s => s.id === id);
if (idx === -1) throw new Error('Secret not found');
secrets[idx] = {
...secrets[idx],
name: data.name ?? secrets[idx].name,
type: data.type ?? secrets[idx].type,
description: data.description ?? secrets[idx].description,
expires_at: data.expires_at ?? secrets[idx].expires_at,
warning_days: data.warning_days !== undefined ? Number(data.warning_days) : secrets[idx].warning_days,
notes: data.notes ?? secrets[idx].notes,
updated_at: new Date().toISOString(),
};
save(secrets);
return secrets[idx];
}
function remove(id) {
const secrets = load();
const filtered = secrets.filter(s => s.id !== id);
if (filtered.length === secrets.length) throw new Error('Secret not found');
save(filtered);
}
/**
* Returns secrets grouped by expiry status.
* Status: 'expired' | 'warning' | 'ok'
*/
function getStatus() {
const secrets = load();
const now = new Date();
return secrets.map(s => {
const expiry = new Date(s.expires_at);
const daysLeft = Math.ceil((expiry - now) / (1000 * 60 * 60 * 24));
let status;
if (daysLeft < 0) status = 'expired';
else if (daysLeft <= s.warning_days) status = 'warning';
else status = 'ok';
return { ...s, daysLeft, status };
});
}
/**
* Returns secrets that are expired or within their warning window.
*/
function getExpiring() {
return getStatus().filter(s => s.status !== 'ok');
}
module.exports = { SECRET_TYPES, getAll, getById, create, update, remove, getStatus, getExpiring };