🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@better-auth/utils

Package Overview
Dependencies
Maintainers
2
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@better-auth/utils - npm Package Compare versions

Comparing version
0.4.2
to
0.4.3
+23
dist/bytes.cjs
//#region src/bytes.ts
function toBufferSource(data) {
if (typeof data === "string") return new TextEncoder().encode(data);
if (!ArrayBuffer.isView(data)) return data;
if (data.buffer instanceof ArrayBuffer) return data;
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength).slice();
}
/**
* Converts strings and binary data into a `Uint8Array`.
*
* `ArrayBuffer` inputs share memory with the returned view, while `TypedArray`
* inputs are copied according to native constructor semantics.
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#buffer | ArrayBuffer constructor behavior}
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray | TypedArray constructor behavior}
*/
function toUint8Array(data) {
if (typeof data === "string") return new TextEncoder().encode(data);
return new Uint8Array(data);
}
//#endregion
exports.toBufferSource = toBufferSource;
exports.toUint8Array = toUint8Array;
//#region src/bytes.ts
function toBufferSource(data) {
if (typeof data === "string") return new TextEncoder().encode(data);
if (!ArrayBuffer.isView(data)) return data;
if (data.buffer instanceof ArrayBuffer) return data;
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength).slice();
}
/**
* Converts strings and binary data into a `Uint8Array`.
*
* `ArrayBuffer` inputs share memory with the returned view, while `TypedArray`
* inputs are copied according to native constructor semantics.
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#buffer | ArrayBuffer constructor behavior}
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray | TypedArray constructor behavior}
*/
function toUint8Array(data) {
if (typeof data === "string") return new TextEncoder().encode(data);
return new Uint8Array(data);
}
//#endregion
export { toBufferSource, toUint8Array };
//#region src/type.d.ts
type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
/**
* Equivalent to `Uint8Array` before TypeScript 5.7, and `Uint8Array<ArrayBuffer>` in TypeScript 5.7
* and beyond.
*
* **Context**
*
* `Uint8Array` became a generic type in TypeScript 5.7, requiring types defined simply as
* `Uint8Array` to be refactored to `Uint8Array<ArrayBuffer>` starting in Deno 2.2. `Uint8Array` is
* _not_ generic in Deno 2.1.x and earlier, though, so this type helps bridge this gap.
*
* Inspired by Deno's std library:
*
* https://github.com/denoland/std/blob/b5a5fe4f96b91c1fe8dba5cc0270092dd11d3287/bytes/_types.ts#L11
*/
type Uint8Array_ = ReturnType<Uint8Array["slice"]>;
type SHAFamily = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";
type EncodingFormat = "hex" | "base64" | "base64url" | "base64urlnopad" | "none";
type ECDSACurve = "P-256" | "P-384" | "P-521";
type ExportKeyFormat = "jwk" | "spki" | "pkcs8" | "raw";
//#endregion
export { ECDSACurve, EncodingFormat, ExportKeyFormat, SHAFamily, TypedArray, Uint8Array_ };
//#region src/type.d.ts
type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
/**
* Equivalent to `Uint8Array` before TypeScript 5.7, and `Uint8Array<ArrayBuffer>` in TypeScript 5.7
* and beyond.
*
* **Context**
*
* `Uint8Array` became a generic type in TypeScript 5.7, requiring types defined simply as
* `Uint8Array` to be refactored to `Uint8Array<ArrayBuffer>` starting in Deno 2.2. `Uint8Array` is
* _not_ generic in Deno 2.1.x and earlier, though, so this type helps bridge this gap.
*
* Inspired by Deno's std library:
*
* https://github.com/denoland/std/blob/b5a5fe4f96b91c1fe8dba5cc0270092dd11d3287/bytes/_types.ts#L11
*/
type Uint8Array_ = ReturnType<Uint8Array["slice"]>;
type SHAFamily = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";
type EncodingFormat = "hex" | "base64" | "base64url" | "base64urlnopad" | "none";
type ECDSACurve = "P-256" | "P-384" | "P-521";
type ExportKeyFormat = "jwk" | "spki" | "pkcs8" | "raw";
//#endregion
export { ECDSACurve, EncodingFormat, ExportKeyFormat, SHAFamily, TypedArray, Uint8Array_ };
+108
-90

@@ -1,104 +0,122 @@

'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_bytes = require("./bytes.cjs");
//#region src/base32.ts
/**
* Returns the Base32 alphabet based on the encoding type.
* @param hex - Whether to use the hexadecimal Base32 alphabet.
* @returns The appropriate Base32 alphabet.
*/
function getAlphabet(hex) {
return hex ? "0123456789ABCDEFGHIJKLMNOPQRSTUV" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
return hex ? "0123456789ABCDEFGHIJKLMNOPQRSTUV" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
}
/**
* Creates a decode map for the given alphabet.
* @param alphabet - The Base32 alphabet.
* @returns A map of characters to their corresponding values.
*/
function createDecodeMap(alphabet) {
const decodeMap = /* @__PURE__ */ new Map();
for (let i = 0; i < alphabet.length; i++) {
decodeMap.set(alphabet[i], i);
}
return decodeMap;
const decodeMap = /* @__PURE__ */ new Map();
for (let i = 0; i < alphabet.length; i++) decodeMap.set(alphabet[i], i);
return decodeMap;
}
/**
* Encodes a Uint8Array into a Base32 string.
* @param data - The data to encode.
* @param alphabet - The Base32 alphabet to use.
* @param padding - Whether to include padding.
* @returns The Base32 encoded string.
*/
function base32Encode(data, alphabet, padding) {
let result = "";
let buffer = 0;
let shift = 0;
for (const byte of data) {
buffer = buffer << 8 | byte;
shift += 8;
while (shift >= 5) {
shift -= 5;
result += alphabet[buffer >> shift & 31];
}
}
if (shift > 0) {
result += alphabet[buffer << 5 - shift & 31];
}
if (padding) {
const padCount = (8 - result.length % 8) % 8;
result += "=".repeat(padCount);
}
return result;
let result = "";
let buffer = 0;
let shift = 0;
for (const byte of data) {
buffer = buffer << 8 | byte;
shift += 8;
while (shift >= 5) {
shift -= 5;
result += alphabet[buffer >> shift & 31];
}
}
if (shift > 0) result += alphabet[buffer << 5 - shift & 31];
if (padding) {
const padCount = (8 - result.length % 8) % 8;
result += "=".repeat(padCount);
}
return result;
}
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string.
* @param alphabet - The Base32 alphabet to use.
* @returns The decoded Uint8Array.
*/
function base32Decode(data, alphabet) {
const decodeMap = createDecodeMap(alphabet);
const result = [];
let buffer = 0;
let bitsCollected = 0;
for (const char of data) {
if (char === "=")
break;
const value = decodeMap.get(char);
if (value === void 0) {
throw new Error(`Invalid Base32 character: ${char}`);
}
buffer = buffer << 5 | value;
bitsCollected += 5;
while (bitsCollected >= 8) {
bitsCollected -= 8;
result.push(buffer >> bitsCollected & 255);
}
}
return Uint8Array.from(result);
const decodeMap = createDecodeMap(alphabet);
const result = [];
let buffer = 0;
let bitsCollected = 0;
for (const char of data) {
if (char === "=") break;
const value = decodeMap.get(char);
if (value === void 0) throw new Error(`Invalid Base32 character: ${char}`);
buffer = buffer << 5 | value;
bitsCollected += 5;
while (bitsCollected >= 8) {
bitsCollected -= 8;
result.push(buffer >> bitsCollected & 255);
}
}
return Uint8Array.from(result);
}
/**
* Base32 encoding and decoding utility.
*/
const base32 = {
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data, options = {}) {
const alphabet = getAlphabet(false);
const buffer = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
return base32Encode(buffer, alphabet, options.padding ?? true);
},
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data) {
if (typeof data !== "string") {
data = new TextDecoder().decode(data);
}
const alphabet = getAlphabet(false);
return base32Decode(data, alphabet);
}
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data, options = {}) {
const alphabet = getAlphabet(false);
return base32Encode(require_bytes.toUint8Array(data), alphabet, options.padding ?? true);
},
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data) {
if (typeof data !== "string") data = new TextDecoder().decode(data);
const alphabet = getAlphabet(false);
return base32Decode(data, alphabet);
}
};
/**
* Base32hex encoding and decoding utility.
*/
const base32hex = {
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data, options = {}) {
const alphabet = getAlphabet(true);
const buffer = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
return base32Encode(buffer, alphabet, options.padding ?? true);
},
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data) {
const alphabet = getAlphabet(true);
return base32Decode(data, alphabet);
}
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data, options = {}) {
const alphabet = getAlphabet(true);
return base32Encode(require_bytes.toUint8Array(data), alphabet, options.padding ?? true);
},
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data) {
return base32Decode(data, getAlphabet(true));
}
};
//#endregion
exports.base32 = base32;
exports.base32hex = base32hex;

@@ -1,3 +0,3 @@

import { T as TypedArray, U as Uint8Array_ } from './shared/utils.ecd028f7.cjs';
import { TypedArray, Uint8Array_ } from "./type.cjs";
//#region src/base32.d.ts
/**

@@ -7,17 +7,17 @@ * Base32 encoding and decoding utility.

declare const base32: {
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data: string | ArrayBuffer | TypedArray): Uint8Array_;
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data: string | ArrayBuffer | TypedArray): Uint8Array_;
};

@@ -28,19 +28,19 @@ /**

declare const base32hex: {
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data: string): Uint8Array_;
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data: string): Uint8Array_;
};
export { base32, base32hex };
//#endregion
export { base32, base32hex };

@@ -1,3 +0,3 @@

import { T as TypedArray, U as Uint8Array_ } from './shared/utils.ecd028f7.mjs';
import { TypedArray, Uint8Array_ } from "./type.mjs";
//#region src/base32.d.ts
/**

@@ -7,17 +7,17 @@ * Base32 encoding and decoding utility.

declare const base32: {
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data: string | ArrayBuffer | TypedArray): Uint8Array_;
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data: string | ArrayBuffer | TypedArray): Uint8Array_;
};

@@ -28,19 +28,19 @@ /**

declare const base32hex: {
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data: string): Uint8Array_;
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data: string): Uint8Array_;
};
export { base32, base32hex };
//#endregion
export { base32, base32hex };

@@ -0,101 +1,120 @@

import { toUint8Array } from "./bytes.mjs";
//#region src/base32.ts
/**
* Returns the Base32 alphabet based on the encoding type.
* @param hex - Whether to use the hexadecimal Base32 alphabet.
* @returns The appropriate Base32 alphabet.
*/
function getAlphabet(hex) {
return hex ? "0123456789ABCDEFGHIJKLMNOPQRSTUV" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
return hex ? "0123456789ABCDEFGHIJKLMNOPQRSTUV" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
}
/**
* Creates a decode map for the given alphabet.
* @param alphabet - The Base32 alphabet.
* @returns A map of characters to their corresponding values.
*/
function createDecodeMap(alphabet) {
const decodeMap = /* @__PURE__ */ new Map();
for (let i = 0; i < alphabet.length; i++) {
decodeMap.set(alphabet[i], i);
}
return decodeMap;
const decodeMap = /* @__PURE__ */ new Map();
for (let i = 0; i < alphabet.length; i++) decodeMap.set(alphabet[i], i);
return decodeMap;
}
/**
* Encodes a Uint8Array into a Base32 string.
* @param data - The data to encode.
* @param alphabet - The Base32 alphabet to use.
* @param padding - Whether to include padding.
* @returns The Base32 encoded string.
*/
function base32Encode(data, alphabet, padding) {
let result = "";
let buffer = 0;
let shift = 0;
for (const byte of data) {
buffer = buffer << 8 | byte;
shift += 8;
while (shift >= 5) {
shift -= 5;
result += alphabet[buffer >> shift & 31];
}
}
if (shift > 0) {
result += alphabet[buffer << 5 - shift & 31];
}
if (padding) {
const padCount = (8 - result.length % 8) % 8;
result += "=".repeat(padCount);
}
return result;
let result = "";
let buffer = 0;
let shift = 0;
for (const byte of data) {
buffer = buffer << 8 | byte;
shift += 8;
while (shift >= 5) {
shift -= 5;
result += alphabet[buffer >> shift & 31];
}
}
if (shift > 0) result += alphabet[buffer << 5 - shift & 31];
if (padding) {
const padCount = (8 - result.length % 8) % 8;
result += "=".repeat(padCount);
}
return result;
}
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string.
* @param alphabet - The Base32 alphabet to use.
* @returns The decoded Uint8Array.
*/
function base32Decode(data, alphabet) {
const decodeMap = createDecodeMap(alphabet);
const result = [];
let buffer = 0;
let bitsCollected = 0;
for (const char of data) {
if (char === "=")
break;
const value = decodeMap.get(char);
if (value === void 0) {
throw new Error(`Invalid Base32 character: ${char}`);
}
buffer = buffer << 5 | value;
bitsCollected += 5;
while (bitsCollected >= 8) {
bitsCollected -= 8;
result.push(buffer >> bitsCollected & 255);
}
}
return Uint8Array.from(result);
const decodeMap = createDecodeMap(alphabet);
const result = [];
let buffer = 0;
let bitsCollected = 0;
for (const char of data) {
if (char === "=") break;
const value = decodeMap.get(char);
if (value === void 0) throw new Error(`Invalid Base32 character: ${char}`);
buffer = buffer << 5 | value;
bitsCollected += 5;
while (bitsCollected >= 8) {
bitsCollected -= 8;
result.push(buffer >> bitsCollected & 255);
}
}
return Uint8Array.from(result);
}
/**
* Base32 encoding and decoding utility.
*/
const base32 = {
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data, options = {}) {
const alphabet = getAlphabet(false);
const buffer = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
return base32Encode(buffer, alphabet, options.padding ?? true);
},
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data) {
if (typeof data !== "string") {
data = new TextDecoder().decode(data);
}
const alphabet = getAlphabet(false);
return base32Decode(data, alphabet);
}
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data, options = {}) {
const alphabet = getAlphabet(false);
return base32Encode(toUint8Array(data), alphabet, options.padding ?? true);
},
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data) {
if (typeof data !== "string") data = new TextDecoder().decode(data);
const alphabet = getAlphabet(false);
return base32Decode(data, alphabet);
}
};
/**
* Base32hex encoding and decoding utility.
*/
const base32hex = {
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data, options = {}) {
const alphabet = getAlphabet(true);
const buffer = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
return base32Encode(buffer, alphabet, options.padding ?? true);
},
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data) {
const alphabet = getAlphabet(true);
return base32Decode(data, alphabet);
}
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data, options = {}) {
const alphabet = getAlphabet(true);
return base32Encode(toUint8Array(data), alphabet, options.padding ?? true);
},
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data) {
return base32Decode(data, getAlphabet(true));
}
};
//#endregion
export { base32, base32hex };

