UNPKG

@pushforge/builder

Version:

A robust, cross-platform Web Push notification library that handles VAPID authentication and payload encryption following the Web Push Protocol standard. Works in Node.js 16+, Browsers, Deno, Bun and Cloudflare Workers.

75 lines (74 loc) 3.04 kB
import { base64UrlDecodeString, base64UrlEncode } from './base64.js'; /** * Converts an ArrayBuffer or Uint8Array to a string. * * @param {ArrayBuffer | Uint8Array} s - The input array to convert. * @returns {string} The resulting string representation of the input. */ export const stringFromArrayBuffer = (s) => { let result = ''; for (const code of new Uint8Array(s)) result += String.fromCharCode(code); return result; }; /** * Cross-platform function to decode a Base64 string into a binary string. * Works in both browser and Node.js environments. * * @param {string} base64String - The Base64 encoded string to decode. * @returns {string} The decoded binary string. */ export const base64Decode = (base64String) => { // Add padding if needed const paddedBase64 = base64String.padEnd(base64String.length + ((4 - (base64String.length % 4 || 4)) % 4), '='); // Node.js environment if (typeof Buffer !== 'undefined') { return Buffer.from(paddedBase64, 'base64').toString('binary'); } // Browser environment if (typeof atob === 'function') { return atob(paddedBase64); } // Pure JavaScript implementation for environments without atob or Buffer const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; let result = ''; let i = 0; while (i < paddedBase64.length) { const enc1 = characters.indexOf(paddedBase64.charAt(i++)); const enc2 = characters.indexOf(paddedBase64.charAt(i++)); const enc3 = characters.indexOf(paddedBase64.charAt(i++)); const enc4 = characters.indexOf(paddedBase64.charAt(i++)); const char1 = (enc1 << 2) | (enc2 >> 4); const char2 = ((enc2 & 15) << 4) | (enc3 >> 2); const char3 = ((enc3 & 3) << 6) | enc4; result += String.fromCharCode(char1); if (enc3 !== 64) result += String.fromCharCode(char2); if (enc4 !== 64) result += String.fromCharCode(char3); } return result; }; /** * Extracts the public key from a JSON Web Key (JWK) and encodes it in base64 URL format. * * @param {JsonWebKey} jwk - The JSON Web Key from which to extract the public key. * @returns {string} The base64 URL encoded public key. */ export const getPublicKeyFromJwk = (jwk) => base64UrlEncode(`\x04${base64Decode(base64UrlDecodeString(jwk.x))}${base64Decode(base64UrlDecodeString(jwk.y))}`); /** * Concatenates multiple Uint8Array instances into a single Uint8Array. * * @param {Uint8Array[]} arrays - An array of Uint8Array instances to concatenate. * @returns {Uint8Array} A new Uint8Array containing all the concatenated data. */ export const concatTypedArrays = (arrays) => { const length = arrays.reduce((accumulator, current) => accumulator + current.byteLength, 0); let index = 0; const targetArray = new Uint8Array(length); for (const array of arrays) { targetArray.set(array, index); index += array.byteLength; } return targetArray; };