From 7921929f733ef89c90da177a2b377283efb62475 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 20 May 2026 11:22:45 +0200 Subject: [PATCH] feat: add Bearer token authentication All /api/* routes require Authorization: Bearer . Tokens are configured via API_TOKENS env var (comma-separated for multiple). /health remains public for Coolify health checks. Co-Authored-By: Claude Sonnet 4.6 --- src/index.js | 5 +++-- src/middleware/auth.js | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 src/middleware/auth.js diff --git a/src/index.js b/src/index.js index 6d3b8d4..f8405a1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ require('dotenv').config(); const express = require('express'); const cors = require('cors'); +const auth = require('./middleware/auth'); const { pool } = require('./db'); const app = express(); @@ -20,8 +21,8 @@ app.get('/health', async (req, res) => { res.json({ status: 'ok', db }); }); -// Routes -app.use('/api', require('./routes/index')); +// Routes — protected by Bearer token +app.use('/api', auth, require('./routes/index')); // 404 app.use((req, res) => { diff --git a/src/middleware/auth.js b/src/middleware/auth.js new file mode 100644 index 0000000..4b804f2 --- /dev/null +++ b/src/middleware/auth.js @@ -0,0 +1,12 @@ +const TOKENS = (process.env.API_TOKENS || '').split(',').map(t => t.trim()).filter(Boolean); + +module.exports = function auth(req, res, next) { + const header = req.headers['authorization'] || ''; + const token = header.startsWith('Bearer ') ? header.slice(7) : null; + + if (!token || !TOKENS.includes(token)) { + return res.status(401).json({ error: 'Unauthorized' }); + } + + next(); +};