@better-auth/utils
Advanced tools
| //#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; |
+34
-34
@@ -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 }; |
+34
-34
@@ -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 }; |
+107
-88
@@ -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 }; |
+55
-68
@@ -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; |
+12
-12
@@ -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 }; |
+12
-12
@@ -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 }; |
+54
-66
@@ -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 }; |
+8
-11
@@ -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 }; |
+7
-9
@@ -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 }; |
+43
-87
@@ -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; |
+17
-17
@@ -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 }; |
+17
-17
@@ -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 }; |
+42
-85
@@ -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 }; |
+16
-28
@@ -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; |
+5
-5
@@ -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 }; |
+5
-5
@@ -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 }; |
+15
-26
@@ -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 }; |
+19
-37
@@ -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; |
+7
-6
@@ -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 }; |
+7
-6
@@ -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 }; |
+18
-35
@@ -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 }; |
+30
-55
@@ -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; |
+7
-7
@@ -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 }; |
+7
-7
@@ -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 }; |
+29
-53
@@ -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 }; |
+6
-7
@@ -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; |
+3
-2
@@ -0,3 +1,4 @@ | ||
| //#region src/index.d.ts | ||
| declare function getWebcryptoSubtle(): SubtleCrypto; | ||
| export { getWebcryptoSubtle }; | ||
| //#endregion | ||
| export { getWebcryptoSubtle }; |
+3
-2
@@ -0,3 +1,4 @@ | ||
| //#region src/index.d.ts | ||
| declare function getWebcryptoSubtle(): SubtleCrypto; | ||
| export { getWebcryptoSubtle }; | ||
| //#endregion | ||
| export { getWebcryptoSubtle }; |
+5
-5
@@ -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 }; |
+75
-84
@@ -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; |
+11
-10
@@ -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 }; |
+11
-10
@@ -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 }; |
+74
-82
@@ -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 }; |
+23
-26
@@ -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 }; |
+22
-24
@@ -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 }; |
+24
-37
@@ -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 }; |
+23
-35
@@ -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 }; |
+37
-50
@@ -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 }; |
+36
-48
@@ -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 }; |
+44
-73
@@ -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; |
+14
-13
@@ -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 }; |
+14
-13
@@ -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 }; |
+43
-71
@@ -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 }; |
+4
-4
| { | ||
| "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" |
+9
-1
@@ -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 }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
393
2.08%69488
-10.02%58
-17.14%1176
-24.23%1
Infinity%