Files
shokuninmarche/routes/auth.js
Fullstack Developer e003c7146d Initial fullstack scaffold: Events, Guests, Budget, Bookings
- Express backend with PostgreSQL (JWT auth, full CRUD)
- React + Vite + TailwindCSS frontend in Hebrew (RTL)
- Features: Digital Booking System, Guest Management, Smart Budget Management
- Docker Compose with postgres healthcheck
- Auto-runs migrations on startup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 18:28:03 +00:00

75 lines
2.4 KiB
JavaScript

const express = require('express');
const router = express.Router();
const pool = require('../db');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const JWT_SECRET = process.env.JWT_SECRET || 'airewit-secret-key-2026';
// Register
router.post('/register', async (req, res) => {
const { email, name, password } = req.body;
if (!email || !name || !password) {
return res.status(400).json({ error: 'Missing required fields' });
}
try {
const hashed = await bcrypt.hash(password, 10);
const result = await pool.query(
'INSERT INTO users (email, name, password) VALUES ($1, $2, $3) RETURNING id, email, name, created_at',
[email, name, hashed]
);
const user = result.rows[0];
const token = jwt.sign({ userId: user.id }, JWT_SECRET, { expiresIn: '7d' });
res.status(201).json({ token, user });
} catch (err) {
if (err.code === '23505') {
return res.status(409).json({ error: 'Email already registered' });
}
console.error(err);
res.status(500).json({ error: 'Server error' });
}
});
// Login
router.post('/login', async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ error: 'Missing email or password' });
}
try {
const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]);
if (result.rows.length === 0) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const user = result.rows[0];
const valid = await bcrypt.compare(password, user.password);
if (!valid) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const token = jwt.sign({ userId: user.id }, JWT_SECRET, { expiresIn: '7d' });
res.json({ token, user: { id: user.id, email: user.email, name: user.name } });
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Server error' });
}
});
// Middleware
function authMiddleware(req, res, next) {
const auth = req.headers.authorization;
if (!auth || !auth.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
const token = auth.split(' ')[1];
const payload = jwt.verify(token, JWT_SECRET);
req.userId = payload.userId;
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}
module.exports = router;
module.exports.authMiddleware = authMiddleware;