UNPKG

@nerdlat/auth

Version:

Authentication library similar to Clerk for React and Express applications

148 lines (147 loc) 5.88 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAuthRouter = createAuthRouter; exports.requireAuth = requireAuth; // src/server/createAuthRouter.ts const express_1 = __importDefault(require("express")); const jwt_1 = require("./jwt"); const users_1 = require("./users"); function createAuthRouter(options = {}) { const router = express_1.default.Router(); const cookieName = options.sessionCookie || 'auth-token'; // Middleware para parsear cookies si no existe router.use((req, res, next) => { if (!req.cookies && req.headers.cookie) { req.cookies = {}; req.headers.cookie.split(';').forEach(cookie => { const [name, value] = cookie.trim().split('='); req.cookies[name] = value; }); } next(); }); router.post('/login', async (req, res) => { try { const { email, password } = req.body; if (!email || !password) { return res.status(400).json({ error: 'Email and password are required' }); } const user = users_1.users.find(u => u.email === email && u.password === password); if (!user) { return res.status(401).json({ error: 'Invalid credentials' }); } const token = (0, jwt_1.signToken)(user); const userResponse = { id: user.id, email: user.email }; // No devolver password res.cookie(cookieName, token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', maxAge: 7 * 24 * 60 * 60 * 1000 // 7as }); if (options.onUserLogin) { options.onUserLogin(userResponse); } res.json(userResponse); } catch (error) { res.status(500).json({ error: 'Internal server error' }); } }); router.post('/signup', (req, res) => { try { const { email, password } = req.body; if (!email || !password) { return res.status(400).json({ error: 'Email and password are required' }); } if (options.validateEmail && !options.validateEmail(email)) { return res.status(400).json({ error: 'Invalid email format' }); } if (options.validatePassword && !options.validatePassword(password)) { return res.status(400).json({ error: 'Password does not meet requirements' }); } if (users_1.users.find(u => u.email === email)) { return res.status(400).json({ error: 'User already exists' }); } const id = users_1.users.length + 1; const user = { id, email, password }; users_1.users.push(user); const token = (0, jwt_1.signToken)(user); const userResponse = { id: user.id, email: user.email }; res.cookie(cookieName, token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', maxAge: 7 * 24 * 60 * 60 * 1000 }); if (options.onUserCreate) { options.onUserCreate(userResponse); } res.json(userResponse); } catch (error) { res.status(500).json({ error: 'Internal server error' }); } }); router.get('/me', (req, res) => { try { const token = req.cookies[cookieName]; if (!token) { return res.status(401).json({ error: 'No token provided' }); } const decoded = (0, jwt_1.verifyToken)(token); const user = users_1.users.find(u => u.id === decoded.id); if (!user) { return res.status(401).json({ error: 'User not found' }); } res.json({ id: user.id, email: user.email }); } catch (error) { res.status(401).json({ error: 'Invalid token' }); } }); router.post('/logout', (req, res) => { res.clearCookie(cookieName); res.json({ message: 'Logged out successfully' }); }); router.post('/reset-password', (req, res) => { try { const { email, newPassword } = req.body; if (!email || !newPassword) { return res.status(400).json({ error: 'Email and new password are required' }); } if (options.validatePassword && !options.validatePassword(newPassword)) { return res.status(400).json({ error: 'Password does not meet requirements' }); } const user = users_1.users.find(u => u.email === email); if (!user) { return res.status(404).json({ error: 'User not found' }); } user.password = newPassword; res.json({ message: 'Password reset successfully' }); } catch (error) { res.status(500).json({ error: 'Internal server error' }); } }); return router; } // Middleware para proteger rutas function requireAuth(cookieName = 'auth-token') { return (req, res, next) => { try { const token = req.cookies[cookieName]; if (!token) { return res.status(401).json({ error: 'Authentication required' }); } const decoded = (0, jwt_1.verifyToken)(token); req.user = decoded; // Agregar usuario al request next(); } catch (error) { res.status(401).json({ error: 'Invalid token' }); } }; }