jose 4.11.3 → 4.12.0
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 +1 -1
- package/dist/browser/jwks/local.js +25 -10
- package/dist/browser/util/errors.js +1 -0
- package/dist/node/cjs/jwks/local.js +26 -11
- package/dist/node/cjs/util/errors.js +1 -0
- package/dist/node/esm/jwks/local.js +25 -10
- package/dist/node/esm/util/errors.js +1 -0
- package/dist/types/jwks/local.d.ts +41 -4
- package/dist/types/jwks/remote.d.ts +44 -6
- package/dist/types/jwt/sign.d.ts +1 -1
- package/dist/types/util/errors.d.ts +3 -0
- package/package.json +3 -2
- package/dist/deno/README.md +0 -51
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ export class LocalJWKSet {
|
|
|
38
38
|
this._jwks = clone(jwks);
|
|
39
39
|
}
|
|
40
40
|
async getKey(protectedHeader, token) {
|
|
41
|
-
const { alg, kid } = { ...protectedHeader, ...token.header };
|
|
41
|
+
const { alg, kid } = { ...protectedHeader, ...token === null || token === void 0 ? void 0 : token.header };
|
|
42
42
|
const kty = getKtyFromAlg(alg);
|
|
43
43
|
const candidates = this._jwks.keys.filter((jwk) => {
|
|
44
44
|
let candidate = kty === jwk.kty;
|
|
@@ -80,18 +80,33 @@ export class LocalJWKSet {
|
|
|
80
80
|
throw new JWKSNoMatchingKey();
|
|
81
81
|
}
|
|
82
82
|
else if (length !== 1) {
|
|
83
|
-
|
|
83
|
+
const error = new JWKSMultipleMatchingKeys();
|
|
84
|
+
const { _cached } = this;
|
|
85
|
+
error[Symbol.asyncIterator] = async function* () {
|
|
86
|
+
for (const jwk of candidates) {
|
|
87
|
+
try {
|
|
88
|
+
yield await importWithAlgCache(_cached, jwk, alg);
|
|
89
|
+
}
|
|
90
|
+
catch (_a) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
throw error;
|
|
84
96
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
return importWithAlgCache(this._cached, jwk, alg);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function importWithAlgCache(cache, jwk, alg) {
|
|
101
|
+
const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk);
|
|
102
|
+
if (cached[alg] === undefined) {
|
|
103
|
+
const keyObject = await importJWK({ ...jwk, ext: true }, alg);
|
|
104
|
+
if (keyObject.type !== 'public') {
|
|
105
|
+
throw new JWKSInvalid('JSON Web Key Set members must be public keys');
|
|
92
106
|
}
|
|
93
|
-
|
|
107
|
+
cached[alg] = keyObject;
|
|
94
108
|
}
|
|
109
|
+
return cached[alg];
|
|
95
110
|
}
|
|
96
111
|
export function createLocalJWKSet(jwks) {
|
|
97
112
|
return LocalJWKSet.prototype.getKey.bind(new LocalJWKSet(jwks));
|
|
@@ -42,7 +42,7 @@ class LocalJWKSet {
|
|
|
42
42
|
this._jwks = clone(jwks);
|
|
43
43
|
}
|
|
44
44
|
async getKey(protectedHeader, token) {
|
|
45
|
-
const { alg, kid } = { ...protectedHeader, ...token.header };
|
|
45
|
+
const { alg, kid } = { ...protectedHeader, ...token === null || token === void 0 ? void 0 : token.header };
|
|
46
46
|
const kty = getKtyFromAlg(alg);
|
|
47
47
|
const candidates = this._jwks.keys.filter((jwk) => {
|
|
48
48
|
let candidate = kty === jwk.kty;
|
|
@@ -84,20 +84,35 @@ class LocalJWKSet {
|
|
|
84
84
|
throw new errors_js_1.JWKSNoMatchingKey();
|
|
85
85
|
}
|
|
86
86
|
else if (length !== 1) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
87
|
+
const error = new errors_js_1.JWKSMultipleMatchingKeys();
|
|
88
|
+
const { _cached } = this;
|
|
89
|
+
error[Symbol.asyncIterator] = async function* () {
|
|
90
|
+
for (const jwk of candidates) {
|
|
91
|
+
try {
|
|
92
|
+
yield await importWithAlgCache(_cached, jwk, alg);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
throw error;
|
|
96
100
|
}
|
|
97
|
-
return
|
|
101
|
+
return importWithAlgCache(this._cached, jwk, alg);
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
exports.LocalJWKSet = LocalJWKSet;
|
|
105
|
+
async function importWithAlgCache(cache, jwk, alg) {
|
|
106
|
+
const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk);
|
|
107
|
+
if (cached[alg] === undefined) {
|
|
108
|
+
const keyObject = await (0, import_js_1.importJWK)({ ...jwk, ext: true }, alg);
|
|
109
|
+
if (keyObject.type !== 'public') {
|
|
110
|
+
throw new errors_js_1.JWKSInvalid('JSON Web Key Set members must be public keys');
|
|
111
|
+
}
|
|
112
|
+
cached[alg] = keyObject;
|
|
113
|
+
}
|
|
114
|
+
return cached[alg];
|
|
115
|
+
}
|
|
101
116
|
function createLocalJWKSet(jwks) {
|
|
102
117
|
return LocalJWKSet.prototype.getKey.bind(new LocalJWKSet(jwks));
|
|
103
118
|
}
|
|
@@ -38,7 +38,7 @@ export class LocalJWKSet {
|
|
|
38
38
|
this._jwks = clone(jwks);
|
|
39
39
|
}
|
|
40
40
|
async getKey(protectedHeader, token) {
|
|
41
|
-
const { alg, kid } = { ...protectedHeader, ...token.header };
|
|
41
|
+
const { alg, kid } = { ...protectedHeader, ...token === null || token === void 0 ? void 0 : token.header };
|
|
42
42
|
const kty = getKtyFromAlg(alg);
|
|
43
43
|
const candidates = this._jwks.keys.filter((jwk) => {
|
|
44
44
|
let candidate = kty === jwk.kty;
|
|
@@ -80,18 +80,33 @@ export class LocalJWKSet {
|
|
|
80
80
|
throw new JWKSNoMatchingKey();
|
|
81
81
|
}
|
|
82
82
|
else if (length !== 1) {
|
|
83
|
-
|
|
83
|
+
const error = new JWKSMultipleMatchingKeys();
|
|
84
|
+
const { _cached } = this;
|
|
85
|
+
error[Symbol.asyncIterator] = async function* () {
|
|
86
|
+
for (const jwk of candidates) {
|
|
87
|
+
try {
|
|
88
|
+
yield await importWithAlgCache(_cached, jwk, alg);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
throw error;
|
|
84
96
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
return importWithAlgCache(this._cached, jwk, alg);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function importWithAlgCache(cache, jwk, alg) {
|
|
101
|
+
const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk);
|
|
102
|
+
if (cached[alg] === undefined) {
|
|
103
|
+
const keyObject = await importJWK({ ...jwk, ext: true }, alg);
|
|
104
|
+
if (keyObject.type !== 'public') {
|
|
105
|
+
throw new JWKSInvalid('JSON Web Key Set members must be public keys');
|
|
92
106
|
}
|
|
93
|
-
|
|
107
|
+
cached[alg] = keyObject;
|
|
94
108
|
}
|
|
109
|
+
return cached[alg];
|
|
95
110
|
}
|
|
96
111
|
export function createLocalJWKSet(jwks) {
|
|
97
112
|
return LocalJWKSet.prototype.getKey.bind(new LocalJWKSet(jwks));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { KeyLike, JWSHeaderParameters, JSONWebKeySet, FlattenedJWSInput
|
|
1
|
+
import type { KeyLike, JWSHeaderParameters, JSONWebKeySet, FlattenedJWSInput } from '../types';
|
|
2
2
|
/** @private */
|
|
3
3
|
export declare function isJWKSLike(jwks: unknown): jwks is JSONWebKeySet;
|
|
4
4
|
/** @private */
|
|
@@ -6,13 +6,20 @@ export declare class LocalJWKSet {
|
|
|
6
6
|
protected _jwks?: JSONWebKeySet;
|
|
7
7
|
private _cached;
|
|
8
8
|
constructor(jwks: unknown);
|
|
9
|
-
getKey(protectedHeader
|
|
9
|
+
getKey(protectedHeader?: JWSHeaderParameters, token?: FlattenedJWSInput): Promise<KeyLike>;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Returns a function that resolves to a key object from a locally stored, or otherwise available,
|
|
13
13
|
* JSON Web Key Set.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* It uses the "alg" (JWS Algorithm) Header Parameter to determine the right JWK "kty" (Key Type),
|
|
16
|
+
* then proceeds to match the JWK "kid" (Key ID) with one found in the JWS Header Parameters (if
|
|
17
|
+
* there is one) while also respecting the JWK "use" (Public Key Use) and JWK "key_ops" (Key
|
|
18
|
+
* Operations) Parameters (if they are present on the JWK).
|
|
19
|
+
*
|
|
20
|
+
* Only a single public key must match the selection process. As shown in the example below when
|
|
21
|
+
* multiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt
|
|
22
|
+
* verification in an iterative manner.
|
|
16
23
|
*
|
|
17
24
|
* @example Usage
|
|
18
25
|
*
|
|
@@ -43,6 +50,36 @@ export declare class LocalJWKSet {
|
|
|
43
50
|
* console.log(payload)
|
|
44
51
|
* ```
|
|
45
52
|
*
|
|
53
|
+
* @example Opting-in to multiple JWKS matches using `createLocalJWKSet`
|
|
54
|
+
*
|
|
55
|
+
* ```js
|
|
56
|
+
* const options = {
|
|
57
|
+
* issuer: 'urn:example:issuer',
|
|
58
|
+
* audience: 'urn:example:audience',
|
|
59
|
+
* }
|
|
60
|
+
* const { payload, protectedHeader } = await jose
|
|
61
|
+
* .jwtVerify(jwt, JWKS, options)
|
|
62
|
+
* .catch(async (error) => {
|
|
63
|
+
* if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {
|
|
64
|
+
* for await (const publicKey of error) {
|
|
65
|
+
* try {
|
|
66
|
+
* return await jose.jwtVerify(jwt, publicKey, options)
|
|
67
|
+
* } catch (innerError) {
|
|
68
|
+
* if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {
|
|
69
|
+
* continue
|
|
70
|
+
* }
|
|
71
|
+
* throw innerError
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
* throw new jose.errors.JWSSignatureVerificationFailed()
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* throw error
|
|
78
|
+
* })
|
|
79
|
+
* console.log(protectedHeader)
|
|
80
|
+
* console.log(payload)
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
46
83
|
* @param jwks JSON Web Key Set formatted object.
|
|
47
84
|
*/
|
|
48
|
-
export declare function createLocalJWKSet(jwks: JSONWebKeySet):
|
|
85
|
+
export declare function createLocalJWKSet(jwks: JSONWebKeySet): (protectedHeader?: JWSHeaderParameters | undefined, token?: FlattenedJWSInput | undefined) => Promise<KeyLike>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JWSHeaderParameters, FlattenedJWSInput
|
|
1
|
+
import type { KeyLike, JWSHeaderParameters, FlattenedJWSInput } from '../types';
|
|
2
2
|
/** Options for the remote JSON Web Key Set. */
|
|
3
3
|
export interface RemoteJWKSetOptions {
|
|
4
4
|
/**
|
|
@@ -30,10 +30,18 @@ export interface RemoteJWKSetOptions {
|
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* Returns a function that resolves to a key object downloaded from a remote endpoint returning a
|
|
33
|
-
* JSON Web Key Set, that is, for example, an OAuth 2.0 or OIDC jwks_uri.
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
33
|
+
* JSON Web Key Set, that is, for example, an OAuth 2.0 or OIDC jwks_uri. The JSON Web Key Set is
|
|
34
|
+
* fetched when no key matches the selection process but only as frequently as the
|
|
35
|
+
* `cooldownDuration` option allows to prevent abuse.
|
|
36
|
+
*
|
|
37
|
+
* It uses the "alg" (JWS Algorithm) Header Parameter to determine the right JWK "kty" (Key Type),
|
|
38
|
+
* then proceeds to match the JWK "kid" (Key ID) with one found in the JWS Header Parameters (if
|
|
39
|
+
* there is one) while also respecting the JWK "use" (Public Key Use) and JWK "key_ops" (Key
|
|
40
|
+
* Operations) Parameters (if they are present on the JWK).
|
|
41
|
+
*
|
|
42
|
+
* Only a single public key must match the selection process. As shown in the example below when
|
|
43
|
+
* multiple keys get matched it is possible to opt-in to iterate over the matched keys and attempt
|
|
44
|
+
* verification in an iterative manner.
|
|
37
45
|
*
|
|
38
46
|
* @example Usage
|
|
39
47
|
*
|
|
@@ -48,7 +56,37 @@ export interface RemoteJWKSetOptions {
|
|
|
48
56
|
* console.log(payload)
|
|
49
57
|
* ```
|
|
50
58
|
*
|
|
59
|
+
* @example Opting-in to multiple JWKS matches using `createRemoteJWKSet`
|
|
60
|
+
*
|
|
61
|
+
* ```js
|
|
62
|
+
* const options = {
|
|
63
|
+
* issuer: 'urn:example:issuer',
|
|
64
|
+
* audience: 'urn:example:audience',
|
|
65
|
+
* }
|
|
66
|
+
* const { payload, protectedHeader } = await jose
|
|
67
|
+
* .jwtVerify(jwt, JWKS, options)
|
|
68
|
+
* .catch(async (error) => {
|
|
69
|
+
* if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {
|
|
70
|
+
* for await (const publicKey of error) {
|
|
71
|
+
* try {
|
|
72
|
+
* return await jose.jwtVerify(jwt, publicKey, options)
|
|
73
|
+
* } catch (innerError) {
|
|
74
|
+
* if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {
|
|
75
|
+
* continue
|
|
76
|
+
* }
|
|
77
|
+
* throw innerError
|
|
78
|
+
* }
|
|
79
|
+
* }
|
|
80
|
+
* throw new jose.errors.JWSSignatureVerificationFailed()
|
|
81
|
+
* }
|
|
82
|
+
*
|
|
83
|
+
* throw error
|
|
84
|
+
* })
|
|
85
|
+
* console.log(protectedHeader)
|
|
86
|
+
* console.log(payload)
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
51
89
|
* @param url URL to fetch the JSON Web Key Set from.
|
|
52
90
|
* @param options Options for the remote JSON Web Key Set.
|
|
53
91
|
*/
|
|
54
|
-
export declare function createRemoteJWKSet(url: URL, options?: RemoteJWKSetOptions):
|
|
92
|
+
export declare function createRemoteJWKSet(url: URL, options?: RemoteJWKSetOptions): (protectedHeader?: JWSHeaderParameters | undefined, token?: FlattenedJWSInput | undefined) => Promise<KeyLike>;
|
package/dist/types/jwt/sign.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ import { ProduceJWT } from './produce';
|
|
|
53
53
|
* 59lLWBCsocvvbd1cvDMNlRywAAyhsCb1SuX4nEAK9mrSBdfmoF2Nm3eilfsOds0f
|
|
54
54
|
* K5mX069IKG82CMqh3Mzptd7e7lyb9lsoGO0BAtjho3cWtha/UZ70vfaMzGuZ6JmQ
|
|
55
55
|
* ak6k+8+UFd93M4z0Qo74OhXB
|
|
56
|
-
* -----END PRIVATE KEY
|
|
56
|
+
* -----END PRIVATE KEY-----`
|
|
57
57
|
* const privateKey = await jose.importPKCS8(pkcs8, alg)
|
|
58
58
|
*
|
|
59
59
|
* const jwt = await new jose.SignJWT({ 'urn:example:claim': true })
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { KeyLike } from '../types';
|
|
1
2
|
/** A generic Error subclass that all other specific JOSE Error subclasses inherit from. */
|
|
2
3
|
export declare class JOSEError extends Error {
|
|
3
4
|
/** A unique error code for the particular error subclass. */
|
|
@@ -78,6 +79,8 @@ export declare class JWKSNoMatchingKey extends JOSEError {
|
|
|
78
79
|
}
|
|
79
80
|
/** An error subclass thrown when multiple keys match from a JWKS. */
|
|
80
81
|
export declare class JWKSMultipleMatchingKeys extends JOSEError {
|
|
82
|
+
/** @ignore */
|
|
83
|
+
[Symbol.asyncIterator]: () => AsyncIterableIterator<KeyLike>;
|
|
81
84
|
static get code(): 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';
|
|
82
85
|
code: string;
|
|
83
86
|
message: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jose",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0",
|
|
4
4
|
"description": "'JSON Web Almost Everything' - JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"browser",
|
|
@@ -83,7 +83,8 @@
|
|
|
83
83
|
"!dist/**/*.min.js",
|
|
84
84
|
"!dist/node/webcrypto/**/*",
|
|
85
85
|
"!dist/types/runtime/*",
|
|
86
|
-
"!dist/types/lib/*"
|
|
86
|
+
"!dist/types/lib/*",
|
|
87
|
+
"!dist/deno/**/*"
|
|
87
88
|
],
|
|
88
89
|
"deno": "./dist/browser/index.js"
|
|
89
90
|
}
|
package/dist/deno/README.md
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# `jose` Modules API Documentation
|
|
2
|
-
|
|
3
|
-
> "JSON Web Almost Everything" - JWA, JWS, JWE, JWT, JWK, JWKS with no dependencies using runtime's native crypto.
|
|
4
|
-
|
|
5
|
-
## [💗 Help the project](https://github.com/panva/jose/blob/v4.11.3/docs/https://github.com/sponsors/panva)
|
|
6
|
-
|
|
7
|
-
## Available modules
|
|
8
|
-
|
|
9
|
-
**`example`** Deno import
|
|
10
|
-
```js
|
|
11
|
-
import * as jose from 'https://deno.land/x/jose@v4.11.3/index.ts'
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
- JSON Web Tokens (JWT)
|
|
15
|
-
- [Signing](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jwt_sign.SignJWT.md#readme)
|
|
16
|
-
- [Verification & JWT Claims Set Validation](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwt_verify.jwtVerify.md#readme)
|
|
17
|
-
- Encrypted JSON Web Tokens
|
|
18
|
-
- [Encryption](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jwt_encrypt.EncryptJWT.md#readme)
|
|
19
|
-
- [Decryption & JWT Claims Set Validation](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwt_decrypt.jwtDecrypt.md#readme)
|
|
20
|
-
- Key Import
|
|
21
|
-
- [JWK Import](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_import.importJWK.md#readme)
|
|
22
|
-
- [Public Key Import (SPKI)](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_import.importSPKI.md#readme)
|
|
23
|
-
- [Public Key Import (X.509 Certificate)](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_import.importX509.md#readme)
|
|
24
|
-
- [Private Key Import (PKCS #8)](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_import.importPKCS8.md#readme)
|
|
25
|
-
- JSON Web Encryption (JWE)
|
|
26
|
-
- Encryption - [Compact](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jwe_compact_encrypt.CompactEncrypt.md#readme), [Flattened](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jwe_flattened_encrypt.FlattenedEncrypt.md#readme), [General](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jwe_general_encrypt.GeneralEncrypt.md#readme)
|
|
27
|
-
- Decryption - [Compact](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwe_compact_decrypt.compactDecrypt.md#readme), [Flattened](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwe_flattened_decrypt.flattenedDecrypt.md#readme), [General](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwe_general_decrypt.generalDecrypt.md#readme)
|
|
28
|
-
- JSON Web Signature (JWS)
|
|
29
|
-
- Signing - [Compact](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jws_compact_sign.CompactSign.md#readme), [Flattened](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jws_flattened_sign.FlattenedSign.md#readme), [General](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jws_general_sign.GeneralSign.md#readme)
|
|
30
|
-
- Verification - [Compact](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jws_compact_verify.compactVerify.md#readme), [Flattened](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jws_flattened_verify.flattenedVerify.md#readme), [General](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jws_general_verify.generalVerify.md#readme)
|
|
31
|
-
- JSON Web Key (JWK)
|
|
32
|
-
- [Calculating JWK Thumbprint](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwk_thumbprint.calculateJwkThumbprint.md#readme)
|
|
33
|
-
- [Calculating JWK Thumbprint URI](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwk_thumbprint.calculateJwkThumbprintUri.md#readme)
|
|
34
|
-
- [Verification using a JWK Embedded in a JWS Header](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwk_embedded.EmbeddedJWK.md#readme)
|
|
35
|
-
- JSON Web Key Set (JWKS)
|
|
36
|
-
- [Verify using a local JWKSet](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwks_local.createLocalJWKSet.md#readme)
|
|
37
|
-
- [Verify using a remote JWKSet](https://github.com/panva/jose/blob/v4.11.3/docs/functions/jwks_remote.createRemoteJWKSet.md#readme)
|
|
38
|
-
- Key Pair or Secret Generation
|
|
39
|
-
- [Asymmetric Key Pair Generation](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_generate_key_pair.generateKeyPair.md#readme)
|
|
40
|
-
- [Symmetric Secret Generation](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_generate_secret.generateSecret.md#readme)
|
|
41
|
-
- Key Export
|
|
42
|
-
- [JWK Export](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_export.exportJWK.md#readme)
|
|
43
|
-
- [Private Key Export](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_export.exportPKCS8.md#readme)
|
|
44
|
-
- [Public Key Export](https://github.com/panva/jose/blob/v4.11.3/docs/functions/key_export.exportSPKI.md#readme)
|
|
45
|
-
- Utilities
|
|
46
|
-
- [Decoding Token's Protected Header](https://github.com/panva/jose/blob/v4.11.3/docs/functions/util_decode_protected_header.decodeProtectedHeader.md#readme)
|
|
47
|
-
- [Decoding JWT Claims Set](https://github.com/panva/jose/blob/v4.11.3/docs/functions/util_decode_jwt.decodeJwt.md#readme)
|
|
48
|
-
- [Unsecured JWT](https://github.com/panva/jose/blob/v4.11.3/docs/classes/jwt_unsecured.UnsecuredJWT.md#readme)
|
|
49
|
-
- [JOSE Errors](https://github.com/panva/jose/blob/v4.11.3/docs/modules/util_errors.md#readme)
|
|
50
|
-
|
|
51
|
-
[support-sponsor]: https://github.com/sponsors/panva
|