const express = require('express'); const router = express.Router(); const pool = require('../../db'); const crypto = require('crypto'); const { promisify } = require('util'); const { sanitizeLoginInput } = require('../../middleware/sanitize_person_input'); const { strictInput } = require('../../middleware/strict_input'); const { signToken } = require('../../middleware/authenticate_token'); const scrypt = promisify(crypto.scrypt); async function login(req, res) { try { const { email, password } = req.loginInput; const { rows } = await pool.query( 'SELECT id, password FROM people WHERE email = $1', [email] ); if (rows.length === 0) { res.status(401).send('Invalid email or password'); return; } const [salt, storedKeyHex] = rows[0].password.split(':'); const storedKey = Buffer.from(storedKeyHex || '', 'hex'); const derivedKey = await scrypt(password, salt, 64); if ( storedKey.length !== derivedKey.length || !crypto.timingSafeEqual(storedKey, derivedKey) ) { res.status(401).send('Invalid email or password'); return; } const { token, expiresAt } = signToken(rows[0].id); res.cookie('fc_session_token', token, { httpOnly: true, secure: true, sameSite: 'Strict', path: '/', }); res.status(200).json({ id: rows[0].id, token, expires_at: expiresAt }); } catch (err) { console.error('login failed', { message: err.message, code: err.code }); res.status(500).send('Login failed, request could not be completed'); } }; router.post('/', strictInput({ body: ['email', 'password'] }), sanitizeLoginInput, login); module.exports = router;