Initial PlayBull release with Trilogy Hub integration.
Includes homelab deploy tooling, image position/zoom manifest persistence, and full trading/casino stack. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
70
server/auth.js
Normal file
70
server/auth.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import bcrypt from 'bcryptjs';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { config } from './config.js';
|
||||
import { Users } from './db.js';
|
||||
|
||||
const COOKIE = 'pb_token';
|
||||
|
||||
export function signToken(user) {
|
||||
return jwt.sign({ id: user.id, username: user.username }, config.JWT_SECRET, { expiresIn: '30d' });
|
||||
}
|
||||
|
||||
export function setAuthCookie(res, token) {
|
||||
res.cookie(COOKIE, token, {
|
||||
httpOnly: true,
|
||||
sameSite: 'lax',
|
||||
maxAge: 30 * 24 * 60 * 60 * 1000,
|
||||
});
|
||||
}
|
||||
|
||||
export function clearAuthCookie(res) {
|
||||
res.clearCookie(COOKIE);
|
||||
}
|
||||
|
||||
function readToken(req) {
|
||||
const c = req.cookies?.[COOKIE];
|
||||
if (c) return c;
|
||||
const h = req.headers.authorization;
|
||||
if (h && h.startsWith('Bearer ')) return h.slice(7);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Haengt req.user an, wenn eingeloggt (sonst null). Blockiert nicht.
|
||||
export function optionalAuth(req, _res, next) {
|
||||
req.user = null;
|
||||
const token = readToken(req);
|
||||
if (token) {
|
||||
try {
|
||||
const decoded = jwt.verify(token, config.JWT_SECRET);
|
||||
const u = Users.byId(decoded.id);
|
||||
if (u) req.user = u;
|
||||
} catch { /* ungueltig -> Gast */ }
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
// Erzwingt Login (fuer Gamble & Trades).
|
||||
export function requireAuth(req, res, next) {
|
||||
if (!req.user) return res.status(401).json({ error: 'Login erforderlich' });
|
||||
next();
|
||||
}
|
||||
|
||||
export async function registerUser(username, password) {
|
||||
username = String(username || '').trim();
|
||||
if (username.length < 3 || username.length > 20) throw new Error('Username: 3-20 Zeichen');
|
||||
if (!/^[a-zA-Z0-9_]+$/.test(username)) throw new Error('Nur Buchstaben, Zahlen, _');
|
||||
if (String(password || '').length < 4) throw new Error('Passwort: min. 4 Zeichen');
|
||||
if (Users.byName(username)) throw new Error('Username bereits vergeben');
|
||||
const hash = await bcrypt.hash(password, 10);
|
||||
return Users.create(username, hash, config.START_BALANCE);
|
||||
}
|
||||
|
||||
export async function loginUser(username, password) {
|
||||
const u = Users.byName(String(username || '').trim());
|
||||
if (!u) throw new Error('Falscher Username oder Passwort');
|
||||
const ok = await bcrypt.compare(String(password || ''), u.password_hash);
|
||||
if (!ok) throw new Error('Falscher Username oder Passwort');
|
||||
return u;
|
||||
}
|
||||
|
||||
export { COOKIE };
|
||||
Reference in New Issue
Block a user