lsp-yggdrasil/src/routes/authenticate.js
Qumolama.d 3b8712a212
Some checks reported errors
continuous-integration/drone/push Build encountered an error
添加更多配置文件设置,实现了一个api,完成部分文件的部分测试
2022-05-03 18:57:20 +08:00

130 lines
4.3 KiB
JavaScript

import * as PlayerModel from '../models/player.js'
import { createHash } from 'crypto'
import { generateToken, uuidToNoSymboUUID } from '../generator.js'
export const authenticate = {
method: 'POST',
url: '/authserver/authenticate',
schema: {
body: {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
},
"clientToken": {
"type": "string"
},
"requestUser": {
"type": "boolean"
},
"agent": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "integer"
}
}
}
}
},
response: {
200: {
"type": "object",
"properties": {
"accessToken": {
"type": "string"
},
"clientToken": {
"type": "string"
},
"availableProfiles": {
"type": "array",
"items": [{...PlayerModel.PlayerSeriliazationSchema}]
},
"selectedProfile": PlayerModel.PlayerSeriliazationSchema,
"user": PlayerModel.PlayerAccountSerializationSchema
}
}
}
},
preHandler: async function(req, rep) {
this.conf.custom.overridePrehandler('/authserver/authenticate')
},
handler: async function (req, rep) {
let { username, password, clientToken, requestUser, agent } = req.body
const player = await this.models.Player.findOne({ email: username, password: createHash('sha256').update(password).digest().toString('hex').toLowerCase() })
if(!player || !player.permissions.some((it) => {
return it.node === 'login' && it.allowed && (it.duration === 0 || it.startDate + it.duration > Date.now())
})) {
return await rep.code(401).send({
error: "Unauthorized",
errorMessage: "用户名或密码错误",
cause: "用户名或密码错误"
})
}
if(!clientToken) {
clientToken = createHash('sha256').update( "" + Math.random() * 1.048596).digest().toString('hex')
}
const [token, key] = await generateToken(clientToken, requestUser, agent)
this.log.info(`/authserver/authenticate > 为玩家 ${username} 生成令牌: ${token} | 随机 key = ${key}`)
const account = {
id: uuidToNoSymboUUID(player.uuid),
properties: [
{
preferredLanguage: "zh_CN"
}
]
}
const textures = {
timestamp: 0,
profileId: uuidToNoSymboUUID(player.uuid),
profileName: player.username,
textures: { }
}
if(player.textures.skin && player.textures.skin != 0) { // Must be '!=' if this change to '!==' will never works
textures.textures.SKIN = {
url: player.textures.skin,
metadata
}
}
const profile = {
uuid: uuidToNoSymboUUID(player.uuid),
name: player.username,
properties: [
{
name: "texturs",
value: Buffer.from(JSON.stringify(textures)).toString('base64')
}
]
}
new this.models.Token({
uuid: player.uuid,
token: token,
expireDate: Date.now() + 1000 * 60 * 60 * 24 * 15,
deadDate: Date.now() + 1000 * 60 * 60 * 24 * 30,
state: 'alive'
}).save()
return await rep.send({
accessToken: token,
clientToken: clientToken,
availableProfiles: [ profile ],
selectedProfile: profile,
user: account
})
}
}