import { BufferSource } from 'node:stream/web'; import { Base64 } from 'js-base64'; // This module is used by the FE and the BE, so it must be compatible with both. // For both sides, we are using the Web Crypto API. This API is supported by all modern browsers, and // newer versions of Node.js. /** * Returns the SHA-256 hash of the given message. * @param message The message to hash, that could be a string or a binary. If a string is given, it will be encoded as UTF-8. * @returns The raw SHA-256 hash of the given message in binary form. */ async function sha256(message: string | BufferSource): Promise { // If the message is a string, we need convert it to a Uint8Array because the Web Crypto API does not support strings. // Otherwise, we can pass the message directly to the Web Crypto API. if (typeof message === 'string') { // Note: `TextEncoder` always encodes as UTF-8. message = new TextEncoder().encode(message); } return await crypto.subtle.digest('SHA-256', message); } /** * Returns the SHA-256 hash of the given message, encoded as a base64 string. * @param message The message to hash, that could be a string or a binary. If a string is given, it will be encoded as UTF-8. * @returns The SHA-256 hash of the given message, encoded as a base64 string. */ export async function sha256Base64(message: string | BufferSource): Promise { const rawHash = await sha256(message); return Base64.fromUint8Array(new Uint8Array(rawHash)); }