import fs from 'fs'; import path from 'path'; import crypto from 'crypto'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const USERS_FILE = process.env.PICUPPER_USERS_FILE || path.join(__dirname, 'users.json'); /** * Load users from JSON file */ export function loadUsers() { if (!fs.existsSync(USERS_FILE)) { return {}; } try { const data = fs.readFileSync(USERS_FILE, 'utf-8'); return JSON.parse(data); } catch (error) { console.error('Error loading users file:', error.message); return {}; } } /** * Save users to JSON file */ export function saveUsers(users) { fs.writeFileSync(USERS_FILE, JSON.stringify(users, null, 2)); } /** * Generate a secure API key */ export function generateApiKey() { return crypto.randomBytes(32).toString('hex'); } /** * Add a new user with generated API key */ export function addUser(username, description = '') { const users = loadUsers(); if (users[username]) { throw new Error(`User '${username}' already exists`); } const apiKey = generateApiKey(); users[username] = { apiKey, description, createdAt: new Date().toISOString(), enabled: true }; saveUsers(users); return apiKey; } /** * Remove a user */ export function removeUser(username) { const users = loadUsers(); if (!users[username]) { throw new Error(`User '${username}' not found`); } delete users[username]; saveUsers(users); } /** * Regenerate API key for a user */ export function regenerateApiKey(username) { const users = loadUsers(); if (!users[username]) { throw new Error(`User '${username}' not found`); } const newApiKey = generateApiKey(); users[username].apiKey = newApiKey; users[username].keyRegeneratedAt = new Date().toISOString(); saveUsers(users); return newApiKey; } /** * Enable/disable a user */ export function setUserEnabled(username, enabled) { const users = loadUsers(); if (!users[username]) { throw new Error(`User '${username}' not found`); } users[username].enabled = enabled; saveUsers(users); } /** * List all users (without exposing full API keys) */ export function listUsers() { const users = loadUsers(); return Object.entries(users).map(([username, data]) => ({ username, description: data.description, createdAt: data.createdAt, enabled: data.enabled, keyPreview: data.apiKey.substring(0, 8) + '...' })); } /** * Validate an API key and return the username if valid */ export function validateApiKey(apiKey) { const users = loadUsers(); for (const [username, data] of Object.entries(users)) { if (data.apiKey === apiKey && data.enabled) { return username; } } return null; }