diff --git a/src/gateway/events/Connection.ts b/src/gateway/events/Connection.ts
index 7ad37176..37e2ebac 100644
--- a/src/gateway/events/Connection.ts
+++ b/src/gateway/events/Connection.ts
@@ -42,37 +42,22 @@ try {
// TODO: specify rate limit in config
// TODO: check msg max size
-export async function Connection(
- this: WS.Server,
- socket: WebSocket,
- request: IncomingMessage,
-) {
+export async function Connection(this: WS.Server, socket: WebSocket, request: IncomingMessage) {
const forwardedFor = Config.get().security.forwardedFor;
- const ipAddress = forwardedFor
- ? (request.headers[forwardedFor.toLowerCase()] as string)
- : request.socket.remoteAddress;
+ const ipAddress = forwardedFor ? (request.headers[forwardedFor.toLowerCase()] as string) : request.socket.remoteAddress;
socket.ipAddress = ipAddress;
socket.userAgent = request.headers["user-agent"] as string;
if (!ipAddress && Config.get().security.cdnSignatureIncludeIp) {
- return socket.close(
- CLOSECODES.Decode_error,
- "Gateway connection rejected: IP address is required.",
- );
+ return socket.close(CLOSECODES.Decode_error, "Gateway connection rejected: IP address is required.");
}
- if (
- !socket.userAgent &&
- Config.get().security.cdnSignatureIncludeUserAgent
- ) {
- return socket.close(
- CLOSECODES.Decode_error,
- "Gateway connection rejected: User-Agent header is required.",
- );
+ if (!socket.userAgent && Config.get().security.cdnSignatureIncludeUserAgent) {
+ return socket.close(CLOSECODES.Decode_error, "Gateway connection rejected: User-Agent header is required.");
}
- if (request.headers.cookie?.split("; ").find(x => x.startsWith("__sb_sessid="))) {
+ if (request.headers.cookie?.split("; ").find((x) => x.startsWith("__sb_sessid="))) {
socket.fingerprint = request.headers.cookie
.split("; ")
.find((x) => x.startsWith("__sb_sessid="))
@@ -91,9 +76,7 @@ export async function Connection(
socket.on("error", (err) => console.error("[Gateway]", err));
- console.log(
- `[Gateway] New connection from ${ipAddress}, total ${this.clients.size}`,
- );
+ console.log(`[Gateway] New connection from ${ipAddress}, total ${this.clients.size}`);
if (process.env.WS_LOGEVENTS)
[
@@ -112,15 +95,12 @@ export async function Connection(
const { searchParams } = new URL(`http://localhost${request.url}`);
// @ts-ignore
socket.encoding = searchParams.get("encoding") || "json";
- if (!["json", "etf"].includes(socket.encoding))
- return socket.close(CLOSECODES.Decode_error);
+ if (!["json", "etf"].includes(socket.encoding)) return socket.close(CLOSECODES.Decode_error);
- if (socket.encoding === "etf" && !erlpack)
- throw new Error("Erlpack is not installed: 'npm i @yukikaze-bot/erlpack'");
+ if (socket.encoding === "etf" && !erlpack) throw new Error("Erlpack is not installed: 'npm i @yukikaze-bot/erlpack'");
socket.version = Number(searchParams.get("version")) || 8;
- if (socket.version != 8)
- return socket.close(CLOSECODES.Invalid_API_version);
+ if (socket.version != 8) return socket.close(CLOSECODES.Invalid_API_version);
// @ts-ignore
socket.compress = searchParams.get("compress") || "";
diff --git a/src/gateway/events/Message.ts b/src/gateway/events/Message.ts
index 2987f464..dbdad935 100644
--- a/src/gateway/events/Message.ts
+++ b/src/gateway/events/Message.ts
@@ -24,7 +24,7 @@ import path from "path";
import WS from "ws";
import OPCodeHandlers from "../opcodes";
import { check } from "../opcodes/instanceOf";
-import { PayloadSchema } from "@spacebar/schemas"
+import { PayloadSchema } from "@spacebar/schemas";
const bigIntJson = BigIntJson({ storeAsString: true });
@@ -67,22 +67,15 @@ export async function Message(this: WebSocket, buffer: WS.Data) {
}
} else return this.close(CLOSECODES.Decode_error);
- if (process.env.WS_VERBOSE)
- console.log(`[Websocket] Incomming message: ${JSON.stringify(data)}`);
+ if (process.env.WS_VERBOSE) console.log(`[Websocket] Incomming message: ${JSON.stringify(data)}`);
if (process.env.WS_DUMP) {
const id = this.session_id || "unknown";
await fs.mkdir(path.join("dump", id), { recursive: true });
- await fs.writeFile(
- path.join("dump", id, `${Date.now()}.in.json`),
- JSON.stringify(data, null, 2),
- );
+ await fs.writeFile(path.join("dump", id, `${Date.now()}.in.json`), JSON.stringify(data, null, 2));
- if (!this.session_id)
- console.log(
- "[Gateway] Unknown session id, dumping to unknown folder",
- );
+ if (!this.session_id) console.log("[Gateway] Unknown session id, dumping to unknown folder");
}
check.call(this, PayloadSchema, data);
diff --git a/src/gateway/util/Send.ts b/src/gateway/util/Send.ts
index cee3aa8c..90c1f942 100644
--- a/src/gateway/util/Send.ts
+++ b/src/gateway/util/Send.ts
@@ -37,15 +37,13 @@ const recurseJsonReplace = (json: any) => {
json[key] = JSONReplacer.call(json, key, json[key]);
- if (typeof json[key] == "object" && json[key] !== null)
- json[key] = recurseJsonReplace(json[key]);
+ if (typeof json[key] == "object" && json[key] !== null) json[key] = recurseJsonReplace(json[key]);
}
return json;
};
export async function Send(socket: WebSocket, data: Payload) {
- if (process.env.WS_VERBOSE)
- console.log(`[Websocket] Outgoing message: ${JSON.stringify(data)}`);
+ if (process.env.WS_VERBOSE) console.log(`[Websocket] Outgoing message: ${JSON.stringify(data)}`);
if (process.env.WS_DUMP) {
const id = socket.session_id || "unknown";
@@ -53,10 +51,7 @@ export async function Send(socket: WebSocket, data: Payload) {
await fs.mkdir(path.join("dump", id), {
recursive: true,
});
- await fs.writeFile(
- path.join("dump", id, `${Date.now()}.out.json`),
- JSON.stringify(data, null, 2),
- );
+ await fs.writeFile(path.join("dump", id, `${Date.now()}.out.json`), JSON.stringify(data, null, 2));
}
let buffer: Buffer | string;
@@ -66,18 +61,16 @@ export async function Send(socket: WebSocket, data: Payload) {
buffer = erlpack.pack(data);
}
// TODO: encode circular object
- else if (socket.encoding === "json")
- buffer = JSON.stringify(data, JSONReplacer);
+ else if (socket.encoding === "json") buffer = JSON.stringify(data, JSONReplacer);
else return;
// TODO: compression
if (socket.compress === "zlib-stream") {
buffer = socket.deflate!.process(buffer) as Buffer;
} else if (socket.compress === "zstd-stream") {
- if (typeof(buffer) === "string")
- buffer = Buffer.from(buffer as string);
+ if (typeof buffer === "string") buffer = Buffer.from(buffer as string);
- buffer = await socket.zstdEncoder!.encode(buffer as Buffer) as Buffer;
+ buffer = (await socket.zstdEncoder!.encode(buffer as Buffer)) as Buffer;
}
return new Promise((res, rej) => {
diff --git a/src/gateway/util/Utils.ts b/src/gateway/util/Utils.ts
index 54cfaf3d..614b074b 100644
--- a/src/gateway/util/Utils.ts
+++ b/src/gateway/util/Utils.ts
@@ -14,11 +14,7 @@ export function parseStreamKey(streamKey: string): {
throw new Error(`Invalid stream key type: ${type}`);
}
- if (
- (type === "guild" && streamKeyArray.length < 3) ||
- (type === "call" && streamKeyArray.length < 2)
- )
- throw new Error(`Invalid stream key: ${streamKey}`); // invalid stream key
+ if ((type === "guild" && streamKeyArray.length < 3) || (type === "call" && streamKeyArray.length < 2)) throw new Error(`Invalid stream key: ${streamKey}`); // invalid stream key
let guildId: string | undefined;
if (type === "guild") {
@@ -33,12 +29,7 @@ export function parseStreamKey(streamKey: string): {
return { type, channelId, guildId, userId };
}
-export function generateStreamKey(
- type: "guild" | "call",
- guildId: string | undefined,
- channelId: string,
- userId: string,
-): string {
+export function generateStreamKey(type: "guild" | "call", guildId: string | undefined, channelId: string, userId: string): string {
const streamKey = `${type}${type === "guild" ? `:${guildId}` : ""}:${channelId}:${userId}`;
return streamKey;
diff --git a/src/util/Signing.ts b/src/util/Signing.ts
index 651c3372..17f5d648 100644
--- a/src/util/Signing.ts
+++ b/src/util/Signing.ts
@@ -40,26 +40,17 @@ export class NewUrlSignatureData extends NewUrlUserSignatureData {
this.path = data.path;
this.url = data.url;
if (!this.path && !this.url) {
- throw new Error(
- "Either path or url must be provided for URL signing",
- );
+ throw new Error("Either path or url must be provided for URL signing");
}
if (this.path && this.url) {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.warn(
- "[Signing] Both path and url are provided, using path for signing",
- this,
- new Error().stack,
- );
+ if (process.env["LOG_CDN_SIGNATURES"]) console.warn("[Signing] Both path and url are provided, using path for signing", this, new Error().stack);
}
if (this.url) {
try {
const parsedUrl = new URL(this.url);
this.path = parsedUrl.pathname;
} catch (e) {
- throw new Error(
- "Invalid URL provided for signing: " + this.url,
- );
+ throw new Error("Invalid URL provided for signing: " + this.url);
}
}
}
@@ -101,15 +92,10 @@ export class UrlSignResult {
static fromUrl(url: URL | string): UrlSignResult {
if (typeof url === "string") {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.debug("[Signing] Parsing URL from string:", url);
+ if (process.env["LOG_CDN_SIGNATURES"]) console.debug("[Signing] Parsing URL from string:", url);
url = new URL(url);
}
- if (process.env["LOG_CDN_SIGNATURES"])
- console.debug(
- "[Signing] Parsing URL from URL object:",
- url.toString(),
- );
+ if (process.env["LOG_CDN_SIGNATURES"]) console.debug("[Signing] Parsing URL from URL object:", url.toString());
const ex = url.searchParams.get("ex");
const is = url.searchParams.get("is");
const hm = url.searchParams.get("hm");
@@ -133,9 +119,7 @@ export const getUrlSignature = (data: NewUrlSignatureData): UrlSignResult => {
// calculate the expiration time
const now = Date.now();
const issuedAt = now.toString(16);
- const expiresAt = (now + ms(cdnSignatureDuration as StringValue)).toString(
- 16,
- );
+ const expiresAt = (now + ms(cdnSignatureDuration as StringValue)).toString(16);
// hash the url with the cdnSignatureKey
return calculateHash(
@@ -160,11 +144,7 @@ function calculateHash(request: UrlSignatureData): UrlSignResult {
"[Signing] CDN Signature IP is enabled but we couldn't find the IP field in the request. This may cause issues with signature validation. Please report this to the Spacebar team!",
);
else {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.log(
- "[Signing] CDN Signature IP is enabled, adding IP to hash:",
- request.ip,
- );
+ if (process.env["LOG_CDN_SIGNATURES"]) console.log("[Signing] CDN Signature IP is enabled, adding IP to hash:", request.ip);
data.update(request.ip!);
}
}
@@ -175,11 +155,7 @@ function calculateHash(request: UrlSignatureData): UrlSignResult {
"[Signing] CDN Signature User-Agent is enabled but we couldn't find the user-agent header in the request. This may cause issues with signature validation. Please report this to the Spacebar team!",
);
else {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.log(
- "[Signing] CDN Signature User-Agent is enabled, adding User-Agent to hash:",
- request.userAgent,
- );
+ if (process.env["LOG_CDN_SIGNATURES"]) console.log("[Signing] CDN Signature User-Agent is enabled, adding User-Agent to hash:", request.userAgent);
data.update(request.userAgent!);
}
}
@@ -197,12 +173,8 @@ function calculateHash(request: UrlSignatureData): UrlSignResult {
{
path: request.path,
validity: request.issuedAt + " .. " + request.expiresAt,
- ua: Config.get().security.cdnSignatureIncludeUserAgent
- ? request.userAgent
- : "[disabled]",
- ip: Config.get().security.cdnSignatureIncludeIp
- ? request.ip
- : "[disabled]",
+ ua: Config.get().security.cdnSignatureIncludeUserAgent ? request.userAgent : "[disabled]",
+ ip: Config.get().security.cdnSignatureIncludeIp ? request.ip : "[disabled]",
},
"->",
result,
@@ -216,8 +188,7 @@ export const isExpired = (data: UrlSignResult | UrlSignatureData) => {
const expiresAt = parseInt(data.expiresAt, 16);
if (Number.isNaN(issuedAt) || Number.isNaN(expiresAt)) {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.debug("[Signing] Invalid timestamps in query");
+ if (process.env["LOG_CDN_SIGNATURES"]) console.debug("[Signing] Invalid timestamps in query");
return true;
}
@@ -225,38 +196,29 @@ export const isExpired = (data: UrlSignResult | UrlSignatureData) => {
const isExpired = expiresAt < currentTime;
if (isExpired) {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.debug("[Signing] Signature expired");
+ if (process.env["LOG_CDN_SIGNATURES"]) console.debug("[Signing] Signature expired");
return true;
}
const isValidIssuedAt = issuedAt < currentTime;
if (!isValidIssuedAt) {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.debug("[Signing] Signature issued in the future");
+ if (process.env["LOG_CDN_SIGNATURES"]) console.debug("[Signing] Signature issued in the future");
return true;
}
return false;
};
-export const hasValidSignature = (
- req: NewUrlUserSignatureData,
- sig: UrlSignResult,
-) => {
+export const hasValidSignature = (req: NewUrlUserSignatureData, sig: UrlSignResult) => {
// if the required query parameters are not present, return false
if (!sig.expiresAt || !sig.issuedAt || !sig.hash) {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.warn(
- "[Signing] Missing required query parameters for signature validation",
- );
+ if (process.env["LOG_CDN_SIGNATURES"]) console.warn("[Signing] Missing required query parameters for signature validation");
return false;
}
// check if the signature is expired
if (isExpired(sig)) {
- if (process.env["LOG_CDN_SIGNATURES"])
- console.warn("[Signing] Signature is expired");
+ if (process.env["LOG_CDN_SIGNATURES"]) console.warn("[Signing] Signature is expired");
return false;
}
@@ -273,42 +235,26 @@ export const hasValidSignature = (
const calculated = Buffer.from(calcd);
const received = Buffer.from(sig.hash as string);
- console.assert(
- sig.issuedAt == calcResult.issuedAt,
- "[Signing] Mismatched issuedAt",
- {
- is: sig.issuedAt,
- calculated: calcResult.issuedAt,
- },
- );
+ console.assert(sig.issuedAt == calcResult.issuedAt, "[Signing] Mismatched issuedAt", {
+ is: sig.issuedAt,
+ calculated: calcResult.issuedAt,
+ });
- console.assert(
- sig.expiresAt == calcResult.expiresAt,
- "[Signing] Mismatched expiresAt",
- {
- ex: sig.expiresAt,
- calculated: calcResult.expiresAt,
- },
- );
+ console.assert(sig.expiresAt == calcResult.expiresAt, "[Signing] Mismatched expiresAt", {
+ ex: sig.expiresAt,
+ calculated: calcResult.expiresAt,
+ });
- console.assert(
- calculated.length === received.length,
- "[Signing] Mismatched hash length",
- {
- calculated: calculated.length,
- received: received.length,
- },
- );
+ console.assert(calculated.length === received.length, "[Signing] Mismatched hash length", {
+ calculated: calculated.length,
+ received: received.length,
+ });
- const isHashValid =
- calculated.length === received.length &&
- timingSafeEqual(calculated, received);
+ const isHashValid = calculated.length === received.length && timingSafeEqual(calculated, received);
if (!isHashValid)
if (process.env["LOG_CDN_SIGNATURES"])
- console.warn(
- `Signature validation for ${sig.path} (is=${sig.issuedAt}, ex=${sig.expiresAt}) failed: calculated: ${calcd}, received: ${sig.hash}`,
- );
+ console.warn(`Signature validation for ${sig.path} (is=${sig.issuedAt}, ex=${sig.expiresAt}) failed: calculated: ${calcd}, received: ${sig.hash}`);
return isHashValid;
};
|