Add session service with profile and session management
Introduces sessionService.js providing functions for legacy session registration and validation, profile retrieval with skin/cape data, server join handling, and blocked server listing. Integrates with auth and session repositories and includes error handling for various session operations.
This commit is contained in:
parent
bdb6457d1d
commit
64d632eac9
162
services/sessionService.js
Normal file
162
services/sessionService.js
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
const utils = require("../modules/utils")
|
||||||
|
const authRepository = require("../repositories/authRepository")
|
||||||
|
const sessionRepository = require("../repositories/sessionRepository")
|
||||||
|
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
|
||||||
|
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
|
||||||
|
const activeCape = capeResult.data
|
||||||
|
const profileActions = actionsResult.data || []
|
||||||
|
|
||||||
|
const isSkinBanned = profileActions.includes("USING_BANNED_SKIN")
|
||||||
|
const hasValidSkin = activeSkin && !isSkinBanned
|
||||||
|
const hasValidCape = !!activeCape
|
||||||
|
|
||||||
|
const skinNode = hasValidSkin ? {
|
||||||
|
url: activeSkin.url,
|
||||||
|
metadata: activeSkin.variant === "SLIM" ? { model: "slim" } : undefined
|
||||||
|
} : undefined
|
||||||
|
|
||||||
|
const capeNode = hasValidCape ? {
|
||||||
|
url: 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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getProfile,
|
||||||
|
joinServer,
|
||||||
|
hasJoinedServer,
|
||||||
|
getBlockedServers,
|
||||||
|
registerLegacySession,
|
||||||
|
validateLegacySession,
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user