const express = require('express'); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); const cors = require('cors'); const mysql = require('mysql2/promise'); require('dotenv').config({ path: '../.env' }); const app = express(); const PORT = process.env.AUTH_PORT || 3011; // Database configuration const dbConfig = { host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, }; // Create a connection pool const pool = mysql.createPool(dbConfig); app.use(cors({ origin: [ 'https://inventory.kent.pw', 'http://localhost:5173', 'http://127.0.0.1:5173', /^http:\/\/192\.168\.\d+\.\d+(:\d+)?$/, /^http:\/\/10\.\d+\.\d+\.\d+(:\d+)?$/ ], methods: ['GET', 'POST', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'], credentials: true, exposedHeaders: ['set-cookie'] })); app.use(express.json()); // Debug middleware to log request details app.use((req, res, next) => { console.log('Request details:', { method: req.method, url: req.url, origin: req.get('Origin'), headers: req.headers, body: req.body, }); next(); }); // Registration endpoint app.post('/register', async (req, res) => { try { const { username, password } = req.body; const hashedPassword = await bcrypt.hash(password, 10); const connection = await pool.getConnection(); await connection.query('INSERT INTO users (username, password) VALUES (?, ?)', [username, hashedPassword]); connection.release(); res.status(201).json({ message: 'User registered successfully' }); } catch (error) { console.error('Registration error:', error); res.status(500).json({ error: 'Registration failed' }); } }); // Login endpoint app.post('/login', async (req, res) => { try { const { username, password } = req.body; console.log(`Login attempt for user: ${username}`); const connection = await pool.getConnection(); const [rows] = await connection.query( 'SELECT * FROM users WHERE username = ?', [username], ); connection.release(); if (rows.length === 1) { const user = rows[0]; const passwordMatch = await bcrypt.compare(password, user.password); if (passwordMatch) { console.log(`User ${username} authenticated successfully`); const token = jwt.sign( { username: user.username }, process.env.JWT_SECRET, { expiresIn: '1h' }, ); res.json({ token }); } else { console.error(`Invalid password for user: ${username}`); res.status(401).json({ error: 'Invalid credentials' }); } } else { console.error(`User not found: ${username}`); res.status(401).json({ error: 'Invalid credentials' }); } } catch (error) { console.error('Login error:', error); res.status(500).json({ error: 'Login failed' }); } }); // Protected endpoint example app.get('/protected', async (req, res) => { const authHeader = req.headers.authorization; if (!authHeader) { return res.status(401).json({ error: 'Unauthorized' }); } const token = authHeader.split(' ')[1]; try { const decoded = jwt.verify(token, process.env.JWT_SECRET); // Optionally, you can fetch the user from the database here // to verify that the user still exists or to get more user information const connection = await pool.getConnection(); const [rows] = await connection.query('SELECT * FROM users WHERE username = ?', [decoded.username]); connection.release(); if (rows.length === 0) { return res.status(401).json({ error: 'User not found' }); } res.json({ message: 'Protected resource accessed', user: decoded }); } catch (error) { console.error('Protected endpoint error:', error); res.status(403).json({ error: 'Invalid token' }); } }); app.listen(PORT, "0.0.0.0", () => { console.log(`Auth server running on port ${PORT}`); });