Add legacy authentication and session routes

Introduces legacy endpoints for login, joinserver, and checkserver, along with their input validation schemas. Updates sessionsService with joinLegacyServer to support legacy session handling. This enables compatibility with legacy clients requiring these authentication flows.
This commit is contained in:
Gilles Lazures 2025-12-28 23:19:38 +01:00
parent e8f58e63cd
commit 3cd42103e5
7 changed files with 139 additions and 0 deletions

View File

@ -0,0 +1,24 @@
const express = require("express")
const router = express.Router()
const sessionsService = require("../../services/sessionsService")
router.get("/", async (req, res) => {
const { user, serverId } = req.query
try {
const result = await sessionsService.hasJoinedServer({
username: user,
serverId,
ip: null
})
if (result.code === 200) {
return res.send("YES")
} else {
return res.send("NO")
}
} catch (err) {
return res.send("NO")
}
})
module.exports = router

View File

@ -0,0 +1,26 @@
const express = require("express")
const router = express.Router()
const sessionsService = require("../../services/sessionsService")
const logger = require("../../modules/logger")
router.get("/", async (req, res) => {
const { user, sessionId, serverId } = req.query
const clientIp = req.ip || req.connection.remoteAddress
try {
await sessionsService.joinLegacyServer({
name: user,
sessionId,
serverId,
ip: clientIp
})
logger.log(`Legacy Join: ${user} -> ${serverId}`, ["AUTH", "green"])
return res.send("OK")
} catch (err) {
return res.send("Bad login")
}
})
module.exports = router

36
routes/legacy/login.js Normal file
View File

@ -0,0 +1,36 @@
const express = require("express")
const router = express.Router()
const crypto = require("crypto")
const authService = require("../../services/authService")
const sessionsService = require("../../services/sessionsService")
const logger = require("../../modules/logger")
router.all("/", async (req, res) => {
const { user, password } = { ...req.query, ...req.body }
try {
const result = await authService.authenticate({
identifier: user,
password,
clientToken: "",
requireUser: false
})
const profile = result.response.selectedProfile
const sessionId = crypto.randomBytes(16).toString("hex")
await sessionsService.registerLegacySession({
uuid: profile.id,
sessionId
})
logger.log(`Legacy Login: ${user}`, ["AUTH", "green"])
const timestamp = Date.now()
return res.send(`${timestamp}:deprecated:${profile.name}:${sessionId}:${profile.id}`)
} catch (err) {
return res.send("Bad login")
}
})
module.exports = router

View File

@ -0,0 +1,11 @@
const z = require("zod")
module.exports = {
GET: {
query: z.object({
user: z.string().min(1),
sessionId: z.string().min(1),
serverId: z.string().min(1)
})
}
}

View File

@ -0,0 +1,10 @@
const z = require("zod")
module.exports = {
GET: {
query: z.object({
user: z.string().min(1),
serverId: z.string().min(1)
})
}
}

16
schemas/legacy/login.js Normal file
View File

@ -0,0 +1,16 @@
const z = require("zod")
const loginShape = {
user: z.string().min(1, { message: "Username required" }),
password: z.string().min(1, { message: "Password required" }),
version: z.union([z.string(), z.number()]).optional()
}
module.exports = {
POST: {
body: z.object(loginShape),
},
GET: {
query: z.object(loginShape)
}
}

View File

@ -152,10 +152,26 @@ async function hasJoinedServer({ username, serverId, ip }) {
})
}
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" }
}
module.exports = {
getProfile,
joinServer,
hasJoinedServer,
joinLegacyServer,
getBlockedServers,
registerLegacySession,
validateLegacySession,