Refactor logger usage and add userRepository module
Replaces custom logger instantiation with a shared logger import across modules and routes. Moves player property and privilege management from authRepository to a new userRepository, expanding userRepository with additional user management functions (ban, unban, preferences, privileges, bans). Updates service and route files to use userRepository where appropriate. Adds new session join route and schema, and utility for UUID formatting.
This commit is contained in:
parent
80bca31d9a
commit
2519d8078a
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 = {}) {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -85,6 +85,6 @@ function stripColors(string) {
|
||||
return string.replace(/\x1B\[[0-9;]*[mK]/g, "")
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createLogger
|
||||
}
|
||||
const logger = createLogger(path.join(__dirname, ".."))
|
||||
|
||||
module.exports = logger
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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")
|
||||
|
||||
|
||||
312
repositories/userRepository.js
Normal file
312
repositories/userRepository.js
Normal file
@ -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,
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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
|
||||
|
||||
66
routes/sessionsserver/session/minecraft/join.js
Normal file
66
routes/sessionsserver/session/minecraft/join.js
Normal file
@ -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
|
||||
@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
19
schemas/sessionsserver/session/minecraft/hasJoined.js
Normal file
19
schemas/sessionsserver/session/minecraft/hasJoined.js
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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")
|
||||
|
||||
@ -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")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user