When a user submits a credit request, an email is sent to all configured NOTIFY_TO recipients with approve buttons (5M, 10M, 20M), a custom amount option, and a reject button. Each button is a signed HMAC-SHA256 webhook URL that expires after WEBHOOK_TTL_HOURS. Clicking approve from email processes the top-up identical to the admin dashboard — balance update, history log, request status change. Double-approval protection prevents the same link from being used twice. Portal approval still works alongside email approval. New dependencies: nodemailer New files: services/email.js, routes/webhooks.js Modified: server.js, routes/requests.js, .env.example Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
70 lines
1.9 KiB
JavaScript
70 lines
1.9 KiB
JavaScript
require('dotenv').config();
|
|
const express = require('express');
|
|
const path = require('path');
|
|
const { MongoClient } = require('mongodb');
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3002;
|
|
const MONGO_URI = process.env.MONGO_URI || 'mongodb://localhost:27017/LibreChat';
|
|
const API_KEY = process.env.API_KEY || 'change-me';
|
|
|
|
let db;
|
|
|
|
async function connectDB() {
|
|
const client = new MongoClient(MONGO_URI);
|
|
await client.connect();
|
|
db = client.db();
|
|
console.log('Connected to MongoDB');
|
|
return db;
|
|
}
|
|
|
|
function authMiddleware(req, res, next) {
|
|
const key = req.headers['x-api-key'] || req.query.key;
|
|
if (key !== API_KEY) {
|
|
return res.status(401).json({ error: 'Unauthorized' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
function dbMiddleware(req, res, next) {
|
|
req.db = db;
|
|
next();
|
|
}
|
|
|
|
app.use(express.json());
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
|
|
const apiRoutes = require('./routes/api');
|
|
const requestRoutes = require('./routes/requests');
|
|
const webhookRoutes = require('./routes/webhooks');
|
|
|
|
// Public: submit a credit request (no auth needed)
|
|
app.use('/api/requests', requestRoutes.publicRouter);
|
|
|
|
// Public: email webhook approve/reject (secured by HMAC tokens)
|
|
app.use('/api/webhooks', webhookRoutes);
|
|
|
|
// Admin: manage credit requests (auth required)
|
|
app.use('/api/admin/requests', authMiddleware, requestRoutes.adminRouter);
|
|
|
|
// Admin: balance management API (auth required)
|
|
app.use('/api', dbMiddleware, authMiddleware, apiRoutes);
|
|
|
|
app.get('/health', (req, res) => res.json({ status: 'ok' }));
|
|
|
|
app.get('/request', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'public', 'request.html'));
|
|
});
|
|
|
|
app.get('*', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
|
});
|
|
|
|
connectDB().then(() => {
|
|
app.listen(PORT, '0.0.0.0', () => {
|
|
console.log(`Balance Manager running on http://localhost:${PORT}`);
|
|
});
|
|
}).catch(err => {
|
|
console.error('Failed to connect to MongoDB:', err);
|
|
process.exit(1);
|
|
});
|