jose
Version:
JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes
76 lines (75 loc) • 2.75 kB
JavaScript
const encoder = new TextEncoder(), decoder = new TextDecoder(), strictDecoder = new TextDecoder("utf-8", { fatal: !0 }), UINT32_RANGE = 2 ** 32;
function concat(...buffers) {
const size = buffers.reduce((acc, { length }) => acc + length, 0), buf = new Uint8Array(size);
let i = 0;
for (const buffer of buffers)
buf.set(buffer, i), i += buffer.length;
return buf;
}
function writeUInt32BE(buf, value, offset) {
if (value < 0 || value >= UINT32_RANGE)
throw new RangeError(`value must be >= 0 and <= ${UINT32_RANGE - 1}. Received ${value}`);
buf.set([value >>> 24, value >>> 16, value >>> 8, value & 255], offset);
}
function uint64be(value) {
const high = Math.floor(value / UINT32_RANGE), low = value % UINT32_RANGE, buf = new Uint8Array(8);
return writeUInt32BE(buf, high, 0), writeUInt32BE(buf, low, 4), buf;
}
function uint32be(value) {
const buf = new Uint8Array(4);
return writeUInt32BE(buf, value), buf;
}
const NON_ASCII = /[^\x00-\x7f]/;
function encode(string) {
if (typeof string == "string" && string.length >= 128) {
if (NON_ASCII.test(string))
throw new TypeError("non-ASCII string encountered in encode()");
return encoder.encode(string);
}
const bytes = new Uint8Array(string.length);
for (let i = 0; i < string.length; i++) {
const code = string.charCodeAt(i);
if (code > 127)
throw new TypeError("non-ASCII string encountered in encode()");
bytes[i] = code;
}
return bytes;
}
function encodeBase64(input, url = !1) {
if (Uint8Array.prototype.toBase64)
return input.toBase64({ alphabet: url ? "base64url" : "base64", omitPadding: url });
const CHUNK_SIZE = 32768, arr = [];
for (let i = 0; i < input.length; i += CHUNK_SIZE)
arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
const encoded = btoa(arr.join(""));
return url ? encoded.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_") : encoded;
}
function decodeBase64(encoded, url = !1) {
if (Uint8Array.fromBase64)
return Uint8Array.fromBase64(encoded, { alphabet: url ? "base64url" : "base64" });
if (url) {
if (encoded.includes("+") || encoded.includes("/"))
throw new TypeError("Invalid base64url");
encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
}
const binary = atob(encoded), bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++)
bytes[i] = binary.charCodeAt(i);
return bytes;
}
async function digest(algorithm, data) {
const subtleDigest = `SHA-${algorithm.slice(-3)}`;
return new Uint8Array(await crypto.subtle.digest(subtleDigest, data));
}
export {
concat,
decodeBase64,
decoder,
digest,
encode,
encodeBase64,
encoder,
strictDecoder,
uint32be,
uint64be
};