UNPKG

@authlink/client

Version:

Official client SDK for integrating with the Authlink Identity Provider

128 lines (127 loc) 4.23 kB
/** * Creates a code verifier. * @returns The code verifier string. * */ export function createCodeVerifier() { return generateRandomString(64); } /** * Creates a code challenge from the given code verifier. * */ export async function createCodeChallenge(codeVerifier, method) { if (method == "plain") return codeVerifier; let hashed = await sha256(codeVerifier); return base64UrlEncode(hashed); } /** * Computes the SHA-256 hash of the given string. * @param plain The string to hash. * @returns A promise that resolves to the hash. */ async function sha256(plain) { const encoder = new TextEncoder(); const data = encoder.encode(plain); return await crypto.subtle.digest("SHA-256", data); } /** * Encodes an ArrayBuffer to a base64 URL encoded string. * @param arrayBuffer The ArrayBuffer to encode. * @returns The base64 URL encoded string. */ function base64UrlEncode(arrayBuffer) { const bytes = new Uint8Array(arrayBuffer); let str = String.fromCharCode(...bytes); return btoa(str) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/, ""); } /** * Generate a random string of the specified length using the Web Crypto API. * @param length The length of the string to generate. * @returns A random string in hexadecimal format. * */ export function generateRandomString(length) { const array = new Uint8Array(length); window.crypto.getRandomValues(array); return Array .from(array, byte => ('0' + byte.toString(16)).slice(-2)) .join(''); } /** * Creates a silent iframe to load a URL without user interaction. * @param url The URL to load in the iframe. * @return The created iframe element. * */ export function createSilentIframe(url) { const iframe = document.createElement("iframe"); iframe.style.display = "none"; iframe.src = url; document.body.appendChild(iframe); return iframe; } /** * Listens for a web message with the specified state and origin. * @param state The expected state of the authorization response. * @param expectedOrigin The expected origin of the message. * @returns A promise that resolves with the authorization response data. */ export function listenForWebMessage(state, expectedOrigin) { return new Promise((resolve, _) => { function handler(event) { if (event.origin !== expectedOrigin) return; const { data } = event; if (data.type !== "authorization_response" || data.state !== state) return; window.removeEventListener("message", handler); resolve(event.data); } window.addEventListener("message", handler); }); } /** * Maps the JSON response from the token endpoint to a TokenResponse object. * @param json The JSON response from the token endpoint. * @return A TokenResponse object containing the token information. * */ export function mapTokenResponse(json) { return { tokenType: json.token_type, accessToken: json.access_token, expiresIn: json.expires_in, refreshToken: json.refresh_token, idToken: json.id_token, scope: json.scope, issuedTokenType: json.issued_token_type }; } /** * Maps the JSON response from the authorization endpoint to an AuthorizeResponse object. * @param json The JSON response from the authorization endpoint. * @return An AuthorizeResponse object containing the authorization information. * */ export function mapAuthorizeResponse(json) { return { type: json.type, state: json.state, code: json.code, idToken: json.id_token, accessToken: json.access_token, expiresIn: json.expires_in, error: json.error, errorDescription: json.error_description }; } /** * Maps the JSON response from the OpenID configuration endpoint to an OpenIdConfiguration object. * @param json The JSON response from the OpenID configuration endpoint. * @return An OpenIdConfiguration object containing the issuer and JWKS URI. * */ export function mapOpenIdConfiguration(json) { return { issuer: json.issuer, jwksUri: json.jwks_uri }; }