@@ -1,80 +0,67 @@

'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_bytes = require("./bytes.cjs");
//#region src/base64.ts
function getAlphabet(urlSafe) {
return urlSafe ? "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
return urlSafe ? "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
}
function base64Encode(data, alphabet, padding) {
let result = "";
let buffer = 0;
let shift = 0;
for (const byte of data) {
buffer = buffer << 8 | byte;
shift += 8;
while (shift >= 6) {
shift -= 6;
result += alphabet[buffer >> shift & 63];
}
}
if (shift > 0) {
result += alphabet[buffer << 6 - shift & 63];
}
if (padding) {
const padCount = (4 - result.length % 4) % 4;
result += "=".repeat(padCount);
}
return result;
let result = "";
let buffer = 0;
let shift = 0;
for (const byte of data) {
buffer = buffer << 8 | byte;
shift += 8;
while (shift >= 6) {
shift -= 6;
result += alphabet[buffer >> shift & 63];
}
}
if (shift > 0) result += alphabet[buffer << 6 - shift & 63];
if (padding) {
const padCount = (4 - result.length % 4) % 4;
result += "=".repeat(padCount);
}
return result;
}
function base64Decode(data, alphabet) {
const decodeMap = /* @__PURE__ */ new Map();
for (let i = 0; i < alphabet.length; i++) {
decodeMap.set(alphabet[i], i);
}
const result = [];
let buffer = 0;
let bitsCollected = 0;
for (const char of data) {
if (char === "=")
break;
const value = decodeMap.get(char);
if (value === void 0) {
throw new Error(`Invalid Base64 character: ${char}`);
}
buffer = buffer << 6 | value;
bitsCollected += 6;
if (bitsCollected >= 8) {
bitsCollected -= 8;
result.push(buffer >> bitsCollected & 255);
}
}
return Uint8Array.from(result);
const decodeMap = /* @__PURE__ */ new Map();
for (let i = 0; i < alphabet.length; i++) decodeMap.set(alphabet[i], i);
const result = [];
let buffer = 0;
let bitsCollected = 0;
for (const char of data) {
if (char === "=") break;
const value = decodeMap.get(char);
if (value === void 0) throw new Error(`Invalid Base64 character: ${char}`);
buffer = buffer << 6 | value;
bitsCollected += 6;
if (bitsCollected >= 8) {
bitsCollected -= 8;
result.push(buffer >> bitsCollected & 255);
}
}
return Uint8Array.from(result);
}
const base64 = {
encode(data, options = {}) {
const alphabet = getAlphabet(false);
const buffer = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
return base64Encode(buffer, alphabet, options.padding ?? true);
},
decode(data) {
if (typeof data !== "string") {
data = new TextDecoder().decode(data);
}
const urlSafe = data.includes("-") || data.includes("_");
const alphabet = getAlphabet(urlSafe);
return base64Decode(data, alphabet);
}
encode(data, options = {}) {
const alphabet = getAlphabet(false);
return base64Encode(require_bytes.toUint8Array(data), alphabet, options.padding ?? true);
},
decode(data) {
if (typeof data !== "string") data = new TextDecoder().decode(data);
const alphabet = getAlphabet(data.includes("-") || data.includes("_"));
return base64Decode(data, alphabet);
}
};
const base64Url = {
encode(data, options = {}) {
const alphabet = getAlphabet(true);
const buffer = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
return base64Encode(buffer, alphabet, options.padding ?? true);
},
decode(data) {
const urlSafe = data.includes("-") || data.includes("_");
const alphabet = getAlphabet(urlSafe);
return base64Decode(data, alphabet);
}
encode(data, options = {}) {
const alphabet = getAlphabet(true);
return base64Encode(require_bytes.toUint8Array(data), alphabet, options.padding ?? true);
},
decode(data) {
return base64Decode(data, getAlphabet(data.includes("-") || data.includes("_")));
}
};
//#endregion
exports.base64 = base64;
exports.base64Url = base64Url;

@@ -1,16 +0,16 @@

import { T as TypedArray } from './shared/utils.ecd028f7.cjs';
import { TypedArray } from "./type.cjs";
//#region src/base64.d.ts
declare const base64: {
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string | ArrayBuffer | TypedArray): Uint8Array<ArrayBuffer>;
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string | ArrayBuffer | TypedArray): Uint8Array<ArrayBuffer>;
};
declare const base64Url: {
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string): Uint8Array<ArrayBuffer>;
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string): Uint8Array<ArrayBuffer>;
};
export { base64, base64Url };
//#endregion
export { base64, base64Url };

@@ -1,16 +0,16 @@

import { T as TypedArray } from './shared/utils.ecd028f7.mjs';
import { TypedArray } from "./type.mjs";
//#region src/base64.d.ts
declare const base64: {
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string | ArrayBuffer | TypedArray): Uint8Array<ArrayBuffer>;
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string | ArrayBuffer | TypedArray): Uint8Array<ArrayBuffer>;
};
declare const base64Url: {
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string): Uint8Array<ArrayBuffer>;
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string): Uint8Array<ArrayBuffer>;
};
export { base64, base64Url };
//#endregion
export { base64, base64Url };

@@ -0,77 +1,65 @@

import { toUint8Array } from "./bytes.mjs";
//#region src/base64.ts
function getAlphabet(urlSafe) {
return urlSafe ? "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
return urlSafe ? "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
}
function base64Encode(data, alphabet, padding) {
let result = "";
let buffer = 0;
let shift = 0;
for (const byte of data) {
buffer = buffer << 8 | byte;
shift += 8;
while (shift >= 6) {
shift -= 6;
result += alphabet[buffer >> shift & 63];
}
}
if (shift > 0) {
result += alphabet[buffer << 6 - shift & 63];
}
if (padding) {
const padCount = (4 - result.length % 4) % 4;
result += "=".repeat(padCount);
}
return result;
let result = "";
let buffer = 0;
let shift = 0;
for (const byte of data) {
buffer = buffer << 8 | byte;
shift += 8;
while (shift >= 6) {
shift -= 6;
result += alphabet[buffer >> shift & 63];
}
}
if (shift > 0) result += alphabet[buffer << 6 - shift & 63];
if (padding) {
const padCount = (4 - result.length % 4) % 4;
result += "=".repeat(padCount);
}
return result;
}
function base64Decode(data, alphabet) {
const decodeMap = /* @__PURE__ */ new Map();
for (let i = 0; i < alphabet.length; i++) {
decodeMap.set(alphabet[i], i);
}
const result = [];
let buffer = 0;
let bitsCollected = 0;
for (const char of data) {
if (char === "=")
break;
const value = decodeMap.get(char);
if (value === void 0) {
throw new Error(`Invalid Base64 character: ${char}`);
}
buffer = buffer << 6 | value;
bitsCollected += 6;
if (bitsCollected >= 8) {
bitsCollected -= 8;
result.push(buffer >> bitsCollected & 255);
}
}
return Uint8Array.from(result);
const decodeMap = /* @__PURE__ */ new Map();
for (let i = 0; i < alphabet.length; i++) decodeMap.set(alphabet[i], i);
const result = [];
let buffer = 0;
let bitsCollected = 0;
for (const char of data) {
if (char === "=") break;
const value = decodeMap.get(char);
if (value === void 0) throw new Error(`Invalid Base64 character: ${char}`);
buffer = buffer << 6 | value;
bitsCollected += 6;
if (bitsCollected >= 8) {
bitsCollected -= 8;
result.push(buffer >> bitsCollected & 255);
}
}
return Uint8Array.from(result);
}
const base64 = {
encode(data, options = {}) {
const alphabet = getAlphabet(false);
const buffer = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
return base64Encode(buffer, alphabet, options.padding ?? true);
},
decode(data) {
if (typeof data !== "string") {
data = new TextDecoder().decode(data);
}
const urlSafe = data.includes("-") || data.includes("_");
const alphabet = getAlphabet(urlSafe);
return base64Decode(data, alphabet);
}
encode(data, options = {}) {
const alphabet = getAlphabet(false);
return base64Encode(toUint8Array(data), alphabet, options.padding ?? true);
},
decode(data) {
if (typeof data !== "string") data = new TextDecoder().decode(data);
const alphabet = getAlphabet(data.includes("-") || data.includes("_"));
return base64Decode(data, alphabet);
}
};
const base64Url = {
encode(data, options = {}) {
const alphabet = getAlphabet(true);
const buffer = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
return base64Encode(buffer, alphabet, options.padding ?? true);
},
decode(data) {
const urlSafe = data.includes("-") || data.includes("_");
const alphabet = getAlphabet(urlSafe);
return base64Decode(data, alphabet);
}
encode(data, options = {}) {
const alphabet = getAlphabet(true);
return base64Encode(toUint8Array(data), alphabet, options.padding ?? true);
},
decode(data) {
return base64Decode(data, getAlphabet(data.includes("-") || data.includes("_")));
}
};
//#endregion
export { base64, base64Url };

@@ -1,16 +0,13 @@

'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#region src/binary.ts
const decoders = /* @__PURE__ */ new Map();
const encoder = new TextEncoder();
const binary = {
decode: (data, encoding = "utf-8") => {
if (!decoders.has(encoding)) {
decoders.set(encoding, new TextDecoder(encoding));
}
const decoder = decoders.get(encoding);
return decoder.decode(data);
},
encode: encoder.encode
decode: (data, encoding = "utf-8") => {
if (!decoders.has(encoding)) decoders.set(encoding, new TextDecoder(encoding));
return decoders.get(encoding).decode(data);
},
encode: (input) => encoder.encode(input)
};
//#endregion
exports.binary = binary;

@@ -0,8 +1,10 @@

import { Uint8Array_ } from "./type.cjs";
//#region src/binary.d.ts
type Encoding = "utf-8" | "utf-16" | "iso-8859-1";
type BinaryData = ArrayBuffer | ArrayBufferView;
declare const binary: {
decode: (data: BinaryData, encoding?: Encoding) => string;
encode: (input?: string) => Uint8Array;
decode: (data: BinaryData, encoding?: Encoding) => string;
encode: (input?: string) => Uint8Array_;
};
export { binary };
//#endregion
export { binary };

@@ -0,8 +1,10 @@

import { Uint8Array_ } from "./type.mjs";
//#region src/binary.d.ts
type Encoding = "utf-8" | "utf-16" | "iso-8859-1";
type BinaryData = ArrayBuffer | ArrayBufferView;
declare const binary: {
decode: (data: BinaryData, encoding?: Encoding) => string;
encode: (input?: string) => Uint8Array;
decode: (data: BinaryData, encoding?: Encoding) => string;
encode: (input?: string) => Uint8Array_;
};
export { binary };
//#endregion
export { binary };

@@ -0,14 +1,12 @@

//#region src/binary.ts
const decoders = /* @__PURE__ */ new Map();
const encoder = new TextEncoder();
const binary = {
decode: (data, encoding = "utf-8") => {
if (!decoders.has(encoding)) {
decoders.set(encoding, new TextDecoder(encoding));
}
const decoder = decoders.get(encoding);
return decoder.decode(data);
},
encode: encoder.encode
decode: (data, encoding = "utf-8") => {
if (!decoders.has(encoding)) decoders.set(encoding, new TextDecoder(encoding));
return decoders.get(encoding).decode(data);
},
encode: (input) => encoder.encode(input)
};
//#endregion
export { binary };

