unjwt 0.8.4 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +3 -9
  2. package/dist/_chunks/{_import-key.mjs → algorithms.mjs} +194 -399
  3. package/dist/_chunks/{_codec-jwe.d.mts → codec-jwe.d.mts} +40 -9
  4. package/dist/_chunks/{_codec-jws.mjs → codec-jws.mjs} +133 -80
  5. package/dist/_chunks/cookie.mjs +50 -0
  6. package/dist/_chunks/digest.mjs +10 -3
  7. package/dist/_chunks/error.d.mts +103 -0
  8. package/dist/_chunks/export.mjs +97 -0
  9. package/dist/_chunks/index.d.mts +5 -103
  10. package/dist/_chunks/index2.d.mts +206 -12
  11. package/dist/_chunks/index3.d.mts +12 -109
  12. package/dist/_chunks/{jwe.d.mts → index4.d.mts} +2 -1
  13. package/dist/_chunks/{jws.d.mts → index5.d.mts} +2 -1
  14. package/dist/_chunks/index6.d.mts +113 -0
  15. package/dist/_chunks/jwe.mjs +205 -72
  16. package/dist/{core → _chunks}/jwk.mjs +210 -495
  17. package/dist/_chunks/jws.mjs +280 -193
  18. package/dist/_chunks/jwt.d.mts +2 -1
  19. package/dist/_chunks/{_jwt-internal.mjs → jwt.mjs} +110 -54
  20. package/dist/_chunks/libs/unsecure.d.mts +35 -25
  21. package/dist/_chunks/libs/unsecure.mjs +101 -268
  22. package/dist/_chunks/{_internal.d.mts → limits.d.mts} +1 -1
  23. package/dist/_chunks/payload.mjs +23 -0
  24. package/dist/_chunks/wrap.mjs +209 -0
  25. package/dist/adapters/elysia/index.d.mts +4 -4
  26. package/dist/adapters/elysia/index.mjs +4 -3
  27. package/dist/adapters/h3/index.d.mts +13 -13
  28. package/dist/adapters/h3/index.mjs +8 -11
  29. package/dist/adapters/h3v1/index.d.mts +5 -5
  30. package/dist/adapters/h3v1/index.mjs +6 -9
  31. package/dist/core/internal.mjs +1 -1
  32. package/dist/core/{jwe.d.mts → jwe/index.d.mts} +5 -4
  33. package/dist/core/jwe/index.mjs +5 -0
  34. package/dist/core/{jwk.d.mts → jwk/index.d.mts} +5 -4
  35. package/dist/core/jwk/index.mjs +7 -0
  36. package/dist/core/{jws.d.mts → jws/index.d.mts} +5 -4
  37. package/dist/core/jws/index.mjs +5 -0
  38. package/dist/dpop/index.d.mts +73 -0
  39. package/dist/dpop/index.mjs +296 -0
  40. package/dist/error.d.mts +3 -0
  41. package/dist/error.mjs +20 -0
  42. package/dist/index.d.mts +10 -9
  43. package/dist/index.mjs +7 -4
  44. package/dist/session/index.d.mts +4 -4
  45. package/dist/session/index.mjs +6 -47
  46. package/dist/utils/index.d.mts +7 -0
  47. package/dist/{core/utils → utils}/index.mjs +4 -3
  48. package/package.json +21 -10
  49. package/dist/_chunks/jwk.d.mts +0 -205
  50. package/dist/core/jwe.mjs +0 -5
  51. package/dist/core/jws.mjs +0 -5
  52. package/dist/core/utils/index.d.mts +0 -6
  53. /package/dist/_chunks/{_cookie-attributes.d.mts → cookie-attributes.d.mts} +0 -0
