Files
inventory/inventory-server/auth/server.js

135 lines
3.9 KiB
JavaScript

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}`);
});