Add controllers for matches and users.

This commit is contained in:
Mercury. 2025-02-15 18:57:23 +01:00
parent 6d81495a38
commit 3326386d4f
3 changed files with 292 additions and 0 deletions

View file

@ -0,0 +1,74 @@
const jwt = require('jsonwebtoken');
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
async function getUserIdFromToken(token) {
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
return decoded.id;
} catch (err) {
throw new Error('Invalid token');
}
}
async function createMatch(req, res) {
const token = req.headers['authorization']?.split(' ')[1];
if (!token) {
return res.status(403).json({ error: 'Token is required.' });
}
try {
const player1_uid = await getUserIdFromToken(token);
const client = await pool.connect();
try {
const result = await client.query(
'INSERT INTO matches (player1_uid) VALUES ($1) RETURNING match_id;',
[player1_uid]
);
const match_id = result.rows[0].match_id;
return res.status(200).json({ match_id });
} finally {
client.release();
}
} catch (error) {
console.error('Error creating match:', error);
return res.status(400).json({ error: error.message });
}
}
async function createMatch2v2(req, res) {
const token = req.headers['authorization']?.split(' ')[1];
if (!token) {
return res.status(403).json({ error: 'Token is required.' });
}
try {
const player1_uid = await getUserIdFromToken(token);
const client = await pool.connect();
try {
const result = await client.query(
'INSERT INTO matches_2v2 (player1_team1_uid) VALUES ($1) RETURNING match_id;',
[player1_uid]
);
const match_id = result.rows[0].match_id;
return res.status(200).json({ match_id });
} finally {
client.release();
}
} catch (error) {
console.error('Error creating 2v2 match:', error);
return res.status(400).json({ error: error.message });
}
}
module.exports = {
createMatch,
createMatch2v2,
};

104
controllers/social.js Normal file
View file

@ -0,0 +1,104 @@
const jwt = require('jsonwebtoken');
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
async function addFriend(req, res) {
const { friend_uid } = req.body;
const token = req.headers['authorization'] && req.headers['authorization'].split(' ')[1];
if (!token) {
return res.status(403).json({ error: 'Access denied. No token provided.' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const userUid = decoded.uid;
const client = await pool.connect();
try {
const result = await client.query(
'SELECT friend_list FROM users WHERE uid = $1;',
[userUid]
);
let friends = result.rows[0]?.friend_list || {};
if (Object.values(friends).includes(friend_uid)) {
return res.status(400).json({ error: 'Friend already in the list.' });
}
const friendKey = `friend${Object.keys(friends).length}`;
friends[friendKey] = friend_uid;
const friendsJson = JSON.stringify(friends);
await client.query(
'UPDATE users SET friend_list = $1 WHERE uid = $2;',
[friendsJson, userUid]
);
res.status(200).json({ message: 'Friend added successfully!' });
} finally {
client.release();
}
} catch (error) {
console.error('Error adding friend:', error);
res.status(500).json({ error: 'Server error' });
}
}
async function getFriendDetails(friendUid) {
const client = await pool.connect();
try {
const result = await client.query('SELECT display_name, uid FROM users WHERE uid = $1', [friendUid]);
if (result.rows.length > 0) {
return result.rows[0];
}
return null;
} finally {
client.release();
}
}
async function getFriendsList(req, res) {
const userId = req.user.id;
try {
const client = await pool.connect();
try {
const result = await client.query(
'SELECT friend_list FROM users WHERE uid = $1;',
[userId]
);
const user = result.rows[0];
if (!user || !user.friend_list) {
return res.status(404).json({ error: 'No friends found.' });
}
const friends = JSON.parse(user.friend_list);
const friendsDetails = [];
for (const key in friends) {
const friendUid = friends[key];
const friendDetails = await getFriendDetails(friendUid);
if (friendDetails) {
friendsDetails.push(friendDetails);
}
}
return res.status(200).json({ friends: friendsDetails });
} finally {
client.release();
}
} catch (error) {
console.error('Error fetching friends:', error);
res.status(400).json({ error: error.message });
}
}
module.exports = {
addFriend
};

114
controllers/users.js Normal file
View file

@ -0,0 +1,114 @@
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
async function registerUser(req, res) {
const { email, display_name, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);
try {
const client = await pool.connect();
try {
const result = await client.query(
`INSERT INTO users (email, display_name, password_hash) VALUES ($1, $2, $3) RETURNING uid;`,
[email, display_name, hashedPassword]
);
const uid = result.rows[0].uid;
res.status(201).json({ uid });
} finally {
client.release();
}
} catch (error) {
console.error('Error registering user:', error);
res.status(500).json({ error: 'Server error' });
}
}
async function authenticateUser(req, res) {
const { email, password } = req.body;
try {
const client = await pool.connect();
try {
const result = await client.query('SELECT uid, password_hash FROM users WHERE email = $1;', [email]);
const user = result.rows[0];
if (user && bcrypt.compareSync(password, user.password_hash)) {
const token = jwt.sign(
{ uid: user.uid, email: email },
process.env.JWT_SECRET,
{ expiresIn: '5d' }
);
res.status(200).json({ token });
} else {
res.status(401).json({ error: 'Invalid credentials' });
}
} finally {
client.release();
}
} catch (error) {
console.error('Error authenticating user:', error);
res.status(500).json({ error: 'Server error' });
}
}
async function resetPassword(req, res) {
const { uid, email, new_password } = req.body;
const hashedPassword = await bcrypt.hash(new_password, 10);
try {
const client = await pool.connect();
try {
const result = await client.query(
'UPDATE users SET password_hash = $1 WHERE uid = $2 AND email = $3;',
[hashedPassword, uid, email]
);
if (result.rowCount === 0) {
return res.status(400).json({ error: 'User not found' });
}
res.status(200).json({ message: 'Password reset successfully' });
} finally {
client.release();
}
} catch (error) {
console.error('Error resetting password:', error);
res.status(500).json({ error: 'Server error' });
}
}
async function getLeaderboard(req, res) {
try {
const client = await pool.connect();
try {
const result = await client.query(
'SELECT display_name, openskill_mu, current_elo, uid FROM users WHERE current_elo IS NOT NULL ORDER BY current_elo DESC;'
);
const players = result.rows;
const playerEloList = players.map(player => ({
player_name: player.display_name,
osk_mu: player.openskill_mu,
elo_rating: player.current_elo,
friend_code: player.uid
}));
res.status(200).json(playerEloList);
} finally {
client.release();
}
} catch (error) {
console.error('Error fetching leaderboard:', error);
res.status(500).json({ error: 'Server error' });
}
}
module.exports = {
registerUser,
authenticateUser,
resetPassword,
getLeaderboard,
};