@@ -1,90 +0,46 @@

'use strict';
const index = require('./index.cjs');
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_index = require("./index.cjs");
const require_bytes = require("./bytes.cjs");
//#region src/ecdsa.ts
const ecdsa = {
generateKeyPair: async (curve = "P-256") => {
const subtle = index.getWebcryptoSubtle();
const keyPair = await subtle.generateKey(
{
name: "ECDSA",
namedCurve: curve
},
true,
["sign", "verify"]
);
const privateKey = await subtle.exportKey("pkcs8", keyPair.privateKey);
const publicKey = await subtle.exportKey("spki", keyPair.publicKey);
return { privateKey, publicKey };
},
importPrivateKey: async (privateKey, curve, extractable = false) => {
if (typeof privateKey === "string") {
privateKey = new TextEncoder().encode(privateKey);
}
return await index.getWebcryptoSubtle().importKey(
"pkcs8",
privateKey,
{
name: "ECDSA",
namedCurve: curve
},
extractable,
["sign"]
);
},
importPublicKey: async (publicKey, curve, extractable = false) => {
if (typeof publicKey === "string") {
publicKey = new TextEncoder().encode(publicKey);
}
return await index.getWebcryptoSubtle().importKey(
"spki",
publicKey,
{
name: "ECDSA",
namedCurve: curve
},
extractable,
["verify"]
);
},
sign: async (privateKey, data, hash = "SHA-256") => {
if (typeof data === "string") {
data = new TextEncoder().encode(data);
}
const signature = await index.getWebcryptoSubtle().sign(
{
name: "ECDSA",
hash: { name: hash }
},
privateKey,
data
);
return signature;
},
verify: async (publicKey, {
signature,
data,
hash = "SHA-256"
}) => {
if (typeof signature === "string") {
signature = new TextEncoder().encode(signature);
}
if (typeof data === "string") {
data = new TextEncoder().encode(data);
}
return await index.getWebcryptoSubtle().verify(
{
name: "ECDSA",
hash: { name: hash }
},
publicKey,
signature,
data
);
},
exportKey: async (key, format) => {
return await index.getWebcryptoSubtle().exportKey(format, key);
}
generateKeyPair: async (curve = "P-256") => {
const subtle = require_index.getWebcryptoSubtle();
const keyPair = await subtle.generateKey({
name: "ECDSA",
namedCurve: curve
}, true, ["sign", "verify"]);
return {
privateKey: await subtle.exportKey("pkcs8", keyPair.privateKey),
publicKey: await subtle.exportKey("spki", keyPair.publicKey)
};
},
importPrivateKey: async (privateKey, curve, extractable = false) => {
return await require_index.getWebcryptoSubtle().importKey("pkcs8", require_bytes.toBufferSource(privateKey), {
name: "ECDSA",
namedCurve: curve
}, extractable, ["sign"]);
},
importPublicKey: async (publicKey, curve, extractable = false) => {
return await require_index.getWebcryptoSubtle().importKey("spki", require_bytes.toBufferSource(publicKey), {
name: "ECDSA",
namedCurve: curve
}, extractable, ["verify"]);
},
sign: async (privateKey, data, hash = "SHA-256") => {
return await require_index.getWebcryptoSubtle().sign({
name: "ECDSA",
hash: { name: hash }
}, privateKey, require_bytes.toBufferSource(data));
},
verify: async (publicKey, { signature, data, hash = "SHA-256" }) => {
return await require_index.getWebcryptoSubtle().verify({
name: "ECDSA",
hash: { name: hash }
}, publicKey, require_bytes.toBufferSource(signature), require_bytes.toBufferSource(data));
},
exportKey: async (key, format) => {
return await require_index.getWebcryptoSubtle().exportKey(format, key);
}
};
//#endregion
exports.ecdsa = ecdsa;

@@ -1,19 +0,19 @@

