First commit
This commit is contained in:
parent
cf99f21b9a
commit
b4c388b551
4
.gitignore
vendored
4
.gitignore
vendored
@ -130,3 +130,7 @@ dist
|
|||||||
.yarn/install-state.gz
|
.yarn/install-state.gz
|
||||||
.pnp.*
|
.pnp.*
|
||||||
|
|
||||||
|
# Project specifc files to ignore
|
||||||
|
test.js
|
||||||
|
config.json
|
||||||
|
keys/
|
||||||
@ -1,2 +1,2 @@
|
|||||||
# Yuzu-Online-JS
|
# YuZu-Online
|
||||||
|
Nothing more simple, you just have to launch the server
|
||||||
15
config.example.json
Normal file
15
config.example.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"web": {
|
||||||
|
"port": 4862
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"defaultProvider": "discord",
|
||||||
|
"providers": {
|
||||||
|
"discord": {
|
||||||
|
"clientId": "",
|
||||||
|
"clientSecret": "",
|
||||||
|
"redirectUri": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
313
controllers/db.js
Normal file
313
controllers/db.js
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
const Database = require("better-sqlite3")
|
||||||
|
const logger = require("../modules/logger")
|
||||||
|
const path = require("node:path")
|
||||||
|
const jwt = require("jsonwebtoken")
|
||||||
|
const fs = require("node:fs")
|
||||||
|
require("colors")
|
||||||
|
|
||||||
|
const db = new Database(path.join(__dirname, "..", "data", "lobby.db"), { verbose: (message) => logger.log(`[${"SQLite".yellow}] ${message}`) })
|
||||||
|
const privateKey = fs.readFileSync(path.join(__dirname, "..", "keys", "private.pem"))
|
||||||
|
|
||||||
|
function initDB() {
|
||||||
|
db.exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS rooms (
|
||||||
|
externalGuid TEXT PRIMARY KEY,
|
||||||
|
id TEXT NOT NULL,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
owner TEXT NOT NULL,
|
||||||
|
port INTEGER NOT NULL,
|
||||||
|
preferredGameName TEXT NOT NULL,
|
||||||
|
preferredGameId INTEGER NOT NULL,
|
||||||
|
maxPlayers INTEGER NOT NULL,
|
||||||
|
netVersion TEXT NOT NULL,
|
||||||
|
hasPassword BOOLEAN NOT NULL DEFAULT 0,
|
||||||
|
password TEXT DEFAULT ""
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
db.exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
discordId TEXT NOT NULL,
|
||||||
|
username TEXT NOT NULL PRIMARY KEY,
|
||||||
|
nickname TEXT NOT NULL,
|
||||||
|
avatarUrl TEXT NOT NULL,
|
||||||
|
token TEXT NOT NULL
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
db.exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS players (
|
||||||
|
nickname TEXT NOT NULL,
|
||||||
|
username TEXT NOT NULL,
|
||||||
|
avatarUrl TEXT NOT NULL,
|
||||||
|
roomId TEXT NOT NULL,
|
||||||
|
gameId INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY(roomId) REFERENCES rooms(externalGuid)
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function loginWithTokenAndToken(username, token) {
|
||||||
|
const stmt = db.prepare("SELECT * FROM users WHERE username = ?")
|
||||||
|
const user = stmt.get(username)
|
||||||
|
if (user) {
|
||||||
|
if (user.token == token) {
|
||||||
|
delete user.token
|
||||||
|
return user
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "Invalid token", code: 401 }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "No user found with that username.", code: 404 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loginWithToken(token) {
|
||||||
|
try {
|
||||||
|
const payload = jwt.verify(token, privateKey)
|
||||||
|
const stmt = db.prepare("SELECT * FROM users WHERE username = ?")
|
||||||
|
const user = stmt.get(payload.username)
|
||||||
|
if (user) {
|
||||||
|
delete user.token
|
||||||
|
return user
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "No user found with that username.", code: 404 }
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: "Invalid token.", code: 401 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function login(req, res, next) {
|
||||||
|
const xToken = req.headers["x-token"]
|
||||||
|
const xUsername = req.headers["x-username"]
|
||||||
|
const bearer = res.headers["authorization"]
|
||||||
|
const token = bearer && bearer.startsWith("Bearer ") ? bearer.split(" ")[1] : null
|
||||||
|
if (!xToken && !xUsername && !token) {
|
||||||
|
return res.status(401).json({ error: "No token or/and username provided." })
|
||||||
|
}
|
||||||
|
if (!xToken || !xUsername) {
|
||||||
|
return res.status(422).json({ error: "No token or/and username provided." })
|
||||||
|
}
|
||||||
|
if (token) {
|
||||||
|
const user = loginWithToken(token)
|
||||||
|
if (user.error) {
|
||||||
|
return res.status(user.code).json({ error: user.error })
|
||||||
|
} else {
|
||||||
|
req.user = user
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const user = loginWithTokenAndToken(xUsername, xToken)
|
||||||
|
if (user.error) {
|
||||||
|
return res.status(user.code).json({ error: user.error })
|
||||||
|
} else {
|
||||||
|
req.user = user
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlayersFromRoom(roomId) {
|
||||||
|
const stmt = db.prepare("SELECT * FROM players WHERE roomId = ?")
|
||||||
|
const players = stmt.all(roomId)
|
||||||
|
if (players) {
|
||||||
|
return { success: true, players: players }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "No players found in that room.", code: 404 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function putPlayerInRoom(username, roomId, nickname, avatarUrl, gameId) {
|
||||||
|
const stmt = db.prepare("INSERT INTO players (username, roomId, nickname, avatarUrl, gameId) VALUES (?, ?, ?, ?, ?)")
|
||||||
|
try {
|
||||||
|
stmt.run(username, roomId, nickname, avatarUrl, gameId)
|
||||||
|
return { success: true }
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return { success: false, error: "Failed to add player to the room.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addRoomToLobby(externalGuid, id, address, name, description, owner, port, preferredGameName, preferredGameId, maxPlayers, netVersion, hasPassword, password) {
|
||||||
|
const stmt = db.prepare("INSERT INTO rooms (externalGuid, id, address, name, description, owner, port, preferredGameName, preferredGameId, maxPlayers, netVersion, hasPassword, password) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
||||||
|
try {
|
||||||
|
stmt.run(externalGuid, id, address, name, description, owner, port, preferredGameName, preferredGameId, maxPlayers, netVersion, hasPassword, password)
|
||||||
|
return { success: true }
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return { success: false, error: "Failed to room to lobby", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function movePlayerAnotherRoom(username, roomId) {
|
||||||
|
const stmt = db.prepare("UPDATE players SET roomId = ? WHERE username = ?")
|
||||||
|
try {
|
||||||
|
const result = stmt.run(roomId, username)
|
||||||
|
if (result.changes > 0) {
|
||||||
|
return { success: true }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "Player not found or already in the specified room.", code: 404 }
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: "Failed to move player to another room.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removePlayer(username, roomId) {
|
||||||
|
const stmt = db.prepare("DELETE FROM players WHERE username = ? AND roomId = ?")
|
||||||
|
try {
|
||||||
|
const result = stmt.run(username, roomId)
|
||||||
|
if (result.changes > 0) {
|
||||||
|
return { success: true }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "Player not found in the specified room.", code: 404 }
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: "Failed to remove player from the room.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function listRooms() {
|
||||||
|
const stmt = db.prepare("SELECT * FROM rooms")
|
||||||
|
try {
|
||||||
|
const rooms = stmt.all()
|
||||||
|
return { success: true, rooms: rooms, code: 200 }
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: "Failed to retrieve rooms.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteRoom(roomId) {
|
||||||
|
const stmt = db.prepare("DELETE FROM rooms WHERE id = ?")
|
||||||
|
try {
|
||||||
|
stmt.run(roomId)
|
||||||
|
return { success: true, code: 204 }
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return { success: false, error: "Failed to delete room", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoom(roomId) {
|
||||||
|
const stmt = db.prepare("SELECT * FROM rooms WHERE id = ?")
|
||||||
|
const room = stmt.get(roomId)
|
||||||
|
if (room) {
|
||||||
|
return { success: true, code: 200, room }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "No room found with that ID.", code: 404 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateKeyAndValueForRoom(roomId, key, value) {
|
||||||
|
const stmt = db.prepare(`UPDATE rooms SET ${key} = ? WHERE id = ?`)
|
||||||
|
try {
|
||||||
|
const result = stmt.run(value, roomId)
|
||||||
|
if (result.changes > 0) {
|
||||||
|
return { success: true }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "Room not found or no changes made.", code: 404 }
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return { success: false, error: "Failed to update room.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addUser(discordId, username, nickname, avatarUrl) {
|
||||||
|
const stmt = db.prepare("INSERT INTO users (discordId, username, nickname, avatarUrl, token) VALUES (?, ?, ?, ?, ?)")
|
||||||
|
try {
|
||||||
|
const token = jwt.sign({ username, nickname, avatarUrl }, privateKey, { algorithm: "RS256", expiresIn: "168h" })
|
||||||
|
stmt.run(discordId, username, nickname, avatarUrl, token)
|
||||||
|
return { success: true, user: { username, nickname, avatarUrl, token } }
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return { success: false, error: "Failed to register user.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeUser(username) {
|
||||||
|
const stmt = db.prepare("DELETE FROM users WHERE username = ?")
|
||||||
|
try {
|
||||||
|
stmt.run(username)
|
||||||
|
return { success: true, code: 204 }
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return { success: false, error: "Failed to delete user", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateUserNickname(nickname, discordId) {
|
||||||
|
const stmt = db.prepare("UPDATE users SET nickname = ? WHERE discordId = ?")
|
||||||
|
try {
|
||||||
|
const result = stmt.run(nickname, discordId)
|
||||||
|
if (result.changes > 0) {
|
||||||
|
return { success: true }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "Player not found or already in the specified room.", code: 404 }
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: "Failed to move player to another room.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateUserUsername(username, discordId) {
|
||||||
|
const stmt = db.prepare("UPDATE users SET username = ? WHERE discordId = ?")
|
||||||
|
try {
|
||||||
|
const result = stmt.run(username, discordId)
|
||||||
|
if (result.changes > 0) {
|
||||||
|
return { success: true }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "Player not found or already in the specified room.", code: 404 }
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: "Failed to move player to another room.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateUserAvatar(avatarUrl, discordId) {
|
||||||
|
const stmt = db.prepare("UPDATE users SET avatarUrl = ? WHERE discordId = ?")
|
||||||
|
try {
|
||||||
|
const result = stmt.run(avatarUrl, discordId)
|
||||||
|
if (result.changes > 0) {
|
||||||
|
return { success: true }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "Player not found or already in the specified room.", code: 404 }
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: "Failed to move player to another room.", code: 500 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUser(userId) {
|
||||||
|
const stmt = db.prepare("SELECT * FROM users WHERE discordId = ?")
|
||||||
|
const user = stmt.get(userId)
|
||||||
|
if (user) {
|
||||||
|
return { success: true, code: 200, user }
|
||||||
|
} else {
|
||||||
|
return { success: false, error: "No user found with that ID.", code: 404 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initDB,
|
||||||
|
login,
|
||||||
|
loginWithToken,
|
||||||
|
loginWithTokenAndToken,
|
||||||
|
getPlayersFromRoom,
|
||||||
|
putPlayerInRoom,
|
||||||
|
movePlayerAnotherRoom,
|
||||||
|
removePlayer,
|
||||||
|
listRooms,
|
||||||
|
addRoomToLobby,
|
||||||
|
deleteRoom,
|
||||||
|
getRoom,
|
||||||
|
updateKeyAndValueForRoom,
|
||||||
|
removeUser,
|
||||||
|
addUser,
|
||||||
|
updateUserAvatar,
|
||||||
|
updateUserNickname,
|
||||||
|
updateUserUsername,
|
||||||
|
getUser
|
||||||
|
}
|
||||||
33
controllers/keys.js
Normal file
33
controllers/keys.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
const fs = require("node:fs")
|
||||||
|
const path = require("node:path")
|
||||||
|
const crypto = require("node:crypto")
|
||||||
|
const logger = require("../modules/logger")
|
||||||
|
require("colors")
|
||||||
|
|
||||||
|
function initKeys() {
|
||||||
|
if (!isExists("private.pem") && isExists("public.pem")) {
|
||||||
|
logger.log(`[${"RSA Keys".blue}] Public key is missing.`)
|
||||||
|
fs.unlinkSync("public.pem")
|
||||||
|
}
|
||||||
|
if (!isExists("public.pem") && isExists("private.pem")) {
|
||||||
|
logger.log(`[${"RSA Keys".blue}] Private key is missing`)
|
||||||
|
fs.unlinkSync("private.pem")
|
||||||
|
}
|
||||||
|
if (!isExists("private.pem") && !isExists("public.pem")) {
|
||||||
|
logger.log(`[${"RSA Keys".blue}] RSA Keys are missings, generating`)
|
||||||
|
const { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", {
|
||||||
|
modulusLength: 2048
|
||||||
|
})
|
||||||
|
fs.writeFileSync(path.join(__dirname, "..", "keys", "private.pem"), privateKey.export({ type: "pkcs1", format: "pem" }))
|
||||||
|
fs.writeFileSync(path.join(__dirname, "..", "keys", "public.pem"), publicKey.export({ type: "spki", format: "pem" }))
|
||||||
|
logger.log(`[${"RSA Keys".blue}] RSA Keys generated`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isExists(filename) {
|
||||||
|
return fs.existsSync(path.join(__dirname, "keys", filename))
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initKeys
|
||||||
|
}
|
||||||
BIN
data/lobby.db
Normal file
BIN
data/lobby.db
Normal file
Binary file not shown.
22
modules/logger.js
Normal file
22
modules/logger.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
const fs = require("node:fs")
|
||||||
|
const path = require("node:path")
|
||||||
|
require("colors")
|
||||||
|
|
||||||
|
if (!fs.existsSync(path.join(__dirname, "..", "logs"))) {
|
||||||
|
fs.mkdirSync(path.join(__dirname, "..", "logs"))
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(message) {
|
||||||
|
console.log(`[${new Date().toISOString().magenta}] [${"INFO".green}] : ${message}`)
|
||||||
|
fs.appendFileSync(path.join(__dirname, "..", "logs", "info.log") ,`[${new Date().toISOString()}] [INFO] :\r\n${message}\r\n`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(message) {
|
||||||
|
console.error(`[${new Date().toISOString().magenta}] [${"ERROR".red}] : ${message}`)
|
||||||
|
fs.appendFileSync(path.join(__dirname, "..", "logs", "error.log") ,`[${new Date().toISOString()}] [ERROR] :\r\n${message}\r\n`)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
error,
|
||||||
|
log
|
||||||
|
}
|
||||||
1680
package-lock.json
generated
Normal file
1680
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
41
package.json
Normal file
41
package.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "yuzu-online-js",
|
||||||
|
"version": "0.0.1-alpha",
|
||||||
|
"description": "attempt to implement yuzu online server in js and use discord oauth2 to auth people and get profile info without ui",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node .",
|
||||||
|
"start:dev": "nodemon ."
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://gitea.azures.fr/azures04/Yuzu-Online-JS"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"yuzu",
|
||||||
|
"online",
|
||||||
|
"room",
|
||||||
|
"rooms",
|
||||||
|
"yuzu-rooms",
|
||||||
|
"yuzu-room",
|
||||||
|
"yuzu-online",
|
||||||
|
"multiplayer",
|
||||||
|
"yuzu-multiplayer"
|
||||||
|
],
|
||||||
|
"author": {
|
||||||
|
"email": "gilleslazure04@gmail.com",
|
||||||
|
"name": "Gilles Lazure <azures04>",
|
||||||
|
"url": "https://gitea.azures.fr/azures04"
|
||||||
|
},
|
||||||
|
"license": "AGPL-3.0-or-later",
|
||||||
|
"dependencies": {
|
||||||
|
"better-sqlite3": "^11.9.1",
|
||||||
|
"colors": "^1.4.0",
|
||||||
|
"discord-oauth2": "^2.12.1",
|
||||||
|
"express": "^5.1.0",
|
||||||
|
"jsonwebtoken": "^9.0.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^3.1.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
51
routes/auth/provider/discord.js
Normal file
51
routes/auth/provider/discord.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
const express = require("express")
|
||||||
|
const router = express()
|
||||||
|
const config = require("../../../config.json")
|
||||||
|
const controller = require("../../../controllers/db")
|
||||||
|
const DiscordOauth2 = require("discord-oauth2")
|
||||||
|
|
||||||
|
const oauth2 = new DiscordOauth2({
|
||||||
|
clientId: config.auth.providers.discord.clientId,
|
||||||
|
clientSecret: config.auth.providers.discord.clientSecret,
|
||||||
|
redirectUri: config.auth.providers.discord.redirectUri,
|
||||||
|
})
|
||||||
|
|
||||||
|
router.get("", async (req, res) => {
|
||||||
|
const { code } = req.query
|
||||||
|
if (code) {
|
||||||
|
try {
|
||||||
|
const token = await oauth2.tokenRequest({ code, grantType: "authorization_code", scope: "identify" })
|
||||||
|
const user = await oauth2.getUser(token.access_token)
|
||||||
|
if (user) {
|
||||||
|
const isUserAlreadyRegisteredRequest = controller.getUser(user.id)
|
||||||
|
if (isUserAlreadyRegisteredRequest.success) {
|
||||||
|
const $user = isUserAlreadyRegisteredRequest.user
|
||||||
|
if (user.username != $user.username) {
|
||||||
|
controller.updateUserUsername(user.id, user.username)
|
||||||
|
}
|
||||||
|
if (user.global_name != $user.nickname) {
|
||||||
|
controller.updateUserNickname(user.id, user.global_name)
|
||||||
|
}
|
||||||
|
if (buildAvatarURL(user.id, user.avatar) != $user.avatarUrl) {
|
||||||
|
controller.updateUserAvatar(user.id, buildAvatarURL(user.id, user.avatar))
|
||||||
|
}
|
||||||
|
res.json(controller.getUser(user.id))
|
||||||
|
} else {
|
||||||
|
const registerUserRequest = controller.addUser(user.id, user.username, user.global_name, `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png`)
|
||||||
|
res.json(registerUserRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ error: new String(error) })
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.redirect(config.auth.providers.discord.oauth2Route)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function buildAvatarURL(discordId, avatarId) {
|
||||||
|
return `https://cdn.discordapp.com/avatars/${discordId}/${avatarId}.png?size=2048`
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = router
|
||||||
9
routes/index.js
Normal file
9
routes/index.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const express = require("express")
|
||||||
|
const router = express.Router()
|
||||||
|
const config = require("../config.json")
|
||||||
|
|
||||||
|
router.get("", (req, res) => {
|
||||||
|
res.redirect(`/auth/provider/${config.auth.defaultProvider}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router
|
||||||
20
routes/jwt.js
Normal file
20
routes/jwt.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const fs = require("node:fs")
|
||||||
|
const jwt = require("jsonwebtoken")
|
||||||
|
const path = require("node:path")
|
||||||
|
const express = require("express")
|
||||||
|
const router = express.Router()
|
||||||
|
const controller = require("../controllers/db")
|
||||||
|
|
||||||
|
const privateKey = fs.readFileSync(path.join(__dirname, "..", "keys", "private.pem"))
|
||||||
|
|
||||||
|
router.get("/external/key.pem", (req, res) => {
|
||||||
|
res.sendFile(path.join(__dirname, "..", "keys", "public.pem"))
|
||||||
|
})
|
||||||
|
|
||||||
|
router.post("/internal", controller.login, (req, res) => {
|
||||||
|
delete req.user.token
|
||||||
|
const token = jwt.sign(req.user, privateKey, { algorithm: "RS256", expiresIn: "168h" })
|
||||||
|
res.status(200).send(token)
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router
|
||||||
85
routes/lobby.js
Normal file
85
routes/lobby.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
const express = require("express")
|
||||||
|
const controller = require("../controllers/db")
|
||||||
|
const router = express.Router()
|
||||||
|
|
||||||
|
router.get("/", (req, res) => {
|
||||||
|
const roomsRequest = controller.listRooms()
|
||||||
|
if (!roomsRequest.success) {
|
||||||
|
res.status(roomsRequest.code).json({
|
||||||
|
error: roomsRequest.error,
|
||||||
|
code: roomsRequest.code
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const rooms = []
|
||||||
|
for (const room of roomsRequest.rooms) {
|
||||||
|
const playersRequest = controller.getPlayersFromRoom(room.id)
|
||||||
|
if (!playersRequest.success) {
|
||||||
|
res.status(playersRequest.code).json({
|
||||||
|
error: playersRequest.error,
|
||||||
|
code: playersRequest.code
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
delete room.password
|
||||||
|
room.players = playersRequest.players
|
||||||
|
rooms.push(room)
|
||||||
|
}
|
||||||
|
res.json(rooms)
|
||||||
|
})
|
||||||
|
|
||||||
|
//TO-DO : Finish it
|
||||||
|
router.post("/:roomId", controller.login, (req, res) => {
|
||||||
|
const { roomId } = req.params
|
||||||
|
const roomGetRequest = controller.getRoom(roomId)
|
||||||
|
if (roomGetRequest.success) {
|
||||||
|
if (roomGetRequest.room.owner == req.user.username) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
res.status(401).json({ success: false, error: "You must be the owner of this room to update it.", code: 401 })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.status(roomGetRequest.code).json(roomGetRequest)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
router.post("/:roomId/room", controller.login, (req, res) => {
|
||||||
|
const { roomId } = req.params
|
||||||
|
const { password } = req.body
|
||||||
|
const roomGetRequest = controller.getRoom(roomId)
|
||||||
|
if (roomGetRequest.success) {
|
||||||
|
if (!roomGetRequest.room.hasPassword) {
|
||||||
|
res.status(200).send()
|
||||||
|
} else {
|
||||||
|
if (!password) {
|
||||||
|
res.status(422).json({
|
||||||
|
code: 422,
|
||||||
|
message: "Missing parameter in body (password)"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (password == roomGetRequest.room.password) {
|
||||||
|
res.status(200).send()
|
||||||
|
} else {
|
||||||
|
res.status(401).json({ code: 401, error: "Invalid credential." })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.status(roomGetRequest.code).json(roomGetRequest)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
router.delete("/:roomId", controller.login, (req, res) => {
|
||||||
|
const { roomId } = req.params
|
||||||
|
const roomGetRequest = controller.getRoom(roomId)
|
||||||
|
if (roomGetRequest.success) {
|
||||||
|
if (roomGetRequest.room.owner == req.user.username) {
|
||||||
|
const roomDeleteRequest = controller.deleteRoom()
|
||||||
|
res.json(roomDeleteRequest)
|
||||||
|
} else {
|
||||||
|
res.status(401).json({ success: false, error: "You must be the owner of this room to delete it.", code: 401 })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.status(roomGetRequest.code).json(roomGetRequest)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router
|
||||||
10
routes/profile.js
Normal file
10
routes/profile.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const express = require("express")
|
||||||
|
const controller = require("../controllers/db")
|
||||||
|
const router = express.Router()
|
||||||
|
|
||||||
|
router.use("", controller.login, (req, res) => {
|
||||||
|
delete req.user.token
|
||||||
|
res.json(req.user)
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router
|
||||||
38
server.js
Normal file
38
server.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
const fs = require("node:fs")
|
||||||
|
const path = require("node:path")
|
||||||
|
const logger = require("./modules/logger")
|
||||||
|
const config = require("./config.json")
|
||||||
|
const express = require("express")
|
||||||
|
const dbController = require("./controllers/db")
|
||||||
|
const keysController = require("./controllers/keys")
|
||||||
|
const app = express()
|
||||||
|
|
||||||
|
app.use(express.json())
|
||||||
|
app.use(express.urlencoded({ extended: true }))
|
||||||
|
|
||||||
|
keysController.initKeys()
|
||||||
|
dbController.initDB()
|
||||||
|
|
||||||
|
const routes = fs.readdirSync(path.join(__dirname, "routes"), { recursive: true })
|
||||||
|
|
||||||
|
for (let route of routes) {
|
||||||
|
if (route.endsWith(".js")) {
|
||||||
|
if (route.endsWith("index.js")) {
|
||||||
|
route = "/" + route.replace("index.js", "/").replace(/\\/g, "/").replace(/\/\//g, "")
|
||||||
|
} else {
|
||||||
|
route = "/" + route.replace(".js", "").replace(/\\/g, "/")
|
||||||
|
}
|
||||||
|
const routeHandler = require(`./routes/${route}`)
|
||||||
|
app.use(route, routeHandler)
|
||||||
|
logger.log(`Route ${route.cyan.bold} registered`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// app.use("/", (req, res) => {
|
||||||
|
// console.log(req.headers)
|
||||||
|
// console.log(req.path)
|
||||||
|
// })
|
||||||
|
|
||||||
|
app.listen(config.web.port, () => {
|
||||||
|
logger.log(`Server listening at port : ${config.web.port}`)
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user