auth-vir
Version:
Auth made easy and secure via JWT cookies, CSRF tokens, and password hashing helpers.
78 lines (77 loc) • 2.45 kB
JavaScript
import { check } from '@augment-vir/assert';
import { safeMatch } from '@augment-vir/common';
import { convertDuration } from 'date-vir';
import { parseUrl } from 'url-vir';
import { createUserJwt, parseUserJwt } from './user-jwt.js';
/**
* Generate a secure cookie that stores the user JWT data. Used in host (backend) code.
*
* @category Internal
*/
export async function generateAuthCookie(userJwtData, cookieConfig) {
return generateCookie({
[cookieConfig.cookieName || 'auth']: await createUserJwt(userJwtData, cookieConfig.jwtParams),
Domain: parseUrl(cookieConfig.hostOrigin).hostname,
HttpOnly: true,
Path: '/',
SameSite: 'Strict',
'MAX-AGE': convertDuration(cookieConfig.cookieDuration, { seconds: true }).seconds,
Secure: !cookieConfig.isDev,
});
}
/**
* Generate a cookie value that will clear the previous auth cookie. Use this when signing out.
*
* @category Internal
*/
export function clearAuthCookie(cookieConfig) {
return generateCookie({
[cookieConfig.cookieName || 'auth']: 'redacted',
Domain: parseUrl(cookieConfig.hostOrigin).hostname,
HttpOnly: true,
Path: '/',
SameSite: 'Strict',
'MAX-AGE': 0,
Secure: !cookieConfig.isDev,
});
}
/**
* Generate a cookie string from a raw set of parameters.
*
* @category Internal
*/
export function generateCookie(params) {
return Object.entries(params)
.map(([key, value,]) => {
if (value == undefined || value === false) {
return undefined;
}
else if (value === '' || value === true) {
return key;
}
else {
return [
key,
value,
].join('=');
}
})
.filter(check.isTruthy)
.join('; ');
}
/**
* Extract an auth cookie from a cookie string. Used in host (backend) code.
*
* @category Internal
* @returns The extracted auth Cookie JWT data or `undefined` if no valid auth JWT data was found.
*/
export async function extractCookieJwt(rawCookie, jwtParams, cookieName = 'auth') {
const cookieRegExp = new RegExp(`${cookieName}=[^;]+(?:;|$)`);
const [auth] = safeMatch(rawCookie, cookieRegExp);
if (!auth) {
return undefined;
}
const rawJwt = auth.replace(`${cookieName}=`, '').replace(';', '');
const jwt = await parseUserJwt(rawJwt, jwtParams);
return jwt;
}