import { a as ECDSACurve, T as TypedArray, S as SHAFamily, b as ExportKeyFormat } from './shared/utils.ecd028f7.cjs';
import { ECDSACurve, ExportKeyFormat, SHAFamily, TypedArray } from "./type.cjs";
//#region src/ecdsa.d.ts
declare const ecdsa: {
generateKeyPair: (curve?: ECDSACurve) => Promise<{
privateKey: ArrayBuffer;
publicKey: ArrayBuffer;
}>;
importPrivateKey: (privateKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
importPublicKey: (publicKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
sign: (privateKey: CryptoKey, data: ArrayBuffer | TypedArray | string, hash?: SHAFamily) => Promise<ArrayBuffer>;
verify: (publicKey: CryptoKey, { signature, data, hash, }: {
signature: ArrayBuffer | TypedArray | string;
data: ArrayBuffer | string;
hash?: SHAFamily;
}) => Promise<boolean>;
exportKey: <E extends ExportKeyFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
generateKeyPair: (curve?: ECDSACurve) => Promise<{
privateKey: ArrayBuffer;
publicKey: ArrayBuffer;
}>;
importPrivateKey: (privateKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
importPublicKey: (publicKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
sign: (privateKey: CryptoKey, data: ArrayBuffer | TypedArray | string, hash?: SHAFamily) => Promise<ArrayBuffer>;
verify: (publicKey: CryptoKey, { signature, data, hash }: {
signature: ArrayBuffer | TypedArray | string;
data: ArrayBuffer | string;
hash?: SHAFamily;
}) => Promise<boolean>;
exportKey: <E extends ExportKeyFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
};
export { ecdsa };
//#endregion
export { ecdsa };

@@ -1,19 +0,19 @@

import { a as ECDSACurve, T as TypedArray, S as SHAFamily, b as ExportKeyFormat } from './shared/utils.ecd028f7.mjs';
import { ECDSACurve, ExportKeyFormat, SHAFamily, TypedArray } from "./type.mjs";
//#region src/ecdsa.d.ts
declare const ecdsa: {
generateKeyPair: (curve?: ECDSACurve) => Promise<{
privateKey: ArrayBuffer;
publicKey: ArrayBuffer;
}>;
importPrivateKey: (privateKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
importPublicKey: (publicKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
sign: (privateKey: CryptoKey, data: ArrayBuffer | TypedArray | string, hash?: SHAFamily) => Promise<ArrayBuffer>;
verify: (publicKey: CryptoKey, { signature, data, hash, }: {
signature: ArrayBuffer | TypedArray | string;
data: ArrayBuffer | string;
hash?: SHAFamily;
}) => Promise<boolean>;
exportKey: <E extends ExportKeyFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
generateKeyPair: (curve?: ECDSACurve) => Promise<{
privateKey: ArrayBuffer;
publicKey: ArrayBuffer;
}>;
importPrivateKey: (privateKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
importPublicKey: (publicKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
sign: (privateKey: CryptoKey, data: ArrayBuffer | TypedArray | string, hash?: SHAFamily) => Promise<ArrayBuffer>;
verify: (publicKey: CryptoKey, { signature, data, hash }: {
signature: ArrayBuffer | TypedArray | string;
data: ArrayBuffer | string;
hash?: SHAFamily;
}) => Promise<boolean>;
exportKey: <E extends ExportKeyFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
};
export { ecdsa };
//#endregion
export { ecdsa };

@@ -1,88 +0,45 @@

import { getWebcryptoSubtle } from './index.mjs';
import { getWebcryptoSubtle } from "./index.mjs";
import { toBufferSource } from "./bytes.mjs";
//#region src/ecdsa.ts
const ecdsa = {
generateKeyPair: async (curve = "P-256") => {
const subtle = getWebcryptoSubtle();
const keyPair = await subtle.generateKey(
{
name: "ECDSA",
namedCurve: curve
},
true,
["sign", "verify"]
);
const privateKey = await subtle.exportKey("pkcs8", keyPair.privateKey);
const publicKey = await subtle.exportKey("spki", keyPair.publicKey);
return { privateKey, publicKey };
},
importPrivateKey: async (privateKey, curve, extractable = false) => {
if (typeof privateKey === "string") {
privateKey = new TextEncoder().encode(privateKey);
}
return await getWebcryptoSubtle().importKey(
"pkcs8",
privateKey,
{
name: "ECDSA",
namedCurve: curve
},
extractable,
["sign"]
);
},
importPublicKey: async (publicKey, curve, extractable = false) => {
if (typeof publicKey === "string") {
publicKey = new TextEncoder().encode(publicKey);
}
return await getWebcryptoSubtle().importKey(
"spki",
publicKey,
{
name: "ECDSA",
namedCurve: curve
},
extractable,
["verify"]
);
},
sign: async (privateKey, data, hash = "SHA-256") => {
if (typeof data === "string") {
data = new TextEncoder().encode(data);
}
const signature = await getWebcryptoSubtle().sign(
{
name: "ECDSA",
hash: { name: hash }
},
privateKey,
data
);
return signature;
},
verify: async (publicKey, {
signature,
data,
hash = "SHA-256"
}) => {
if (typeof signature === "string") {
signature = new TextEncoder().encode(signature);
}
if (typeof data === "string") {
data = new TextEncoder().encode(data);
}
return await getWebcryptoSubtle().verify(
{
name: "ECDSA",
hash: { name: hash }
},
publicKey,
signature,
data
);
},
exportKey: async (key, format) => {
return await getWebcryptoSubtle().exportKey(format, key);
}
generateKeyPair: async (curve = "P-256") => {
const subtle = getWebcryptoSubtle();
const keyPair = await subtle.generateKey({
name: "ECDSA",
namedCurve: curve
}, true, ["sign", "verify"]);
return {
privateKey: await subtle.exportKey("pkcs8", keyPair.privateKey),
publicKey: await subtle.exportKey("spki", keyPair.publicKey)
};
},
importPrivateKey: async (privateKey, curve, extractable = false) => {
return await getWebcryptoSubtle().importKey("pkcs8", toBufferSource(privateKey), {
name: "ECDSA",
namedCurve: curve
}, extractable, ["sign"]);
},
importPublicKey: async (publicKey, curve, extractable = false) => {
return await getWebcryptoSubtle().importKey("spki", toBufferSource(publicKey), {
name: "ECDSA",
namedCurve: curve
}, extractable, ["verify"]);
},
sign: async (privateKey, data, hash = "SHA-256") => {
return await getWebcryptoSubtle().sign({
name: "ECDSA",
hash: { name: hash }
}, privateKey, toBufferSource(data));
},
verify: async (publicKey, { signature, data, hash = "SHA-256" }) => {
return await getWebcryptoSubtle().verify({
name: "ECDSA",
hash: { name: hash }
}, publicKey, toBufferSource(signature), toBufferSource(data));
},
exportKey: async (key, format) => {
return await getWebcryptoSubtle().exportKey(format, key);
}
};
//#endregion
export { ecdsa };

@@ -1,31 +0,19 @@

'use strict';
const base64 = require('./base64.cjs');
const index = require('./index.cjs');
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_index = require("./index.cjs");
const require_bytes = require("./bytes.cjs");
const require_base64 = require("./base64.cjs");
//#region src/hash.ts
function createHash(algorithm, encoding) {
return {
digest: async (input) => {
const encoder = new TextEncoder();
const data = typeof input === "string" ? encoder.encode(input) : input;
const hashBuffer = await index.getWebcryptoSubtle().digest(algorithm, data);
if (encoding === "hex") {
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
return hashHex;
}
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") {
if (encoding.includes("url")) {
return base64.base64Url.encode(hashBuffer, {
padding: encoding !== "base64urlnopad"
});
}
const hashBase64 = base64.base64.encode(hashBuffer);
return hashBase64;
}
return hashBuffer;
}
};
return { digest: async (input) => {
const data = require_bytes.toBufferSource(input);
const hashBuffer = await require_index.getWebcryptoSubtle().digest(algorithm, data);
if (encoding === "hex") return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") {
if (encoding.includes("url")) return require_base64.base64Url.encode(hashBuffer, { padding: encoding !== "base64urlnopad" });
return require_base64.base64.encode(hashBuffer);
}
return hashBuffer;
} };
}
//#endregion
exports.createHash = createHash;

@@ -1,7 +0,7 @@

import { E as EncodingFormat, S as SHAFamily, T as TypedArray } from './shared/utils.ecd028f7.cjs';
import { EncodingFormat, SHAFamily, TypedArray } from "./type.cjs";
//#region src/hash.d.ts
declare function createHash<Encoding extends EncodingFormat = "none">(algorithm: SHAFamily, encoding?: Encoding): {
digest: (input: string | ArrayBuffer | TypedArray) => Promise<Encoding extends "none" ? ArrayBuffer : string>;
digest: (input: string | ArrayBuffer | TypedArray) => Promise<Encoding extends "none" ? ArrayBuffer : string>;
};
export { createHash };
//#endregion
export { createHash };

@@ -1,7 +0,7 @@

import { E as EncodingFormat, S as SHAFamily, T as TypedArray } from './shared/utils.ecd028f7.mjs';
import { EncodingFormat, SHAFamily, TypedArray } from "./type.mjs";
//#region src/hash.d.ts
declare function createHash<Encoding extends EncodingFormat = "none">(algorithm: SHAFamily, encoding?: Encoding): {
digest: (input: string | ArrayBuffer | TypedArray) => Promise<Encoding extends "none" ? ArrayBuffer : string>;
digest: (input: string | ArrayBuffer | TypedArray) => Promise<Encoding extends "none" ? ArrayBuffer : string>;
};
export { createHash };
//#endregion
export { createHash };

@@ -1,29 +0,18 @@

import { base64Url, base64 } from './base64.mjs';
import { getWebcryptoSubtle } from './index.mjs';
import { getWebcryptoSubtle } from "./index.mjs";
import { toBufferSource } from "./bytes.mjs";
import { base64, base64Url } from "./base64.mjs";
//#region src/hash.ts
function createHash(algorithm, encoding) {
return {
digest: async (input) => {
const encoder = new TextEncoder();
const data = typeof input === "string" ? encoder.encode(input) : input;
const hashBuffer = await getWebcryptoSubtle().digest(algorithm, data);
if (encoding === "hex") {
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
return hashHex;
}
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") {
if (encoding.includes("url")) {
return base64Url.encode(hashBuffer, {
padding: encoding !== "base64urlnopad"
});
}
const hashBase64 = base64.encode(hashBuffer);
return hashBase64;
}
return hashBuffer;
}
};
return { digest: async (input) => {
const data = toBufferSource(input);
const hashBuffer = await getWebcryptoSubtle().digest(algorithm, data);
if (encoding === "hex") return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") {
if (encoding.includes("url")) return base64Url.encode(hashBuffer, { padding: encoding !== "base64urlnopad" });
return base64.encode(hashBuffer);
}
return hashBuffer;
} };
}
//#endregion
export { createHash };

@@ -1,40 +0,22 @@

'use strict';
const hexadecimal = "0123456789abcdef";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_bytes = require("./bytes.cjs");
let _noble_hashes_utils_js = require("@noble/hashes/utils.js");
//#region src/hex.ts
const toBytes = (data) => (0, _noble_hashes_utils_js.hexToBytes)(data);
const hex = {
encode: (data) => {
if (typeof data === "string") {
data = new TextEncoder().encode(data);
}
if (data.byteLength === 0) {
return "";
}
const buffer = new Uint8Array(data);
let result = "";
for (const byte of buffer) {
result += byte.toString(16).padStart(2, "0");
}
return result;
},
decode: (data) => {
if (!data) {
return "";
}
if (typeof data === "string") {
if (data.length % 2 !== 0) {
throw new Error("Invalid hexadecimal string");
}
if (!new RegExp(`^[${hexadecimal}]+$`).test(data)) {
throw new Error("Invalid hexadecimal string");
}
const result = new Uint8Array(data.length / 2);
for (let i = 0; i < data.length; i += 2) {
result[i / 2] = parseInt(data.slice(i, i + 2), 16);
}
return new TextDecoder().decode(result);
}
return new TextDecoder().decode(data);
}
encode: (data) => {
const buffer = require_bytes.toUint8Array(data);
if (buffer.byteLength === 0) return "";
let result = "";
for (const byte of buffer) result += byte.toString(16).padStart(2, "0");
return result;
},
decode: (data) => {
if (!data) return "";
if (typeof data === "string") return new TextDecoder().decode(toBytes(data));
return new TextDecoder().decode(data);
},
toBytes
};
//#endregion
exports.hex = hex;

@@ -1,8 +0,9 @@

import { T as TypedArray } from './shared/utils.ecd028f7.cjs';
import { TypedArray, Uint8Array_ } from "./type.cjs";
//#region src/hex.d.ts
declare const hex: {
encode: (data: string | ArrayBuffer | TypedArray) => string;
decode: (data: string | ArrayBuffer | TypedArray) => string;
encode: (data: string | ArrayBuffer | TypedArray) => string;
decode: (data: string | ArrayBuffer | TypedArray) => string;
toBytes: (data: string) => Uint8Array_;
};
export { hex };
//#endregion
export { hex };

@@ -1,8 +0,9 @@

import { T as TypedArray } from './shared/utils.ecd028f7.mjs';
import { TypedArray, Uint8Array_ } from "./type.mjs";
//#region src/hex.d.ts
declare const hex: {
encode: (data: string | ArrayBuffer | TypedArray) => string;
decode: (data: string | ArrayBuffer | TypedArray) => string;
encode: (data: string | ArrayBuffer | TypedArray) => string;
decode: (data: string | ArrayBuffer | TypedArray) => string;
toBytes: (data: string) => Uint8Array_;
};
export { hex };
//#endregion
export { hex };

@@ -1,38 +0,21 @@

const hexadecimal = "0123456789abcdef";
import { toUint8Array } from "./bytes.mjs";
import { hexToBytes } from "@noble/hashes/utils.js";
//#region src/hex.ts
const toBytes = (data) => hexToBytes(data);
const hex = {
encode: (data) => {
if (typeof data === "string") {
data = new TextEncoder().encode(data);
}
if (data.byteLength === 0) {
return "";
}
const buffer = new Uint8Array(data);
let result = "";
for (const byte of buffer) {
result += byte.toString(16).padStart(2, "0");
}
return result;
},
decode: (data) => {
if (!data) {
return "";
}
if (typeof data === "string") {
if (data.length % 2 !== 0) {
throw new Error("Invalid hexadecimal string");
}
if (!new RegExp(`^[${hexadecimal}]+$`).test(data)) {
throw new Error("Invalid hexadecimal string");
}
const result = new Uint8Array(data.length / 2);
for (let i = 0; i < data.length; i += 2) {
result[i / 2] = parseInt(data.slice(i, i + 2), 16);
}
return new TextDecoder().decode(result);
}
return new TextDecoder().decode(data);
}
encode: (data) => {
const buffer = toUint8Array(data);
if (buffer.byteLength === 0) return "";
let result = "";
for (const byte of buffer) result += byte.toString(16).padStart(2, "0");
return result;
},
decode: (data) => {
if (!data) return "";
if (typeof data === "string") return new TextDecoder().decode(toBytes(data));
return new TextDecoder().decode(data);
},
toBytes
};
//#endregion
export { hex };

@@ -1,58 +0,33 @@

'use strict';
const hex = require('./hex.cjs');
const base64 = require('./base64.cjs');
const index = require('./index.cjs');
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_index = require("./index.cjs");
const require_bytes = require("./bytes.cjs");
const require_base64 = require("./base64.cjs");
const require_hex = require("./hex.cjs");
//#region src/hmac.ts
const createHMAC = (algorithm = "SHA-256", encoding = "none") => {
const hmac = {
importKey: async (key, keyUsage) => {
return index.getWebcryptoSubtle().importKey(
"raw",
typeof key === "string" ? new TextEncoder().encode(key) : key,
{ name: "HMAC", hash: { name: algorithm } },
false,
[keyUsage]
);
},
sign: async (hmacKey, data) => {
if (typeof hmacKey === "string") {
hmacKey = await hmac.importKey(hmacKey, "sign");
}
const signature = await index.getWebcryptoSubtle().sign(
"HMAC",
hmacKey,
typeof data === "string" ? new TextEncoder().encode(data) : data
);
if (encoding === "hex") {
return hex.hex.encode(signature);
}
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") {
return base64.base64Url.encode(signature, {
padding: encoding !== "base64urlnopad"
});
}
return signature;
},
verify: async (hmacKey, data, signature) => {
if (typeof hmacKey === "string") {
hmacKey = await hmac.importKey(hmacKey, "verify");
}
if (encoding === "hex") {
signature = hex.hex.decode(signature);
}
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") {
signature = await base64.base64.decode(signature);
}
return index.getWebcryptoSubtle().verify(
"HMAC",
hmacKey,
typeof signature === "string" ? new TextEncoder().encode(signature) : signature,
typeof data === "string" ? new TextEncoder().encode(data) : data
);
}
};
return hmac;
const hmac = {
importKey: async (key, keyUsage) => {
return require_index.getWebcryptoSubtle().importKey("raw", require_bytes.toBufferSource(key), {
name: "HMAC",
hash: { name: algorithm }
}, false, [keyUsage]);
},
sign: async (hmacKey, data) => {
if (typeof hmacKey === "string") hmacKey = await hmac.importKey(hmacKey, "sign");
const signature = await require_index.getWebcryptoSubtle().sign("HMAC", hmacKey, require_bytes.toBufferSource(data));
if (encoding === "hex") return require_hex.hex.encode(signature);
if (encoding === "base64") return require_base64.base64.encode(signature);
if (encoding === "base64url" || encoding === "base64urlnopad") return require_base64.base64Url.encode(signature, { padding: encoding !== "base64urlnopad" });
return signature;
},
verify: async (hmacKey, data, signature) => {
if (typeof hmacKey === "string") hmacKey = await hmac.importKey(hmacKey, "verify");
if (encoding === "hex") signature = typeof signature === "string" ? require_hex.hex.toBytes(signature) : signature;
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") signature = await require_base64.base64.decode(signature);
return require_index.getWebcryptoSubtle().verify("HMAC", hmacKey, require_bytes.toBufferSource(signature), require_bytes.toBufferSource(data));
}
};
return hmac;
};
//#endregion
exports.createHMAC = createHMAC;

@@ -1,9 +0,9 @@

import { E as EncodingFormat, S as SHAFamily, T as TypedArray } from './shared/utils.ecd028f7.cjs';
import { EncodingFormat, SHAFamily, TypedArray } from "./type.cjs";
//#region src/hmac.d.ts
declare const createHMAC: <E extends EncodingFormat = "none">(algorithm?: SHAFamily, encoding?: E) => {
importKey: (key: string | ArrayBuffer | TypedArray, keyUsage: "sign" | "verify") => Promise<CryptoKey>;
sign: (hmacKey: string | CryptoKey, data: string | ArrayBuffer | TypedArray) => Promise<E extends "none" ? ArrayBuffer : string>;
verify: (hmacKey: CryptoKey | string, data: string | ArrayBuffer | TypedArray, signature: string | ArrayBuffer | TypedArray) => Promise<boolean>;
importKey: (key: string | ArrayBuffer | TypedArray, keyUsage: "sign" | "verify") => Promise<CryptoKey>;
sign: (hmacKey: string | CryptoKey, data: string | ArrayBuffer | TypedArray) => Promise<E extends "none" ? ArrayBuffer : string>;
verify: (hmacKey: CryptoKey | string, data: string | ArrayBuffer | TypedArray, signature: string | ArrayBuffer | TypedArray) => Promise<boolean>;
};
export { createHMAC };
//#endregion
export { createHMAC };

@@ -1,9 +0,9 @@

import { E as EncodingFormat, S as SHAFamily, T as TypedArray } from './shared/utils.ecd028f7.mjs';
import { EncodingFormat, SHAFamily, TypedArray } from "./type.mjs";
//#region src/hmac.d.ts
declare const createHMAC: <E extends EncodingFormat = "none">(algorithm?: SHAFamily, encoding?: E) => {
importKey: (key: string | ArrayBuffer | TypedArray, keyUsage: "sign" | "verify") => Promise<CryptoKey>;
sign: (hmacKey: string | CryptoKey, data: string | ArrayBuffer | TypedArray) => Promise<E extends "none" ? ArrayBuffer : string>;
verify: (hmacKey: CryptoKey | string, data: string | ArrayBuffer | TypedArray, signature: string | ArrayBuffer | TypedArray) => Promise<boolean>;
importKey: (key: string | ArrayBuffer | TypedArray, keyUsage: "sign" | "verify") => Promise<CryptoKey>;
sign: (hmacKey: string | CryptoKey, data: string | ArrayBuffer | TypedArray) => Promise<E extends "none" ? ArrayBuffer : string>;
verify: (hmacKey: CryptoKey | string, data: string | ArrayBuffer | TypedArray, signature: string | ArrayBuffer | TypedArray) => Promise<boolean>;
};
export { createHMAC };
//#endregion
export { createHMAC };

@@ -1,56 +0,32 @@

import { hex } from './hex.mjs';
import { base64Url, base64 } from './base64.mjs';
import { getWebcryptoSubtle } from './index.mjs';
import { getWebcryptoSubtle } from "./index.mjs";
import { toBufferSource } from "./bytes.mjs";
import { base64, base64Url } from "./base64.mjs";
import { hex } from "./hex.mjs";
//#region src/hmac.ts
const createHMAC = (algorithm = "SHA-256", encoding = "none") => {
const hmac = {
importKey: async (key, keyUsage) => {
return getWebcryptoSubtle().importKey(
"raw",
typeof key === "string" ? new TextEncoder().encode(key) : key,
{ name: "HMAC", hash: { name: algorithm } },
false,
[keyUsage]
);
},
sign: async (hmacKey, data) => {
if (typeof hmacKey === "string") {
hmacKey = await hmac.importKey(hmacKey, "sign");
}
const signature = await getWebcryptoSubtle().sign(
"HMAC",
hmacKey,
typeof data === "string" ? new TextEncoder().encode(data) : data
);
if (encoding === "hex") {
return hex.encode(signature);
}
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") {
return base64Url.encode(signature, {
padding: encoding !== "base64urlnopad"
});
}
return signature;
},
verify: async (hmacKey, data, signature) => {
if (typeof hmacKey === "string") {
hmacKey = await hmac.importKey(hmacKey, "verify");
}
if (encoding === "hex") {
signature = hex.decode(signature);
}
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") {
signature = await base64.decode(signature);
}
return getWebcryptoSubtle().verify(
"HMAC",
hmacKey,
typeof signature === "string" ? new TextEncoder().encode(signature) : signature,
typeof data === "string" ? new TextEncoder().encode(data) : data
);
}
};
return hmac;
const hmac = {
importKey: async (key, keyUsage) => {
return getWebcryptoSubtle().importKey("raw", toBufferSource(key), {
name: "HMAC",
hash: { name: algorithm }
}, false, [keyUsage]);
},
sign: async (hmacKey, data) => {
if (typeof hmacKey === "string") hmacKey = await hmac.importKey(hmacKey, "sign");
const signature = await getWebcryptoSubtle().sign("HMAC", hmacKey, toBufferSource(data));
if (encoding === "hex") return hex.encode(signature);
if (encoding === "base64") return base64.encode(signature);
if (encoding === "base64url" || encoding === "base64urlnopad") return base64Url.encode(signature, { padding: encoding !== "base64urlnopad" });
return signature;
},
verify: async (hmacKey, data, signature) => {
if (typeof hmacKey === "string") hmacKey = await hmac.importKey(hmacKey, "verify");
if (encoding === "hex") signature = typeof signature === "string" ? hex.toBytes(signature) : signature;
if (encoding === "base64" || encoding === "base64url" || encoding === "base64urlnopad") signature = await base64.decode(signature);
return getWebcryptoSubtle().verify("HMAC", hmacKey, toBufferSource(signature), toBufferSource(data));
}
};
return hmac;
};
//#endregion
export { createHMAC };

