Spaces:
Paused
Paused
File size: 3,616 Bytes
498f280 63383e6 498f280 63383e6 498f280 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | /**
* Provider Auth Controller - Independent Authentication for Hotel & Service Providers
*/
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { getPool } = require('../db');
const PROVIDER_JWT_SECRET = process.env.PROVIDER_JWT_SECRET;
const JWT_EXPIRES_IN = '12h';
// Security check: Ensure PROVIDER_JWT_SECRET is configured
if (!PROVIDER_JWT_SECRET) {
console.error('⚠️ SECURITY WARNING: PROVIDER_JWT_SECRET environment variable is not set!');
if (process.env.NODE_ENV === 'production') {
console.error('❌ FATAL: Cannot run in production without PROVIDER_JWT_SECRET');
process.exit(1);
}
}
/**
* Generate JWT for Hotel/Service Provider
*/
function generateToken(provider) {
return jwt.sign(
{
id: provider.id,
username: provider.username,
email: provider.email,
role: 'hotel_provider',
provider_type: provider.provider_type
},
PROVIDER_JWT_SECRET,
{ expiresIn: JWT_EXPIRES_IN }
);
}
/**
* Register Hotel/Service Provider
*/
async function register(req, res) {
const { username, email, password, name, provider_type = 'hotel' } = req.body;
const pool = getPool();
if (!pool) return res.status(500).json({ error: 'Database not connected' });
try {
const existing = await pool.query('SELECT id FROM service_providers WHERE email = $1 OR username = $2', [email, username]);
if (existing.rows.length > 0) {
return res.status(400).json({ error: 'Provider account already exists' });
}
const hashedPassword = await bcrypt.hash(password, 12);
const result = await pool.query(
'INSERT INTO service_providers (username, email, password_hash, name, provider_type) VALUES ($1, $2, $3, $4, $5) RETURNING id, username, email, name, provider_type',
[username, email, hashedPassword, name, provider_type]
);
const provider = result.rows[0];
const token = generateToken(provider);
res.status(201).json({ user: provider, token });
} catch (error) {
console.error('[Provider Register Error]', error.message);
res.status(500).json({ error: 'Failed to register provider staff' });
}
}
/**
* Login Hotel/Service Provider
*/
async function login(req, res) {
const { email, password } = req.body;
const pool = getPool();
if (!pool) return res.status(500).json({ error: 'Database not connected' });
try {
const result = await pool.query('SELECT * FROM service_providers WHERE email = $1', [email]);
if (result.rows.length === 0) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const provider = result.rows[0];
const valid = await bcrypt.compare(password, provider.password_hash);
if (!valid) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const token = generateToken(provider);
delete provider.password_hash;
res.json({ user: provider, token });
} catch (error) {
console.error('[Provider Login Error]', error.message);
res.status(500).json({ error: 'Login failed' });
}
}
/**
* Get current provider profile
*/
async function getMe(req, res) {
const pool = getPool();
try {
const result = await pool.query('SELECT id, username, email, name, provider_type FROM service_providers WHERE id = $1', [req.user.id]);
if (result.rows.length === 0) return res.status(404).json({ error: 'Provider not found' });
res.json({ user: result.rows[0] });
} catch (error) {
res.status(500).json({ error: 'Failed to fetch profile' });
}
}
module.exports = { register, login, getMe };
|