finished, functional API

This commit is contained in:
Tzvetan Trave
2025-10-02 16:04:50 +02:00
parent 22da9af53d
commit 439e5a0acf
18 changed files with 368 additions and 322 deletions

View File

@ -1,15 +1,7 @@
Todo :
- test matchHistory & wins/losses
- create users with an avatar (by default) -> POST/GET/PATCH/DELETE avatar
- create a whole image upload API that ensures files are not executables, converts to a single type, stores the image and returns a UID to address them
- add a privacy setting so not anybody can GET friends, match history, etc. ?
- choose where to use == and ===
- use more schema in endpoints for querystring and body
- split code into files with functions called in the endpoints
- add a privacy setting so not anybody can GET friends, match history, etc. (what are the RGPD requirements ?) ?

23
src/api/user/dFriend.js Normal file
View File

@ -0,0 +1,23 @@
export async function dFriend(request, reply, fastify, getUserInfo, getFriend, deleteFriend) {
try {
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
if (request.user !== 'admin' && request.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
const friendId = request.params.friendId;
if (!getFriend.get(userId, friendId)) {
return reply.code(404).send({ error: "Friend does not exist" });
}
deleteFriend.run(userId, friendId);
return reply.code(200).send({ msg: "Friend deleted successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

19
src/api/user/dFriends.js Normal file
View File

@ -0,0 +1,19 @@
export async function dFriends(request, reply, fastify, getUserInfo, deleteFriends) {
try {
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
if (request.user !== 'admin' && request.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
deleteFriends.run(userId);
return reply.code(200).send({ msg: "Friends deleted successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

View File

@ -0,0 +1,20 @@
export async function dMatchHistory(request, reply, fastify, getUserInfo, deleteMatchHistory, deleteStats) {
try {
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
if (request.user !== 'admin' && request.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
deleteMatchHistory.run(userId);
deleteStats.run(userId);
return reply.code(200).send({ msg: "Match history deleted successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

25
src/api/user/dMember.js Normal file
View File

@ -0,0 +1,25 @@
export async function dMember(request, reply, fastify, getUserInfo, changeDisplayName) {
try {
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const user = request.user;
const member = request.params.member;
if (user === 'admin' || user === request.params.userId) {
if (member === 'displayName') {
changeDisplayName.run("", request.params.userId);
return reply.code(200).send({ msg: "Display name deleted successfully" });
}
return reply.code(400).send({ msg: "Member does not exist" })
} else {
return reply.code(401).send({ error: 'You dont have the right to delete this' });
}
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

14
src/api/user/dUser.js Normal file
View File

@ -0,0 +1,14 @@
export async function dUser(request, reply, fastify, getUserInfo, deleteMatchHistory, deleteFriends, deleteUser) {
try {
if (!getUserInfo.get(request.params.userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
deleteMatchHistory.run(request.params.userId);
deleteFriends.run(request.params.userId);
deleteUser.run(request.params.userId);
return reply.code(200).send({ msg: "User deleted successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

View File

@ -2,6 +2,23 @@ import fastifyJWT from '@fastify/jwt';
import fastifyCookie from '@fastify/cookie';
import Database from 'better-sqlite3';
import { gUsers } from './gUsers.js'
import { gUser } from './gUser.js'
import { gNumberUsers } from './gNumberUsers.js'
import { gFriends } from './gFriends.js'
import { gNumberFriends } from './gNumberFriends.js'
import { gMatchHistory } from './gMatchHistory.js'
import { gNumberMatches } from './gNumberMatches.js'
import { pUser } from './pUser.js'
import { pFriend } from './pFriend.js'
import { pMatchHistory } from './pMatchHistory.js'
import { uMember } from './uMember.js'
import { dUser } from './dUser.js'
import { dMember } from './dMember.js'
import { dFriends } from './dFriends.js'
import { dFriend } from './dFriend.js'
import { dMatchHistory } from './dMatchHistory.js'
const env = process.env.NODE_ENV || 'development';
let database;
@ -72,10 +89,9 @@ const deleteFriends = database.prepare('DELETE FROM friends WHERE username = ?;'
const deleteMatchHistory = database.prepare('DELETE FROM matchHistory WHERE username = ?;');
const deleteStats = database.prepare('UPDATE userData SET wins = 0, losses = 0 WHERE username = ?;');
/**
* @param {import('fastify').FastifyInstance} fastify
* @param {import('fastify').FastifyPluginOptions} options
*/
const querySchema = { type: 'object', required: ['iStart', 'iEnd'], properties: { iStart: { type: 'integer', minimum: 0 }, iEnd: { type: 'integer', minimum: 0 } } }
const bodySchema = { type: 'object', required: ['opponent', 'myScore', 'opponentScore'], properties: { opponent: { type: 'string' }, myScore: { type: 'integer', minimum: 0 }, opponentScore: { type: 'integer', minimum: 0 } } }
export default async function(fastify, options) {
fastify.register(fastifyJWT, {
secret: process.env.JWT_SECRET || '123456789101112131415161718192021',
@ -106,347 +122,58 @@ export default async function(fastify, options) {
});
// GET
fastify.get('/users', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const { iStart, iEnd } = request.query;
if (!iStart || !iEnd) {
return reply.code(400).send({ error: "Please specify both a starting and an ending index" });
}
if (Number(iEnd) < Number(iStart)) {
return reply.code(400).send({ error: "Starting index cannot be strictly inferior to ending index" });
}
const users = getUserData.all(Number(iEnd) - Number(iStart), Number(iStart));
if (!users.length) {
return reply.code(404).send({ error: "No users exist in the selected range" });
}
return reply.code(200).send({ users });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
fastify.get('/users', { preHandler: [fastify.authenticate], schema: { querystring: querySchema } }, async (request, reply) => {
return gUsers(request, reply, fastify, getUserData);
});
fastify.get('/users/count', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const row = getNumberUsers.get();
return reply.code(200).send({ n_users: row.n_users });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return gNumberUsers(request, reply, fastify, getNumberUsers);
});
fastify.get('/users/:userId', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const userInfo = getUserInfo.get(request.params.userId);
return reply.code(200).send({ userInfo });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return gUser(request, reply, fastify, getUserInfo);
});
fastify.get('/users/:userId/friends', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const { iStart, iEnd } = request.query;
if (!iStart || !iEnd) {
return reply.code(400).send({ error: "Please specify both a starting and an ending index" });
}
if (Number(iEnd) < Number(iStart)) {
return reply.code(400).send({ error: "Starting index cannot be strictly inferior to ending index" });
}
const friends = getFriends.all(userId, Number(iEnd) - Number(iStart), Number(iStart));
if (!friends.length) {
return reply.code(404).send({ error: "No friends exist in the selected range" });
}
return reply.code(200).send({ friends });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
fastify.get('/users/:userId/friends', { preHandler: [fastify.authenticate], schema: { querystring: querySchema } }, async (request, reply) => {
return gFriends(request, reply, fastify, getUserInfo, getFriends);
});
fastify.get('/users/:userId/friends/count', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const row = getNumberFriends.get(userId);
return reply.code(200).send({ n_friends: row.n_friends });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return gNumberFriends(request, reply, fastify, getUserInfo, getNumberFriends);
});
fastify.get('/users/:userId/matchHistory', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const { iStart, iEnd } = request.query;
if (!iStart || !iEnd) {
return reply.code(400).send({ error: "Please specify both a starting and an ending index" });
}
if (Number(iEnd) < Number(iStart)) {
return reply.code(400).send({ error: "Starting index cannot be strictly inferior to ending index" });
}
const matchHistoryId = getMatchHistory.all(userId, Number(iEnd) - Number(iStart), Number(iStart));
if (!matchHistoryId.length) {
return reply.code(404).send({ error: "No matches exist in the selected range" });
}
const promises = matchHistoryId.map(async (id) => {
const res = await fetch('https://transcendence-api-scoreStore:3000/' + id, { method: "GET", headers: { "Content-Type": "application/json" } });
if (!res.ok)
throw new Error('Failed to fetch item from blockchain API');
return res.json();
});
const matchHistory = await Promise.all(promises);
return reply.code(200).send({ matchHistory });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
fastify.get('/users/:userId/matchHistory', { preHandler: [fastify.authenticate], schema: { querystring: querySchema } }, async (request, reply) => {
return gMatchHistory(request, reply, fastify, getUserInfo, getMatchHistory);
});
fastify.get('/users/:userId/matchHistory/count', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const row = getNumberMatches.get(userId);
return reply.code(200).send({ n_matches: row.n_matches });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return gNumberMatches(request, reply, fastify, getUserInfo, getNumberMatches);
});
// POST
fastify.post('/users/:userId', { preHandler: [fastify.authenticateAdmin] }, async (request, reply) => {
try {
const userId = request.params.userId;
if (!request.user || !request.user.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
if (request.user.user !== 'admin') {
return reply.code(401).send({ error: "Unauthorized" });
}
if (getUserInfo.get(userId)) {
return reply.code(400).send({ error: "User already exist" });
}
if (!request.body || !request.body.displayName) {
return reply.code(400).send({ error: "Please specify a display name" });
}
createUser.run(userId, request.body.displayName);
return reply.code(200).send({ msg: "User created successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return pUser(request, reply, fastify, getUserInfo, createUser);
});
fastify.post('/users/:userId/friends/:friendId', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const userId = request.params.userId;
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
if (request.user !== 'admin' && request.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const friendId = request.params.friendId;
if (!getUserInfo.get(friendId)) {
return reply.code(404).send({ error: "Friend does not exist" });
}
if (friendId === userId) {
return reply.code(400).send({ error: "You can't add yourself :D" });
}
if (getFriend.get(userId, friendId)) {
return reply.code(400).send({ error: "Friend already added" });
}
addFriend.run(userId, friendId)
return reply.code(200).send({ msg: "Friend added successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return pFriend(request, reply, fastify, getUserInfo, getFriend, addFriend);
});
fastify.post('/users/:userId/matchHistory', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const userId = request.params.userId;
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
if (request.user !== 'admin' && request.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
if (!request.body || !request.body.opponent || !request.body.p1Score || !request.body.p2Score) {
return reply.code(400).send({ error: "Please specify the opponent and the score of both players" });
}
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
if (!getUserInfo.get(request.body.opponent)) {
return reply.code(404).send({ error: "Opponent does not exist" });
}
if (request.body.opponent === userId) {
return reply.code(400).send({ error: "Do you have dementia ? You cannot have played a match against yourself gramps" });
}
if (request.body.p1Score < 0 || request.body.p2Score < 0) {
return reply.code(400).send({ error: "A score cannot be strictly negative" });
}
const res = await fetch('http://localhost:3003/', { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ p1: userId, p2: request.body.opponent, p1Score: request.body.p1Score, p2Score: request.body.p2Score }) });
if (!res.ok)
return reply.code(500).send({ error: "Internal server error" });
addMatch.run(userId, res.id);
if (request.body.p1Score > request.body.p2Score) {
incWins.run(userId);
} else if (request.body.p1Score < request.body.p2Score) {
incLosses.run(userId);
}
return reply.code(200).send({ msg: "Match successfully saved to the blockchain" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
fastify.post('/users/:userId/matchHistory', { preHandler: [fastify.authenticate], schema: { body: bodySchema } }, async (request, reply) => {
return pMatchHistory(request, reply, fastify, getUserInfo, addMatch, incWins, incLosses);
});
// PATCH
fastify.patch('/users/:userId/:member', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
const userId = request.params.userId;
if (!request.user || !request.user.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
if (request.user.user !== 'admin' && request.user.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const member = request.params.member;
if (member === 'displayName') {
if (!request.body || !request.body.displayName) {
return reply.code(400).send({ error: "Please specify a displayName" });
}
changeDisplayName.run(request.body.displayName, userId);
return reply.code(200).send({ msg: "Display name modified successfully" });
}
return reply.code(400).send({ error: "Member does not exist" })
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return uMember(request, reply, fastify, getUserInfo, changeDisplayName);
});
// DELETE
fastify.delete('/users/:userId', { preHandler: [fastify.authenticateAdmin] }, async (request, reply) => {
try {
if (!getUserInfo(request.params.userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
deleteMatchHistory.run(request.params.userId);
deleteFriends.run(request.params.userId);
deleteUser.run(request.params.userId);
return reply.code(200).send({ msg: "User deleted successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return dUser(request, reply, fastify, getUserInfo, deleteMatchHistory, deleteFriends, deleteUser);
});
fastify.delete('/users/:userId/:member', { preHandler: fastify.authenticate }, async (request, reply) => {
try {
if (!request.user || !request.user.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const user = request.user.user;
const member = request.params.member;
if (user == 'admin' || user == request.params.userId) {
if (member === 'displayName') {
changeDisplayName.run("", request.params.userId);
return reply.code(200).send({ msg: "Display name deleted successfully" });
}
return reply.code(400).send({ msg: "Member does not exist" })
} else {
return reply.code(401).send({ error: 'You dont have the right to delete this' });
}
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return dMember(request, reply, fastify, getUserInfo, changeDisplayName);
});
fastify.delete('/users/:userId/friends', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
if (!request.user || !request.user.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
if (request.user.user != 'admin' && request.user.user != userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
deleteFriends.run(userId);
return reply.code(200).send({ msg: "Friends deleted successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return dFriends(request, reply, fastify, getUserInfo, deleteFriends);
});
fastify.delete('/users/:userId/friends/:friendId', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
if (!request.user || !request.user.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
if (request.user.user != 'admin' && request.user.user != userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
const friendId = request.params.friendId;
if (!getFriend.get(friendId)) {
return reply.code(404).send({ error: "Friend does not exist" });
}
deleteFriend.run(userId, friendId);
return reply.code(200).send({ msg: "Friend deleted successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return dFriend(request, reply, fastify, getUserInfo, getFriend, deleteFriend);
});
fastify.delete('/users/:userId/matchHistory', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
if (!request.user || !request.user.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
if (request.user.user != 'admin' && request.user.user != userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
deleteMatchHistory.run(userId);
deleteStats.run(userId);
return reply.code(200).send({ msg: "Match history deleted successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
return dMatchHistory(request, reply, fastify, getUserInfo, deleteMatchHistory, deleteStats);
});
}

20
src/api/user/gFriends.js Normal file
View File

@ -0,0 +1,20 @@
export async function gFriends(request, reply, fastify, getUserInfo, getFriends) {
try {
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const { iStart, iEnd } = request.query;
if (Number(iEnd) < Number(iStart)) {
return reply.code(400).send({ error: "Starting index cannot be strictly inferior to ending index" });
}
const friends = getFriends.all(userId, Number(iEnd) - Number(iStart), Number(iStart));
if (!friends.length) {
return reply.code(404).send({ error: "No friends exist in the selected range" });
}
return reply.code(200).send({ friends });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

View File

@ -0,0 +1,29 @@
export async function gMatchHistory(request, reply, fastify, getUserInfo, getMatchHistory) {
try {
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const { iStart, iEnd } = request.query;
if (Number(iEnd) < Number(iStart)) {
return reply.code(400).send({ error: "Starting index cannot be strictly inferior to ending index" });
}
const matchHistoryId = getMatchHistory.all(userId, Number(iEnd) - Number(iStart), Number(iStart));
if (!matchHistoryId.length) {
return reply.code(404).send({ error: "No matches exist in the selected range" });
}
const ids = matchHistoryId.map(obj => Object.values(obj)[0]);
const promises = ids.map(async (id) => {
const res = await fetch(`http://localhost:3003/${id}`, { method: "GET" });
if (!res.ok) {
throw new Error('Failed to fetch item from blockchain API');
}
return await res.json();
});
const matchHistory = await Promise.all(promises);
return reply.code(200).send({ matchHistory });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

View File

@ -0,0 +1,13 @@
export async function gNumberFriends(request, reply, fastify, getUserInfo, getNumberFriends) {
try {
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const row = getNumberFriends.get(userId);
return reply.code(200).send({ n_friends: row.n_friends });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

View File

@ -0,0 +1,13 @@
export async function gNumberMatches(request, reply, fastify, getUserInfo, getNumberMatches) {
try {
const userId = request.params.userId;
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const row = getNumberMatches.get(userId);
return reply.code(200).send({ n_matches: row.n_matches });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

View File

@ -0,0 +1,9 @@
export async function gNumberUsers(request, reply, fastify, getNumberUsers) {
try {
const row = getNumberUsers.get();
return reply.code(200).send({ n_users: row.n_users });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

13
src/api/user/gUser.js Normal file
View File

@ -0,0 +1,13 @@
export async function gUser(request, reply, fastify, getUserInfo) {
try {
const userId = request.params.userId;
const userInfo = getUserInfo.get(userId);
if (!userInfo) {
return reply.code(404).send({ error: "User does not exist" });
}
return reply.code(200).send({ userInfo });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

16
src/api/user/gUsers.js Normal file
View File

@ -0,0 +1,16 @@
export async function gUsers(request, reply, fastify, getUserData) {
try {
const { iStart, iEnd } = request.query;
if (Number(iEnd) < Number(iStart)) {
return reply.code(400).send({ error: "Starting index cannot be strictly inferior to ending index" });
}
const users = getUserData.all(Number(iEnd) - Number(iStart), Number(iStart));
if (!users.length) {
return reply.code(404).send({ error: "No users exist in the selected range" });
}
return reply.code(200).send({ users });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

29
src/api/user/pFriend.js Normal file
View File

@ -0,0 +1,29 @@
export async function pFriend(request, reply, fastify, getUserInfo, getFriend, addFriend) {
try {
const userId = request.params.userId;
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
if (request.user !== 'admin' && request.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const friendId = request.params.friendId;
if (!getUserInfo.get(friendId)) {
return reply.code(404).send({ error: "Friend does not exist" });
}
if (friendId === userId) {
return reply.code(400).send({ error: "You can't add yourself :D" });
}
if (getFriend.get(userId, friendId)) {
return reply.code(400).send({ error: "Friend already added" });
}
addFriend.run(userId, friendId)
return reply.code(200).send({ msg: "Friend added successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

View File

@ -0,0 +1,36 @@
export async function pMatchHistory(request, reply, fastify, getUserInfo, addMatch, incWins, incLosses) {
try {
const userId = request.params.userId;
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
if (request.user !== 'admin' && request.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
if (!getUserInfo.get(request.body.opponent)) {
return reply.code(404).send({ error: "Opponent does not exist" });
}
if (request.body.opponent === userId) {
return reply.code(400).send({ error: "Do you have dementia ? You cannot have played a match against yourself gramps" });
}
const res = await fetch('http://localhost:3003/', { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ p1: userId, p2: request.body.opponent, p1Score: request.body.myScore, p2Score: request.body.opponentScore }) });
if (!res.ok)
return reply.code(500).send({ error: "Internal server error" });
const data = await res.json();
addMatch.run(userId, data.id);
if (request.body.myScore > request.body.opponentScore) {
incWins.run(userId);
incLosses.run(request.body.opponent);
} else if (request.body.myScore < request.body.opponentScore) {
incWins.run(request.body.opponent);
incLosses.run(userId);
}
return reply.code(200).send({ msg: "Match successfully saved to the blockchain" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

22
src/api/user/pUser.js Normal file
View File

@ -0,0 +1,22 @@
export async function pUser(request, reply, fastify, getUserInfo, createUser) {
try {
const userId = request.params.userId;
if (!request.user || !request.user.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
if (request.user.user !== 'admin') {
return reply.code(401).send({ error: "Unauthorized" });
}
if (getUserInfo.get(userId)) {
return reply.code(400).send({ error: "User already exist" });
}
if (!request.body || !request.body.displayName) {
return reply.code(400).send({ error: "Please specify a display name" });
}
createUser.run(userId, request.body.displayName);
return reply.code(200).send({ msg: "User created successfully" });
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}

26
src/api/user/uMember.js Normal file
View File

@ -0,0 +1,26 @@
export async function uMember(request, reply, fastify, getUserInfo, changeDisplayName) {
try {
const userId = request.params.userId;
if (!request.user) {
return reply.code(400).send({ error: "Please specify a user" });
}
if (request.user !== 'admin' && request.user !== userId) {
return reply.code(401).send({ error: "Unauthorized" });
}
if (!getUserInfo.get(userId)) {
return reply.code(404).send({ error: "User does not exist" });
}
const member = request.params.member;
if (member === 'displayName') {
if (!request.body || !request.body.displayName) {
return reply.code(400).send({ error: "Please specify a displayName" });
}
changeDisplayName.run(request.body.displayName, userId);
return reply.code(200).send({ msg: "Display name modified successfully" });
}
return reply.code(400).send({ error: "Member does not exist" })
} catch (err) {
fastify.log.error(err);
return reply.code(500).send({ error: "Internal server error" });
}
}