@@ -1,10 +0,9 @@

'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#region src/index.ts
function getWebcryptoSubtle() {
const cr = typeof globalThis !== "undefined" && globalThis.crypto;
if (cr && typeof cr.subtle === "object" && cr.subtle != null)
return cr.subtle;
throw new Error("crypto.subtle must be defined");
const cr = typeof globalThis !== "undefined" && globalThis.crypto;
if (cr && typeof cr.subtle === "object" && cr.subtle != null) return cr.subtle;
throw new Error("crypto.subtle must be defined");
}
//#endregion
exports.getWebcryptoSubtle = getWebcryptoSubtle;

@@ -0,3 +1,4 @@

//#region src/index.d.ts
declare function getWebcryptoSubtle(): SubtleCrypto;
export { getWebcryptoSubtle };
//#endregion
export { getWebcryptoSubtle };

@@ -0,3 +1,4 @@

//#region src/index.d.ts
declare function getWebcryptoSubtle(): SubtleCrypto;
export { getWebcryptoSubtle };
//#endregion
export { getWebcryptoSubtle };

@@ -0,8 +1,8 @@

//#region src/index.ts
function getWebcryptoSubtle() {
const cr = typeof globalThis !== "undefined" && globalThis.crypto;
if (cr && typeof cr.subtle === "object" && cr.subtle != null)
return cr.subtle;
throw new Error("crypto.subtle must be defined");
const cr = typeof globalThis !== "undefined" && globalThis.crypto;
if (cr && typeof cr.subtle === "object" && cr.subtle != null) return cr.subtle;
throw new Error("crypto.subtle must be defined");
}
//#endregion
export { getWebcryptoSubtle };

@@ -1,96 +0,87 @@

