XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

fix: add try/catch around websocket message event handler (#2529)

Re #2528 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2529 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

c0ca9d93
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

3 个文件 +68 -58
Modified src/middleware/errorHandler.ts +2 -7
@@ -1,16 +1,11 @@
1 1 import { NextFunction, Request, Response } from "express";
2 import { logger } from "@/src/utils/logger";
2 import { logError } from "@/src/utils/logger";
3 3
4 4 export const errorHandler = (err: Error, req: Request, res: Response, _next: NextFunction): void => {
5 5 if (err.message == "Invalid accountId-nonce pair") {
6 6 res.status(400).send("Log-in expired");
7 } else if (err.stack) {
8 const stackArr = err.stack.split("\n");
9 stackArr[0] += ` while processing ${req.path} request`;
10 logger.error(stackArr.join("\n"));
11 res.status(500).end();
12 7 } else {
13 logger.error(`uncaught error while processing ${req.path} request: ${err.message}`);
8 logError(err, `processing ${req.path} request`);
14 9 res.status(500).end();
15 10 }
16 11 };
Modified src/services/wsService.ts +56 -51
@@ -5,6 +5,7 @@ import { Account } from "@/src/models/loginModel";
5 5 import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "@/src/services/loginService";
6 6 import { IDatabaseAccountJson } from "@/src/types/loginTypes";
7 7 import { HydratedDocument } from "mongoose";
8 import { logError } from "@/src/utils/logger";
8 9
9 10 let wsServer: ws.Server | undefined;
10 11 let wssServer: ws.Server | undefined;
@@ -88,63 +89,67 @@ const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
88 89
89 90 // eslint-disable-next-line @typescript-eslint/no-misused-promises
90 91 ws.on("message", async msg => {
91 const data = JSON.parse(String(msg)) as IWsMsgFromClient;
92 if (data.auth) {
93 let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email });
94 if (account) {
95 if (isCorrectPassword(data.auth.password, account.password)) {
96 if (!account.Nonce) {
97 account.ClientType = "webui";
98 account.Nonce = createNonce();
99 await (account as HydratedDocument<IDatabaseAccountJson>).save();
92 try {
93 const data = JSON.parse(String(msg)) as IWsMsgFromClient;
94 if (data.auth) {
95 let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email });
96 if (account) {
97 if (isCorrectPassword(data.auth.password, account.password)) {
98 if (!account.Nonce) {
99 account.ClientType = "webui";
100 account.Nonce = createNonce();
101 await (account as HydratedDocument<IDatabaseAccountJson>).save();
102 }
103 } else {
104 account = null;
100 105 }
106 } else if (data.auth.isRegister) {
107 const name = await getUsernameFromEmail(data.auth.email);
108 account = await createAccount({
109 email: data.auth.email,
110 password: data.auth.password,
111 ClientType: "webui",
112 LastLogin: new Date(),
113 DisplayName: name,
114 Nonce: createNonce()
115 });
116 }
117 if (account) {
118 (ws as IWsCustomData).accountId = account.id;
119 ws.send(
120 JSON.stringify({
121 auth_succ: {
122 id: account.id,
123 DisplayName: account.DisplayName,
124 Nonce: account.Nonce
125 }
126 } satisfies IWsMsgToClient)
127 );
101 128 } else {
102 account = null;
129 ws.send(
130 JSON.stringify({
131 auth_fail: {
132 isRegister: data.auth.isRegister
133 }
134 } satisfies IWsMsgToClient)
135 );
103 136 }
104 } else if (data.auth.isRegister) {
105 const name = await getUsernameFromEmail(data.auth.email);
106 account = await createAccount({
107 email: data.auth.email,
108 password: data.auth.password,
109 ClientType: "webui",
110 LastLogin: new Date(),
111 DisplayName: name,
112 Nonce: createNonce()
113 });
114 137 }
115 if (account) {
116 (ws as IWsCustomData).accountId = account.id;
117 ws.send(
118 JSON.stringify({
119 auth_succ: {
120 id: account.id,
121 DisplayName: account.DisplayName,
122 Nonce: account.Nonce
123 }
124 } satisfies IWsMsgToClient)
125 );
126 } else {
127 ws.send(
128 JSON.stringify({
129 auth_fail: {
130 isRegister: data.auth.isRegister
131 }
132 } satisfies IWsMsgToClient)
138 if (data.logout) {
139 const accountId = (ws as IWsCustomData).accountId;
140 (ws as IWsCustomData).accountId = undefined;
141 await Account.updateOne(
142 {
143 _id: accountId,
144 ClientType: "webui"
145 },
146 {
147 Nonce: 0
148 }
133 149 );
134 150 }
135 }
136 if (data.logout) {
137 const accountId = (ws as IWsCustomData).accountId;
138 (ws as IWsCustomData).accountId = undefined;
139 await Account.updateOne(
140 {
141 _id: accountId,
142 ClientType: "webui"
143 },
144 {
145 Nonce: 0
146 }
147 );
151 } catch (e) {
152 logError(e as Error, `processing websocket message`);
148 153 }
149 154 });
150 155 };
Modified src/utils/logger.ts +10 -0
@@ -108,3 +108,13 @@ errorLog.on("new", filename => logger.info(`Using error log file: ${filename}`))
108 108 combinedLog.on("new", filename => logger.info(`Using combined log file: ${filename}`));
109 109 errorLog.on("rotate", filename => logger.info(`Rotated error log file: ${filename}`));
110 110 combinedLog.on("rotate", filename => logger.info(`Rotated combined log file: ${filename}`));
111
112 export const logError = (err: Error, context: string): void => {
113 if (err.stack) {
114 const stackArr = err.stack.split("\n");
115 stackArr[0] += ` while ${context}`;
116 logger.error(stackArr.join("\n"));
117 } else {
118 logger.error(`uncaught error while ${context}: ${err.message}`);
119 }
120 };