WorkshopTasker/server/utils/SessionToken.ts
Wroclaw ebf5690519 [BREAKING] Auth: replace current auth tokens with more secure ones
previously tokens were only like IDs, time based and incrementing counter.
An attacker could easily bruteforce them.
This patch changes tokens to be completely random.

fixes #2
2023-11-09 18:28:09 +01:00

49 lines
1.6 KiB
TypeScript

import crypto from "node:crypto";
import { type Session } from "@prisma/client";
import Snowflake from "~/utils/snowflake";
/** Represents a Session token, without expiry data. */
export default class SessionToken {
userId: bigint;
sessionId: bigint;
sessionToken: Buffer;
constructor(userId: bigint, sessionId?: bigint, sessionToken?: Buffer) {
this.userId = userId;
this.sessionId = sessionId ?? new Snowflake().state;
this.sessionToken = sessionToken ?? crypto.randomBytes(64);
}
/** Creates SessionToken from a string.
* @param string The strinct to create from.
* @returns The SessionToken object.
*/
static fromString(string: string): SessionToken {
const parameters = string.split(".");
return new SessionToken(
Buffer.from(parameters[0], "base64").readBigUInt64LE(),
Buffer.from(parameters[1], "base64").readBigUInt64LE(),
Buffer.from(parameters[2], "base64"),
);
}
toString(): string {
const stringUserId = Buffer.copyBytesFrom(new BigUint64Array([this.userId])).toString("base64");
const stringSessionId = Buffer.copyBytesFrom(new BigUint64Array([this.sessionId])).toString("base64");
const stringSessionToken = this.sessionToken.toString("base64");
return `${stringUserId}.${stringSessionId}.${stringSessionToken}`;
}
/** Returns this SessionToken as Prisma object.
* For use in where parameter.
* @returns this as prisma object.
*/
toPrisma(): Omit<Session, "expiry_date"> {
return {
id: this.sessionId,
userId: this.userId,
sessionToken: this.sessionToken,
};
}
}