@@ -1,109 +1,12 @@
1
- import { BytesSource, DecodeOptions, DecodeReturnAs } from "./libs/unsecure.mjs";
2
- import { JWK, JWKSet, JWK_EC_Private, JWK_EC_Public, JWK_OKP_Private, JWK_OKP_Public, JWK_Private, JWK_Public, JWK_RSA_Private, JWK_RSA_Public, JWK_oct, JWSAlgorithm, KeyManagementAlgorithm } from "./index.mjs";
3
- import "./digest.mjs";
4
- import { ComputeJwtTimeClaimsOptions as ComputeJwtTimeClaimsOptions$1, ParsePayloadOptions, applyTypDefault, assertCritShape as assertCritShape$1, computeJwtTimeClaims as computeJwtTimeClaims$1, getPlaintextBytes as getPlaintextBytes$1, parsePayloadBytes, parsePayloadSegment, validateCriticalHeadersJWE as validateCriticalHeadersJWE$1, validateCriticalHeadersJWS as validateCriticalHeadersJWS$1 } from "./jwt.mjs";
5
- /**
6
- * Encode bytes or a UTF-8 string as base64url the way JOSE defines it
7
- * (RFC 7515 §2): URL-safe alphabet, no `=` padding, no line breaks.
8
- */
9
- export declare function base64UrlStringify(data: string | BytesSource): string;
10
- /**
11
- * Decode JOSE base64url (RFC 7515 §2). Strict: only the canonical, unpadded
12
- * encoding of a byte string is accepted — `=`, whitespace, characters outside
13
- * the URL-safe alphabet and set bits past the final byte are rejected, and a
14
- * `string` result must be valid UTF-8. The return type mirrors the input unless
15
- * `returnAs` is given. `{ loose: true }` drops what it cannot use instead of
16
- * throwing: meant for application data, never for token material.
17
- *
18
- * @throws {UnsecureError} `MALFORMED` unless `loose`; `INVALID_TYPE` for input that is neither text nor bytes
19
- */
20
- export declare function base64UrlParse<T extends DecodeReturnAs>(input: string | Uint8Array, options: DecodeOptions & {
21
- returnAs: T;
22
- }): T extends "string" ? string : Uint8Array<ArrayBuffer>;
23
- export declare function base64UrlParse(input: string, options?: DecodeOptions): string;
24
- export declare function base64UrlParse(input: Uint8Array, options?: DecodeOptions): Uint8Array<ArrayBuffer>;
25
- /** Encode bytes or a UTF-8 string as standard base64 (RFC 4648 §4), with `=` padding. */
26
- export declare function base64Stringify(data: string | BytesSource): string;
27
- /**
28
- * Decode standard base64 (RFC 4648 §4). Strict: the canonical encoding with its
29
- * `=` padding present. Otherwise the same contract as {@link base64UrlParse}.
30
- *
31
- * @throws {UnsecureError} `MALFORMED` unless `loose`; `INVALID_TYPE` for input that is neither text nor bytes
32
- */
33
- export declare function base64Parse<T extends DecodeReturnAs>(input: string | Uint8Array, options: DecodeOptions & {
34
- returnAs: T;
35
- }): T extends "string" ? string : Uint8Array<ArrayBuffer>;
36
- export declare function base64Parse(input: string, options?: DecodeOptions): string;
37
- export declare function base64Parse(input: Uint8Array, options?: DecodeOptions): Uint8Array<ArrayBuffer>;
38
- /** @deprecated Renamed to {@link base64UrlStringify} in v0.8.0; removed in v0.9.0. */
39
- export declare const base64UrlEncode: typeof base64UrlStringify;
40
- /** @deprecated Renamed to {@link base64UrlParse} in v0.8.0; removed in v0.9.0. */
41
- export declare const base64UrlDecode: typeof base64UrlParse;
42
- /** @deprecated Renamed to {@link base64Stringify} in v0.8.0; removed in v0.9.0. */
43
- export declare const base64Encode: typeof base64Stringify;
44
- /** @deprecated Renamed to {@link base64Parse} in v0.8.0; removed in v0.9.0. */
45
- export declare const base64Decode: typeof base64Parse;
46
- /** Concatenate multiple `Uint8Array`s into a single contiguous buffer. */
47
- export declare function concatUint8Arrays(...arrays: Readonly<Uint8Array<ArrayBuffer>[]>): Uint8Array<ArrayBuffer>;
48
- /** Wrap a value in an array; returns the array unchanged if already an array. */
49
- export declare function maybeArray<T>(item: T | T[]): T[];
50
- /** Whether `key` is a JWK whose `kty` this library models (`oct`, `RSA`, `EC`, `OKP`). */
51
- export declare function isJWK(key: unknown): key is JWK;
52
- /** Whether `key` is an object with a `keys` array. */
53
- export declare function isJWKSet(key: unknown): key is JWKSet;
54
- /** Asserts that `key` is a `CryptoKey`; throws `ERR_JWK_INVALID` otherwise. */
55
- export declare function assertCryptoKey(key: unknown): asserts key is CryptoKey;
56
- /** Whether `key` is a `CryptoKey`, checked via `Symbol.toStringTag` to work across realms. */
57
- export declare function isCryptoKey(key: unknown): key is CryptoKey;
58
- /** Whether `key` is a `CryptoKeyPair` of two CryptoKeys. */
59
- export declare const isCryptoKeyPair: (key: unknown) => key is CryptoKeyPair;
60
- /** Whether the JWK is symmetric (`oct`); its `k` is always secret. */
61
- export declare function isSymmetricJWK<T extends JWK>(key: T): key is Extract<T, JWK_oct>;
62
- export declare function isSymmetricJWK(key: unknown): key is JWK_oct;
63
- /** Whether the JWK is asymmetric (RSA, EC, OKP). */
64
- export declare function isAsymmetricJWK<T extends JWK>(key: T): key is Exclude<T, JWK_oct>;
65
- export declare function isAsymmetricJWK(key: unknown): key is Exclude<JWK, JWK_oct>;
66
- /**
67
- * Whether the JWK holds asymmetric private material (`d`). It is `false` for `oct` keys,
68
- * so `!isPrivateJWK(key)` is not a "safe to publish" check; use `isPublicJWK`.
69
- */
70
- export declare function isPrivateJWK<T extends JWK>(key: T): key is Extract<T, JWK_EC_Private | JWK_OKP_Private | JWK_RSA_Private>;
71
- export declare function isPrivateJWK(key: unknown): key is JWK_Private;
72
- /** Whether the JWK is an asymmetric public key without `d`: the "safe to publish" check. */
73
- export declare function isPublicJWK<T extends JWK>(key: T): key is Exclude<Extract<T, JWK_EC_Public | JWK_OKP_Public | JWK_RSA_Public>, JWK_Private>;
74
- export declare function isPublicJWK(key: unknown): key is JWK_Public;
75
- /** How a JWK Set's entries are read during algorithm inference. */
76
- export interface InferAlgorithmsOptions {
77
- /** Admit `oct` entries of a JWK Set. Defaults to `false`. */
78
- allowSymmetric?: boolean;
79
- }
80
- /**
81
- * Infer the JWS algorithms a key unambiguously supports, or `undefined` when it cannot
82
- * (raw bytes, ambiguous JWK, lookup function) and `options.algorithms` must be passed.
83
- */
84
- export declare function inferJWSAllowedAlgorithms(key: unknown, options?: InferAlgorithmsOptions): JWSAlgorithm[] | undefined;
85
- /**
86
- * Infer the JWE key management algorithms a key unambiguously supports, or `undefined`
87
- * when it cannot; a password string infers the PBES2 variants, raw bytes nothing.
88
- */
89
- export declare function inferJWEAllowedAlgorithms(key: unknown, options?: InferAlgorithmsOptions): KeyManagementAlgorithm[] | undefined;
90
- /** @deprecated Use `ParsePayloadOptions` from `unjwt/internal`; removed in v0.9.0. */
91
- export type DecodePayloadOptions = ParsePayloadOptions;
92
- /** @deprecated Use `ComputeJwtTimeClaimsOptions` from `unjwt/internal`; removed in v0.9.0. */
93
- export type ComputeJwtTimeClaimsOptions = ComputeJwtTimeClaimsOptions$1;
94
- /** @deprecated Use `applyTypDefault` from `unjwt/internal`; removed in v0.9.0. */
95
- export declare const applyTypCtyDefaults: typeof applyTypDefault;
96
- /** @deprecated Use `parsePayloadBytes` from `unjwt/internal`; removed in v0.9.0. */
97
- export declare const decodePayloadFromBytes: typeof parsePayloadBytes;
98
- /** @deprecated Use `parsePayloadSegment` from `unjwt/internal`; removed in v0.9.0. */
99
- export declare const decodePayloadFromB64UrlSegment: typeof parsePayloadSegment;
100
- /** @deprecated Use `getPlaintextBytes` from `unjwt/internal`; removed in v0.9.0. */
101
- export declare const getPlaintextBytes: typeof getPlaintextBytes$1;
102
- /** @deprecated Use `computeJwtTimeClaims` from `unjwt/internal`; removed in v0.9.0. */
103
- export declare const computeJwtTimeClaims: typeof computeJwtTimeClaims$1;
104
- /** @deprecated Use `validateCriticalHeadersJWS` from `unjwt/internal`; removed in v0.9.0. */
105
- export declare const validateCriticalHeadersJWS: typeof validateCriticalHeadersJWS$1;
106
- /** @deprecated Use `validateCriticalHeadersJWE` from `unjwt/internal`; removed in v0.9.0. */
107
- export declare const validateCriticalHeadersJWE: typeof validateCriticalHeadersJWE$1;
108
- /** @deprecated Use `assertCritShape` from `unjwt/internal`; removed in v0.9.0. */
109
- export declare const assertCritShape: typeof assertCritShape$1;
1
+ import { JWK } from "./index.mjs";
2
+ import { DigestHash } from "./digest.mjs";
3
+ /** Hash functions RFC 7638 §3.4 leaves open to the application. */
4
+ export type ThumbprintHash = DigestHash;
5
+ /**
6
+ * The base64url JWK Thumbprint of a key (RFC 7638), over its required members only, so a
7
+ * public key and its private counterpart share one. `hash` defaults to `"SHA-256"`
8
+ * (RFC 7638 §3.4); a missing required member or unknown `kty` throws `ERR_JWK_INVALID`.
9
+ */
10
+ export declare function thumbprint(jwk: JWK, options?: {
11
+ hash?: ThumbprintHash;
12
+ }): Promise<string>;
@@ -1,5 +1,6 @@
1
+ import "./error.mjs";
1
2
  import { ContentEncryptionAlgorithm, JOSEPayload, JOSEPayloadMode, JWEDecryptJWK, JWEDecryptOptions, JWEDecryptResult, JWEEncryptJWK, JWEEncryptOptions, JWEFlattenedSerialization, JWEGeneralSerialization, JWEKeyLookup, JWEMultiDecryptKey, JWEMultiDecryptOptions, JWEMultiDecryptResult, JWEMultiEncryptOptions, JWEMultiRecipient, JWKSet, JWTClaims, KeyManagementAlgorithm, PayloadOf } from "./index.mjs";
