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.
- package/README.md +3 -9
- package/dist/_chunks/{_import-key.mjs → algorithms.mjs} +194 -399
- package/dist/_chunks/{_codec-jwe.d.mts → codec-jwe.d.mts} +40 -9
- package/dist/_chunks/{_codec-jws.mjs → codec-jws.mjs} +133 -80
- package/dist/_chunks/cookie.mjs +50 -0
- package/dist/_chunks/digest.mjs +10 -3
- package/dist/_chunks/error.d.mts +103 -0
- package/dist/_chunks/export.mjs +97 -0
- package/dist/_chunks/index.d.mts +5 -103
- package/dist/_chunks/index2.d.mts +206 -12
- package/dist/_chunks/index3.d.mts +12 -109
- package/dist/_chunks/{jwe.d.mts → index4.d.mts} +2 -1
- package/dist/_chunks/{jws.d.mts → index5.d.mts} +2 -1
- package/dist/_chunks/index6.d.mts +113 -0
- package/dist/_chunks/jwe.mjs +205 -72
- package/dist/{core → _chunks}/jwk.mjs +210 -495
- package/dist/_chunks/jws.mjs +280 -193
- package/dist/_chunks/jwt.d.mts +2 -1
- package/dist/_chunks/{_jwt-internal.mjs → jwt.mjs} +110 -54
- package/dist/_chunks/libs/unsecure.d.mts +35 -25
- package/dist/_chunks/libs/unsecure.mjs +101 -268
- package/dist/_chunks/{_internal.d.mts → limits.d.mts} +1 -1
- package/dist/_chunks/payload.mjs +23 -0
- package/dist/_chunks/wrap.mjs +209 -0
- package/dist/adapters/elysia/index.d.mts +4 -4
- package/dist/adapters/elysia/index.mjs +4 -3
- package/dist/adapters/h3/index.d.mts +13 -13
- package/dist/adapters/h3/index.mjs +8 -11
- package/dist/adapters/h3v1/index.d.mts +5 -5
- package/dist/adapters/h3v1/index.mjs +6 -9
- package/dist/core/internal.mjs +1 -1
- package/dist/core/{jwe.d.mts → jwe/index.d.mts} +5 -4
- package/dist/core/jwe/index.mjs +5 -0
- package/dist/core/{jwk.d.mts → jwk/index.d.mts} +5 -4
- package/dist/core/jwk/index.mjs +7 -0
- package/dist/core/{jws.d.mts → jws/index.d.mts} +5 -4
- package/dist/core/jws/index.mjs +5 -0
- package/dist/dpop/index.d.mts +73 -0
- package/dist/dpop/index.mjs +296 -0
- package/dist/error.d.mts +3 -0
- package/dist/error.mjs +20 -0
- package/dist/index.d.mts +10 -9
- package/dist/index.mjs +7 -4
- package/dist/session/index.d.mts +4 -4
- package/dist/session/index.mjs +6 -47
- package/dist/utils/index.d.mts +7 -0
- package/dist/{core/utils → utils}/index.mjs +4 -3
- package/package.json +21 -10
- package/dist/_chunks/jwk.d.mts +0 -205
- package/dist/core/jwe.mjs +0 -5
- package/dist/core/jws.mjs +0 -5
- package/dist/core/utils/index.d.mts +0 -6
- /package/dist/_chunks/{_cookie-attributes.d.mts → cookie-attributes.d.mts} +0 -0
|
@@ -1,109 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 "./
|
|
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 "./
|
|
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;
|
package/dist/_chunks/jwe.mjs
CHANGED
|
@@ -1,8 +1,117 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { JWTError
|
|
3
|
-
import {
|
|
4
|
-
import { DEFAULT_PBES2_ITERATIONS,
|
|
5
|
-
import {
|
|
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 =
|
|
113
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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);
|