const utils = require("../modules/utils") const authRepository = require("../repositories/authRepository") const sessionRepository = require("../repositories/sessionsRepository") const { DefaultError } = require("../errors/errors") async function registerLegacySession({ uuid, sessionId }) { try { await sessionRepository.insertLegacyClientSessions(sessionId, uuid) return { code: 200 } } catch (error) { if (error instanceof DefaultError) throw error throw new DefaultError(500, "Internal Server Error", error.toString()) } } async function validateLegacySession({ name, sessionId }) { let userResult try { userResult = await authRepository.getUser(name) } catch (error) { if (error.code === 404) { throw error } throw error } try { await sessionRepository.validateLegacyClientSession(sessionId, userResult.user.uuid) return { code: 200 } } catch (error) { if (error.code === 404) { throw new DefaultError(403, "Invalid session.", "ForbiddenOperationException") } throw error } } async function getBlockedServers() { try { return await sessionRepository.getBlockedServers() } catch (error) { throw new DefaultError(500, "Unable to fetch blocked servers.", error.toString()) } } async function getProfile({ uuid, unsigned = false }) { let userResult, $uuid = utils.addDashesToUUID(uuid) try { userResult = await authRepository.getUser($uuid, false) } catch (error) { if (error.code === 404) { return { code: 204, message: "User not found" } } throw error } const dbUser = userResult.user const username = dbUser.username const cleanUuid = dbUser.uuid.replace(/-/g, "") const [skinResult, capeResult, actionsResult] = await Promise.all([ sessionRepository.getActiveSkin(dbUser.uuid).catch(() => ({ data: null })), sessionRepository.getActiveCape(dbUser.uuid).catch(() => ({ data: null })), sessionRepository.getProfileActionsList(dbUser.uuid).catch(() => ({ data: [] })) ]) const activeSkin = skinResult.data[0] const activeCape = capeResult.data[0] const profileActions = actionsResult.data || [] const isSkinBanned = profileActions.includes("USING_BANNED_SKIN") const hasValidSkin = activeSkin && !isSkinBanned const hasValidCape = !!activeCape const skinNode = hasValidSkin ? { url: (process.env.TEXTURES_ENDPOINTS || `http://localhost:${process.env.WEB_PORT}/textures`) + activeSkin.url, metadata: activeSkin.variant === "SLIM" ? { model: "slim" } : undefined } : undefined const capeNode = hasValidCape ? { url: (process.env.TEXTURES_ENDPOINTS || `http://localhost:${process.env.WEB_PORT}/textures`) + activeCape.url } : undefined const texturesObject = { ...(skinNode && { SKIN: skinNode }), ...(capeNode && { CAPE: capeNode }) } const texturePayload = { timestamp: Date.now(), profileId: cleanUuid, profileName: username, signatureRequired: !unsigned, textures: texturesObject } const payloadJson = JSON.stringify(texturePayload) const base64Value = Buffer.from(payloadJson).toString("base64") const signature = unsigned ? null : utils.signProfileData(base64Value) const propertyNode = { name: "textures", value: base64Value, ...(signature && { signature: signature }) } return { code: 200, data: { id: cleanUuid, name: username, properties: [propertyNode], profileActions: profileActions } } } async function joinServer({ accessToken, selectedProfile, clientToken, serverId, ip }) { try { await authRepository.validateClientSession(accessToken, clientToken) } catch (error) { throw new DefaultError(403, "Invalid access token", "ForbiddenOperationException") } await sessionRepository.saveServerSession(selectedProfile, accessToken, serverId, ip) return { code: 204 } } async function hasJoinedServer({ username, serverId, ip }) { let userResult try { userResult = await authRepository.getUser(username, false) } catch (error) { if (error.code === 404) return { code: 204, message: "User not found" } throw error } const { uuid } = userResult.user const joinCheck = await sessionRepository.getServerSession(uuid, serverId) if (joinCheck.code !== 200 || !joinCheck.valid) { return { code: 204, message: "Join verification failed" } } if (ip && ip.trim() !== "" && joinCheck.ip !== ip) { return { code: 204, message: "Invalid IP address" } } return await getProfile({ uuid: uuid, unsigned: false }) } async function joinLegacyServer({ name, sessionId, serverId }) { try { await validateLegacySession({ name, sessionId }) } catch (error) { throw new DefaultError(403, "Bad login", "ForbiddenOperationException") } const userResult = await authRepository.getUser(name) const uuid = userResult.user.uuid await sessionRepository.saveServerSession(uuid, sessionId, serverId, "0.0.0.0") return { code: 200, message: "OK" } } async function getActiveSkin({ username }) { try { const dbUser = await authRepository.getUser(username) const activeSkin = await sessionRepository.getActiveSkin(dbUser.user.uuid) return activeSkin } catch (error) { if (!(error instanceof DefaultError)) { throw new DefaultError(400, "Bad Request", error.toString()) } throw error } } async function getActiveCape({ username }) { try { const dbUser = await authRepository.getUser(username) const activeCape = await sessionRepository.getActiveCape(dbUser.user.uuid) return activeCape } catch (error) { if (!(error instanceof DefaultError)) { throw new DefaultError(400, "Bad Request", error.toString()) } throw error } } module.exports = { getProfile, joinServer, getActiveCape, getActiveSkin, hasJoinedServer, joinLegacyServer, getBlockedServers, registerLegacySession, validateLegacySession, }