initial commit
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
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 };
|
||||
Reference in New Issue
Block a user