diff --git a/errors/SessionError.js b/errors/SessionError.js index e40638f..364dfb4 100644 --- a/errors/SessionError.js +++ b/errors/SessionError.js @@ -1,7 +1,8 @@ class SessionError extends Error { - constructor(statusCode, errorMessage, path) { + constructor(statusCode, error, errorMessage, path) { super(errorMessage) this.path = path + this.error = error this.statusCode = statusCode this.errorMessage = errorMessage this.isOperational = true @@ -13,6 +14,9 @@ class SessionError extends Error { path: this.path, errorMessage: this.errorMessage } + if (this.error != undefined) { + response.error = this.error + } return response } } diff --git a/errors/ValidationError.js b/errors/ValidationError.js index 5d1a31a..71ca835 100644 --- a/errors/ValidationError.js +++ b/errors/ValidationError.js @@ -1,7 +1,6 @@ const path = require("node:path") const DefaultError = require("./DefaultError") -const Logger = require("../modules/logger") -const logger = Logger.createLogger(path.join(__dirname, "..")) +const logger = require("../modules/logger") class ValidationError extends DefaultError { constructor(zodResult, config = {}, context = {}) { diff --git a/modules/databaseGlobals.js b/modules/databaseGlobals.js index d02530b..7de608e 100644 --- a/modules/databaseGlobals.js +++ b/modules/databaseGlobals.js @@ -1,7 +1,6 @@ const path = require("node:path") const mariadb = require("mariadb") -const Logger = require("./logger") -const logger = Logger.createLogger(path.join(__dirname, "..")) +const logger = require("./logger") const crypto = require("node:crypto") const rootConfig = { @@ -326,7 +325,7 @@ async function setupDatabase() { await conn.query(` CREATE TABLE IF NOT EXISTS serverSessions ( uuid VARCHAR(36) PRIMARY KEY, - accessToken VARCHAR(512) NOT NULL, + accessToken TEXT NOT NULL, serverId VARCHAR(255) NOT NULL, ip VARCHAR(45) NULL, createdAt DATETIME DEFAULT CURRENT_TIMESTAMP, diff --git a/modules/logger.js b/modules/logger.js index 20c125c..47651d8 100644 --- a/modules/logger.js +++ b/modules/logger.js @@ -85,6 +85,6 @@ function stripColors(string) { return string.replace(/\x1B\[[0-9;]*[mK]/g, "") } -module.exports = { - createLogger -} \ No newline at end of file +const logger = createLogger(path.join(__dirname, "..")) + +module.exports = logger \ No newline at end of file diff --git a/modules/utils.js b/modules/utils.js index 79cb333..09c155a 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -1,7 +1,6 @@ const path = require("node:path") -const Logger = require("./logger") +const logger = require("./logger") const crypto = require("node:crypto") -const logger = Logger.createLogger(path.join(__dirname, "..")) const certificatesManager = require("./certificatesManager") const serverKeys = certificatesManager.getKeys() @@ -40,7 +39,22 @@ function signProfileData(dataBase64) { } } +function addDashesToUUID(uuid) { + if (typeof uuid !== "string" || uuid.length !== 32) { + return uuid + } + + return ( + uuid.slice(0, 8) + "-" + + uuid.slice(8, 12) + "-" + + uuid.slice(12, 16) + "-" + + uuid.slice(16, 20) + "-" + + uuid.slice(20) + ) +} + module.exports = { getRegistrationCountryFromIp, + addDashesToUUID, signProfileData } \ No newline at end of file diff --git a/repositories/authRepository.js b/repositories/authRepository.js index 343aede..e301eb0 100644 --- a/repositories/authRepository.js +++ b/repositories/authRepository.js @@ -1,6 +1,4 @@ -const path = require("node:path") -const Logger = require("../modules/logger") -const logger = Logger.createLogger(path.join(__dirname, "..")) +const logger = require("../modules/logger") const bcrypt = require("bcryptjs") const database = require("../modules/database") const { DefaultError } = require("../errors/errors") @@ -77,39 +75,6 @@ async function checkUsernameAvailability(username) { return { code: 200, allowed: true } } -async function addPropertyToPlayer(key, value, uuid) { - try { - const sql = `INSERT INTO playersProperties (name, value, uuid) VALUES (?, ?, ?)` - const result = await database.query(sql, [key, value, uuid]) - - if (result.affectedRows > 0) { - return { code: 200, key, value, uuid } - } else { - throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") - } - } catch (error) { - logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) - throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") - } -} - -async function deletePropertyToPlayer(key, uuid) { - try { - const sql = `DELETE FROM playersProperties WHERE name = ? AND uuid = ?` - const result = await database.query(sql, [key, uuid]) - - if (result.affectedRows > 0) { - return { code: 200, key, uuid } - } else { - throw new DefaultError(500, "Property not found for this user/key combination.") - } - } catch (error) { - if (error instanceof DefaultError) throw error - logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) - throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") - } -} - async function insertClientSession(accessToken, clientToken, uuid) { try { const sql = `INSERT INTO clientSessions (accessToken, clientToken, uuid) VALUES (?, ?, ?)` @@ -265,10 +230,8 @@ module.exports = { getClientSession, revokeAccessTokens, insertClientSession, - addPropertyToPlayer, getPlayerProperties, validateClientSession, - deletePropertyToPlayer, invalidateClientSession, validateClientSessionWithoutClientToken } \ No newline at end of file diff --git a/repositories/sessionsRepository.js b/repositories/sessionsRepository.js index bae91a4..1e32e21 100644 --- a/repositories/sessionsRepository.js +++ b/repositories/sessionsRepository.js @@ -1,6 +1,4 @@ -const path = require("node:path") -const Logger = require("../modules/logger") -const logger = Logger.createLogger(path.join(__dirname, "..")) +const logger = require("../modules/logger") const database = require("../modules/database") const { DefaultError } = require("../errors/errors") diff --git a/repositories/userRepository.js b/repositories/userRepository.js new file mode 100644 index 0000000..c7bbd34 --- /dev/null +++ b/repositories/userRepository.js @@ -0,0 +1,312 @@ +const crypto = require("node:crypto") +const logger = require("../modules/logger") +const database = require("../modules/database") +const { DefaultError } = require("../errors/errors") + +async function addPropertyToPlayer(key, value, uuid) { + try { + const sql = `INSERT INTO playersProperties (name, value, uuid) VALUES (?, ?, ?)` + const result = await database.query(sql, [key, value, uuid]) + + if (result.affectedRows > 0) { + return { code: 200, key, value, uuid } + } else { + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } + } catch (error) { + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function deletePropertyToPlayer(key, uuid) { + try { + const sql = `DELETE FROM playersProperties WHERE name = ? AND uuid = ?` + const result = await database.query(sql, [key, uuid]) + + if (result.affectedRows > 0) { + return { code: 200, key, uuid } + } else { + throw new DefaultError(500, "Property not found for this user/key combination.") + } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function updatePropertyToPlayer(key, value, uuid) { + try { + const sql = `UPDATE playersProperties SET value = ? WHERE name = ? AND uuid = ?` + const result = await database.query(sql, [value, key, uuid]) + if (result.affectedRows > 0) { + return { code: 200, key, value, uuid } + } else { + throw new DefaultError(404, "Property not found for this user/key combination") + } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function getPlayerProperties(uuid) { + try { + const sql = `SELECT * FROM playersProperties WHERE uuid = ?` + const rows = await database.query(sql, [uuid]) + if (rows.length === 0) { + throw new DefaultError(404, "Properties not found for this user") + } + return { + code: 200, + properties: rows.map(property => ({ name: property.name, value: property.value })) + } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function getPlayerProperty(key, uuid) { + try { + const sql = `SELECT * FROM playersProperties WHERE name = ? AND uuid = ?` + const rows = await database.query(sql, [key, uuid]) + const property = rows[0] + if (!property) { + throw new DefaultError(404, "Property not found for this user/key combination") + } + return { code: 200, property } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function getPlayerSettingsSchema() { + const RAW_SCHEMA_CACHE = { + privileges: {}, + preferences: {} + } + try { + const privilegesRows = await database.query("DESCRIBE playersPrivileges") + const preferencesRows = await database.query("DESCRIBE playersPreferences") + RAW_SCHEMA_CACHE.privileges = privilegesRows.map(c => c.Field).filter(n => n !== "uuid") + RAW_SCHEMA_CACHE.preferences = preferencesRows.map(c => c.Field).filter(n => n !== "uuid") + return RAW_SCHEMA_CACHE + } catch (err) { + logger.log("Database Schema Error: " + err.toString(), ["MariaDB", "red"]) + throw new DefaultError(500, "Internal Server Error", "Database Schema Error") + } +} + +async function updatePlayerPreferences(uuid, updates) { + try { + const keys = Object.keys(updates) + if (keys.length === 0) { + throw new DefaultError(400, "No fields provided for update.") + } + const setClause = keys.map(key => `\`${key}\` = ?`).join(', ') + const sql = `UPDATE playersPreferences SET ${setClause} WHERE uuid = ?` + const values = keys.map(key => updates[key]) + values.push(uuid) + const result = await database.query(sql, values) + if (result.affectedRows > 0) { + return { + code: 200, + message: "Preferences updated successfully." + } + } else { + throw new DefaultError(404, "Player preferences not found or no changes made.") + } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function getPlayerPreferences(uuid) { + try { + const sql = `SELECT profanityFilter FROM playersPreferences WHERE uuid = ?` + const rows = await database.query(sql, [uuid]) + const data = rows[0] + + if (data) { + return { + code: 200, + message: "Preferences retrieved successfully.", + data: data + } + } else { + throw new DefaultError(404, "Preferences not found for this UUID.") + } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function getPlayerPrivileges(uuid) { + try { + const sql = ` + SELECT onlineChat, multiplayerServer, multiplayerRealms, telemetry + FROM playersPrivileges + WHERE uuid = ? + ` + const rows = await database.query(sql, [uuid]) + const data = rows[0] + if (data) { + return { + code: 200, + message: "Privileges retrieved successfully.", + data: data + } + } else { + throw new DefaultError(404, "Privileges not found for this UUID.") + } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function updatePlayerPrivileges(uuid, updates) { + try { + const keys = Object.keys(updates) + if (keys.length === 0) { + throw new DefaultError(404, "No fields provided for update.") + } + const setClause = keys.map(key => `\`${key}\` = ?`).join(', ') + const sql = `UPDATE playersPrivileges SET ${setClause} WHERE uuid = ?` + const values = keys.map(key => updates[key]) + values.push(uuid) + const result = await database.query(sql, values) + if (result.affectedRows > 0) { + return { + code: 200, + message: "Privileges updated successfully." + } + } else { + throw new DefaultError(404, "Player privileges not found or no changes made.") + } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function banUser(uuid, { reasonKey, reasonMessage, expires = null }) { + try { + if (!uuid || !reasonKey) { + throw new DefaultError(400, "Missing uuid or reasonKey.") + } + + let reasonId + const reasonRows = await database.query("SELECT id FROM banReasons WHERE reason_key = ?", [reasonKey]) + if (reasonRows.length > 0) { + reasonId = reasonRows[0].id + } else { + const insertReason = await database.query("INSERT INTO banReasons (reason_key) VALUES (?)", [reasonKey]) + reasonId = insertReason.insertId + } + + const banId = crypto.randomUUID() + const insertSql = ` + INSERT INTO bans (banId, uuid, reason, reasonMessage, expires) + VALUES (?, ?, ?, ?, ?) + ` + const result = await database.query(insertSql, [banId, uuid, reasonId, reasonMessage || "Banned by operator", expires]) + + if (result.affectedRows > 0) { + return { + code: 200, + message: "User successfully banned.", + banId: banId + } + } else { + throw new DefaultError(500, "Failed to ban user.") + } + + } catch (error) { + if (error instanceof DefaultError) throw error + if (error.code === "ER_NO_REFERENCED_ROW_2" || error.toString().includes("foreign key constraint")) { + throw new DefaultError(404, "User not found (cannot ban a ghost).") + } + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Internal Server Error", error.toString()) + } +} + +async function unbanUser(uuid) { + try { + if (!uuid) { + throw new DefaultError(400, "Missing uuid.") + } + const sql = "DELETE FROM bans WHERE uuid = ?" + const result = await database.query(sql, [uuid]) + if (result.affectedRows > 0) { + return { + code: 200, + message: "User successfully unbanned.", + count: result.affectedRows + } + } else { + throw new DefaultError(404, "User was not banned.") + } + + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +async function getPlayerBans(uuid) { + try { + const sql = ` + SELECT + b.banId, + b.expires, + b.reasonMessage, + r.reason_key as reason + FROM bans b + JOIN banReasons r ON b.reason = r.id + WHERE b.uuid = ? + ORDER BY b.expires ASC + ` + const rows = await database.query(sql, [uuid]) + + if (rows.length > 0) { + return { code: 200, bans: rows } + } else { + return { code: 204 } + } + } catch (error) { + if (error instanceof DefaultError) throw error + logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"]) + throw new DefaultError(500, "Please contact an administrator.", "InternalServerError") + } +} + +module.exports = { + banUser, + unbanUser, + getPlayerBans, + getPlayerProperty, + getPlayerPrivileges, + getPlayerProperties, + addPropertyToPlayer, + getPlayerPreferences, + updatePlayerPrivileges, + deletePropertyToPlayer, + updatePropertyToPlayer, + getPlayerSettingsSchema, + updatePlayerPreferences, +} \ No newline at end of file diff --git a/routes/authserver/authenticate.js b/routes/authserver/authenticate.js index c9ebd95..ccf5ba0 100644 --- a/routes/authserver/authenticate.js +++ b/routes/authserver/authenticate.js @@ -1,11 +1,9 @@ -const path = require("path") const express = require("express") const router = express.Router() const { YggdrasilError } = require("../../errors/errors") const rateLimit = require("express-rate-limit") const authService = require("../../services/authService") -const Logger = require("../../modules/logger") -const logger = Logger.createLogger(path.join(__dirname, "..", "..")) +const logger = require("../../modules/logger") const limiter = rateLimit({ windowMs: 15 * 60 * 1000, diff --git a/routes/authserver/refresh.js b/routes/authserver/refresh.js index 8ddf58f..1fb8b64 100644 --- a/routes/authserver/refresh.js +++ b/routes/authserver/refresh.js @@ -1,9 +1,7 @@ -const path = require("node:path") const express = require("express") const router = express.Router() const authService = require("../../services/authService") -const Logger = require("../../modules/logger") -const logger = Logger.createLogger(path.join(__dirname, "..", "..")) +const logger = require("../../modules/logger") const { DefaultError, YggdrasilError } = require("../../errors/errors") router.post("/", async (req, res) => { diff --git a/routes/authserver/signout.js b/routes/authserver/signout.js index 9ba2b65..8fa5720 100644 --- a/routes/authserver/signout.js +++ b/routes/authserver/signout.js @@ -1,9 +1,7 @@ -const path = require("node:path") const express = require("express") const router = express.Router() const authService = require("../../services/authService") -const Logger = require("../../modules/logger") -const logger = Logger.createLogger(path.join(__dirname, "..", "..")) +const logger = require("../../modules/logger") const { DefaultError, YggdrasilError } = require("../../errors/errors") router.post("/", async (req, res) => { diff --git a/routes/register.js b/routes/register.js index 89a70ad..d2df668 100644 --- a/routes/register.js +++ b/routes/register.js @@ -1,8 +1,6 @@ -const path = require("node:path") const express = require("express") const router = express.Router() -const Logger = require("../modules/logger") -const logger = Logger.createLogger(path.join(__dirname, "..")) +const logger = require("../modules/logger") const authService = require("../services/authService") router.post("/", async (req, res) => { diff --git a/routes/sessionsserver/session/minecraft/hasJoined.js b/routes/sessionsserver/session/minecraft/hasJoined.js index 92b8f11..17e1615 100644 --- a/routes/sessionsserver/session/minecraft/hasJoined.js +++ b/routes/sessionsserver/session/minecraft/hasJoined.js @@ -1,10 +1,8 @@ -const path = require("path") const express = require("express") const router = express.Router() const sessionsService = require("../../../../services/sessionsService") -const Logger = require("../../../../modules/logger") +const logger = require("../../../../modules/logger") const { YggdrasilError, DefaultError } = require("../../../../errors/errors") -const logger = Logger.createLogger(path.join(__dirname, "..", "..", "..", "..")) router.get("/", async (req, res) => { const { username, serverId, ip } = req.query diff --git a/routes/sessionsserver/session/minecraft/join.js b/routes/sessionsserver/session/minecraft/join.js new file mode 100644 index 0000000..4e5e50f --- /dev/null +++ b/routes/sessionsserver/session/minecraft/join.js @@ -0,0 +1,66 @@ +const path = require("path") +const express = require("express") +const router = express.Router() +const utils = require("../../../../modules/utils") +const authService = require("../../../../services/authService") +const sessionsService = require("../../../../services/sessionsService") +const userRepository = require("../../../../repositories/userRepository") +const logger = require("../../../../modules/logger") +const { SessionError, DefaultError } = require("../../../../errors/errors") + +router.post("/", async (req, res) => { + const { accessToken, selectedProfile, serverId } = req.body + + try { + const verificationResult = await authService.verifyAccessToken({ accessToken }) + const tokenUuid = verificationResult.user.uuid + const requestedProfile = utils.addDashesToUUID(selectedProfile) + + if (tokenUuid !== requestedProfile) { + throw new SessionError(403, "Forbidden", "You cannot join with a profile that is not yours.", req.originalUrl) + } + + const bansResult = await userRepository.getPlayerBans(tokenUuid) + if (bansResult.code === 200 && bansResult.bans && bansResult.bans.length > 0) { + const activeBan = bansResult.bans[0] + throw new SessionError( + 403, + "UserBannedException", + activeBan.reasonMessage || "You are banned from multiplayer.", + req.originalUrl + ) + } + + try { + const privsResult = await userRepository.getPlayerPrivileges(tokenUuid) + if (privsResult.code === 200 && privsResult.data) { + if (!privsResult.data.multiplayerServer) { + throw new SessionError(403, "InsufficientPrivilegesException", "Multiplayer is disabled for your account.", req.originalUrl) + } + } + } catch (privError) { + if (privError instanceof DefaultError && privError.code !== 404) throw privError + } + const ip = req.headers["x-forwarded-for"] || req.socket.remoteAddress + await sessionsService.joinServer({ + clientToken: verificationResult.session.clientToken, + accessToken, + selectedProfile: requestedProfile, + serverId, + ip + }) + logger.log(`Server join success: ${verificationResult.user.username}`, ["SESSION", "green"]) + return res.status(204).end() + } catch (err) { + console.log(err) + if (err instanceof SessionError) throw err + if (err instanceof DefaultError) { + const statusCode = err.code === 401 ? 403 : (err.code || 500) + const errorName = "Forbidden" + throw new SessionError(statusCode, errorName, err.message, req.originalUrl) + } + throw new SessionError(500, "Forbidden", "Internal Server Error", req.originalUrl) + } +}) + +module.exports = router \ No newline at end of file diff --git a/routes/sessionsserver/session/minecraft/profile/[uuid].js b/routes/sessionsserver/session/minecraft/profile/[uuid].js index f03da48..daf0a7f 100644 --- a/routes/sessionsserver/session/minecraft/profile/[uuid].js +++ b/routes/sessionsserver/session/minecraft/profile/[uuid].js @@ -17,12 +17,12 @@ router.get("", async (req, res) => { return res.status(200).json(result.data) } if (result.code === 204) { - throw new SessionError(404, "Not a valid UUID", req.originalUrl) + throw new SessionError(404, undefined, "Not a valid UUID", req.originalUrl) } - throw new DefaultError(500, "Unknown error") + throw new DefaultError(500, undefined, "Unknown error", req.originalUrl) } catch (err) { const errorMessage = err.message || "Not a valid UUID" - throw new SessionError(400, errorMessage, req.originalUrl) + throw new SessionError(400, undefined, errorMessage, req.originalUrl) } }) diff --git a/schemas/sessionsserver/session/minecraft/hasJoined.js b/schemas/sessionsserver/session/minecraft/hasJoined.js new file mode 100644 index 0000000..ebdce31 --- /dev/null +++ b/schemas/sessionsserver/session/minecraft/hasJoined.js @@ -0,0 +1,19 @@ +const z = require("zod") + +module.exports = { + GET: { + query: z.object({ + username: z.string() + .min(3) + .max(16), + serverId: z.string() + .min(1), + ip: z.string() + .optional() + }), + error: { + code: 204, + message: "Ignored" + } + } +} \ No newline at end of file diff --git a/server.js b/server.js index 7c50aaf..4242b64 100644 --- a/server.js +++ b/server.js @@ -4,8 +4,7 @@ const app = express() const cors = require("cors") const path = require("node:path") const utils = require("./modules/utils") -const Logger = require("./modules/logger") -const logger = Logger.createLogger(__dirname) +const logger = require("./modules/logger") const helmet = require("helmet") const loader = require("./modules/loader") const DefaultError = require("./errors/DefaultError") diff --git a/services/authService.js b/services/authService.js index 5de930f..65f9bbf 100644 --- a/services/authService.js +++ b/services/authService.js @@ -2,6 +2,7 @@ const jwt = require("jsonwebtoken") const utils = require("../modules/utils") const bcrypt = require("bcryptjs") const crypto = require("node:crypto") +const userRepository = require("../repositories/userRepository") const authRepository = require("../repositories/authRepository") const certsManager = require("../modules/certificatesManager") const { DefaultError } = require("../errors/errors") @@ -30,15 +31,14 @@ async function registerUser({ username, password, email, registrationCountry, pr const { uuid } = userRegistration const resolvedCountry = registrationCountry || await utils.getRegistrationCountryFromIp(clientIp) - await authRepository.addPropertyToPlayer("registrationCountry", resolvedCountry || "UNKNOWN", uuid) - await authRepository.addPropertyToPlayer("userPreferredLanguage", preferredLanguage || "fr-FR", uuid) + await userRepository.addPropertyToPlayer("registrationCountry", resolvedCountry || "UNKNOWN", uuid) + await userRepository.addPropertyToPlayer("userPreferredLanguage", preferredLanguage || "fr-FR", uuid) return { code: 200, message: "User created successfully", uuid } } async function authenticate({ identifier, password, clientToken, requireUser }) { let userResult - try { userResult = await authRepository.getUser(identifier, true) } catch (error) { @@ -47,7 +47,6 @@ async function authenticate({ identifier, password, clientToken, requireUser }) } throw error } - const passwordValidationProcess = await bcrypt.compare(password, userResult.user.password) if (!passwordValidationProcess) { throw new DefaultError(403, "Invalid credentials. Invalid username or password.", "ForbiddenOperationException")