UNPKG

auth-vir

Version:

Auth made easy and secure via JWT cookies, CSRF tokens, and password hashing helpers.

58 lines (57 loc) 1.8 kB
import { assertWrap } from '@augment-vir/assert'; import { base64url } from 'jose'; const signingKeyOptions = [ { name: 'HMAC', hash: 'SHA-512', }, true, [ 'sign', 'verify', ], ]; /** * Generate fresh and serialized JWT signing and encryption keys. These should be stored in a secure * secrets database (such as AWS Secrets Manager) for later parsing by {@link parseJwtKeys}. * * These keys should be kept secret and never shared with any frontend, client, etc. * * @category Keys */ export async function generateNewJwtKeys() { return { encryptionKey: assertWrap.isDefined((await globalThis.crypto.subtle.exportKey('jwk', await globalThis.crypto.subtle.generateKey({ name: 'AES-GCM', length: 256, }, true, [ 'encrypt', 'decrypt', ]))).k), signingKey: assertWrap.isDefined((await globalThis.crypto.subtle.exportKey('jwk', await globalThis.crypto.subtle.generateKey(...signingKeyOptions))).k), }; } /** * Parses an instance of {@link RawJwtKeys} and produces the final {@link JwtKeys} object required by * all authentication functionality. * * @category Keys */ export async function parseJwtKeys(rawKeys) { if (!rawKeys.encryptionKey) { throw new Error('JWT encryption key is empty'); } else if (!rawKeys.signingKey) { throw new Error('JWT signing key is empty'); } return { encryptionKey: base64url.decode(rawKeys.encryptionKey), signingKey: await crypto.subtle.importKey('jwk', { k: rawKeys.signingKey, alg: 'HS512', ext: signingKeyOptions[1], key_ops: [...signingKeyOptions[2]], kty: 'oct', }, ...signingKeyOptions), }; }