Initial commit: Sudoku game with accounts, history, leaderboard, themes and i18n

Node/Express + SQLite backend, vanilla JS frontend, deployed via Docker Compose.
This commit is contained in:
2026-08-27 21:24:38 +02:00
commit 00e8dcb7d2
16 changed files with 2405 additions and 0 deletions

60
server/auth.js Normal file
View File

@@ -0,0 +1,60 @@
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const JWT_SECRET = process.env.JWT_SECRET || 'dev-secret-change-me-please';
const COOKIE_NAME = 'sudoku_token';
const TOKEN_TTL = '30d';
const COOKIE_MAX_AGE = 30 * 24 * 60 * 60 * 1000;
function hashPassword(password) {
return bcrypt.hashSync(password, 10);
}
function verifyPassword(password, hash) {
return bcrypt.compareSync(password, hash);
}
function signToken(user) {
return jwt.sign({ id: user.id, pseudo: user.pseudo }, JWT_SECRET, { expiresIn: TOKEN_TTL });
}
function setAuthCookie(res, token) {
res.cookie(COOKIE_NAME, token, {
httpOnly: true,
sameSite: 'lax',
secure: false,
maxAge: COOKIE_MAX_AGE,
});
}
function clearAuthCookie(res) {
res.clearCookie(COOKIE_NAME);
}
function authMiddleware(req, res, next) {
const token = req.cookies ? req.cookies[COOKIE_NAME] : null;
req.user = null;
if (token) {
try {
req.user = jwt.verify(token, JWT_SECRET);
} catch (e) {
req.user = null;
}
}
next();
}
function requireAuth(req, res, next) {
if (!req.user) return res.status(401).json({ error: 'AUTH_REQUIRED' });
next();
}
module.exports = {
hashPassword,
verifyPassword,
signToken,
setAuthCookie,
clearAuthCookie,
authMiddleware,
requireAuth,
};