WeightTracker/auth-middleware.js

104 lines
2.5 KiB
JavaScript

/**
* Authentication Middleware for Weight Tracker
* Handles password protection and session management
*/
const bcrypt = require('bcryptjs');
const session = require('express-session');
const cookieParser = require('cookie-parser');
// Default session configuration
const sessionConfig = {
secret: process.env.SESSION_SECRET || 'weight-tracker-secret',
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.COOKIE_SECURE === 'true',
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}
};
/**
* Initialize authentication middleware
* @param {Object} app - Express app
*/
function initAuth(app) {
// Parse cookies
app.use(cookieParser());
// Session management
app.use(session(sessionConfig));
// Serve login page
app.get('/login', (req, res) => {
if (req.session.authenticated) {
return res.redirect('/');
}
res.sendFile('login.html', { root: __dirname });
});
// Handle login form submission
app.post('/auth/login', (req, res) => {
const { password } = req.body;
const storedHash = process.env.PASSWORD_HASH;
if (!storedHash) {
console.error('PASSWORD_HASH environment variable not set');
return res.redirect('/login?error=config');
}
// Verify password
bcrypt.compare(password, storedHash, (err, isMatch) => {
if (err) {
console.error('Error verifying password:', err);
return res.redirect('/login?error=server');
}
if (isMatch) {
// Set session as authenticated
req.session.authenticated = true;
res.redirect('/');
} else {
res.redirect('/login?error=invalid');
}
});
});
// Logout endpoint
app.get('/auth/logout', (req, res) => {
req.session.destroy();
res.redirect('/login');
});
// Authentication middleware for all other routes
app.use((req, res, next) => {
// Skip auth for login-related routes
if (req.path === '/login' || req.path === '/auth/login') {
return next();
}
// Check if user is authenticated
if (req.session.authenticated) {
return next();
}
// Redirect to login page
res.redirect('/login');
});
}
/**
* Generate a password hash (utility function)
* @param {string} password - Plain text password
* @returns {Promise<string>} - Hashed password
*/
function generateHash(password) {
return bcrypt.hash(password, 10);
}
module.exports = {
initAuth,
generateHash
};