diff options
author | Madeline <46743919+MaddyUnderStars@users.noreply.github.com> | 2023-02-21 11:56:56 +1100 |
---|---|---|
committer | Madeline <46743919+MaddyUnderStars@users.noreply.github.com> | 2023-02-21 12:01:49 +1100 |
commit | eee98516dd09516f1c1cf891526339420807d50c (patch) | |
tree | 8d60f6717eac0416bcb73421ca71c31bdc1fff68 | |
parent | Close #954 (diff) | |
download | server-eee98516dd09516f1c1cf891526339420807d50c.tar.xz |
Fix gateway encoding Date objects as {} when using erlpack. Fixes NaN/NaN/NaN timestamps in desktop client
-rw-r--r-- | src/api/Server.ts | 20 | ||||
-rw-r--r-- | src/gateway/util/Send.ts | 26 | ||||
-rw-r--r-- | src/util/util/JSON.ts | 15 | ||||
-rw-r--r-- | src/util/util/index.ts | 1 |
4 files changed, 41 insertions, 21 deletions
diff --git a/src/api/Server.ts b/src/api/Server.ts index 78870669..7eb4e6f1 100644 --- a/src/api/Server.ts +++ b/src/api/Server.ts @@ -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" })); diff --git a/src/gateway/util/Send.ts b/src/gateway/util/Send.ts index 38e5ab4a..e39554a4 100644 --- a/src/gateway/util/Send.ts +++ b/src/gateway/util/Send.ts @@ -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) { diff --git a/src/util/util/JSON.ts b/src/util/util/JSON.ts new file mode 100644 index 00000000..b092eb88 --- /dev/null +++ b/src/util/util/JSON.ts @@ -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 }; diff --git a/src/util/util/index.ts b/src/util/util/index.ts index 543a49a9..6eb686d0 100644 --- a/src/util/util/index.ts +++ b/src/util/util/index.ts @@ -40,3 +40,4 @@ export * from "./TraverseDirectory"; export * from "./InvisibleCharacters"; export * from "./Sentry"; export * from "./WebAuthn"; +export * from "./JSON"; |