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.
312 lines
12 KiB
JavaScript
312 lines
12 KiB
JavaScript
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,
|
|
} |