diff --git a/errors/SessionError.js b/errors/SessionError.js new file mode 100644 index 0000000..e40638f --- /dev/null +++ b/errors/SessionError.js @@ -0,0 +1,20 @@ +class SessionError extends Error { + constructor(statusCode, errorMessage, path) { + super(errorMessage) + this.path = path + this.statusCode = statusCode + this.errorMessage = errorMessage + this.isOperational = true + Error.captureStackTrace(this, this.constructor) + } + + serialize() { + const response = { + path: this.path, + errorMessage: this.errorMessage + } + return response + } +} + +module.exports = SessionError \ No newline at end of file diff --git a/errors/YggdrasilError.js b/errors/YggdrasilError.js index c1a484f..e6738f1 100644 --- a/errors/YggdrasilError.js +++ b/errors/YggdrasilError.js @@ -1,10 +1,4 @@ class YggdrasilError extends Error { - /** - * @param {number} statusCode - Le code HTTP (ex: 403, 415) - * @param {string} error - Description courte (ex: "ForbiddenOperationException" ou "Unsupported Media Type") - * @param {string} errorMessage - Description longue pour l'utilisateur - * @param {string} [cause] - Cause optionnelle de l'erreur - */ constructor(statusCode, error, errorMessage, cause) { super(errorMessage) this.statusCode = statusCode diff --git a/errors/errors.js b/errors/errors.js index cf41983..b86d7b7 100644 --- a/errors/errors.js +++ b/errors/errors.js @@ -1,9 +1,11 @@ const DefaultError = require("./DefaultError") +const SessionError = require("./SessionError") const YggdrasilError = require("./YggdrasilError") const ValidationError = require("./ValidationError") module.exports = { DefaultError, + SessionError, YggdrasilError, ValidationError } \ No newline at end of file diff --git a/modules/logger.js b/modules/logger.js index 08b1518..20c125c 100644 --- a/modules/logger.js +++ b/modules/logger.js @@ -5,6 +5,8 @@ require("dotenv").config({ quiet: true }) +process.setMaxListeners(15) + function cleanup($stream) { if (!$stream.destroyed) { $stream.end() @@ -49,7 +51,7 @@ function createLogger(root) { } const stream = fs.createWriteStream(path.join(logsDir, `${fileName}.log`), { flags: "a" }) - + process.on("exit", () => { cleanup(stream) }) diff --git a/modules/utils.js b/modules/utils.js index 0e81c13..79cb333 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -1,5 +1,6 @@ const path = require("node:path") const Logger = require("./logger") +const crypto = require("node:crypto") const logger = Logger.createLogger(path.join(__dirname, "..")) const certificatesManager = require("./certificatesManager") const serverKeys = certificatesManager.getKeys() diff --git a/repositories/sessionRepository.js b/repositories/sessionsRepository.js similarity index 100% rename from repositories/sessionRepository.js rename to repositories/sessionsRepository.js diff --git a/routes/sessionsserver/session/minecraft/hasJoined.js b/routes/sessionsserver/session/minecraft/hasJoined.js new file mode 100644 index 0000000..92b8f11 --- /dev/null +++ b/routes/sessionsserver/session/minecraft/hasJoined.js @@ -0,0 +1,26 @@ +const path = require("path") +const express = require("express") +const router = express.Router() +const sessionsService = require("../../../../services/sessionsService") +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 + try { + const result = await sessionsService.hasJoinedServer({ username, serverId, ip }) + if (result.code === 200) { + logger.log(`Server join verified for: ${username}`, ["SESSION", "green"]) + return res.status(200).json(result.data) + } + return res.status(204).end() + } catch (err) { + if (err instanceof DefaultError) { + throw new YggdrasilError(err.code, err.error || "InternalServerError", err.message, err.cause) + } + throw err + } +}) + +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 new file mode 100644 index 0000000..f03da48 --- /dev/null +++ b/routes/sessionsserver/session/minecraft/profile/[uuid].js @@ -0,0 +1,29 @@ +const express = require("express") +const router = express.Router({ mergeParams: true }) +const sessionsService = require("../../../../../services/sessionsService") +const { SessionError, DefaultError } = require("../../../../../errors/errors") + +router.get("", async (req, res) => { + const { uuid } = req.params + const { unsigned } = req.query + const isUnsigned = (unsigned == undefined || unsigned == "true") ? true : false + + try { + const result = await sessionsService.getProfile({ + uuid: uuid, + unsigned: isUnsigned + }) + if (result.code === 200) { + return res.status(200).json(result.data) + } + if (result.code === 204) { + throw new SessionError(404, "Not a valid UUID", req.originalUrl) + } + throw new DefaultError(500, "Unknown error") + } catch (err) { + const errorMessage = err.message || "Not a valid UUID" + throw new SessionError(400, errorMessage, req.originalUrl) + } +}) + +module.exports = router \ No newline at end of file diff --git a/services/sessionService.js b/services/sessionsService.js similarity index 98% rename from services/sessionService.js rename to services/sessionsService.js index 4845cc3..c250d5f 100644 --- a/services/sessionService.js +++ b/services/sessionsService.js @@ -1,6 +1,6 @@ const utils = require("../modules/utils") const authRepository = require("../repositories/authRepository") -const sessionRepository = require("../repositories/sessionRepository") +const sessionRepository = require("../repositories/sessionsRepository") const { DefaultError } = require("../errors/errors") async function registerLegacySession({ uuid, sessionId }) {