oauth4webapi 2.6.0 → 2.8.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 +3 -2
- package/build/index.d.ts +61 -4
- package/build/index.js +170 -10
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -15,12 +15,13 @@ The following features are currently in scope and implemented in this software:
|
|
|
15
15
|
- UserInfo and Protected Resource Requests
|
|
16
16
|
- Authorization Server Issuer Identification
|
|
17
17
|
- JWT Secured Introspection, Response Mode (JARM), Authorization Request (JAR), and UserInfo
|
|
18
|
+
- Validating incoming JWT Access Tokens
|
|
18
19
|
|
|
19
20
|
## [Certification](https://openid.net/certification/faq/)
|
|
20
21
|
|
|
21
22
|
[<img width="96" height="50" align="right" src="https://user-images.githubusercontent.com/241506/166977513-7cd710a9-7f60-4944-aebe-a658e9f36375.png" alt="OpenID Certification">](#certification)
|
|
22
23
|
|
|
23
|
-
[Filip Skokan](https://github.com/panva) has certified that [this software](https://github.com/panva/oauth4webapi) conforms to the Basic
|
|
24
|
+
[Filip Skokan](https://github.com/panva) has certified that [this software](https://github.com/panva/oauth4webapi) conforms to the Basic, FAPI 1.0 Advanced, FAPI 2.0 Security Profile, and FAPI 2.0 Message Signing Relying Party Conformance Profiles of the OpenID Connect™ protocol.
|
|
24
25
|
|
|
25
26
|
## [💗 Help the project](https://github.com/sponsors/panva)
|
|
26
27
|
|
|
@@ -43,7 +44,7 @@ import * as oauth2 from 'oauth4webapi'
|
|
|
43
44
|
**`example`** Deno import
|
|
44
45
|
|
|
45
46
|
```js
|
|
46
|
-
import * as oauth2 from 'https://deno.land/x/oauth4webapi@v2.
|
|
47
|
+
import * as oauth2 from 'https://deno.land/x/oauth4webapi@v2.8.0/mod.ts'
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
- Authorization Code Flow - OpenID Connect [source](examples/code.ts), or plain OAuth 2 [source](examples/oauth.ts)
|
package/build/index.d.ts
CHANGED
|
@@ -1109,6 +1109,7 @@ interface JWTPayload {
|
|
|
1109
1109
|
readonly nbf?: number;
|
|
1110
1110
|
readonly exp?: number;
|
|
1111
1111
|
readonly iat?: number;
|
|
1112
|
+
readonly cnf?: ConfirmationClaims;
|
|
1112
1113
|
readonly [claim: string]: JsonValue | undefined;
|
|
1113
1114
|
}
|
|
1114
1115
|
export interface IDToken extends JWTPayload {
|
|
@@ -1120,6 +1121,7 @@ export interface IDToken extends JWTPayload {
|
|
|
1120
1121
|
readonly nonce?: string;
|
|
1121
1122
|
readonly auth_time?: number;
|
|
1122
1123
|
readonly azp?: string;
|
|
1124
|
+
readonly [claim: string]: JsonValue | undefined;
|
|
1123
1125
|
}
|
|
1124
1126
|
export interface TokenEndpointResponse {
|
|
1125
1127
|
readonly access_token: string;
|
|
@@ -1304,11 +1306,13 @@ export interface IntrospectionRequestOptions extends HttpRequestOptions, Authent
|
|
|
1304
1306
|
* @see [draft-ietf-oauth-jwt-introspection-response-12 - JWT Response for OAuth Token Introspection](https://www.ietf.org/archive/id/draft-ietf-oauth-jwt-introspection-response-12.html#section-4)
|
|
1305
1307
|
*/
|
|
1306
1308
|
export declare function introspectionRequest(as: AuthorizationServer, client: Client, token: string, options?: IntrospectionRequestOptions): Promise<Response>;
|
|
1307
|
-
export interface
|
|
1309
|
+
export interface ConfirmationClaims {
|
|
1308
1310
|
readonly 'x5t#S256'?: string;
|
|
1309
1311
|
readonly jkt?: string;
|
|
1310
1312
|
readonly [claim: string]: JsonValue | undefined;
|
|
1311
1313
|
}
|
|
1314
|
+
/** @ignore */
|
|
1315
|
+
export type IntrospectionConfirmationClaims = ConfirmationClaims;
|
|
1312
1316
|
export interface IntrospectionResponse {
|
|
1313
1317
|
readonly active: boolean;
|
|
1314
1318
|
readonly client_id?: string;
|
|
@@ -1323,7 +1327,7 @@ export interface IntrospectionResponse {
|
|
|
1323
1327
|
readonly sub?: string;
|
|
1324
1328
|
readonly nbf?: number;
|
|
1325
1329
|
readonly token_type?: string;
|
|
1326
|
-
readonly cnf?:
|
|
1330
|
+
readonly cnf?: ConfirmationClaims;
|
|
1327
1331
|
readonly [claim: string]: JsonValue | undefined;
|
|
1328
1332
|
}
|
|
1329
1333
|
/**
|
|
@@ -1370,7 +1374,8 @@ export declare function validateJwtAuthResponse(as: AuthorizationServer, client:
|
|
|
1370
1374
|
*
|
|
1371
1375
|
* @param as Authorization Server Metadata.
|
|
1372
1376
|
* @param client Client Metadata.
|
|
1373
|
-
* @param parameters Authorization Response
|
|
1377
|
+
* @param parameters Authorization Response parameters as URLSearchParams or an instance of URL with
|
|
1378
|
+
* parameters in a fragment/hash.
|
|
1374
1379
|
* @param expectedNonce Expected ID Token `nonce` claim value.
|
|
1375
1380
|
* @param expectedState Expected `state` parameter value. Default is {@link expectNoState}.
|
|
1376
1381
|
* @param maxAge ID Token {@link IDToken.auth_time `auth_time`} claim value will be checked to be
|
|
@@ -1386,7 +1391,7 @@ export declare function validateJwtAuthResponse(as: AuthorizationServer, client:
|
|
|
1386
1391
|
*
|
|
1387
1392
|
* @see [Financial-grade API Security Profile 1.0 - Part 2: Advanced](https://openid.net/specs/openid-financial-api-part-2-1_0.html#id-token-as-detached-signature)
|
|
1388
1393
|
*/
|
|
1389
|
-
export declare function experimental_validateDetachedSignatureResponse(as: AuthorizationServer, client: Client, parameters: URLSearchParams, expectedNonce: string, expectedState?: string | typeof expectNoState, maxAge?: number | typeof skipAuthTimeCheck, options?: HttpRequestOptions): Promise<URLSearchParams | OAuth2Error>;
|
|
1394
|
+
export declare function experimental_validateDetachedSignatureResponse(as: AuthorizationServer, client: Client, parameters: URLSearchParams | URL, expectedNonce: string, expectedState?: string | typeof expectNoState, maxAge?: number | typeof skipAuthTimeCheck, options?: HttpRequestOptions): Promise<URLSearchParams | OAuth2Error>;
|
|
1390
1395
|
/**
|
|
1391
1396
|
* DANGER ZONE
|
|
1392
1397
|
*
|
|
@@ -1511,4 +1516,56 @@ export interface GenerateKeyPairOptions {
|
|
|
1511
1516
|
* @group Utilities
|
|
1512
1517
|
*/
|
|
1513
1518
|
export declare function generateKeyPair(alg: JWSAlgorithm, options?: GenerateKeyPairOptions): Promise<CryptoKeyPair>;
|
|
1519
|
+
export interface JWTAccessTokenClaims extends JWTPayload {
|
|
1520
|
+
readonly iss: string;
|
|
1521
|
+
readonly exp: number;
|
|
1522
|
+
readonly aud: string | string[];
|
|
1523
|
+
readonly sub: string;
|
|
1524
|
+
readonly iat: number;
|
|
1525
|
+
readonly jti: string;
|
|
1526
|
+
readonly client_id: string;
|
|
1527
|
+
readonly [claim: string]: JsonValue | undefined;
|
|
1528
|
+
}
|
|
1529
|
+
export interface ValidateJWTAccessTokenOptions extends HttpRequestOptions {
|
|
1530
|
+
/** Indicates whether DPoP use is required. */
|
|
1531
|
+
requireDPoP?: boolean;
|
|
1532
|
+
/** Same functionality as in {@link Client} */
|
|
1533
|
+
[clockSkew]?: number;
|
|
1534
|
+
/** Same functionality as in {@link Client} */
|
|
1535
|
+
[clockTolerance]?: number;
|
|
1536
|
+
}
|
|
1537
|
+
/**
|
|
1538
|
+
* This is an experimental feature, it is not subject to semantic versioning rules. Non-backward
|
|
1539
|
+
* compatible changes or removal may occur in any future release.
|
|
1540
|
+
*
|
|
1541
|
+
* Validates use of JSON Web Token (JWT) OAuth 2.0 Access Tokens for a given {@link Request} as per
|
|
1542
|
+
* RFC 9068 and optionally also RFC 9449.
|
|
1543
|
+
*
|
|
1544
|
+
* This does validate the presence and type of all required claims as well as the values of the
|
|
1545
|
+
* {@link JWTAccessTokenClaims.iss `iss`}, {@link JWTAccessTokenClaims.exp `exp`},
|
|
1546
|
+
* {@link JWTAccessTokenClaims.aud `aud`} claims.
|
|
1547
|
+
*
|
|
1548
|
+
* This does NOT validate the {@link JWTAccessTokenClaims.sub `sub`},
|
|
1549
|
+
* {@link JWTAccessTokenClaims.jti `jti`}, and {@link JWTAccessTokenClaims.client_id `client_id`}
|
|
1550
|
+
* claims beyond just checking that they're present and that their type is a string. If you need to
|
|
1551
|
+
* validate these values further you would do so after this function's execution.
|
|
1552
|
+
*
|
|
1553
|
+
* This does NOT validate the DPoP Proof JWT nonce. If your server indicates RS-provided nonces to
|
|
1554
|
+
* clients you would check these after this function's execution.
|
|
1555
|
+
*
|
|
1556
|
+
* This does NOT validate authorization claims such as `scope` either, you would do so after this
|
|
1557
|
+
* function's execution.
|
|
1558
|
+
*
|
|
1559
|
+
* @param as Authorization Server to accept JWT Access Tokens from.
|
|
1560
|
+
* @param request
|
|
1561
|
+
* @param expectedAudience Audience identifier the resource server expects for itself.
|
|
1562
|
+
* @param options
|
|
1563
|
+
*
|
|
1564
|
+
* @group JWT Access Tokens
|
|
1565
|
+
* @group Experimental
|
|
1566
|
+
*
|
|
1567
|
+
* @see [RFC 9068 - JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens](https://www.rfc-editor.org/rfc/rfc9068.html)
|
|
1568
|
+
* @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html)
|
|
1569
|
+
*/
|
|
1570
|
+
export declare function experimental_validateJwtAccessToken(as: AuthorizationServer, request: Request, expectedAudience: string, options?: ValidateJWTAccessTokenOptions): Promise<JWTAccessTokenClaims>;
|
|
1514
1571
|
export {};
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
let USER_AGENT;
|
|
2
2
|
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
|
|
3
3
|
const NAME = 'oauth4webapi';
|
|
4
|
-
const VERSION = 'v2.
|
|
4
|
+
const VERSION = 'v2.8.0';
|
|
5
5
|
USER_AGENT = `${NAME}/${VERSION}`;
|
|
6
6
|
}
|
|
7
7
|
function looseInstanceOf(input, expected) {
|
|
@@ -344,15 +344,19 @@ function keyToJws(key) {
|
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
346
|
function getClockSkew(client) {
|
|
347
|
-
if (
|
|
348
|
-
|
|
347
|
+
if (client && clockSkew in client) {
|
|
348
|
+
if (Number.isFinite(client[clockSkew])) {
|
|
349
|
+
return client[clockSkew];
|
|
350
|
+
}
|
|
349
351
|
}
|
|
350
352
|
return 0;
|
|
351
353
|
}
|
|
352
354
|
function getClockTolerance(client) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
355
|
+
if (client && clockTolerance in client) {
|
|
356
|
+
const tolerance = client[clockTolerance];
|
|
357
|
+
if (Number.isFinite(tolerance) && Math.sign(tolerance) !== -1) {
|
|
358
|
+
return tolerance;
|
|
359
|
+
}
|
|
356
360
|
}
|
|
357
361
|
return 30;
|
|
358
362
|
}
|
|
@@ -1019,20 +1023,26 @@ export async function authorizationCodeGrantRequest(as, client, callbackParamete
|
|
|
1019
1023
|
parameters.set('code', code);
|
|
1020
1024
|
return tokenEndpointRequest(as, client, 'authorization_code', parameters, options);
|
|
1021
1025
|
}
|
|
1022
|
-
const
|
|
1026
|
+
const jwtClaimNames = {
|
|
1023
1027
|
aud: 'audience',
|
|
1028
|
+
c_hash: 'code hash',
|
|
1029
|
+
client_id: 'client id',
|
|
1024
1030
|
exp: 'expiration time',
|
|
1025
1031
|
iat: 'issued at',
|
|
1026
1032
|
iss: 'issuer',
|
|
1027
|
-
|
|
1033
|
+
jti: 'jwt id',
|
|
1028
1034
|
nonce: 'nonce',
|
|
1029
1035
|
s_hash: 'state hash',
|
|
1030
|
-
|
|
1036
|
+
sub: 'subject',
|
|
1037
|
+
ath: 'access token hash',
|
|
1038
|
+
htm: 'http method',
|
|
1039
|
+
htu: 'http uri',
|
|
1040
|
+
cnf: 'confirmation',
|
|
1031
1041
|
};
|
|
1032
1042
|
function validatePresence(required, result) {
|
|
1033
1043
|
for (const claim of required) {
|
|
1034
1044
|
if (result.claims[claim] === undefined) {
|
|
1035
|
-
throw new OPE(`JWT "${claim}" (${
|
|
1045
|
+
throw new OPE(`JWT "${claim}" (${jwtClaimNames[claim]}) claim missing`);
|
|
1036
1046
|
}
|
|
1037
1047
|
}
|
|
1038
1048
|
return result;
|
|
@@ -1465,6 +1475,12 @@ async function idTokenHashMatches(data, actual, alg, key) {
|
|
|
1465
1475
|
export async function experimental_validateDetachedSignatureResponse(as, client, parameters, expectedNonce, expectedState, maxAge, options) {
|
|
1466
1476
|
assertAs(as);
|
|
1467
1477
|
assertClient(client);
|
|
1478
|
+
if (parameters instanceof URL) {
|
|
1479
|
+
if (!parameters.hash.length) {
|
|
1480
|
+
throw new TypeError('"parameters" as an instance of URL must contain a hash (fragment) with the Authorization Response parameters');
|
|
1481
|
+
}
|
|
1482
|
+
parameters = new URLSearchParams(parameters.hash.slice(1));
|
|
1483
|
+
}
|
|
1468
1484
|
if (!(parameters instanceof URLSearchParams)) {
|
|
1469
1485
|
throw new TypeError('"parameters" must be an instance of URLSearchParams');
|
|
1470
1486
|
}
|
|
@@ -1753,3 +1769,147 @@ export async function generateKeyPair(alg, options) {
|
|
|
1753
1769
|
}
|
|
1754
1770
|
return (crypto.subtle.generateKey(algorithm, options?.extractable ?? false, ['sign', 'verify']));
|
|
1755
1771
|
}
|
|
1772
|
+
function normalizeHtu(htu) {
|
|
1773
|
+
const url = new URL(htu);
|
|
1774
|
+
url.search = '';
|
|
1775
|
+
url.hash = '';
|
|
1776
|
+
return url.href;
|
|
1777
|
+
}
|
|
1778
|
+
async function validateDPoP(as, request, accessTokenClaims, options) {
|
|
1779
|
+
if (!request.headers.has('dpop')) {
|
|
1780
|
+
throw new OPE('operation indicated DPoP use but the request has no DPoP HTTP Header');
|
|
1781
|
+
}
|
|
1782
|
+
if (request.headers.get('authorization')?.toLowerCase().startsWith('dpop ') === false) {
|
|
1783
|
+
throw new OPE(`operation indicated DPoP use but the request's Authorization HTTP Header scheme is not DPoP`);
|
|
1784
|
+
}
|
|
1785
|
+
if (typeof accessTokenClaims.cnf?.jkt !== 'string') {
|
|
1786
|
+
throw new OPE('operation indicated DPoP use but the JWT Access Token has no jkt confirmation claim');
|
|
1787
|
+
}
|
|
1788
|
+
const proof = await validateJwt(request.headers.get('dpop'), checkSigningAlgorithm.bind(undefined, undefined, as?.dpop_signing_alg_values_supported || SUPPORTED_JWS_ALGS), async ({ jwk, alg }) => {
|
|
1789
|
+
if (!jwk) {
|
|
1790
|
+
throw new OPE('DPoP Proof is missing the jwk header parameter');
|
|
1791
|
+
}
|
|
1792
|
+
const key = await importJwk(alg, jwk);
|
|
1793
|
+
if (key.type !== 'public') {
|
|
1794
|
+
throw new OPE('DPoP Proof jwk header parameter must contain a public key');
|
|
1795
|
+
}
|
|
1796
|
+
return key;
|
|
1797
|
+
}, getClockSkew(options), getClockTolerance(options))
|
|
1798
|
+
.then(checkJwtType.bind(undefined, 'dpop+jwt'))
|
|
1799
|
+
.then(validatePresence.bind(undefined, ['iat', 'jti', 'ath', 'htm', 'htu']));
|
|
1800
|
+
if (proof.claims.htm !== request.method) {
|
|
1801
|
+
throw new OPE('DPoP Proof htm mismatch');
|
|
1802
|
+
}
|
|
1803
|
+
if (typeof proof.claims.htu !== 'string' ||
|
|
1804
|
+
normalizeHtu(proof.claims.htu) !== normalizeHtu(request.url)) {
|
|
1805
|
+
throw new OPE('DPoP Proof htu mismatch');
|
|
1806
|
+
}
|
|
1807
|
+
{
|
|
1808
|
+
const accessToken = request.headers.get('authorization').split(' ')[1];
|
|
1809
|
+
const expected = b64u(await crypto.subtle.digest('SHA-256', encoder.encode(accessToken)));
|
|
1810
|
+
if (proof.claims.ath !== expected) {
|
|
1811
|
+
throw new OPE('DPoP Proof ath mismatch');
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
{
|
|
1815
|
+
let components;
|
|
1816
|
+
switch (proof.header.jwk.kty) {
|
|
1817
|
+
case 'EC':
|
|
1818
|
+
components = {
|
|
1819
|
+
crv: proof.header.jwk.crv,
|
|
1820
|
+
kty: proof.header.jwk.kty,
|
|
1821
|
+
x: proof.header.jwk.x,
|
|
1822
|
+
y: proof.header.jwk.y,
|
|
1823
|
+
};
|
|
1824
|
+
break;
|
|
1825
|
+
case 'OKP':
|
|
1826
|
+
components = {
|
|
1827
|
+
crv: proof.header.jwk.crv,
|
|
1828
|
+
kty: proof.header.jwk.kty,
|
|
1829
|
+
x: proof.header.jwk.x,
|
|
1830
|
+
};
|
|
1831
|
+
break;
|
|
1832
|
+
case 'RSA':
|
|
1833
|
+
components = {
|
|
1834
|
+
e: proof.header.jwk.e,
|
|
1835
|
+
kty: proof.header.jwk.kty,
|
|
1836
|
+
n: proof.header.jwk.n,
|
|
1837
|
+
};
|
|
1838
|
+
break;
|
|
1839
|
+
default:
|
|
1840
|
+
throw new UnsupportedOperationError();
|
|
1841
|
+
}
|
|
1842
|
+
const expected = b64u(await crypto.subtle.digest('SHA-256', encoder.encode(JSON.stringify(components))));
|
|
1843
|
+
if (accessTokenClaims.cnf.jkt !== expected) {
|
|
1844
|
+
throw new OPE('JWT Access Token confirmation mismatch');
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
export async function experimental_validateJwtAccessToken(as, request, expectedAudience, options) {
|
|
1849
|
+
assertAs(as);
|
|
1850
|
+
if (!looseInstanceOf(request, Request)) {
|
|
1851
|
+
throw new TypeError('"request" must be an instance of Request');
|
|
1852
|
+
}
|
|
1853
|
+
if (!validateString(expectedAudience)) {
|
|
1854
|
+
throw new OPE('"expectedAudience" must be a non-empty string');
|
|
1855
|
+
}
|
|
1856
|
+
const authorization = request.headers.get('authorization');
|
|
1857
|
+
if (!authorization) {
|
|
1858
|
+
throw new OPE('"request" is missing an Authorization HTTP Header');
|
|
1859
|
+
}
|
|
1860
|
+
let { 0: scheme, 1: accessToken, length } = authorization.split(' ');
|
|
1861
|
+
scheme = scheme.toLowerCase();
|
|
1862
|
+
switch (scheme) {
|
|
1863
|
+
case 'dpop':
|
|
1864
|
+
case 'bearer':
|
|
1865
|
+
break;
|
|
1866
|
+
default:
|
|
1867
|
+
throw new UnsupportedOperationError('unsupported Authorization HTTP Header scheme');
|
|
1868
|
+
}
|
|
1869
|
+
if (length !== 2) {
|
|
1870
|
+
throw new OPE('invalid Authorization HTTP Header format');
|
|
1871
|
+
}
|
|
1872
|
+
const requiredClaims = [
|
|
1873
|
+
'iss',
|
|
1874
|
+
'exp',
|
|
1875
|
+
'aud',
|
|
1876
|
+
'sub',
|
|
1877
|
+
'iat',
|
|
1878
|
+
'jti',
|
|
1879
|
+
'client_id',
|
|
1880
|
+
];
|
|
1881
|
+
if (options?.requireDPoP || scheme === 'dpop' || request.headers.has('dpop')) {
|
|
1882
|
+
requiredClaims.push('cnf');
|
|
1883
|
+
}
|
|
1884
|
+
const { claims } = await validateJwt(accessToken, checkSigningAlgorithm.bind(undefined, undefined, SUPPORTED_JWS_ALGS), getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options), getClockSkew(options), getClockTolerance(options))
|
|
1885
|
+
.then(checkJwtType.bind(undefined, 'at+jwt'))
|
|
1886
|
+
.then(validatePresence.bind(undefined, requiredClaims))
|
|
1887
|
+
.then(validateIssuer.bind(undefined, as.issuer))
|
|
1888
|
+
.then(validateAudience.bind(undefined, expectedAudience));
|
|
1889
|
+
for (const claim of ['client_id', 'jti', 'sub']) {
|
|
1890
|
+
if (typeof claims[claim] !== 'string') {
|
|
1891
|
+
throw new OPE(`unexpected JWT "${claim}" claim type`);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
if ('cnf' in claims) {
|
|
1895
|
+
if (!isJsonObject(claims.cnf)) {
|
|
1896
|
+
throw new OPE('unexpected JWT "cnf" (confirmation) claim value');
|
|
1897
|
+
}
|
|
1898
|
+
const { 0: cnf, length } = Object.keys(claims.cnf);
|
|
1899
|
+
if (length) {
|
|
1900
|
+
if (length !== 1) {
|
|
1901
|
+
throw new UnsupportedOperationError('multiple confirmation claims are not supported');
|
|
1902
|
+
}
|
|
1903
|
+
if (cnf !== 'jkt') {
|
|
1904
|
+
throw new UnsupportedOperationError('unsupported JWT Confirmation method');
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
if (options?.requireDPoP ||
|
|
1909
|
+
scheme === 'dpop' ||
|
|
1910
|
+
claims.cnf?.jkt !== undefined ||
|
|
1911
|
+
request.headers.has('dpop')) {
|
|
1912
|
+
await validateDPoP(as, request, claims, options);
|
|
1913
|
+
}
|
|
1914
|
+
return claims;
|
|
1915
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oauth4webapi",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "OAuth 2 / OpenID Connect for JavaScript Runtimes",
|
|
5
5
|
"keywords": [
|
|
6
|
+
"access token",
|
|
6
7
|
"auth",
|
|
7
8
|
"authentication",
|
|
8
9
|
"authorization",
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
"electron",
|
|
18
19
|
"fapi",
|
|
19
20
|
"javascript",
|
|
21
|
+
"jwt",
|
|
20
22
|
"netlify",
|
|
21
23
|
"next",
|
|
22
24
|
"nextjs",
|
|
@@ -65,18 +67,18 @@
|
|
|
65
67
|
"devDependencies": {
|
|
66
68
|
"@koa/cors": "^5.0.0",
|
|
67
69
|
"@types/koa__cors": "^5.0.0",
|
|
68
|
-
"@types/node": "^20.
|
|
70
|
+
"@types/node": "^20.11.5",
|
|
69
71
|
"@types/oidc-provider": "^8.4.3",
|
|
70
|
-
"@types/qunit": "^2.19.
|
|
72
|
+
"@types/qunit": "^2.19.10",
|
|
71
73
|
"archiver": "^6.0.1",
|
|
72
74
|
"ava": "^5.3.1",
|
|
73
75
|
"chrome-launcher": "^1.1.0",
|
|
74
|
-
"edge-runtime": "^2.5.
|
|
76
|
+
"edge-runtime": "^2.5.8",
|
|
75
77
|
"esbuild": "^0.19.11",
|
|
76
78
|
"jose": "^5.2.0",
|
|
77
|
-
"oidc-provider": "^8.4.
|
|
79
|
+
"oidc-provider": "^8.4.5",
|
|
78
80
|
"patch-package": "^8.0.0",
|
|
79
|
-
"prettier": "^3.
|
|
81
|
+
"prettier": "^3.2.4",
|
|
80
82
|
"prettier-plugin-jsdoc": "^1.3.0",
|
|
81
83
|
"puppeteer-core": "^21.7.0",
|
|
82
84
|
"qunit": "^2.20.0",
|
|
@@ -86,7 +88,7 @@
|
|
|
86
88
|
"tsx": "^4.7.0",
|
|
87
89
|
"typedoc": "^0.25.7",
|
|
88
90
|
"typedoc-plugin-markdown": "^3.17.1",
|
|
89
|
-
"typedoc-plugin-mdn-links": "^3.1.
|
|
91
|
+
"typedoc-plugin-mdn-links": "^3.1.13",
|
|
90
92
|
"typescript": "^5.3.3",
|
|
91
93
|
"undici": "^5.28.2"
|
|
92
94
|
}
|