2
- import "./_internal.mjs";
3
+ import "./limits.mjs";
3
4
  /**
4
5
  * Encrypt a payload to multiple recipients as JWE General JSON Serialization (RFC 7516 §7.2.1).
5
6
  * Each recipient's `alg` comes from `key.alg` (`ERR_JWE_RECIPIENT_ALG_INFERENCE` when absent);
@@ -1,5 +1,6 @@
1
+ import "./error.mjs";
1
2
  import { JOSEPayload, JOSEPayloadMode, JWKSet, JWSAlgorithm, JWSFlattenedSerialization, JWSGeneralSerialization, JWSKeyLookup, JWSMultiSignOptions, JWSMultiSigner, JWSMultiVerifyAllOptions, JWSMultiVerifyOptions, JWSMultiVerifyOutcome, JWSMultiVerifyResult, JWSSignJWK, JWSSignOptions, JWSVerifyJWK, JWSVerifyOptions, JWSVerifyResult, JWTClaims, PayloadOf } from "./index.mjs";
2
- import "./_internal.mjs";
3
+ import "./limits.mjs";
3
4
  /**
4
5
  * Signs a payload with multiple signers as a JWS General JSON Serialization (RFC 7515 §7.2.1).
5
6
  * Each signer's `alg` is inferred from its key when omitted (`ERR_JWS_SIGNER_ALG_INFERENCE`);
@@ -0,0 +1,113 @@
1
+ import "./libs/unsecure.mjs";
2
+ import "./error.mjs";
3
+ import { JWK, JWKSet, JWK_EC_Private, JWK_EC_Public, JWK_OKP_Private, JWK_OKP_Public, JWK_Private, JWK_Public, JWK_RSA_Private, JWK_RSA_Public, JWK_oct, JWSAlgorithm, KeyManagementAlgorithm } from "./index.mjs";
4
+ import "./digest.mjs";
5
+ import { ComputeJwtTimeClaimsOptions as ComputeJwtTimeClaimsOptions$1, ParsePayloadOptions, applyTypDefault, assertCritShape as assertCritShape$1, computeJwtTimeClaims as computeJwtTimeClaims$1, getPlaintextBytes as getPlaintextBytes$1, parsePayloadBytes, parsePayloadSegment, validateCriticalHeadersJWE as validateCriticalHeadersJWE$1, validateCriticalHeadersJWS as validateCriticalHeadersJWS$1 } from "./jwt.mjs";
6
+ /** Decoder output shape. `"bytes"` aliases `"uint8array"`. */
7
+ export type DecodeReturnAs = "string" | "uint8array" | "bytes";
8
+ export interface Base64ParseOptions {
9
+ /**
10
+ * Output shape: UTF-8 text, or the bytes themselves.
11
+ * @default "string"
12
+ */
13
+ returnAs?: DecodeReturnAs;
14
+ }
15
+ /** Encode bytes, or the UTF-8 bytes of a string, as unpadded base64url (RFC 7515 §2). */
16
+ export declare function base64UrlStringify(data: string | Uint8Array): string;
17
+ /** Encode bytes, or the UTF-8 bytes of a string, as padded standard base64 (RFC 4648 §4). */
18
+ export declare function base64Stringify(data: string | Uint8Array): string;
19
+ /**
20
+ * Decode unpadded base64url (RFC 7515 §2). Strict: only the canonical encoding of a byte string
21
+ * is accepted, so `=`, whitespace, characters outside the URL-safe alphabet and set bits past
22
+ * the final byte are rejected; a `string` result must be valid UTF-8.
23
+ *
24
+ * @throws {UnsecureError} `MALFORMED` for text that is not such an encoding; `INVALID_TYPE` for input that is not a string
25
+ */
26
+ export declare function base64UrlParse<T extends DecodeReturnAs>(text: string, options: Base64ParseOptions & {
27
+ returnAs: T;
28
+ }): T extends "string" ? string : Uint8Array<ArrayBuffer>;
29
+ export declare function base64UrlParse(text: string, options?: Base64ParseOptions): string;
30
+ /**
31
+ * Decode padded standard base64 (RFC 4648 §4). Strict: the canonical encoding with its `=` run
32
+ * present, no whitespace, no set bits past the final byte; a `string` result must be valid UTF-8.
33
+ *
34
+ * @throws {UnsecureError} `MALFORMED` for text that is not such an encoding; `INVALID_TYPE` for input that is not a string
35
+ */
36
+ export declare function base64Parse<T extends DecodeReturnAs>(text: string, options: Base64ParseOptions & {
37
+ returnAs: T;
38
+ }): T extends "string" ? string : Uint8Array<ArrayBuffer>;
39
+ export declare function base64Parse(text: string, options?: Base64ParseOptions): string;
40
+ /** @deprecated Renamed to {@link Base64ParseOptions}; removed in v0.9.0. */
41
+ export type DecodeOptions = Base64ParseOptions;
42
+ /** @deprecated Renamed to {@link base64UrlStringify} in v0.8.0; removed in v0.9.0. */
43
+ export declare const base64UrlEncode: typeof base64UrlStringify;
44
+ /** @deprecated Renamed to {@link base64UrlParse} in v0.8.0; removed in v0.9.0. */
45
+ export declare const base64UrlDecode: typeof base64UrlParse;
46
+ /** @deprecated Renamed to {@link base64Stringify} in v0.8.0; removed in v0.9.0. */
47
+ export declare const base64Encode: typeof base64Stringify;
48
+ /** @deprecated Renamed to {@link base64Parse} in v0.8.0; removed in v0.9.0. */
49
+ export declare const base64Decode: typeof base64Parse;
50
+ /** Concatenate multiple `Uint8Array`s into a single contiguous buffer. */
51
+ export declare function concatUint8Arrays(...arrays: Readonly<Uint8Array<ArrayBuffer>[]>): Uint8Array<ArrayBuffer>;
52
+ /** Wrap a value in an array; returns the array unchanged if already an array. */
53
+ export declare function maybeArray<T>(item: T | T[]): T[];
54
+ /** Whether `key` is a JWK whose `kty` this library models (`oct`, `RSA`, `EC`, `OKP`). */
55
+ export declare function isJWK(key: unknown): key is JWK;
56
+ /** Whether `key` is an object with a `keys` array. */
57
+ export declare function isJWKSet(key: unknown): key is JWKSet;
58
+ /** Asserts that `key` is a `CryptoKey`; throws `ERR_JWK_INVALID` otherwise. */
59
+ export declare function assertCryptoKey(key: unknown): asserts key is CryptoKey;
60
+ /** Whether `key` is a `CryptoKey`, checked via `Symbol.toStringTag` to work across realms. */
61
+ export declare function isCryptoKey(key: unknown): key is CryptoKey;
62
+ /** Whether `key` is a `CryptoKeyPair` of two CryptoKeys. */
63
+ export declare const isCryptoKeyPair: (key: unknown) => key is CryptoKeyPair;
64
+ /** Whether the JWK is symmetric (`oct`); its `k` is always secret. */
65
+ export declare function isSymmetricJWK<T extends JWK>(key: T): key is Extract<T, JWK_oct>;
66
+ export declare function isSymmetricJWK(key: unknown): key is JWK_oct;
67
+ /** Whether the JWK is asymmetric (RSA, EC, OKP). */
68
+ export declare function isAsymmetricJWK<T extends JWK>(key: T): key is Exclude<T, JWK_oct>;
69
+ export declare function isAsymmetricJWK(key: unknown): key is Exclude<JWK, JWK_oct>;
70
+ /**
71
+ * Whether the JWK holds asymmetric private material (`d`). It is `false` for `oct` keys,
72
+ * so `!isPrivateJWK(key)` is not a "safe to publish" check; use `isPublicJWK`.
73
+ */
74
+ export declare function isPrivateJWK<T extends JWK>(key: T): key is Extract<T, JWK_EC_Private | JWK_OKP_Private | JWK_RSA_Private>;
75
+ export declare function isPrivateJWK(key: unknown): key is JWK_Private;
76
+ /** Whether the JWK is an asymmetric public key without `d`: the "safe to publish" check. */
77
+ export declare function isPublicJWK<T extends JWK>(key: T): key is Exclude<Extract<T, JWK_EC_Public | JWK_OKP_Public | JWK_RSA_Public>, JWK_Private>;
78
+ export declare function isPublicJWK(key: unknown): key is JWK_Public;
79
+ /** How a JWK Set's entries are read during algorithm inference. */
80
+ export interface InferAlgorithmsOptions {
81
+ /** Admit `oct` entries of a JWK Set. Defaults to `false`. */
82
+ allowSymmetric?: boolean;
83
+ }
84
+ /**
85
+ * Infer the JWS algorithms a key unambiguously supports, or `undefined` when it cannot
86
+ * (raw bytes, ambiguous JWK, lookup function) and `options.algorithms` must be passed.
87
+ */
88
+ export declare function inferJWSAllowedAlgorithms(key: unknown, options?: InferAlgorithmsOptions): JWSAlgorithm[] | undefined;
89
+ /**
90
+ * Infer the JWE key management algorithms a key unambiguously supports, or `undefined`
91
+ * when it cannot; a password string infers the PBES2 variants, raw bytes nothing.
92
+ */
93
+ export declare function inferJWEAllowedAlgorithms(key: unknown, options?: InferAlgorithmsOptions): KeyManagementAlgorithm[] | undefined;
94
+ /** @deprecated Use `ParsePayloadOptions` from `unjwt/internal`; removed in v0.9.0. */
95
+ export type DecodePayloadOptions = ParsePayloadOptions;
96
+ /** @deprecated Use `ComputeJwtTimeClaimsOptions` from `unjwt/internal`; removed in v0.9.0. */
97
+ export type ComputeJwtTimeClaimsOptions = ComputeJwtTimeClaimsOptions$1;
98
+ /** @deprecated Use `applyTypDefault` from `unjwt/internal`; removed in v0.9.0. */
99
+ export declare const applyTypCtyDefaults: typeof applyTypDefault;
100
+ /** @deprecated Use `parsePayloadBytes` from `unjwt/internal`; removed in v0.9.0. */
101
+ export declare const decodePayloadFromBytes: typeof parsePayloadBytes;
102
+ /** @deprecated Use `parsePayloadSegment` from `unjwt/internal`; removed in v0.9.0. */
103
+ export declare const decodePayloadFromB64UrlSegment: typeof parsePayloadSegment;
104
+ /** @deprecated Use `getPlaintextBytes` from `unjwt/internal`; removed in v0.9.0. */
105
+ export declare const getPlaintextBytes: typeof getPlaintextBytes$1;
106
+ /** @deprecated Use `computeJwtTimeClaims` from `unjwt/internal`; removed in v0.9.0. */
107
+ export declare const computeJwtTimeClaims: typeof computeJwtTimeClaims$1;
108
+ /** @deprecated Use `validateCriticalHeadersJWS` from `unjwt/internal`; removed in v0.9.0. */
109
+ export declare const validateCriticalHeadersJWS: typeof validateCriticalHeadersJWS$1;
110
+ /** @deprecated Use `validateCriticalHeadersJWE` from `unjwt/internal`; removed in v0.9.0. */
111
+ export declare const validateCriticalHeadersJWE: typeof validateCriticalHeadersJWE$1;
112
+ /** @deprecated Use `assertCritShape` from `unjwt/internal`; removed in v0.9.0. */
113
+ export declare const assertCritShape: typeof assertCritShape$1;
@@ -1,8 +1,117 @@
1
- import { sanitizeObjectCopy, secureRandomBytes, textEncoder } from "./libs/unsecure.mjs";
2
- import { JWTError, applyTypDefault, base64UrlStringify, computeJwtTimeClaims, getPlaintextBytes, isJWK, isJWKSet, validateCriticalHeadersJWE } from "./_jwt-internal.mjs";
3
- import { isContentEncryptionAlgorithm, isPBES2Algorithm } from "./digest.mjs";
4
- import { DEFAULT_PBES2_ITERATIONS, JWE_ALG_CTX, JWE_DIRECT_ALGS, asDecryptionError, asKeyLookupError, assertCompactToken, assertConsumerOptions, assertDirectKeyRole, assertEntryLimit, assertJWEAlgSupported, assertJWEEncSupported, assertJWKSetCandidates, assertNoZipOption, assertOptionEntry, assertPBES2Params, assertProducerCEK, assertProducerConfirmation, assertProducerCrit, assertProducerIV, assertProducerKeyHeaders, assertProtectedOnlyOption, assertSerializationObject, buildECDHAgreementParams, buildJWKSetFilter, buildUnwrapKeyOptions, checkAlgAllowed, checkJWEAlgSupported, checkJWEContentSegments, checkJWEDirectEncryptedKey, checkJWEEncAllowed, checkJWEEncSupported, checkJWEUnprotectedCrit, checkJWEZip, checkProtectedTyp, checkSerializationEntry, createPBES2Budget, decodeJWEPayload, decodeProtectedHeader, decodeSegment, decrypt as decrypt$1, encrypt as encrypt$1, encryptKey, exportReturnedCek, generateCEK, generateIV, getJWKsFromSet, importKey, isJWEAlgSupported, keyMatchesHeader, resolveKeyInput, resolveLimit, resolvePasswordKey, resolvePayloadMode, serializeProtectedHeader, validateClaimsIfJson } from "./_import-key.mjs";
5
- import { unwrapKey } from "../core/jwk.mjs";
1
+ import { secureRandomBytes, textEncoder } from "./libs/unsecure.mjs";
2
+ import { JWTError } from "../error.mjs";
3
+ import { applyTypDefault, base64UrlStringify, computeJwtTimeClaims, getPlaintextBytes, isCryptoKey, isJWK, isJWKSet, parsePayloadBytes, validateCriticalHeadersJWE } from "./jwt.mjs";
4
+ import { DEFAULT_PBES2_ITERATIONS, asDecryptionError, asKeyLookupError, assertCompactToken, assertConsumerOptions, assertDirectKeyRole, assertEntryLimit, assertJWEEncSupported, assertJWKSetCandidates, assertOptionEntry, assertPBES2Iterations, assertPBES2Params, assertProducerConfirmation, assertProducerCrit, assertProducerKeyHeaders, assertProtectedOnlyOption, assertSerializationObject, bitLengthCEK, bitLengthIV, bitLengthTag, buildECDHAgreementParams, buildJWKSetFilter, checkAlgAllowed, checkAlgSupported, checkJWEEncSupported, checkProtectedTyp, checkSerializationEntry, copyJsonObject, decodeProtectedHeader, decodeSegment, decrypt as decrypt$1, encrypt as encrypt$1, encryptKey, generateCEK, generateIV, getJWKsFromSet, importKey, keyMatchesHeader, resolveKeyInput, resolveLimit, resolvePasswordKey, serializeProtectedHeader } from "./algorithms.mjs";
5
+ import { inferJWEAllowedAlgorithms, isContentEncryptionAlgorithm, isKeyManagementAlgorithm, isPBES2Algorithm } from "./digest.mjs";
6
+ import { resolvePayloadMode, validateClaimsIfJson } from "./payload.mjs";
7
+ import { unwrapKey } from "./wrap.mjs";
8
+ const JWE_ALG_CTX = /* @__PURE__ */ Object.freeze({
9
+ infer: inferJWEAllowedAlgorithms,
10
+ octRoles: true,
11
+ errorCode: "ERR_JWE_ALG_NOT_ALLOWED",
12
+ label: "Key management algorithm",
13
+ op: "enc"
14
+ });
15
+ const JWE_DIRECT_ALGS = /* @__PURE__ */ new Set(["dir", "ECDH-ES"]);
16
+ function checkJWEAlgSupported(alg) {
17
+ return checkAlgSupported(alg, {
18
+ supported: isKeyManagementAlgorithm,
19
+ code: "ERR_JWE_ALG_NOT_ALLOWED",
20
+ label: "Key management algorithm",
21
+ role: "key management algorithm"
22
+ });
23
+ }
24
+ function isJWEAlgSupported(alg) {
25
+ return isKeyManagementAlgorithm(alg);
26
+ }
27
+ function assertJWEAlgSupported(alg) {
28
+ const error = checkJWEAlgSupported(alg);
29
+ if (error) throw error;
30
+ }
31
+ function checkJWEEncAllowed(enc, encryptionAlgorithms) {
32
+ if (encryptionAlgorithms === void 0 || encryptionAlgorithms.includes(enc)) return void 0;
33
+ return new JWTError(`Content encryption algorithm not allowed: ${enc}`, "ERR_JWE_ALG_NOT_ALLOWED");
34
+ }
35
+ function assertProducerCEK(cek, enc) {
36
+ if (cek === void 0) return;
37
+ const expected = bitLengthCEK(enc) >> 3;
38
+ if (!(cek instanceof Uint8Array) || cek.length !== expected) throw new JWTError(`"cek" must be ${expected} bytes for ${enc}.`, "ERR_INVALID_OPTION");
39
+ }
40
+ function assertProducerIV(iv, enc) {
41
+ if (iv === void 0) return;
42
+ const expected = bitLengthIV(enc) >> 3;
43
+ if (!(iv instanceof Uint8Array) || iv.length !== expected) throw new JWTError(`"contentEncryptionIV" must be ${expected} bytes for ${enc}.`, "ERR_INVALID_OPTION");
44
+ }
45
+ function checkJWEDirectEncryptedKey(alg, encryptedKey) {
46
+ if (!JWE_DIRECT_ALGS.has(alg) || !encryptedKey) return void 0;
47
+ return new JWTError(`Invalid JWE: Encrypted key must be empty for ${alg}.`, "ERR_JWE_INVALID");
48
+ }
49
+ function checkJWEContentSegments(enc, iv, tag) {
50
+ const ivBytes = bitLengthIV(enc) >> 3;
51
+ if (iv.length !== ivBytes) return new JWTError(`Invalid JWE: Initialization vector must be ${ivBytes} bytes for ${enc} (got ${iv.length}).`, "ERR_JWE_INVALID");
52
+ const tagBytes = bitLengthTag(enc) >> 3;
53
+ if (tag.length !== tagBytes) return new JWTError(`Invalid JWE: Authentication tag must be ${tagBytes} bytes for ${enc} (got ${tag.length}).`, "ERR_JWE_INVALID");
54
+ }
55
+ function checkJWEZip(header) {
56
+ if (!header || !Object.hasOwn(header, "zip")) return void 0;
57
+ return new JWTError("Invalid JWE: compression is not supported.", "ERR_JWE_INVALID");
58
+ }
59
+ function assertNoZipOption(header, tier) {
60
+ if (!header || !Object.hasOwn(header, "zip")) return;
61
+ throw new JWTError(`JWE compression ("zip") in the ${tier} header is not supported.`, "ERR_INVALID_OPTION");
62
+ }
63
+ function checkJWEUnprotectedCrit(header) {
64
+ if (!header || !Object.hasOwn(header, "crit")) return void 0;
65
+ return new JWTError("Invalid JWE: \"crit\" must be integrity protected.", "ERR_JWE_INVALID");
66
+ }
67
+ function createPBES2Budget(limit) {
68
+ let remaining = limit;
69
+ return { spend(attempt) {
70
+ const { alg, p2c } = attempt;
71
+ if (!alg.startsWith("PBES2")) return;
72
+ if (typeof p2c !== "number" || !(p2c > 0)) return;
73
+ assertPBES2Iterations(p2c, attempt);
74
+ if (p2c > remaining) throw new JWTError(`PBES2 iteration budget of ${limit} exhausted.`, "ERR_JWE_INVALID");
75
+ remaining -= p2c;
76
+ } };
77
+ }
78
+ const JWE_ENC_CEK_FORMAT = /* @__PURE__ */ Object.freeze({
79
+ "A128GCM": "cryptokey",
80
+ "A192GCM": "cryptokey",
81
+ "A256GCM": "cryptokey",
82
+ "A128CBC-HS256": "raw",
83
+ "A192CBC-HS384": "raw",
84
+ "A256CBC-HS512": "raw"
85
+ });
86
+ async function exportReturnedCek(cek) {
87
+ if (!isCryptoKey(cek)) return cek;
88
+ if (!cek.extractable) throw new JWTError("\"returnCek\" requires an extractable content encryption key.", "ERR_INVALID_OPTION");
89
+ return new Uint8Array(await crypto.subtle.exportKey("raw", cek));
90
+ }
91
+ function cekFormatForEnc(enc) {
92
+ return JWE_ENC_CEK_FORMAT[enc];
93
+ }
94
+ function buildUnwrapKeyOptions(header, algorithms, options) {
95
+ const { alg, enc } = algorithms;
96
+ const opts = {
97
+ alg,
98
+ enc,
99
+ format: cekFormatForEnc(enc),
100
+ keyUsage: options?.keyUsage || ["decrypt"]
101
+ };
102
+ if (header.iv) opts.iv = header.iv;
103
+ if (header.tag) opts.tag = header.tag;
104
+ if (header.p2s) opts.p2s = header.p2s;
105
+ if (header.p2c) opts.p2c = header.p2c;
106
+ if (header.epk) opts.epk = header.epk;
107
+ if (header.apu) opts.apu = header.apu;
108
+ if (header.apv) opts.apv = header.apv;
109
+ if (options?.unwrappedKeyAlgorithm) opts.unwrappedKeyAlgorithm = options.unwrappedKeyAlgorithm;
110
+ if (options?.extractable !== void 0) opts.extractable = options.extractable;
111
+ if (options?.minIterations !== void 0) opts.minIterations = options.minIterations;
112
+ if (options?.maxIterations !== void 0) opts.maxIterations = options.maxIterations;
113
+ return opts;
114
+ }
6
115
  function buildKeyManagementParams(alg, source) {
7
116
  const { keyManagementIV, p2s, p2c, ecdh } = source;
8
117
  const isPBES2 = alg.startsWith("PBES2");
@@ -62,6 +171,77 @@ async function unwrapAndDecrypt(alg, rawKeyMaterial, options) {
62
171
  throw asDecryptionError(err);
63
172
  }
64
173
  }
