From 00af8862d3f642edc1f38beecfbd703fe562f722 Mon Sep 17 00:00:00 2001 From: Tuan-Dat Tran Date: Mon, 23 Feb 2026 13:47:44 +0100 Subject: [PATCH] feat(api): add backend api with express and sqlite --- backend/.dockerignore | 3 +++ backend/Dockerfile | 18 +++++++++++++++++ backend/middleware/auth.js | 41 ++++++++++++++++++++++++++++++++++++++ backend/vitest.config.js | 8 ++++++++ 4 files changed, 70 insertions(+) create mode 100644 backend/.dockerignore create mode 100644 backend/Dockerfile create mode 100644 backend/middleware/auth.js create mode 100644 backend/vitest.config.js diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..e250b4f --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,3 @@ +node_modules +*.log +.git diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..b95087b --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,18 @@ +FROM node:20-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/* + +COPY package*.json ./ +RUN npm install --omit=dev --ignore-scripts && \ + cd node_modules/better-sqlite3 && \ + npm run build-release + +COPY . . + +RUN mkdir -p /app/data + +EXPOSE 3001 + +CMD ["node", "server.js"] diff --git a/backend/middleware/auth.js b/backend/middleware/auth.js new file mode 100644 index 0000000..b3a30b8 --- /dev/null +++ b/backend/middleware/auth.js @@ -0,0 +1,41 @@ +const tokens = new Set(); + +export function registerToken(token) { + tokens.add(token); +} + +export function revokeToken(token) { + tokens.delete(token); +} + +export function isValidToken(token) { + return tokens.has(token); +} + +export function authMiddleware(req, res, next) { + if (process.env.USE_KEYCLOAK === 'true') { + const authHeader = req.headers.authorization; + if (!authHeader || !authHeader.startsWith('Bearer ')) { + return res.status(401).json({ error: 'Missing bearer token' }); + } + // In Keycloak mode, token validation would happen here + // For now, we accept any bearer token (real Keycloak integration would verify JWT) + return next(); + } + + const authHeader = req.headers.authorization; + if (!authHeader || !authHeader.startsWith('Bearer ')) { + return res.status(401).json({ error: 'Missing bearer token' }); + } + + const token = authHeader.slice(7); + if (!isValidToken(token)) { + return res.status(401).json({ error: 'Invalid token' }); + } + + next(); +} + +export function optionalAuth(req, res, next) { + next(); +} diff --git a/backend/vitest.config.js b/backend/vitest.config.js new file mode 100644 index 0000000..f1881c1 --- /dev/null +++ b/backend/vitest.config.js @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + environment: 'node', + globals: true, + }, +})