diff --git a/_tools/check_docs.ts b/_tools/check_docs.ts index 3549748ee127..823019eb5c3a 100644 --- a/_tools/check_docs.ts +++ b/_tools/check_docs.ts @@ -30,6 +30,7 @@ const ENTRY_POINTS = [ "../async/mod.ts", "../bytes/mod.ts", "../cli/mod.ts", + "../crypto/mod.ts", "../collections/mod.ts", "../data_structures/mod.ts", "../datetime/mod.ts", diff --git a/crypto/crypto.ts b/crypto/crypto.ts index 5b47db4ffc63..3e9e8f14ff7e 100644 --- a/crypto/crypto.ts +++ b/crypto/crypto.ts @@ -293,7 +293,8 @@ export type FNVAlgorithms = "FNV32" | "FNV32A" | "FNV64" | "FNV64A"; * @deprecated This will be removed in 1.0.0. Use * {@linkcode DIGEST_ALGORITHM_NAMES} instead. */ -export const wasmDigestAlgorithms = DIGEST_ALGORITHM_NAMES; +export const wasmDigestAlgorithms: typeof DIGEST_ALGORITHM_NAMES = + DIGEST_ALGORITHM_NAMES; /** * A digest algorithm name supported by std/crypto with a Wasm implementation. diff --git a/crypto/timing_safe_equal.ts b/crypto/timing_safe_equal.ts index 4b72d7b6e89a..1fa48f2b8b20 100644 --- a/crypto/timing_safe_equal.ts +++ b/crypto/timing_safe_equal.ts @@ -23,6 +23,7 @@ function toDataView( * {@link https://github.com/w3c/webcrypto/issues/270 | w3c/webcrypto#270}), but until * that time, `timingSafeEqual()` is provided: * + * @example Usage * ```ts * import { timingSafeEqual } from "@std/crypto/timing-safe-equal"; * import { assert } from "@std/assert/assert"; @@ -38,6 +39,10 @@ function toDataView( * * assert(timingSafeEqual(a, b)); * ``` + * + * @param a The first value to compare. + * @param b The second value to compare. + * @returns `true` if the values are equal, otherwise `false`. */ export function timingSafeEqual( a: ArrayBufferView | ArrayBufferLike | DataView, diff --git a/crypto/unstable_keystack.ts b/crypto/unstable_keystack.ts index 175edfb79389..93936dbcd698 100644 --- a/crypto/unstable_keystack.ts +++ b/crypto/unstable_keystack.ts @@ -74,17 +74,19 @@ async function compare(a: Data, b: Data): Promise { * * Data is signed as SHA256 HMAC. * - * This was inspired by {@link https://github.com/crypto-utils/keygrip/ | keygrip}. + * This was inspired by + * {@linkcode https://www.npmjs.com/package/keygrip | npm:keygrip}. * - * @example + * @example Usage * ```ts * import { KeyStack } from "@std/crypto/unstable-keystack"; + * import { assert } from "@std/assert/assert"; * * const keyStack = new KeyStack(["hello", "world"]); * const digest = await keyStack.sign("some data"); * * const rotatedStack = new KeyStack(["deno", "says", "hello", "world"]); - * await rotatedStack.verify("some data", digest); // true + * assert(await rotatedStack.verify("some data", digest)); * ``` */ export class KeyStack { @@ -98,18 +100,38 @@ export class KeyStack { return this.#cryptoKeys.get(key)!; } - /** Number of keys */ + /** + * Number of keys + * + * @example Usage + * ```ts + * import { KeyStack } from "@std/crypto/unstable-keystack"; + * import { assertEquals } from "@std/assert/assert-equals"; + * + * const keyStack = new KeyStack(["hello", "world"]); + * assertEquals(keyStack.length, 2); + * ``` + * + * @returns The length of the key stack. + */ get length(): number { return this.#keys.length; } /** - * A class which accepts an array of keys that are used to sign and verify - * data and allows easy key rotation without invalidation of previously signed - * data. + * Constructs a new instance. + * + * @example Usage + * ```ts + * import { KeyStack } from "@std/crypto/unstable-keystack"; + * import { assertInstanceOf } from "@std/assert/assert-instance-of"; + * + * const keyStack = new KeyStack(["hello", "world"]); + * assertInstanceOf(keyStack, KeyStack); + * ``` * * @param keys An iterable of keys, of which the index 0 will be used to sign - * data, but verification can happen against any key. + * data, but verification can happen against any key. */ constructor(keys: Iterable) { const values = Array.isArray(keys) ? keys : [...keys]; @@ -123,6 +145,21 @@ export class KeyStack { * Take `data` and return a SHA256 HMAC digest that uses the current 0 index * of the `keys` passed to the constructor. This digest is in the form of a * URL safe base64 encoded string. + * + * @example Usage + * ```ts + * import { KeyStack } from "@std/crypto/unstable-keystack"; + * import { assert } from "@std/assert/assert"; + * + * const keyStack = new KeyStack(["hello", "world"]); + * const digest = await keyStack.sign("some data"); + * + * const rotatedStack = new KeyStack(["deno", "says", "hello", "world"]); + * assert(await rotatedStack.verify("some data", digest)); + * ``` + * + * @param data The data to sign. + * @returns A URL safe base64 encoded string of the SHA256 HMAC digest. */ async sign(data: Data): Promise { const key = await this.#toCryptoKey(this.#keys[0]!); @@ -133,6 +170,22 @@ export class KeyStack { * Given `data` and a `digest`, verify that one of the `keys` provided the * constructor was used to generate the `digest`. Returns `true` if one of * the keys was used, otherwise `false`. + * + * @example Usage + * ```ts + * import { KeyStack } from "@std/crypto/unstable-keystack"; + * import { assert } from "@std/assert/assert"; + * + * const keyStack = new KeyStack(["hello", "world"]); + * const digest = await keyStack.sign("some data"); + * + * const rotatedStack = new KeyStack(["deno", "says", "hello", "world"]); + * assert(await rotatedStack.verify("some data", digest)); + * ``` + * + * @param data The data to verify. + * @param digest The digest to verify. + * @returns `true` if the digest was generated by one of the keys, otherwise */ async verify(data: Data, digest: string): Promise { return (await this.indexOf(data, digest)) > -1; @@ -142,6 +195,22 @@ export class KeyStack { * Given `data` and a `digest`, return the current index of the key in the * `keys` passed the constructor that was used to generate the digest. If no * key can be found, the method returns `-1`. + * + * @example Usage + * ```ts + * import { KeyStack } from "@std/crypto/unstable-keystack"; + * import { assertEquals } from "@std/assert/assert-equals"; + * + * const keyStack = new KeyStack(["hello", "world"]); + * const digest = await keyStack.sign("some data"); + * + * const rotatedStack = new KeyStack(["deno", "says", "hello", "world"]); + * assertEquals(await rotatedStack.indexOf("some data", digest), 2); + * ``` + * + * @param data The data to verify. + * @param digest The digest to verify. + * @returns The index of the key that was used to generate the digest. */ async indexOf(data: Data, digest: string): Promise { for (let i = 0; i < this.#keys.length; i++) { @@ -156,7 +225,20 @@ export class KeyStack { return -1; } - /** Custom output for {@linkcode Deno.inspect}. */ + /** + * Custom output for {@linkcode Deno.inspect}. + * + * @example Usage + * ```ts + * import { KeyStack } from "@std/crypto/unstable-keystack"; + * + * const keyStack = new KeyStack(["hello", "world"]); + * console.log(Deno.inspect(keyStack)); + * ``` + * + * @param inspect The inspect function. + * @returns A string representation of the key stack. + */ [Symbol.for("Deno.customInspect")]( inspect: (value: unknown) => string, ): string { @@ -164,7 +246,24 @@ export class KeyStack { return `${this.constructor.name} ${inspect({ length })}`; } - /** Custom output for Node's {@linkcode https://nodejs.org/api/util.html#utilinspectobject-options|util.inspect}. */ + /** + * Custom output for Node's + * {@linkcode https://nodejs.org/api/util.html#utilinspectobject-options | util.inspect}. + * + * @example Usage + * ```ts + * import { KeyStack } from "@std/crypto/unstable-keystack"; + * import { inspect } from "node:util"; + * + * const keyStack = new KeyStack(["hello", "world"]); + * console.log(inspect(keyStack)); + * ``` + * + * @param depth The depth to inspect. + * @param options The options to inspect. + * @param inspect The inspect function. + * @returns A string representation of the key stack. + */ [Symbol.for("nodejs.util.inspect.custom")]( depth: number, // deno-lint-ignore no-explicit-any