Set up Node.js with advanced security deps
This commit is contained in:
137
server.js
Normal file
137
server.js
Normal file
@@ -0,0 +1,137 @@
|
||||
const express = require('express');
|
||||
const pg = require('pg');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const socketIo = require('socket.io');
|
||||
const http = require('http');
|
||||
const cors = require('cors');
|
||||
const bodyParser = require('body-parser');
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const io = socketIo(server);
|
||||
|
||||
app.use(cors());
|
||||
app.use(bodyParser.json());
|
||||
app.use(express.static('public'));
|
||||
|
||||
const pool = new pg.Pool({
|
||||
user: process.env.POSTGRES_USER,
|
||||
host: process.env.POSTGRES_HOST,
|
||||
database: process.env.POSTGRES_DB,
|
||||
password: process.env.POSTGRES_PASSWORD,
|
||||
port: 5432,
|
||||
});
|
||||
|
||||
// Auth middleware
|
||||
const authenticate = (req, res, next) => {
|
||||
const token = req.headers.authorization?.split(' ')[1];
|
||||
if (!token) return res.status(401).json({ error: 'Unauthorized' });
|
||||
try {
|
||||
const decoded = jwt.verify(token, process.env.SECRET_KEY);
|
||||
req.user = decoded;
|
||||
next();
|
||||
} catch (err) {
|
||||
res.status(401).json({ error: 'Invalid token' });
|
||||
}
|
||||
};
|
||||
|
||||
const isAdmin = (req, res, next) => {
|
||||
if (req.user.role !== 'admin') return res.status(403).json({ error: 'Forbidden' });
|
||||
next();
|
||||
};
|
||||
|
||||
// Routes: Auth
|
||||
app.post('/api/signup', async (req, res) => {
|
||||
const { username, password, email, promoCode } = req.body;
|
||||
const hashedPw = await bcrypt.hash(password, 10);
|
||||
try {
|
||||
const result = await pool.query('INSERT INTO users (username, password, email) VALUES ($1, $2, $3) RETURNING id', [username, hashedPw, email]);
|
||||
let bonus = 0;
|
||||
if (promoCode) {
|
||||
const promo = await pool.query('SELECT * FROM promo_codes WHERE code = $1 AND used = FALSE', [promoCode]);
|
||||
if (promo.rows[0]) {
|
||||
bonus = promo.rows[0].value;
|
||||
await pool.query('UPDATE promo_codes SET used = TRUE, user_id = $1 WHERE id = $2', [result.rows[0].id, promo.rows[0].id]);
|
||||
await pool.query('UPDATE users SET balance = balance + $1 WHERE id = $2', [bonus, result.rows[0].id]);
|
||||
}
|
||||
}
|
||||
res.json({ message: 'User created', bonus });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/login', async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
try {
|
||||
const user = await pool.query('SELECT * FROM users WHERE username = $1', [username]);
|
||||
if (!user.rows[0] || !(await bcrypt.compare(password, user.rows[0].password))) {
|
||||
return res.status(401).json({ error: 'Invalid credentials' });
|
||||
}
|
||||
const token = jwt.sign({ id: user.rows[0].id, role: user.rows[0].role }, process.env.SECRET_KEY, { expiresIn: '1h' });
|
||||
res.json({ token, balance: user.rows[0].balance });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Games API (example for bet/result)
|
||||
app.post('/api/bet', authenticate, async (req, res) => {
|
||||
const { gameId, amount } = req.body;
|
||||
try {
|
||||
const game = await pool.query('SELECT * FROM games WHERE id = $1 AND enabled = TRUE', [gameId]);
|
||||
if (!game.rows[0] || amount < game.rows[0].min_bet || amount > game.rows[0].max_bet) {
|
||||
return res.status(400).json({ error: 'Invalid bet' });
|
||||
}
|
||||
const user = await pool.query('SELECT balance FROM users WHERE id = $1', [req.user.id]);
|
||||
if (user.rows[0].balance < amount) return res.status(400).json({ error: 'Insufficient balance' });
|
||||
|
||||
// Simulate result (fake, based on win_probability)
|
||||
const win = Math.random() * 100 < game.rows[0].win_probability;
|
||||
const payout = win ? amount * 2 : -amount; // Simple 2x win example; customize per game
|
||||
await pool.query('UPDATE users SET balance = balance + $1 WHERE id = $2', [payout, req.user.id]);
|
||||
await pool.query('INSERT INTO transactions (user_id, type, amount) VALUES ($1, $2, $3)', [req.user.id, win ? 'win' : 'loss', Math.abs(payout)]);
|
||||
|
||||
res.json({ win, payout, newBalance: user.rows[0].balance + payout });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Admin Routes
|
||||
app.get('/api/admin/users', authenticate, isAdmin, async (req, res) => {
|
||||
const users = await pool.query('SELECT id, username, email, balance, role FROM users');
|
||||
res.json(users.rows);
|
||||
});
|
||||
|
||||
app.put('/api/admin/user/:id', authenticate, isAdmin, async (req, res) => {
|
||||
const { balance, role } = req.body;
|
||||
await pool.query('UPDATE users SET balance = $1, role = $2 WHERE id = $3', [balance, role, req.params.id]);
|
||||
res.json({ message: 'User updated' });
|
||||
});
|
||||
|
||||
// Similar routes for promo codes, games, stats (e.g., sum wins/losses)
|
||||
app.get('/api/admin/stats', authenticate, isAdmin, async (req, res) => {
|
||||
const wins = await pool.query("SELECT SUM(amount) FROM transactions WHERE type = 'win'");
|
||||
const losses = await pool.query("SELECT SUM(amount) FROM transactions WHERE type = 'loss'");
|
||||
res.json({ totalWins: wins.rows[0].sum || 0, totalLosses: losses.rows[0].sum || 0 });
|
||||
});
|
||||
|
||||
// Socket.io for multiplayer/chat
|
||||
io.on('connection', (socket) => {
|
||||
console.log('User connected');
|
||||
socket.on('joinGame', (gameId) => {
|
||||
socket.join(gameId);
|
||||
// Broadcast messages/bets; integrate with Diablo-Lounge multiplayer logic
|
||||
});
|
||||
socket.on('chatMessage', (msg) => {
|
||||
io.to(msg.gameId).emit('message', msg);
|
||||
});
|
||||
// Add more for real-time game updates (e.g., card deals)
|
||||
});
|
||||
|
||||
server.listen(process.env.PORT, () => console.log(`Server running on port ${process.env.PORT}`));
|
||||
Reference in New Issue
Block a user