Yggdrasil/repositories/sessionsRepository.js
azures04 439094013d Add admin API, permissions, and player management routes
Introduces admin database tables, repository, and service for managing administrators and permissions. Adds new admin routes for banning players, managing cosmetics (capes), changing player passwords and usernames, and handling player textures. Updates user and session services to support admin actions and permission checks. Adds related schema validation for new endpoints.
2026-01-05 04:44:56 +01:00

174 lines
6.1 KiB
JavaScript

const logger = require("../modules/logger")
const database = require("../modules/database")
const { DefaultError } = require("../errors/errors")
async function insertLegacyClientSessions(sessionId, uuid) {
try {
await database.query(`DELETE FROM legacyClientSessions WHERE uuid = ?`, [uuid])
const sql = `INSERT INTO legacyClientSessions (sessionId, uuid) VALUES (?, ?)`
const result = await database.query(sql, [sessionId, uuid])
if (result.affectedRows > 0) {
return { code: 200, sessionId, uuid }
} else {
throw new DefaultError(500, "Internal Server Error", "Unknown DB Error")
}
} catch (error) {
if (error instanceof DefaultError) throw error
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
throw new DefaultError(500, "Internal Server Error", "Please contact an administrator.")
}
}
async function validateLegacyClientSession(sessionId, uuid) {
try {
const sql = `SELECT * FROM legacyClientSessions WHERE sessionId = ? AND uuid = ?`
const rows = await database.query(sql, [sessionId, uuid])
const session = rows[0]
if (session) {
return {
code: 200,
message: "Client session valid."
}
} else {
return {
code: 404,
message: "Client session not found for this accessToken/clientToken combination"
}
}
} catch (error) {
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
throw new DefaultError(500, "Internal Server Error", "Please contact an administrator.")
}
}
async function getBlockedServers() {
try {
const sql = `SELECT * FROM blockedServers`
const blockedServers = await database.query(sql)
return {
code: 200,
blockedServers: blockedServers.map(bannedServer => ({ sha1: bannedServer.hashedIp }))
}
} catch (error) {
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
throw new DefaultError(500, "Internal Server Error", "Please contact an administrator.")
}
}
async function getActiveSkin(uuid) {
try {
const sql = `
SELECT t.url, ps.variant
FROM playersSkins ps
JOIN textures t ON ps.assetHash = t.hash
WHERE ps.playerUuid = ? AND ps.isSelected = 1
`
const rows = await database.query(sql, [uuid])
const skin = rows[0]
if (!skin) {
throw new DefaultError(404, "Not found", "Not found")
}
return { code: 200, data: skin || null }
} catch (error) {
if (error instanceof DefaultError) {
throw error
}
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
throw new DefaultError(500, "Internal Server Error", "Please contact an administrator.")
}
}
async function getActiveCape(uuid) {
try {
const sql = `
SELECT t.url
FROM playersCapes pc
JOIN textures t ON pc.assetHash = t.hash
WHERE pc.playerUuid = ? AND pc.isSelected = 1
`
const rows = await database.query(sql, [uuid])
const cape = rows[0]
if (!cape) {
throw new DefaultError(404, "Not found", "Not found")
}
return { code: 200, data: cape || null }
} catch (error) {
if (error instanceof DefaultError) {
throw error
}
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
throw new DefaultError(500, "Internal Server Error", "Please contact an administrator.")
}
}
async function getProfileActionsList(uuid) {
try {
const cleanUuid = uuid.replace(/-/g, "")
const sql = "SELECT action FROM playerProfileActions WHERE uuid = ?"
const rows = await database.query(sql, [cleanUuid])
const actions = rows.map(row => row.action)
return { code: 200, data: actions }
} catch (error) {
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
throw new DefaultError(500, "Internal Server Error", "Please contact an administrator.")
}
}
async function saveServerSession(uuid, accessToken, serverId, ip) {
try {
const sql = `
INSERT INTO serverSessions (uuid, accessToken, serverId, ip, createdAt)
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
ON DUPLICATE KEY UPDATE
accessToken = VALUES(accessToken),
serverId = VALUES(serverId),
ip = VALUES(ip),
createdAt = CURRENT_TIMESTAMP
`
const result = await database.query(sql, [uuid, accessToken, serverId, ip])
return { code: 200, success: result.affectedRows > 0 }
} catch (error) {
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
throw new DefaultError(500, "Internal Server Error", "Please contact an administrator.")
}
}
async function getServerSession(uuid, serverId) {
try {
const sql = `
SELECT ip
FROM serverSessions
WHERE uuid = ? AND serverId = ?
AND createdAt > (NOW() - INTERVAL 30 SECOND)
`
const rows = await database.query(sql, [uuid, serverId])
const session = rows[0]
if (!session) {
return { code: 404, valid: false }
}
return { code: 200, valid: true, ip: session.ip }
} catch (error) {
logger.log("Internal Server Error".bold + " : " + error.toString(), ["MariaDB", "yellow"])
throw new DefaultError(500, "Internal Server Error", "Please contact an administrator.")
}
}
module.exports = {
insertLegacyClientSessions,
validateLegacyClientSession,
getBlockedServers,
getActiveSkin,
getActiveCape,
getProfileActionsList,
saveServerSession,
getServerSession
}