mirror of
https://github.com/outline/outline.git
synced 2026-01-06 11:09:55 -06:00
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import { randomBytes, createHmac } from "crypto";
|
|
import { safeEqual } from "./crypto";
|
|
|
|
/**
|
|
* Generates cryptographically secure random bytes
|
|
*
|
|
* @param size The number of bytes to generate
|
|
* @returns A buffer containing random bytes
|
|
*/
|
|
export const generateRawToken = (size: number): Buffer => randomBytes(size);
|
|
|
|
/**
|
|
* Creates an HMAC-SHA256 signature for a token
|
|
*
|
|
* @param token The token to sign
|
|
* @param secret The secret key for signing
|
|
* @returns The HMAC signature as a hex string
|
|
*/
|
|
export const signToken = (token: Buffer, secret: string): string =>
|
|
createHmac("sha256", secret).update(token).digest("hex");
|
|
|
|
/**
|
|
* Bundles a token with its HMAC signature
|
|
*
|
|
* @param token The raw token
|
|
* @param secret The secret key for signing
|
|
* @returns A string containing the token and signature separated by a dot
|
|
*/
|
|
export const bundleToken = (token: Buffer, secret: string): string => {
|
|
const sig = signToken(token, secret);
|
|
return `${token.toString("hex")}.${sig}`;
|
|
};
|
|
|
|
/**
|
|
* Unbundles and verifies a token with its HMAC signature
|
|
*
|
|
* @param bundled The bundled token string
|
|
* @param secret The secret key for verification
|
|
* @returns An object indicating validity and the raw token if valid
|
|
*/
|
|
export const unbundleToken = (
|
|
bundled: string,
|
|
secret: string
|
|
): { valid: boolean; raw?: Buffer } => {
|
|
const [hex, sig] = bundled.split(".");
|
|
if (!hex || !sig) {
|
|
return { valid: false };
|
|
}
|
|
|
|
const token = Buffer.from(hex, "hex");
|
|
const expected = signToken(token, secret);
|
|
|
|
const valid = safeEqual(sig, expected);
|
|
return { valid, raw: valid ? token : undefined };
|
|
};
|