'use strict';
const base32 = require('./base32.cjs');
const hmac = require('./hmac.cjs');
require('./hex.cjs');
require('./base64.cjs');
require('./index.cjs');
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_base32 = require("./base32.cjs");
const require_hmac = require("./hmac.cjs");
//#region src/otp.ts
const defaultPeriod = 30;
const defaultDigits = 6;
/**
* loops over `expected.length` so timing never depends on input length
*
* @internal
*/
function constantTimeEqualOTP(input, expected) {
let difference = input.length ^ expected.length;
for (let i = 0; i < expected.length; i++) {
difference |= input.charCodeAt(i) ^ expected.charCodeAt(i);
}
return difference === 0;
let difference = input.length ^ expected.length;
for (let i = 0; i < expected.length; i++) difference |= input.charCodeAt(i) ^ expected.charCodeAt(i);
return difference === 0;
}
async function generateHOTP(secret, {
counter,
digits,
hash = "SHA-1"
}) {
const _digits = digits ?? defaultDigits;
if (_digits < 1 || _digits > 8) {
throw new TypeError("Digits must be between 1 and 8");
}
const buffer = new ArrayBuffer(8);
new DataView(buffer).setBigUint64(0, BigInt(counter), false);
const bytes = new Uint8Array(buffer);
const hmacResult = new Uint8Array(await hmac.createHMAC(hash).sign(secret, bytes));
const offset = hmacResult[hmacResult.length - 1] & 15;
const truncated = (hmacResult[offset] & 127) << 24 | (hmacResult[offset + 1] & 255) << 16 | (hmacResult[offset + 2] & 255) << 8 | hmacResult[offset + 3] & 255;
const otp = truncated % 10 ** _digits;
return otp.toString().padStart(_digits, "0");
async function generateHOTP(secret, { counter, digits, hash = "SHA-1" }) {
const _digits = digits ?? defaultDigits;
if (_digits < 1 || _digits > 8) throw new TypeError("Digits must be between 1 and 8");
const buffer = /* @__PURE__ */ new ArrayBuffer(8);
new DataView(buffer).setBigUint64(0, BigInt(counter), false);
const bytes = new Uint8Array(buffer);
const hmacResult = new Uint8Array(await require_hmac.createHMAC(hash).sign(secret, bytes));
const offset = hmacResult[hmacResult.length - 1] & 15;
return (((hmacResult[offset] & 127) << 24 | (hmacResult[offset + 1] & 255) << 16 | (hmacResult[offset + 2] & 255) << 8 | hmacResult[offset + 3] & 255) % 10 ** _digits).toString().padStart(_digits, "0");
}
async function generateTOTP(secret, options) {
const digits = options?.digits ?? defaultDigits;
const period = options?.period ?? defaultPeriod;
const milliseconds = period * 1e3;
const counter = Math.floor(Date.now() / milliseconds);
return await generateHOTP(secret, { counter, digits, hash: options?.hash });
const digits = options?.digits ?? defaultDigits;
const milliseconds = (options?.period ?? defaultPeriod) * 1e3;
return await generateHOTP(secret, {
counter: Math.floor(Date.now() / milliseconds),
digits,
hash: options?.hash
});
}
async function verifyTOTP(otp, {
window = 1,
digits = defaultDigits,
secret,
period = defaultPeriod
}) {
const milliseconds = period * 1e3;
const counter = Math.floor(Date.now() / milliseconds);
let matched = false;
for (let i = -window; i <= window; i++) {
const generatedOTP = await generateHOTP(secret, {
counter: counter + i,
digits
});
matched = constantTimeEqualOTP(otp, generatedOTP) || matched;
}
return matched;
async function verifyTOTP(otp, { window = 1, digits = defaultDigits, secret, period = defaultPeriod }) {
const milliseconds = period * 1e3;
const counter = Math.floor(Date.now() / milliseconds);
let matched = false;
for (let i = -window; i <= window; i++) matched = constantTimeEqualOTP(otp, await generateHOTP(secret, {
counter: counter + i,
digits
})) || matched;
return matched;
}
function generateQRCode({
issuer,
account,
secret,
digits = defaultDigits,
period = defaultPeriod
}) {
const encodedIssuer = encodeURIComponent(issuer);
const encodedAccountName = encodeURIComponent(account);
const baseURI = `otpauth://totp/${encodedIssuer}:${encodedAccountName}`;
const params = new URLSearchParams({
secret: base32.base32.encode(secret, {
padding: false
}),
issuer
});
if (digits !== void 0) {
params.set("digits", digits.toString());
}
if (period !== void 0) {
params.set("period", period.toString());
}
return `${baseURI}?${params.toString()}`;
/**
* Generate a QR code URL for the OTP secret
*/
function generateQRCode({ issuer, account, secret, digits = defaultDigits, period = defaultPeriod }) {
const baseURI = `otpauth://totp/${encodeURIComponent(issuer)}:${encodeURIComponent(account)}`;
const params = new URLSearchParams({
secret: require_base32.base32.encode(secret, { padding: false }),
issuer
});
if (digits !== void 0) params.set("digits", digits.toString());
if (period !== void 0) params.set("period", period.toString());
return `${baseURI}?${params.toString()}`;
}
const createOTP = (secret, opts) => {
const digits = opts?.digits ?? defaultDigits;
const period = opts?.period ?? defaultPeriod;
return {
hotp: (counter) => generateHOTP(secret, { counter, digits }),
totp: () => generateTOTP(secret, { digits, period }),
verify: (otp, options) => verifyTOTP(otp, { secret, digits, period, ...options }),
url: (issuer, account) => generateQRCode({ issuer, account, secret, digits, period })
};
const digits = opts?.digits ?? defaultDigits;
const period = opts?.period ?? defaultPeriod;
return {
hotp: (counter) => generateHOTP(secret, {
counter,
digits
}),
totp: () => generateTOTP(secret, {
digits,
period
}),
verify: (otp, options) => verifyTOTP(otp, {
secret,
digits,
period,
...options
}),
url: (issuer, account) => generateQRCode({
issuer,
account,
secret,
digits,
period
})
};
};
//#endregion
exports.createOTP = createOTP;

@@ -0,13 +1,14 @@

//#region src/otp.d.ts
declare const createOTP: (secret: string, opts?: {
digits?: number;
period?: number;
digits?: number;
period?: number;
}) => {
hotp: (counter: number) => Promise<string>;
totp: () => Promise<string>;
verify: (otp: string, options?: {
window?: number;
}) => Promise<boolean>;
url: (issuer: string, account: string) => string;
hotp: (counter: number) => Promise<string>;
totp: () => Promise<string>;
verify: (otp: string, options?: {
window?: number;
}) => Promise<boolean>;
url: (issuer: string, account: string) => string;
};
export { createOTP };
//#endregion
export { createOTP };

@@ -0,13 +1,14 @@

//#region src/otp.d.ts
declare const createOTP: (secret: string, opts?: {
digits?: number;
period?: number;
digits?: number;
period?: number;
}) => {
hotp: (counter: number) => Promise<string>;
totp: () => Promise<string>;
verify: (otp: string, options?: {
window?: number;
}) => Promise<boolean>;
url: (issuer: string, account: string) => string;
hotp: (counter: number) => Promise<string>;
totp: () => Promise<string>;
verify: (otp: string, options?: {
window?: number;
}) => Promise<boolean>;
url: (issuer: string, account: string) => string;
};
export { createOTP };
//#endregion
export { createOTP };

@@ -1,94 +0,86 @@

import { base32 } from './base32.mjs';
import { createHMAC } from './hmac.mjs';
import './hex.mjs';
import './base64.mjs';
import './index.mjs';
import { base32 } from "./base32.mjs";
import { createHMAC } from "./hmac.mjs";
//#region src/otp.ts
const defaultPeriod = 30;
const defaultDigits = 6;
/**
* loops over `expected.length` so timing never depends on input length
*
* @internal
*/
function constantTimeEqualOTP(input, expected) {
let difference = input.length ^ expected.length;
for (let i = 0; i < expected.length; i++) {
difference |= input.charCodeAt(i) ^ expected.charCodeAt(i);
}
return difference === 0;
let difference = input.length ^ expected.length;
for (let i = 0; i < expected.length; i++) difference |= input.charCodeAt(i) ^ expected.charCodeAt(i);
return difference === 0;
}
async function generateHOTP(secret, {
counter,
digits,
hash = "SHA-1"
}) {
const _digits = digits ?? defaultDigits;
if (_digits < 1 || _digits > 8) {
throw new TypeError("Digits must be between 1 and 8");
}
const buffer = new ArrayBuffer(8);
new DataView(buffer).setBigUint64(0, BigInt(counter), false);
const bytes = new Uint8Array(buffer);
const hmacResult = new Uint8Array(await createHMAC(hash).sign(secret, bytes));
const offset = hmacResult[hmacResult.length - 1] & 15;
const truncated = (hmacResult[offset] & 127) << 24 | (hmacResult[offset + 1] & 255) << 16 | (hmacResult[offset + 2] & 255) << 8 | hmacResult[offset + 3] & 255;
const otp = truncated % 10 ** _digits;
return otp.toString().padStart(_digits, "0");
async function generateHOTP(secret, { counter, digits, hash = "SHA-1" }) {
const _digits = digits ?? defaultDigits;
if (_digits < 1 || _digits > 8) throw new TypeError("Digits must be between 1 and 8");
const buffer = /* @__PURE__ */ new ArrayBuffer(8);
new DataView(buffer).setBigUint64(0, BigInt(counter), false);
const bytes = new Uint8Array(buffer);
const hmacResult = new Uint8Array(await createHMAC(hash).sign(secret, bytes));
const offset = hmacResult[hmacResult.length - 1] & 15;
return (((hmacResult[offset] & 127) << 24 | (hmacResult[offset + 1] & 255) << 16 | (hmacResult[offset + 2] & 255) << 8 | hmacResult[offset + 3] & 255) % 10 ** _digits).toString().padStart(_digits, "0");
}
async function generateTOTP(secret, options) {
const digits = options?.digits ?? defaultDigits;
const period = options?.period ?? defaultPeriod;
const milliseconds = period * 1e3;
const counter = Math.floor(Date.now() / milliseconds);
return await generateHOTP(secret, { counter, digits, hash: options?.hash });
const digits = options?.digits ?? defaultDigits;
const milliseconds = (options?.period ?? defaultPeriod) * 1e3;
return await generateHOTP(secret, {
counter: Math.floor(Date.now() / milliseconds),
digits,
hash: options?.hash
});
}
async function verifyTOTP(otp, {
window = 1,
digits = defaultDigits,
secret,
period = defaultPeriod
}) {
const milliseconds = period * 1e3;
const counter = Math.floor(Date.now() / milliseconds);
let matched = false;
for (let i = -window; i <= window; i++) {
const generatedOTP = await generateHOTP(secret, {
counter: counter + i,
digits
});
matched = constantTimeEqualOTP(otp, generatedOTP) || matched;
}
return matched;
async function verifyTOTP(otp, { window = 1, digits = defaultDigits, secret, period = defaultPeriod }) {
const milliseconds = period * 1e3;
const counter = Math.floor(Date.now() / milliseconds);
let matched = false;
for (let i = -window; i <= window; i++) matched = constantTimeEqualOTP(otp, await generateHOTP(secret, {
counter: counter + i,
digits
})) || matched;
return matched;
}
function generateQRCode({
issuer,
account,
secret,
digits = defaultDigits,
period = defaultPeriod
}) {
const encodedIssuer = encodeURIComponent(issuer);
const encodedAccountName = encodeURIComponent(account);
const baseURI = `otpauth://totp/${encodedIssuer}:${encodedAccountName}`;
const params = new URLSearchParams({
secret: base32.encode(secret, {
padding: false
}),
issuer
});
if (digits !== void 0) {
params.set("digits", digits.toString());
}
if (period !== void 0) {
params.set("period", period.toString());
}
return `${baseURI}?${params.toString()}`;
/**
* Generate a QR code URL for the OTP secret
*/
function generateQRCode({ issuer, account, secret, digits = defaultDigits, period = defaultPeriod }) {
const baseURI = `otpauth://totp/${encodeURIComponent(issuer)}:${encodeURIComponent(account)}`;
const params = new URLSearchParams({
secret: base32.encode(secret, { padding: false }),
issuer
});
if (digits !== void 0) params.set("digits", digits.toString());
if (period !== void 0) params.set("period", period.toString());
return `${baseURI}?${params.toString()}`;
}
const createOTP = (secret, opts) => {
const digits = opts?.digits ?? defaultDigits;
const period = opts?.period ?? defaultPeriod;
return {
hotp: (counter) => generateHOTP(secret, { counter, digits }),
totp: () => generateTOTP(secret, { digits, period }),
verify: (otp, options) => verifyTOTP(otp, { secret, digits, period, ...options }),
url: (issuer, account) => generateQRCode({ issuer, account, secret, digits, period })
};
const digits = opts?.digits ?? defaultDigits;
const period = opts?.period ?? defaultPeriod;
return {
hotp: (counter) => generateHOTP(secret, {
counter,
digits
}),
totp: () => generateTOTP(secret, {
digits,
period
}),
verify: (otp, options) => verifyTOTP(otp, {
secret,
digits,
period,
...options
}),
url: (issuer, account) => generateQRCode({
issuer,
account,
secret,
digits,
period
})
};
};
//#endregion
export { createOTP };

@@ -1,36 +0,33 @@

'use strict';
const scrypt_js = require('@noble/hashes/scrypt.js');
const hex = require('./hex.cjs');
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_hex = require("./hex.cjs");
let _noble_hashes_scrypt_js = require("@noble/hashes/scrypt.js");
//#region src/password.ts
const config = {
N: 16384,
r: 16,
p: 1,
dkLen: 64
N: 16384,
r: 16,
p: 1,
dkLen: 64
};
async function generateKey(password, salt) {
return scrypt_js.scryptAsync(password.normalize("NFKC"), salt, {
N: config.N,
r: config.r,
p: config.p,
dkLen: config.dkLen,
maxmem: 128 * config.N * config.r * 2
});
return (0, _noble_hashes_scrypt_js.scryptAsync)(password.normalize("NFKC"), salt, {
N: config.N,
r: config.r,
p: config.p,
dkLen: config.dkLen,
maxmem: 128 * config.N * config.r * 2
});
}
async function hashPassword(password) {
const salt = hex.hex.encode(crypto.getRandomValues(new Uint8Array(16)));
const key = await generateKey(password, salt);
return `${salt}:${hex.hex.encode(key)}`;
const salt = require_hex.hex.encode(crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16)));
const key = await generateKey(password, salt);
return `${salt}:${require_hex.hex.encode(key)}`;
}
async function verifyPassword(hash, password) {
const [salt, key] = hash.split(":");
if (!salt || !key) {
throw new Error("Invalid password hash");
}
const targetKey = await generateKey(password, salt);
return hex.hex.encode(targetKey) === key;
const [salt, key] = hash.split(":");
if (!salt || !key) throw new Error("Invalid password hash");
const targetKey = await generateKey(password, salt);
return require_hex.hex.encode(targetKey) === key;
}
//#endregion
exports.hashPassword = hashPassword;
exports.verifyPassword = verifyPassword;

@@ -0,4 +1,5 @@

//#region src/password.d.ts
declare function hashPassword(password: string): Promise<string>;
declare function verifyPassword(hash: string, password: string): Promise<boolean>;
export { hashPassword, verifyPassword };
//#endregion
export { hashPassword, verifyPassword };

@@ -0,4 +1,5 @@

//#region src/password.d.ts
declare function hashPassword(password: string): Promise<string>;
declare function verifyPassword(hash: string, password: string): Promise<boolean>;
export { hashPassword, verifyPassword };
//#endregion
export { hashPassword, verifyPassword };

@@ -1,33 +0,31 @@

import { scryptAsync } from '@noble/hashes/scrypt.js';
import { hex } from './hex.mjs';
import { hex } from "./hex.mjs";
import { scryptAsync } from "@noble/hashes/scrypt.js";
//#region src/password.ts
const config = {
N: 16384,
r: 16,
p: 1,
dkLen: 64
N: 16384,
r: 16,
p: 1,
dkLen: 64
};
async function generateKey(password, salt) {
return scryptAsync(password.normalize("NFKC"), salt, {
N: config.N,
r: config.r,
p: config.p,
dkLen: config.dkLen,
maxmem: 128 * config.N * config.r * 2
});
return scryptAsync(password.normalize("NFKC"), salt, {
N: config.N,
r: config.r,
p: config.p,
dkLen: config.dkLen,
maxmem: 128 * config.N * config.r * 2
});
}
async function hashPassword(password) {
const salt = hex.encode(crypto.getRandomValues(new Uint8Array(16)));
const key = await generateKey(password, salt);
return `${salt}:${hex.encode(key)}`;
const salt = hex.encode(crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16)));
const key = await generateKey(password, salt);
return `${salt}:${hex.encode(key)}`;
}
async function verifyPassword(hash, password) {
const [salt, key] = hash.split(":");
if (!salt || !key) {
throw new Error("Invalid password hash");
}
const targetKey = await generateKey(password, salt);
return hex.encode(targetKey) === key;
const [salt, key] = hash.split(":");
if (!salt || !key) throw new Error("Invalid password hash");
const targetKey = await generateKey(password, salt);
return hex.encode(targetKey) === key;
}
//#endregion
export { hashPassword, verifyPassword };

@@ -1,47 +0,34 @@

'use strict';
const node_crypto = require('node:crypto');
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
let node_crypto = require("node:crypto");
//#region src/password.node.ts
const config = {
N: 16384,
r: 16,
p: 1,
dkLen: 64
N: 16384,
r: 16,
p: 1,
dkLen: 64
};
function generateKey(password, salt) {
return new Promise((resolve, reject) => {
node_crypto.scrypt(
password.normalize("NFKC"),
salt,
config.dkLen,
{
N: config.N,
r: config.r,
p: config.p,
maxmem: 128 * config.N * config.r * 2
},
(err, key) => {
if (err)
reject(err);
else
resolve(key);
}
);
});
return new Promise((resolve, reject) => {
(0, node_crypto.scrypt)(password.normalize("NFKC"), salt, config.dkLen, {
N: config.N,
r: config.r,
p: config.p,
maxmem: 128 * config.N * config.r * 2
}, (err, key) => {
if (err) reject(err);
else resolve(key);
});
});
}
async function hashPassword(password) {
const salt = node_crypto.randomBytes(16).toString("hex");
const key = await generateKey(password, salt);
return `${salt}:${key.toString("hex")}`;
const salt = (0, node_crypto.randomBytes)(16).toString("hex");
return `${salt}:${(await generateKey(password, salt)).toString("hex")}`;
}
async function verifyPassword(hash, password) {
const [salt, key] = hash.split(":");
if (!salt || !key) {
throw new Error("Invalid password hash");
}
const targetKey = await generateKey(password, salt);
return targetKey.toString("hex") === key;
const [salt, key] = hash.split(":");
if (!salt || !key) throw new Error("Invalid password hash");
return (await generateKey(password, salt)).toString("hex") === key;
}
//#endregion
exports.hashPassword = hashPassword;
exports.verifyPassword = verifyPassword;

@@ -0,4 +1,5 @@

//#region src/password.node.d.ts
declare function hashPassword(password: string): Promise<string>;
declare function verifyPassword(hash: string, password: string): Promise<boolean>;
export { hashPassword, verifyPassword };
//#endregion
export { hashPassword, verifyPassword };

@@ -0,4 +1,5 @@

//#region src/password.node.d.ts
declare function hashPassword(password: string): Promise<string>;
declare function verifyPassword(hash: string, password: string): Promise<boolean>;
export { hashPassword, verifyPassword };
//#endregion
export { hashPassword, verifyPassword };

@@ -1,44 +0,32 @@

import { randomBytes, scrypt } from 'node:crypto';
import { randomBytes, scrypt } from "node:crypto";
//#region src/password.node.ts
const config = {
N: 16384,
r: 16,
p: 1,
dkLen: 64
N: 16384,
r: 16,
p: 1,
dkLen: 64
};
function generateKey(password, salt) {
return new Promise((resolve, reject) => {
scrypt(
password.normalize("NFKC"),
salt,
config.dkLen,
{
N: config.N,
r: config.r,
p: config.p,
maxmem: 128 * config.N * config.r * 2
},
(err, key) => {
if (err)
reject(err);
else
resolve(key);
}
);
});
return new Promise((resolve, reject) => {
scrypt(password.normalize("NFKC"), salt, config.dkLen, {
N: config.N,
r: config.r,
p: config.p,
maxmem: 128 * config.N * config.r * 2
}, (err, key) => {
if (err) reject(err);
else resolve(key);
});
});
}
async function hashPassword(password) {
const salt = randomBytes(16).toString("hex");
const key = await generateKey(password, salt);
return `${salt}:${key.toString("hex")}`;
const salt = randomBytes(16).toString("hex");
return `${salt}:${(await generateKey(password, salt)).toString("hex")}`;
}
async function verifyPassword(hash, password) {
const [salt, key] = hash.split(":");
if (!salt || !key) {
throw new Error("Invalid password hash");
}
const targetKey = await generateKey(password, salt);
return targetKey.toString("hex") === key;
const [salt, key] = hash.split(":");
if (!salt || !key) throw new Error("Invalid password hash");
return (await generateKey(password, salt)).toString("hex") === key;
}
//#endregion
export { hashPassword, verifyPassword };

@@ -1,55 +0,42 @@

'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#region src/random.ts
function expandAlphabet(alphabet) {
switch (alphabet) {
case "a-z":
return "abcdefghijklmnopqrstuvwxyz";
case "A-Z":
return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
case "0-9":
return "0123456789";
case "-_":
return "-_";
default:
throw new Error(`Unsupported alphabet: ${alphabet}`);
}
switch (alphabet) {
case "a-z": return "abcdefghijklmnopqrstuvwxyz";
case "A-Z": return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
case "0-9": return "0123456789";
case "-_": return "-_";
default: throw new Error(`Unsupported alphabet: ${alphabet}`);
}
}
function createRandomStringGenerator(...baseAlphabets) {
const baseCharSet = baseAlphabets.map(expandAlphabet).join("");
if (baseCharSet.length === 0) {
throw new Error(
"No valid characters provided for random string generation."
);
}
const baseCharSetLength = baseCharSet.length;
return (length, ...alphabets) => {
if (length <= 0) {
throw new Error("Length must be a positive integer.");
}
let charSet = baseCharSet;
let charSetLength = baseCharSetLength;
if (alphabets.length > 0) {
charSet = alphabets.map(expandAlphabet).join("");
charSetLength = charSet.length;
}
const maxValid = Math.floor(256 / charSetLength) * charSetLength;
const buf = new Uint8Array(length * 2);
const bufLength = buf.length;
let result = "";
let bufIndex = bufLength;
let rand;
while (result.length < length) {
if (bufIndex >= bufLength) {
crypto.getRandomValues(buf);
bufIndex = 0;
}
rand = buf[bufIndex++];
if (rand < maxValid) {
result += charSet[rand % charSetLength];
}
}
return result;
};
const baseCharSet = baseAlphabets.map(expandAlphabet).join("");
if (baseCharSet.length === 0) throw new Error("No valid characters provided for random string generation.");
const baseCharSetLength = baseCharSet.length;
return (length, ...alphabets) => {
if (length <= 0) throw new Error("Length must be a positive integer.");
let charSet = baseCharSet;
let charSetLength = baseCharSetLength;
if (alphabets.length > 0) {
charSet = alphabets.map(expandAlphabet).join("");
charSetLength = charSet.length;
}
const maxValid = Math.floor(256 / charSetLength) * charSetLength;
const buf = new Uint8Array(length * 2);
const bufLength = buf.length;
let result = "";
let bufIndex = bufLength;
let rand;
while (result.length < length) {
if (bufIndex >= bufLength) {
crypto.getRandomValues(buf);
bufIndex = 0;
}
rand = buf[bufIndex++];
if (rand < maxValid) result += charSet[rand % charSetLength];
}
return result;
};
}
//#endregion
exports.createRandomStringGenerator = createRandomStringGenerator;

@@ -0,4 +1,5 @@

//#region src/random.d.ts
type Alphabet = "a-z" | "A-Z" | "0-9" | "-_";
declare function createRandomStringGenerator<A extends Alphabet>(...baseAlphabets: A[]): <SubA extends Alphabet>(length: number, ...alphabets: SubA[]) => string;
export { createRandomStringGenerator };
//#endregion
export { createRandomStringGenerator };

@@ -0,4 +1,5 @@

//#region src/random.d.ts
type Alphabet = "a-z" | "A-Z" | "0-9" | "-_";
declare function createRandomStringGenerator<A extends Alphabet>(...baseAlphabets: A[]): <SubA extends Alphabet>(length: number, ...alphabets: SubA[]) => string;
export { createRandomStringGenerator };
//#endregion
export { createRandomStringGenerator };

@@ -0,53 +1,41 @@

//#region src/random.ts
function expandAlphabet(alphabet) {
switch (alphabet) {
case "a-z":
return "abcdefghijklmnopqrstuvwxyz";
case "A-Z":
return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
case "0-9":
return "0123456789";
case "-_":
return "-_";
default:
throw new Error(`Unsupported alphabet: ${alphabet}`);
}
switch (alphabet) {
case "a-z": return "abcdefghijklmnopqrstuvwxyz";
case "A-Z": return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
case "0-9": return "0123456789";
case "-_": return "-_";
default: throw new Error(`Unsupported alphabet: ${alphabet}`);
}
}
function createRandomStringGenerator(...baseAlphabets) {
const baseCharSet = baseAlphabets.map(expandAlphabet).join("");
if (baseCharSet.length === 0) {
throw new Error(
"No valid characters provided for random string generation."
);
}
const baseCharSetLength = baseCharSet.length;
return (length, ...alphabets) => {
if (length <= 0) {
throw new Error("Length must be a positive integer.");
}
let charSet = baseCharSet;
let charSetLength = baseCharSetLength;
if (alphabets.length > 0) {
charSet = alphabets.map(expandAlphabet).join("");
charSetLength = charSet.length;
}
const maxValid = Math.floor(256 / charSetLength) * charSetLength;
const buf = new Uint8Array(length * 2);
const bufLength = buf.length;
let result = "";
let bufIndex = bufLength;
let rand;
while (result.length < length) {
if (bufIndex >= bufLength) {
crypto.getRandomValues(buf);
bufIndex = 0;
}
rand = buf[bufIndex++];
if (rand < maxValid) {
result += charSet[rand % charSetLength];
}
}
return result;
};
const baseCharSet = baseAlphabets.map(expandAlphabet).join("");
if (baseCharSet.length === 0) throw new Error("No valid characters provided for random string generation.");
const baseCharSetLength = baseCharSet.length;
return (length, ...alphabets) => {
if (length <= 0) throw new Error("Length must be a positive integer.");
let charSet = baseCharSet;
let charSetLength = baseCharSetLength;
if (alphabets.length > 0) {
charSet = alphabets.map(expandAlphabet).join("");
charSetLength = charSet.length;
}
const maxValid = Math.floor(256 / charSetLength) * charSetLength;
const buf = new Uint8Array(length * 2);
const bufLength = buf.length;
let result = "";
let bufIndex = bufLength;
let rand;
while (result.length < length) {
if (bufIndex >= bufLength) {
crypto.getRandomValues(buf);
bufIndex = 0;
}
rand = buf[bufIndex++];
if (rand < maxValid) result += charSet[rand % charSetLength];
}
return result;
};
}
//#endregion
export { createRandomStringGenerator };

@@ -1,76 +0,47 @@

'use strict';
const index = require('./index.cjs');
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_index = require("./index.cjs");
const require_bytes = require("./bytes.cjs");
//#region src/rsa.ts
const rsa = {
generateKeyPair: async (modulusLength = 2048, hash = "SHA-256") => {
return await index.getWebcryptoSubtle().generateKey(
{
name: "RSA-OAEP",
modulusLength,
publicExponent: new Uint8Array([1, 0, 1]),
hash: { name: hash }
},
true,
["encrypt", "decrypt"]
);
},
exportKey: async (key, format) => {
return await index.getWebcryptoSubtle().exportKey(format, key);
},
importKey: async (key, usage = "encrypt", hash = "SHA-256") => {
return await index.getWebcryptoSubtle().importKey(
"jwk",
key,
{
name: "RSA-OAEP",
hash: { name: hash }
},
true,
[usage]
);
},
encrypt: async (key, data) => {
const encodedData = typeof data === "string" ? new TextEncoder().encode(data) : data;
return await index.getWebcryptoSubtle().encrypt(
{ name: "RSA-OAEP" },
key,
encodedData
);
},
decrypt: async (key, data) => {
return await index.getWebcryptoSubtle().decrypt({ name: "RSA-OAEP" }, key, data);
},
sign: async (key, data, saltLength = 32) => {
const encodedData = typeof data === "string" ? new TextEncoder().encode(data) : data;
return await index.getWebcryptoSubtle().sign(
{
name: "RSA-PSS",
saltLength
},
key,
encodedData
);
},
verify: async (key, {
signature,
data,
saltLength = 32
}) => {
if (typeof signature === "string") {
signature = new TextEncoder().encode(signature);
}
const encodedData = typeof data === "string" ? new TextEncoder().encode(data) : data;
return await index.getWebcryptoSubtle().verify(
{
name: "RSA-PSS",
saltLength
},
key,
signature,
encodedData
);
}
generateKeyPair: async (modulusLength = 2048, hash = "SHA-256") => {
return await require_index.getWebcryptoSubtle().generateKey({
name: "RSA-OAEP",
modulusLength,
publicExponent: new Uint8Array([
1,
0,
1
]),
hash: { name: hash }
}, true, ["encrypt", "decrypt"]);
},
exportKey: async (key, format) => {
return await require_index.getWebcryptoSubtle().exportKey(format, key);
},
importKey: async (key, usage = "encrypt", hash = "SHA-256") => {
return await require_index.getWebcryptoSubtle().importKey("jwk", key, {
name: "RSA-OAEP",
hash: { name: hash }
}, true, [usage]);
},
encrypt: async (key, data) => {
return await require_index.getWebcryptoSubtle().encrypt({ name: "RSA-OAEP" }, key, require_bytes.toBufferSource(data));
},
decrypt: async (key, data) => {
return await require_index.getWebcryptoSubtle().decrypt({ name: "RSA-OAEP" }, key, require_bytes.toBufferSource(data));
},
sign: async (key, data, saltLength = 32) => {
return await require_index.getWebcryptoSubtle().sign({
name: "RSA-PSS",
saltLength
}, key, require_bytes.toBufferSource(data));
},
verify: async (key, { signature, data, saltLength = 32 }) => {
return await require_index.getWebcryptoSubtle().verify({
name: "RSA-PSS",
saltLength
}, key, require_bytes.toBufferSource(signature), require_bytes.toBufferSource(data));
}
};
//#endregion
exports.rsa = rsa;

@@ -0,16 +1,17 @@

//#region src/rsa.d.ts
type ExportFormat = "jwk" | "spki" | "pkcs8";
declare const rsa: {
generateKeyPair: (modulusLength?: 2048 | 4096, hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKeyPair>;
exportKey: <E extends ExportFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
importKey: (key: JsonWebKey, usage?: "encrypt" | "decrypt", hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKey>;
encrypt: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
decrypt: (key: CryptoKey, data: ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
sign: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView, saltLength?: number) => Promise<ArrayBuffer>;
verify: (key: CryptoKey, { signature, data, saltLength, }: {
signature: ArrayBuffer | ArrayBufferView | string;
data: string | ArrayBuffer | ArrayBufferView | string;
saltLength?: number;
}) => Promise<boolean>;
generateKeyPair: (modulusLength?: 2048 | 4096, hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKeyPair>;
exportKey: <E extends ExportFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
importKey: (key: JsonWebKey, usage?: "encrypt" | "decrypt", hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKey>;
encrypt: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
decrypt: (key: CryptoKey, data: ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
sign: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView, saltLength?: number) => Promise<ArrayBuffer>;
verify: (key: CryptoKey, { signature, data, saltLength }: {
signature: ArrayBuffer | ArrayBufferView | string;
data: string | ArrayBuffer | ArrayBufferView | string;
saltLength?: number;
}) => Promise<boolean>;
};
export { rsa };
//#endregion
export { rsa };

@@ -0,16 +1,17 @@

//#region src/rsa.d.ts
type ExportFormat = "jwk" | "spki" | "pkcs8";
declare const rsa: {
generateKeyPair: (modulusLength?: 2048 | 4096, hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKeyPair>;
exportKey: <E extends ExportFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
importKey: (key: JsonWebKey, usage?: "encrypt" | "decrypt", hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKey>;
encrypt: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
decrypt: (key: CryptoKey, data: ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
sign: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView, saltLength?: number) => Promise<ArrayBuffer>;
verify: (key: CryptoKey, { signature, data, saltLength, }: {
signature: ArrayBuffer | ArrayBufferView | string;
data: string | ArrayBuffer | ArrayBufferView | string;
saltLength?: number;
}) => Promise<boolean>;
generateKeyPair: (modulusLength?: 2048 | 4096, hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKeyPair>;
exportKey: <E extends ExportFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
importKey: (key: JsonWebKey, usage?: "encrypt" | "decrypt", hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKey>;
encrypt: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
decrypt: (key: CryptoKey, data: ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
sign: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView, saltLength?: number) => Promise<ArrayBuffer>;
verify: (key: CryptoKey, { signature, data, saltLength }: {
signature: ArrayBuffer | ArrayBufferView | string;
data: string | ArrayBuffer | ArrayBufferView | string;
saltLength?: number;
}) => Promise<boolean>;
};
export { rsa };
//#endregion
export { rsa };

@@ -1,74 +0,46 @@

import { getWebcryptoSubtle } from './index.mjs';
import { getWebcryptoSubtle } from "./index.mjs";
import { toBufferSource } from "./bytes.mjs";
//#region src/rsa.ts
const rsa = {
generateKeyPair: async (modulusLength = 2048, hash = "SHA-256") => {
return await getWebcryptoSubtle().generateKey(
{
name: "RSA-OAEP",
modulusLength,
publicExponent: new Uint8Array([1, 0, 1]),
hash: { name: hash }
},
true,
["encrypt", "decrypt"]
);
},
exportKey: async (key, format) => {
return await getWebcryptoSubtle().exportKey(format, key);
},
importKey: async (key, usage = "encrypt", hash = "SHA-256") => {
return await getWebcryptoSubtle().importKey(
"jwk",
key,
{
name: "RSA-OAEP",
hash: { name: hash }
},
true,
[usage]
);
},
encrypt: async (key, data) => {
const encodedData = typeof data === "string" ? new TextEncoder().encode(data) : data;
return await getWebcryptoSubtle().encrypt(
{ name: "RSA-OAEP" },
key,
encodedData
);
},
decrypt: async (key, data) => {
return await getWebcryptoSubtle().decrypt({ name: "RSA-OAEP" }, key, data);
},
sign: async (key, data, saltLength = 32) => {
const encodedData = typeof data === "string" ? new TextEncoder().encode(data) : data;
return await getWebcryptoSubtle().sign(
{
name: "RSA-PSS",
saltLength
},
key,
encodedData
);
},
verify: async (key, {
signature,
data,
saltLength = 32
}) => {
if (typeof signature === "string") {
signature = new TextEncoder().encode(signature);
}
const encodedData = typeof data === "string" ? new TextEncoder().encode(data) : data;
return await getWebcryptoSubtle().verify(
{
name: "RSA-PSS",
saltLength
},
key,
signature,
encodedData
);
}
generateKeyPair: async (modulusLength = 2048, hash = "SHA-256") => {
return await getWebcryptoSubtle().generateKey({
name: "RSA-OAEP",
modulusLength,
publicExponent: new Uint8Array([
1,
0,
1
]),
hash: { name: hash }
}, true, ["encrypt", "decrypt"]);
},
exportKey: async (key, format) => {
return await getWebcryptoSubtle().exportKey(format, key);
},
importKey: async (key, usage = "encrypt", hash = "SHA-256") => {
return await getWebcryptoSubtle().importKey("jwk", key, {
name: "RSA-OAEP",
hash: { name: hash }
}, true, [usage]);
},
encrypt: async (key, data) => {
return await getWebcryptoSubtle().encrypt({ name: "RSA-OAEP" }, key, toBufferSource(data));
},
decrypt: async (key, data) => {
return await getWebcryptoSubtle().decrypt({ name: "RSA-OAEP" }, key, toBufferSource(data));
},
sign: async (key, data, saltLength = 32) => {
return await getWebcryptoSubtle().sign({
name: "RSA-PSS",
saltLength
}, key, toBufferSource(data));
},
verify: async (key, { signature, data, saltLength = 32 }) => {
return await getWebcryptoSubtle().verify({
name: "RSA-PSS",
saltLength
}, key, toBufferSource(signature), toBufferSource(data));
}
};
//#endregion
export { rsa };
{
"name": "@better-auth/utils",
"version": "0.4.2",
"version": "0.4.3",
"license": "MIT",

@@ -25,4 +25,4 @@ "description": "A collection of utilities for better-auth",

"happy-dom": "^15.11.7",
"typescript": "^5.8.2",
"unbuild": "^2.0.0",
"tsdown": "0.22.9",
"typescript": "^6.0.3",
"vitest": "^2.1.8"

@@ -97,3 +97,3 @@ },

"typecheck": "tsc --noEmit",
"build": "unbuild",
"build": "tsdown",
"bump": "bumpp",

@@ -100,0 +100,0 @@ "lint:fix": "biome check . --write"

@@ -356,3 +356,3 @@ # Better Auth Utils

Decode hexadecimal-encoded data. Input can be a string or `ArrayBuffer`.
Decode hexadecimal-encoded data into a string. Input can be a string, `ArrayBuffer`, or `TypedArray`. Uppercase and lowercase hexadecimal are both accepted.

@@ -363,2 +363,10 @@ ```ts

### Converting to bytes
Convert a hexadecimal string into its raw bytes. Use this when the decoded value is binary data, such as a signature or key, rather than UTF-8 text.
```ts
const bytes = hex.toBytes("48656c6c6f"); // Uint8Array([72, 101, 108, 108, 111])
```
## Binary

@@ -365,0 +373,0 @@

import { T as TypedArray, U as Uint8Array_ } from './shared/utils.ecd028f7.js';
/**
* Base32 encoding and decoding utility.
*/
declare const base32: {
/**
* Encodes data into a Base32 string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32 encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32 string into a Uint8Array.
* @param data - The Base32 encoded string or ArrayBuffer/TypedArray.
* @returns The decoded Uint8Array.
*/
decode(data: string | ArrayBuffer | TypedArray): Uint8Array_;
};
/**
* Base32hex encoding and decoding utility.
*/
declare const base32hex: {
/**
* Encodes data into a Base32hex string.
* @param data - The data to encode (ArrayBuffer, TypedArray, or string).
* @param options - Encoding options.
* @returns The Base32hex encoded string.
*/
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
/**
* Decodes a Base32hex string into a Uint8Array.
* @param data - The Base32hex encoded string.
* @returns The decoded Uint8Array.
*/
decode(data: string): Uint8Array_;
};
export { base32, base32hex };
import { T as TypedArray } from './shared/utils.ecd028f7.js';
declare const base64: {
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string | ArrayBuffer | TypedArray): Uint8Array<ArrayBuffer>;
};
declare const base64Url: {
encode(data: ArrayBuffer | TypedArray | string, options?: {
padding?: boolean;
}): string;
decode(data: string): Uint8Array<ArrayBuffer>;
};
export { base64, base64Url };
type Encoding = "utf-8" | "utf-16" | "iso-8859-1";
type BinaryData = ArrayBuffer | ArrayBufferView;
declare const binary: {
decode: (data: BinaryData, encoding?: Encoding) => string;
encode: (input?: string) => Uint8Array;
};
export { binary };
import { a as ECDSACurve, T as TypedArray, S as SHAFamily, b as ExportKeyFormat } from './shared/utils.ecd028f7.js';
declare const ecdsa: {
generateKeyPair: (curve?: ECDSACurve) => Promise<{
privateKey: ArrayBuffer;
publicKey: ArrayBuffer;
}>;
importPrivateKey: (privateKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
importPublicKey: (publicKey: ArrayBuffer | TypedArray | string, curve: ECDSACurve, extractable?: boolean) => Promise<CryptoKey>;
sign: (privateKey: CryptoKey, data: ArrayBuffer | TypedArray | string, hash?: SHAFamily) => Promise<ArrayBuffer>;
verify: (publicKey: CryptoKey, { signature, data, hash, }: {
signature: ArrayBuffer | TypedArray | string;
data: ArrayBuffer | string;
hash?: SHAFamily;
}) => Promise<boolean>;
exportKey: <E extends ExportKeyFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
};
export { ecdsa };
import { E as EncodingFormat, S as SHAFamily, T as TypedArray } from './shared/utils.ecd028f7.js';
declare function createHash<Encoding extends EncodingFormat = "none">(algorithm: SHAFamily, encoding?: Encoding): {
digest: (input: string | ArrayBuffer | TypedArray) => Promise<Encoding extends "none" ? ArrayBuffer : string>;
};
export { createHash };
import { T as TypedArray } from './shared/utils.ecd028f7.js';
declare const hex: {
encode: (data: string | ArrayBuffer | TypedArray) => string;
decode: (data: string | ArrayBuffer | TypedArray) => string;
};
export { hex };
import { E as EncodingFormat, S as SHAFamily, T as TypedArray } from './shared/utils.ecd028f7.js';
declare const createHMAC: <E extends EncodingFormat = "none">(algorithm?: SHAFamily, encoding?: E) => {
importKey: (key: string | ArrayBuffer | TypedArray, keyUsage: "sign" | "verify") => Promise<CryptoKey>;
sign: (hmacKey: string | CryptoKey, data: string | ArrayBuffer | TypedArray) => Promise<E extends "none" ? ArrayBuffer : string>;
verify: (hmacKey: CryptoKey | string, data: string | ArrayBuffer | TypedArray, signature: string | ArrayBuffer | TypedArray) => Promise<boolean>;
};
export { createHMAC };
declare function getWebcryptoSubtle(): SubtleCrypto;
export { getWebcryptoSubtle };
declare const createOTP: (secret: string, opts?: {
digits?: number;
period?: number;
}) => {
hotp: (counter: number) => Promise<string>;
totp: () => Promise<string>;
verify: (otp: string, options?: {
window?: number;
}) => Promise<boolean>;
url: (issuer: string, account: string) => string;
};
export { createOTP };
declare function hashPassword(password: string): Promise<string>;
declare function verifyPassword(hash: string, password: string): Promise<boolean>;
export { hashPassword, verifyPassword };
declare function hashPassword(password: string): Promise<string>;
declare function verifyPassword(hash: string, password: string): Promise<boolean>;
export { hashPassword, verifyPassword };
type Alphabet = "a-z" | "A-Z" | "0-9" | "-_";
declare function createRandomStringGenerator<A extends Alphabet>(...baseAlphabets: A[]): <SubA extends Alphabet>(length: number, ...alphabets: SubA[]) => string;
export { createRandomStringGenerator };
type ExportFormat = "jwk" | "spki" | "pkcs8";
declare const rsa: {
generateKeyPair: (modulusLength?: 2048 | 4096, hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKeyPair>;
exportKey: <E extends ExportFormat>(key: CryptoKey, format: E) => Promise<E extends "jwk" ? JsonWebKey : ArrayBuffer>;
importKey: (key: JsonWebKey, usage?: "encrypt" | "decrypt", hash?: "SHA-256" | "SHA-384" | "SHA-512") => Promise<CryptoKey>;
encrypt: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
decrypt: (key: CryptoKey, data: ArrayBuffer | ArrayBufferView) => Promise<ArrayBuffer>;
sign: (key: CryptoKey, data: string | ArrayBuffer | ArrayBufferView, saltLength?: number) => Promise<ArrayBuffer>;
verify: (key: CryptoKey, { signature, data, saltLength, }: {
signature: ArrayBuffer | ArrayBufferView | string;
data: string | ArrayBuffer | ArrayBufferView | string;
saltLength?: number;
}) => Promise<boolean>;
};
export { rsa };
type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
/**
* Equivalent to `Uint8Array` before TypeScript 5.7, and `Uint8Array<ArrayBuffer>` in TypeScript 5.7
* and beyond.
*
* **Context**
*
* `Uint8Array` became a generic type in TypeScript 5.7, requiring types defined simply as
* `Uint8Array` to be refactored to `Uint8Array<ArrayBuffer>` starting in Deno 2.2. `Uint8Array` is
* _not_ generic in Deno 2.1.x and earlier, though, so this type helps bridge this gap.
*
* Inspired by Deno's std library:
*
* https://github.com/denoland/std/blob/b5a5fe4f96b91c1fe8dba5cc0270092dd11d3287/bytes/_types.ts#L11
*/
type Uint8Array_ = ReturnType<Uint8Array["slice"]>;
type SHAFamily = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";
type EncodingFormat = "hex" | "base64" | "base64url" | "base64urlnopad" | "none";
type ECDSACurve = "P-256" | "P-384" | "P-521";
type ExportKeyFormat = "jwk" | "spki" | "pkcs8" | "raw";
export type { EncodingFormat as E, SHAFamily as S, TypedArray as T, Uint8Array_ as U, ECDSACurve as a, ExportKeyFormat as b };
type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
/**
* Equivalent to `Uint8Array` before TypeScript 5.7, and `Uint8Array<ArrayBuffer>` in TypeScript 5.7
* and beyond.
*
* **Context**
*
* `Uint8Array` became a generic type in TypeScript 5.7, requiring types defined simply as
* `Uint8Array` to be refactored to `Uint8Array<ArrayBuffer>` starting in Deno 2.2. `Uint8Array` is
* _not_ generic in Deno 2.1.x and earlier, though, so this type helps bridge this gap.
*
* Inspired by Deno's std library:
*
* https://github.com/denoland/std/blob/b5a5fe4f96b91c1fe8dba5cc0270092dd11d3287/bytes/_types.ts#L11
*/
type Uint8Array_ = ReturnType<Uint8Array["slice"]>;
type SHAFamily = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";
type EncodingFormat = "hex" | "base64" | "base64url" | "base64urlnopad" | "none";
type ECDSACurve = "P-256" | "P-384" | "P-521";
type ExportKeyFormat = "jwk" | "spki" | "pkcs8" | "raw";
export type { EncodingFormat as E, SHAFamily as S, TypedArray as T, Uint8Array_ as U, ECDSACurve as a, ExportKeyFormat as b };
type TypedArray = Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
/**
* Equivalent to `Uint8Array` before TypeScript 5.7, and `Uint8Array<ArrayBuffer>` in TypeScript 5.7
* and beyond.
*
* **Context**
*
* `Uint8Array` became a generic type in TypeScript 5.7, requiring types defined simply as
* `Uint8Array` to be refactored to `Uint8Array<ArrayBuffer>` starting in Deno 2.2. `Uint8Array` is
* _not_ generic in Deno 2.1.x and earlier, though, so this type helps bridge this gap.
*
* Inspired by Deno's std library:
*
* https://github.com/denoland/std/blob/b5a5fe4f96b91c1fe8dba5cc0270092dd11d3287/bytes/_types.ts#L11
*/
type Uint8Array_ = ReturnType<Uint8Array["slice"]>;
type SHAFamily = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";
type EncodingFormat = "hex" | "base64" | "base64url" | "base64urlnopad" | "none";
type ECDSACurve = "P-256" | "P-384" | "P-521";
type ExportKeyFormat = "jwk" | "spki" | "pkcs8" | "raw";
export type { EncodingFormat as E, SHAFamily as S, TypedArray as T, Uint8Array_ as U, ECDSACurve as a, ExportKeyFormat as b };