174
+ function decodeJWEPayload(plaintext, mode) {
175
+ return parsePayloadBytes(plaintext, {
176
+ payload: mode,
177
+ family: "JWE"
178
+ });
179
+ }
180
+ function _resolveRecipientAlg(key, index) {
181
+ if (!isJWK(key)) throw new JWTError(`Recipient[${index}] key is not a JWK.`, "ERR_JWE_RECIPIENT_ALG_INFERENCE");
182
+ const declared = key.alg;
183
+ if (!declared) throw new JWTError(`Cannot infer "alg" for recipient[${index}]: the JWK has no "alg" property.`, "ERR_JWE_RECIPIENT_ALG_INFERENCE");
184
+ const alg = key.kty === "oct" && isContentEncryptionAlgorithm(declared) ? "dir" : declared;
185
+ if (JWE_DIRECT_ALGS.has(alg)) throw new JWTError(`Recipient[${index}] "${alg}" allows a single recipient, use encrypt().`, "ERR_JWE_ALG_FORBIDDEN_IN_MULTI");
186
+ assertJWEAlgSupported(alg);
187
+ return alg;
188
+ }
189
+ function _buildPerRecipientHeader(recipient, alg, keyMgmtOut) {
190
+ const header = {};
191
+ if (recipient.key.kid) header.kid = recipient.key.kid;
192
+ const userHeader = copyJsonObject(recipient.header, {
193
+ code: "ERR_INVALID_OPTION",
194
+ message: "A recipient \"header\" must hold only JSON values."
195
+ });
196
+ if (userHeader) Object.assign(header, userHeader);
197
+ if (keyMgmtOut) Object.assign(header, keyMgmtOut);
198
+ header.alg = alg;
199
+ return header;
200
+ }
201
+ function _assertDisjointHeaders(protectedHeader, sharedUnprotected, recipientHeader) {
202
+ const seen = /* @__PURE__ */ new Set();
203
+ const check = (obj) => {
204
+ if (!obj) return;
205
+ for (const k of Object.keys(obj)) {
206
+ if (seen.has(k)) throw new JWTError(`Invalid JWE: header parameter "${k}" is set in more than one header.`, "ERR_JWE_HEADER_PARAMS_NOT_DISJOINT");
207
+ seen.add(k);
208
+ }
209
+ };
210
+ check(protectedHeader);
211
+ check(sharedUnprotected);
212
+ check(recipientHeader);
213
+ }
214
+ function _mergeHeaders(protectedHeader, sharedUnprotected, recipientHeader) {
215
+ const merged = { ...protectedHeader };
216
+ if (sharedUnprotected) Object.assign(merged, sharedUnprotected);
217
+ if (recipientHeader) Object.assign(merged, recipientHeader);
218
+ return merged;
219
+ }
220
+ function _normalizeSerialization(input) {
221
+ assertSerializationObject(input, "JWE");
222
+ if ("recipients" in input) {
223
+ if ("encrypted_key" in input || "header" in input) throw new JWTError("Invalid JWE JSON Serialization: \"recipients\" excludes top-level \"header\" and \"encrypted_key\".", "ERR_JWE_INVALID_SERIALIZATION");
224
+ return input;
225
+ }
226
+ const flattened = input;
227
+ const recipient = {};
228
+ if (flattened.header !== void 0) recipient.header = flattened.header;
229
+ if (flattened.encrypted_key !== void 0) recipient.encrypted_key = flattened.encrypted_key;
230
+ const general = {
231
+ recipients: [recipient],
232
+ iv: flattened.iv,
233
+ ciphertext: flattened.ciphertext,
234
+ tag: flattened.tag
235
+ };
236
+ if (flattened.protected !== void 0) general.protected = flattened.protected;
237
+ if (flattened.unprotected !== void 0) general.unprotected = flattened.unprotected;
238
+ if (flattened.aad !== void 0) general.aad = flattened.aad;
239
+ return general;
240
+ }
241
+ function _assertAADOption(aad) {
242
+ if (aad === void 0 || typeof aad === "string" || aad instanceof Uint8Array) return;
243
+ throw new JWTError("\"aad\" must be a string or a Uint8Array.", "ERR_INVALID_OPTION");
244
+ }
65
245
  async function encryptMulti(payload, recipients, options = {}) {
66
246
  if (!Array.isArray(recipients) || recipients.length === 0) throw new JWTError("encryptMulti requires at least one recipient.", "ERR_JWE_INVALID");
67
247
  assertOptionEntry(options, {
@@ -109,8 +289,14 @@ async function encryptMulti(payload, recipients, options = {}) {
109
289
  p2s: recipient.p2s,
110
290
  p2c: recipient.p2c
111
291
  });
112
- const userProtected = sanitizeObjectCopy(options.protectedHeader);
113
- const sharedUnprotected = sanitizeObjectCopy(options.sharedUnprotectedHeader);
292
+ const userProtected = copyJsonObject(options.protectedHeader, {
293
+ code: "ERR_INVALID_OPTION",
294
+ message: "\"protectedHeader\" must hold only JSON values."
295
+ });
296
+ const sharedUnprotected = copyJsonObject(options.sharedUnprotectedHeader, {
297
+ code: "ERR_INVALID_OPTION",
298
+ message: "\"sharedUnprotectedHeader\" must hold only JSON values."
299
+ });
114
300
  const protectedHeader = {};
115
301
  if (userProtected) Object.assign(protectedHeader, userProtected);
116
302
  protectedHeader.enc = enc;
@@ -179,7 +365,10 @@ async function decryptMulti(jwe, keyOrLookup, options = {}) {
179
365
  if (envelopeError) throw envelopeError;
180
366
  const protectedHeaderEncoded = general.protected ?? "";
181
367
  const protectedHeader = decodeProtectedHeader(protectedHeaderEncoded || void 0, "JWE");
182
- const sharedUnprotected = sanitizeObjectCopy(general.unprotected);
368
+ const sharedUnprotected = copyJsonObject(general.unprotected, {
369
+ code: "ERR_JWE_INVALID",
370
+ message: "Invalid JWE JSON Serialization: \"unprotected\" must hold only JSON values."
371
+ });
183
372
  const sharedError = checkJWEZip(protectedHeader) ?? checkJWEUnprotectedCrit(sharedUnprotected) ?? checkJWEZip(sharedUnprotected);
184
373
  if (sharedError) throw sharedError;
185
374
  _assertDisjointHeaders(protectedHeader, sharedUnprotected, void 0);
@@ -220,7 +409,10 @@ async function decryptMulti(jwe, keyOrLookup, options = {}) {
220
409
  continue;
221
410
  }
222
411
  const wireRecipient = general.recipients[i];
223
- const recipientHeader = sanitizeObjectCopy(wireRecipient.header);
412
+ const recipientHeader = copyJsonObject(wireRecipient.header, {
413
+ code: "ERR_JWE_INVALID",
414
+ message: "Invalid JWE JSON Serialization: a recipient \"header\" must hold only JSON values."
415
+ });
224
416
  const recipientError = checkJWEUnprotectedCrit(recipientHeader) ?? checkJWEZip(recipientHeader);
225
417
  if (recipientError) {
226
418
  lastError = recipientError;
@@ -335,68 +527,6 @@ function generalToFlattened(jwe) {
335
527
  if (recipient.encrypted_key !== void 0) flattened.encrypted_key = recipient.encrypted_key;
336
528
  return flattened;
337
529
  }
338
- function _resolveRecipientAlg(key, index) {
339
- if (!isJWK(key)) throw new JWTError(`Recipient[${index}] key is not a JWK.`, "ERR_JWE_RECIPIENT_ALG_INFERENCE");
340
- const declared = key.alg;
341
- if (!declared) throw new JWTError(`Cannot infer "alg" for recipient[${index}]: the JWK has no "alg" property.`, "ERR_JWE_RECIPIENT_ALG_INFERENCE");
342
- const alg = key.kty === "oct" && isContentEncryptionAlgorithm(declared) ? "dir" : declared;
343
- if (JWE_DIRECT_ALGS.has(alg)) throw new JWTError(`Recipient[${index}] "${alg}" allows a single recipient, use encrypt().`, "ERR_JWE_ALG_FORBIDDEN_IN_MULTI");
344
- assertJWEAlgSupported(alg);
345
- return alg;
346
- }
347
- function _buildPerRecipientHeader(recipient, alg, keyMgmtOut) {
348
- const header = {};
349
- if (recipient.key.kid) header.kid = recipient.key.kid;
350
- const userHeader = sanitizeObjectCopy(recipient.header);
351
- if (userHeader) Object.assign(header, userHeader);
352
- if (keyMgmtOut) Object.assign(header, keyMgmtOut);
353
- header.alg = alg;
354
- return header;
355
- }
356
- function _assertDisjointHeaders(protectedHeader, sharedUnprotected, recipientHeader) {
357
- const seen = /* @__PURE__ */ new Set();
358
- const check = (obj) => {
359
- if (!obj) return;
360
- for (const k of Object.keys(obj)) {
361
- if (seen.has(k)) throw new JWTError(`Invalid JWE: header parameter "${k}" is set in more than one header.`, "ERR_JWE_HEADER_PARAMS_NOT_DISJOINT");
362
- seen.add(k);
363
- }
364
- };
365
- check(protectedHeader);
366
- check(sharedUnprotected);
367
- check(recipientHeader);
368
- }
369
- function _mergeHeaders(protectedHeader, sharedUnprotected, recipientHeader) {
370
- const merged = { ...protectedHeader };
371
- if (sharedUnprotected) Object.assign(merged, sharedUnprotected);
372
- if (recipientHeader) Object.assign(merged, recipientHeader);
373
- return merged;
374
- }
375
- function _normalizeSerialization(input) {
376
- assertSerializationObject(input, "JWE");
377
- if ("recipients" in input) {
378
- if ("encrypted_key" in input || "header" in input) throw new JWTError("Invalid JWE JSON Serialization: \"recipients\" excludes top-level \"header\" and \"encrypted_key\".", "ERR_JWE_INVALID_SERIALIZATION");
379
- return input;
380
- }
381
- const flattened = input;
382
- const recipient = {};
383
- if (flattened.header !== void 0) recipient.header = flattened.header;
384
- if (flattened.encrypted_key !== void 0) recipient.encrypted_key = flattened.encrypted_key;
385
- const general = {
386
- recipients: [recipient],
387
- iv: flattened.iv,
388
- ciphertext: flattened.ciphertext,
389
- tag: flattened.tag
390
- };
391
- if (flattened.protected !== void 0) general.protected = flattened.protected;
392
- if (flattened.unprotected !== void 0) general.unprotected = flattened.unprotected;
393
- if (flattened.aad !== void 0) general.aad = flattened.aad;
394
- return general;
395
- }
396
- function _assertAADOption(aad) {
397
- if (aad === void 0 || typeof aad === "string" || aad instanceof Uint8Array) return;
398
- throw new JWTError("\"aad\" must be a string or a Uint8Array.", "ERR_INVALID_OPTION");
399
- }
400
530
  async function encrypt(payload, key, options = {}) {
401
531
  assertOptionEntry(options, {
402
532
  label: "options",
@@ -539,7 +669,10 @@ async function decrypt(jwe, key, options = {}) {
539
669
  return result;
540
670
  }
541
671
  function _buildJWEHeader(alg, enc, key, userHeader, keyManagementParams, payload) {
542
- const safeHeader = sanitizeObjectCopy(userHeader);
672
+ const safeHeader = copyJsonObject(userHeader, {
673
+ code: "ERR_INVALID_OPTION",
674
+ message: "\"protectedHeader\" must hold only JSON values."
675
+ });
543
676
  const header = {};
544
677
  if (isJWK(key) && key.kid) header.kid = key.kid;
545
678
  if (safeHeader) Object.assign(header, safeHeader);