Server
Core Server Utilities
Examples for rateLimiter.js, metrics.js, and mailer.js.
Rate limiter + failure penalty
const Redis = require('ioredis');
const express = require('express');
const { buildIpRateLimiter, buildFailurePenalty, hashIp } = require('@epheme/core/rateLimiter');
const app = express();
const redis = new Redis(process.env.REDIS_URL);
const roomInfoLimiter = buildIpRateLimiter(redis, 'room_info', 60, 30, 'ROOM_INFO_RATE_LIMIT');
const { penaltyMiddleware, recordFailure } = buildFailurePenalty(redis, 'room_enum');
app.get('/api/rooms/:roomId/info', roomInfoLimiter, penaltyMiddleware, async (req, res) => {
const room = null; // fetch room
if (!room) {
recordFailure(hashIp(req.ip));
return res.status(404).json({ error: 'Room not found' });
}
res.json(room);
});
Anonymous traffic metrics
const express = require('express');
const { recordHit, getStats } = require('@epheme/core/metrics');
const app = express();
app.use((req, res, next) => {
recordHit(); // fire-and-forget, no identities stored
next();
});
app.get('/admin/traffic', async (_req, res) => {
const stats = await getStats();
res.json(stats); // { hitsToday, hitsPast5m }
});
Mailer
const express = require('express');
const { sendMail, isEmailEnabled } = require('@epheme/core/mailer');
const app = express();
app.use(express.json());
app.post('/invite', async (req, res) => {
if (!isEmailEnabled()) return res.status(503).json({ error: 'SMTP not configured' });
await sendMail({
to: req.body.email,
subject: 'Invite',
text: 'You have been invited to Epheme.',
html: 'You have been invited to Epheme.
',
});
res.json({ sent: true });
});