1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-10 04:32:35 +01:00

Fix gateway encoding Date objects as {} when using erlpack. Fixes NaN/NaN/NaN timestamps in desktop client

This commit is contained in:
Madeline 2023-02-21 11:56:56 +11:00
parent 5f553cc614
commit eee98516dd
4 changed files with 41 additions and 21 deletions

View File

@ -23,6 +23,7 @@ import {
Config,
initDatabase,
initEvent,
JSONReplacer,
Sentry,
WebAuthn,
} from "@fosscord/util";
@ -84,24 +85,7 @@ export class FosscordServer extends Server {
);
}
// Discord.com sends ISO strings with +00:00 extension, not Z
// This causes issues with Python bot libs
this.app.set(
"json replacer",
function (
this: { [key: string]: unknown },
key: string,
value: unknown,
) {
if (this[key] instanceof Date) {
return (this[key] as Date)
.toISOString()
.replace("Z", "+00:00");
}
return value;
},
);
this.app.set("json replacer", JSONReplacer);
this.app.use(CORS);
this.app.use(BodyParser({ inflate: true, limit: "10mb" }));

View File

@ -20,7 +20,7 @@ import { Payload, WebSocket } from "@fosscord/gateway";
import fs from "fs/promises";
import path from "path";
import type { ErlpackType } from "@fosscord/util";
import { ErlpackType, JSONReplacer } from "@fosscord/util";
let erlpack: ErlpackType | null = null;
try {
erlpack = require("erlpack") as ErlpackType;
@ -28,6 +28,21 @@ try {
// empty
}
// don't care
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const recurseJsonReplace = (json: any) => {
for (const key in json) {
// eslint-disable-next-line no-prototype-builtins
if (!json.hasOwnProperty(key)) continue;
json[key] = JSONReplacer.call(json, key, json[key]);
if (typeof json[key] == "object" && json[key] !== null)
json[key] = recurseJsonReplace(json[key]);
}
return json;
};
export function Send(socket: WebSocket, data: Payload) {
if (process.env.WS_VERBOSE)
console.log(`[Websocket] Outgoing message: ${JSON.stringify(data)}`);
@ -47,9 +62,14 @@ export function Send(socket: WebSocket, data: Payload) {
}
let buffer: Buffer | string;
if (socket.encoding === "etf" && erlpack) buffer = erlpack.pack(data);
if (socket.encoding === "etf" && erlpack) {
// Erlpack doesn't like Date objects, encodes them as {}
data = recurseJsonReplace(data);
buffer = erlpack.pack(data);
}
// TODO: encode circular object
else if (socket.encoding === "json") buffer = JSON.stringify(data);
else if (socket.encoding === "json")
buffer = JSON.stringify(data, JSONReplacer);
else return;
// TODO: compression
if (socket.deflate) {

15
src/util/util/JSON.ts Normal file
View File

@ -0,0 +1,15 @@
// Discord.com sends ISO strings with +00:00 extension, not Z
// This causes issues with Python bot libs
const JSONReplacer = function (
this: { [key: string]: unknown },
key: string,
value: unknown,
) {
if (this[key] instanceof Date) {
return (this[key] as Date).toISOString().replace("Z", "+00:00");
}
return value;
};
export { JSONReplacer };

View File

@ -40,3 +40,4 @@ export * from "./TraverseDirectory";
export * from "./InvisibleCharacters";
export * from "./Sentry";
export * from "./WebAuthn";
export * from "./JSON";