修正 mongoose 调用,添加更多输出提示
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Qumolama.d 2022-05-16 13:19:28 +08:00
parent 4d448d876e
commit f23a607148
Signed by: Lama3L9R
GPG Key ID: 1762AFC05157CE18
10 changed files with 45 additions and 58 deletions

View File

@ -1,6 +1,5 @@
import { fastify } from 'fastify' import { fastify } from 'fastify'
import { mongoose } from 'mongoose' import { mongoose } from 'mongoose'
import { registerModels } from './models/index.js';
import * as Hooks from './hooks.js' import * as Hooks from './hooks.js'
import * as AuthenticateRoutings from './routes/authenticate.js' import * as AuthenticateRoutings from './routes/authenticate.js'
import * as SessionServerRoutings from './routes/session.js' import * as SessionServerRoutings from './routes/session.js'
@ -10,6 +9,7 @@ import { config } from './config.js'
import { readFileSync } from 'fs' import { readFileSync } from 'fs'
import { Scenes, session, Telegraf } from 'telegraf' import { Scenes, session, Telegraf } from 'telegraf'
import { allScenes, registerAllPlayerCommands } from './telegram/player-commands.js'; import { allScenes, registerAllPlayerCommands } from './telegram/player-commands.js';
import { Player } from './models/player.js'
export const server = fastify({ export const server = fastify({
logger: { logger: {
@ -21,13 +21,12 @@ export const server = fastify({
export const telegraf = new Telegraf(config.telegram.token) export const telegraf = new Telegraf(config.telegram.token)
export const setup = async () => { export const setup = async () => {
const mongooseClient = await mongoose.connect(config.database.url) server.log.info("老色批世界树 > 初始化中...")
const models = registerModels(mongooseClient)
await mongoose.connect(config.database.url)
const publicKey = readFileSync(config.signing.public).toString() const publicKey = readFileSync(config.signing.public).toString()
const privateKey = readFileSync(config.signing.private).toString() const privateKey = readFileSync(config.signing.private).toString()
server.decorate('mongoose', mongooseClient)
server.decorate('models', models)
server.decorate('keys', { publicKey, privateKey }) server.decorate('keys', { publicKey, privateKey })
config.custom.preHooks(server) config.custom.preHooks(server)
@ -55,7 +54,7 @@ export const setup = async () => {
if(process.env["UNIT_TEST"] || process.env["DEVEL_FIRST_RUN"]) { if(process.env["UNIT_TEST"] || process.env["DEVEL_FIRST_RUN"]) {
// Create a test player // Create a test player
await new models.Player({ await new Player({
username: 'test', username: 'test',
password: '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', password: '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92',
email: 'i@lama.icu', email: 'i@lama.icu',
@ -81,9 +80,8 @@ export const setup = async () => {
} }
const launch = async () => { const launch = async () => {
process.on('SIGINT', () => { process.on('SIGINT', shutdown)
new Promise(shutdown) process.on('SIGTERM', shutdown)
})
telegraf.launch() telegraf.launch()
@ -93,9 +91,16 @@ const launch = async () => {
} }
export const shutdown = async () => { export const shutdown = async () => {
server.close() await server.close()
telegraf.stop() server.log.info("老色批世界树 > HTTP 服务器已关闭")
try {
telegraf.stop()
server.log.info("老色批世界树 > Telegram Bot 已关闭")
} catch(err) {
server.log.info("老色批世界树 > Telegram Bot 未运行,已跳过")
}
mongoose.disconnect() mongoose.disconnect()
server.log.info("老色批世界树 > 数据库连接已断开,服务器已关闭")
} }
(async () => { (async () => {

View File

@ -1,11 +0,0 @@
import { TokenSchema } from "./token.js";
import { PlayerSchema } from "./player.js";
import { InviteTokenSchema } from "./invite.js";
export function registerModels(mongoose) {
return {
Token: mongoose.model("Token", TokenSchema),
Player: mongoose.model("Player", PlayerSchema),
Invitation: mongoose.model('Invitation', InviteTokenSchema)
}
}

View File

@ -1,9 +0,0 @@
import mongoose from 'mongoose'
const { Schema } = mongoose
export const InviteTokenSchema = new Schema({
by: String, // Telegram username
token: String
})
// { from: string, id: number, sign: string }

View File

@ -1,9 +1,8 @@
import mongoose from 'mongoose' import mongoose from 'mongoose'
const { Schema } = mongoose
import { uuidToNoSymboUUID } from '../generator.js' import { uuidToNoSymboUUID } from '../generator.js'
import { ImageSecurity } from '../secure.js' import { ImageSecurity } from '../secure.js'
export const PlayerSchema = new Schema({ export const Player = mongoose.model("Player", new mongoose.Schema({
username: String, // 有符号 UUID username: String, // 有符号 UUID
password: String, password: String,
email: String, email: String,
@ -18,7 +17,7 @@ export const PlayerSchema = new Schema({
username: String, username: String,
verified: Boolean, verified: Boolean,
} }
}) }))
export const PlayerSeriliazationSchema = { export const PlayerSeriliazationSchema = {
"type": "object", "type": "object",

View File

@ -1,10 +1,9 @@
import mongoose from 'mongoose' import mongoose from 'mongoose'
const { Schema } = mongoose
export const TokenSchema = new Schema({ export const Token = mongoose.model("Token", new mongoose.Schema({
uuid: String, uuid: String,
token: String, token: String,
clientToken: String, clientToken: String,
expireDate: Number, expireDate: Number,
deadDate: Number, deadDate: Number,
}) }))

View File

@ -1,5 +1,6 @@
import { getOverrideHandler, getOverridePreHandler } from "../config.js" import { getOverrideHandler, getOverridePreHandler } from "../config.js"
import { uuidToNoSymboUUID } from "../generator.js" import { uuidToNoSymboUUID } from "../generator.js"
import { Player } from "../models/player.js"
export const profiles = { export const profiles = {
method: 'POST', method: 'POST',
@ -39,7 +40,7 @@ export const profiles = {
}, },
handler: getOverrideHandler('/api/profiles/minecraft') ?? async function (req, rep) { handler: getOverrideHandler('/api/profiles/minecraft') ?? async function (req, rep) {
const { body } = req const { body } = req
const profiles = await this.models.Player.find({ username: { $in: body } }) const profiles = await Player.find({ username: { $in: body } })
return await rep.code(200).send(profiles.map(profile => ({ return await rep.code(200).send(profiles.map(profile => ({
id: uuidToNoSymboUUID(profile.uuid), id: uuidToNoSymboUUID(profile.uuid),
name: profile.username name: profile.username

View File

@ -2,6 +2,7 @@ import * as PlayerModel from '../models/player.js'
import { createHash } from 'crypto' import { createHash } from 'crypto'
import { generateToken, uuidToNoSymboUUID } from '../generator.js' import { generateToken, uuidToNoSymboUUID } from '../generator.js'
import { getOverrideHandler, getOverridePreHandler } from '../config.js' import { getOverrideHandler, getOverridePreHandler } from '../config.js'
import { Token } from '../models/token.js'
export const authenticate = { export const authenticate = {
method: 'POST', method: 'POST',
@ -67,7 +68,7 @@ export const authenticate = {
}) })
} }
const player = await this.models.Player.findOne({ email: username, password: createHash('sha256').update(password).digest().toString('hex').toLowerCase() }) const player = await PlayerModel.Player.findOne({ email: username, password: createHash('sha256').update(password).digest().toString('hex').toLowerCase() })
if(!player || !player.permissions.some((it) => { if(!player || !player.permissions.some((it) => {
return it.node === 'login' && it.allowed && (it.duration === 0 || it.startDate + it.duration > Date.now()) return it.node === 'login' && it.allowed && (it.duration === 0 || it.startDate + it.duration > Date.now())
})) { })) {
@ -104,7 +105,7 @@ export const authenticate = {
const profile = PlayerModel.getPlayerSerialization(player) const profile = PlayerModel.getPlayerSerialization(player)
new this.models.Token({ new Token({
uuid: player.uuid, uuid: player.uuid,
token: token, token: token,
clientToken: clientToken, clientToken: clientToken,
@ -173,7 +174,7 @@ export const refresh = {
if(clientToken) { if(clientToken) {
query.clientToken = clientToken query.clientToken = clientToken
} }
const token = await this.models.Token.findOne(query) const token = await Token.findOne(query)
if(!token) { if(!token) {
return await rep.code(401).send({ return await rep.code(401).send({
@ -196,7 +197,7 @@ export const refresh = {
const [newToken, key] = generateToken(token.uuid) const [newToken, key] = generateToken(token.uuid)
this.log.info(`/authserver/authenticate > 为玩家 ${token.uuid} 刷新令牌: ${token.uuid}${newToken} | 随机 key = ${key}`) this.log.info(`/authserver/authenticate > 为玩家 ${token.uuid} 刷新令牌: ${token.uuid}${newToken} | 随机 key = ${key}`)
await this.models.Token.updateOne({ await Token.updateOne({
token: accessToken, token: accessToken,
clientToken: clientToken ?? undefined clientToken: clientToken ?? undefined
}, { }, {
@ -206,7 +207,7 @@ export const refresh = {
} }
}) })
new this.models.Token({ new Token({
uuid: uuid, uuid: uuid,
token: newToken, token: newToken,
clientToken: clientToken ?? token.clientToken, clientToken: clientToken ?? token.clientToken,
@ -220,7 +221,7 @@ export const refresh = {
} }
if(requestUser || selectedProfile) { if(requestUser || selectedProfile) {
const player = await this.models.Player.findOne({ uuid }) const player = await PlayerModel.Player.findOne({ uuid })
if(requestUser) { if(requestUser) {
response.user = { response.user = {
@ -276,7 +277,7 @@ export const validate = {
if(clientToken) { if(clientToken) {
query.clientToken = clientToken query.clientToken = clientToken
} }
const token = await this.models.Token.findOne(query) const token = await Token.findOne(query)
if(!token) { if(!token) {
return await rep.code(401).send({ return await rep.code(401).send({
@ -327,7 +328,7 @@ export const invalidate = {
handler: getOverrideHandler("/authserver/authenticate") ?? async function (req, rep) { handler: getOverrideHandler("/authserver/authenticate") ?? async function (req, rep) {
const { accessToken } = req.body const { accessToken } = req.body
const { modifiedCount } = await this.models.Token.updateOne({ const { modifiedCount } = await Token.updateOne({
token: accessToken token: accessToken
}, { }, {
$set: { $set: {
@ -373,7 +374,7 @@ export const signout = {
handler: getOverrideHandler("/authserver/signout") ?? async function (req, rep) { handler: getOverrideHandler("/authserver/signout") ?? async function (req, rep) {
const { username, password } = req.body const { username, password } = req.body
const player = await this.models.Player.findOne({ email: username, password: createHash('sha256').update(password).digest().toString('hex').toLowerCase() }) const player = await PlayerModel.Player.findOne({ email: username, password: createHash('sha256').update(password).digest().toString('hex').toLowerCase() })
if(!player) { if(!player) {
return await rep.code(401).send({ return await rep.code(401).send({
error: "Unauthorized", error: "Unauthorized",
@ -382,7 +383,7 @@ export const signout = {
}) })
} }
await this.models.Token.deleteMany({ await Token.deleteMany({
uuid: player.uuid uuid: player.uuid
}) })

View File

@ -1,6 +1,7 @@
import { getOverrideHandler, getOverridePreHandler } from '../config.js' import { getOverrideHandler, getOverridePreHandler } from '../config.js'
import { toSymboUUID } from '../generator.js' import { toSymboUUID } from '../generator.js'
import { getPlayerSerialization, PlayerSeriliazationSchema } from '../models/player.js' import { getPlayerSerialization, Player, PlayerSeriliazationSchema } from '../models/player.js'
import { Token } from '../models/token.js'
/* /*
Key: string Username Key: string Username
@ -36,7 +37,7 @@ export const join = {
preHandler: getOverridePreHandler('/sessionserver/session/minecraft/join'), preHandler: getOverridePreHandler('/sessionserver/session/minecraft/join'),
handler: getOverrideHandler('/sessionserver/session/minecraft/join') ?? async function (req, rep) { handler: getOverrideHandler('/sessionserver/session/minecraft/join') ?? async function (req, rep) {
const { accessToken, selectedProfile, serverId } = req.body const { accessToken, selectedProfile, serverId } = req.body
const user = await await this.models.Player.findOne({ uuid: toSymboUUID(selectedProfile) }) const user = await await Player.findOne({ uuid: toSymboUUID(selectedProfile) })
if (!user) { if (!user) {
return await rep.code(400).send({ return await rep.code(400).send({
error: "IllegalArgumentException", error: "IllegalArgumentException",
@ -45,7 +46,7 @@ export const join = {
}) })
} }
const session = await this.models.Token.findOne({ token: accessToken }) const session = await Token.findOne({ token: accessToken })
if (!session) { if (!session) {
return await rep.code(401).send({ return await rep.code(401).send({
error: "IllegalArgumentException", error: "IllegalArgumentException",
@ -99,7 +100,7 @@ export const hasJoined = {
handler: getOverrideHandler('/sessionserver/session/minecraft/hasJoined') ?? async function (req, rep) { handler: getOverrideHandler('/sessionserver/session/minecraft/hasJoined') ?? async function (req, rep) {
const { username, serverId, ip } = req.query const { username, serverId, ip } = req.query
const player = await this.models.Player.findOne({ username }) const player = await Player.findOne({ username })
if (!player) { if (!player) {
return await rep.code(400).send({ return await rep.code(400).send({
error: "IllegalArgumentException", error: "IllegalArgumentException",
@ -155,7 +156,7 @@ export const profile = {
preHandler: getOverridePreHandler('/sessionserver/session/minecraft/profile/:uuid'), preHandler: getOverridePreHandler('/sessionserver/session/minecraft/profile/:uuid'),
handler: getOverrideHandler('/sessionserver/session/minecraft/profile/:uuid') ?? async function (req, rep) { handler: getOverrideHandler('/sessionserver/session/minecraft/profile/:uuid') ?? async function (req, rep) {
const { uuid } = req.params const { uuid } = req.params
const player = await this.models.Player.findOne({ uuid: toSymboUUID(uuid) }) const player = await Player.findOne({ uuid: toSymboUUID(uuid) })
if (!player) { if (!player) {
return await rep.code(204).send() return await rep.code(204).send()
} }

View File

@ -3,6 +3,7 @@ import { telegraf, server } from '../index.js'
import { createHash } from 'crypto' import { createHash } from 'crypto'
import axios from 'axios' import axios from 'axios'
import { uuid } from '../generator.js' import { uuid } from '../generator.js'
import { Player } from '../models/player.js'
export const registerAllPlayerCommands = async () => { export const registerAllPlayerCommands = async () => {
await register() await register()
@ -38,7 +39,7 @@ const registerWizard = new Scenes.WizardScene('REGISTRIATION_WIZARD',
ctx.scene.session.data.password = createHash('sha256').update(ctx.message.text).digest('hex') ctx.scene.session.data.password = createHash('sha256').update(ctx.message.text).digest('hex')
const duplicated = await server.models.Player.findOne({ password: ctx.scene.session.data.password }) const duplicated = await Player.findOne({ password: ctx.scene.session.data.password })
if(duplicated) { if(duplicated) {
return ctx.reply(`该密码hash为${ctx.scene.session.data.password.substring(3,10)} 已检测到数据库中存在重复密码(${JSON.stringify({d: duplicated})}),为了安全请重新输入`) return ctx.reply(`该密码hash为${ctx.scene.session.data.password.substring(3,10)} 已检测到数据库中存在重复密码(${JSON.stringify({d: duplicated})}),为了安全请重新输入`)
} }
@ -139,7 +140,7 @@ const registerWizard = new Scenes.WizardScene('REGISTRIATION_WIZARD',
let verified = false let verified = false
if(ctx.scene.session.data.inviteCode) { if(ctx.scene.session.data.inviteCode) {
await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, message.text + '\n验证邀请码中...') await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, message.text + '\n验证邀请码中...')
const invi = server.models.Invitation.findOne({ const invi = Invitation.findOne({
token: ctx.scene.session.data.inviteCode token: ctx.scene.session.data.inviteCode
}) })
if(invi) { if(invi) {
@ -150,7 +151,7 @@ const registerWizard = new Scenes.WizardScene('REGISTRIATION_WIZARD',
} }
} }
const player = new server.models.Player({ const player = new Player({
uuid: uuid("LSP-yggdrasil:" + ctx.scene.session.data.playerUsername), uuid: uuid("LSP-yggdrasil:" + ctx.scene.session.data.playerUsername),
username: ctx.scene.session.data.playerUsername, username: ctx.scene.session.data.playerUsername,
password: ctx.scene.session.data.password, password: ctx.scene.session.data.password,
@ -192,7 +193,7 @@ const register = async () => {
return ctx.reply("请设置 Telegram 用户名!") return ctx.reply("请设置 Telegram 用户名!")
} }
const player = await server.models.Player.findOne({ "telegramBind.username": username }) const player = await Player.findOne({ "telegramBind.username": username })
server.log.info(player) server.log.info(player)
if(!player) { if(!player) {
return ctx.scene.enter('REGISTRIATION_WIZARD') return ctx.scene.enter('REGISTRIATION_WIZARD')

View File

@ -20,7 +20,7 @@ beforeAll(() => {
writeFileSync('private.key', privateKey) writeFileSync('private.key', privateKey)
} }
config.database.url = 'mongodb://setup-database:27017/yggdrasil?readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false' //config.database.url = 'mongodb://setup-database:27017/yggdrasil?readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false'
return setup() return setup()
}) })