Skip to content

Commit

Permalink
feat: support generic token endpoint grant requests
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Sep 15, 2024
1 parent e5b63bb commit 2f454b5
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 5 deletions.
18 changes: 18 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ Support from the community to continue maintaining and improving this module is

- [validateJwtAccessToken](functions/validateJwtAccessToken.md)

## JWT Bearer Token Grant Type

- [genericTokenEndpointRequest](functions/genericTokenEndpointRequest.md)
- [isOAuth2Error](functions/isOAuth2Error.md)
- [parseWwwAuthenticateChallenges](functions/parseWwwAuthenticateChallenges.md)

## JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)

- [validateJwtAuthResponse](functions/validateJwtAuthResponse.md)
Expand Down Expand Up @@ -111,6 +117,18 @@ Support from the community to continue maintaining and improving this module is
- [processRefreshTokenResponse](functions/processRefreshTokenResponse.md)
- [refreshTokenGrantRequest](functions/refreshTokenGrantRequest.md)

## SAML 2.0 Bearer Assertion Grant Type

- [genericTokenEndpointRequest](functions/genericTokenEndpointRequest.md)
- [isOAuth2Error](functions/isOAuth2Error.md)
- [parseWwwAuthenticateChallenges](functions/parseWwwAuthenticateChallenges.md)

## Token Exchange Grant Type

- [genericTokenEndpointRequest](functions/genericTokenEndpointRequest.md)
- [isOAuth2Error](functions/isOAuth2Error.md)
- [parseWwwAuthenticateChallenges](functions/parseWwwAuthenticateChallenges.md)

## Token Introspection

- [introspectionRequest](functions/introspectionRequest.md)
Expand Down
33 changes: 33 additions & 0 deletions docs/functions/genericTokenEndpointRequest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Function: genericTokenEndpointRequest()

[💗 Help the project](https://github.com/sponsors/panva)

Support from the community to continue maintaining and improving this module is welcome. If you find the module useful, please consider supporting the project by [becoming a sponsor](https://github.com/sponsors/panva).

***

**genericTokenEndpointRequest**(`as`, `client`, `grantType`, `parameters`, `options`?): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<[`Response`](https://developer.mozilla.org/docs/Web/API/Response)\>

Performs any Grant request at the [`as.token_endpoint`](../interfaces/AuthorizationServer.md#token_endpoint).
The purpose is to be able to execute grant requests such as Token Exchange Grant Type, JWT Bearer
Token Grant Type, or SAML 2.0 Bearer Assertion Grant Type.

## Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `as` | [`AuthorizationServer`](../interfaces/AuthorizationServer.md) | Authorization Server Metadata. |
| `client` | [`Client`](../interfaces/Client.md) | Client Metadata. |
| `grantType` | `string` | Grant Type. |
| `parameters` | [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)\<`string`, `string`\> \| [`URLSearchParams`](https://developer.mozilla.org/docs/Web/API/URLSearchParams) \| `string`[][] | - |
| `options`? | [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)\<[`TokenEndpointRequestOptions`](../interfaces/TokenEndpointRequestOptions.md), `"additionalParameters"`\> | - |

## Returns

[`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<[`Response`](https://developer.mozilla.org/docs/Web/API/Response)\>

## See

- [Token Exchange Grant Type](https://www.rfc-editor.org/rfc/rfc8693.html)
- [JWT Bearer Token Grant Type](https://www.rfc-editor.org/rfc/rfc7523.html#section-2.1)
- [SAML 2.0 Bearer Assertion Grant Type](https://www.rfc-editor.org/rfc/rfc7522.html#section-2.1)
40 changes: 40 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1883,6 +1883,9 @@ export interface OAuth2Error {
* @group Token Revocation
* @group Refreshing an Access Token
* @group Pushed Authorization Requests (PAR)
* @group JWT Bearer Token Grant Type
* @group SAML 2.0 Bearer Assertion Grant Type
* @group Token Exchange Grant Type
*/
export function isOAuth2Error(
input?:
Expand Down Expand Up @@ -1980,6 +1983,9 @@ function wwwAuth(scheme: string, params: string): WWWAuthenticateChallenge {
* @group Token Revocation
* @group Refreshing an Access Token
* @group Pushed Authorization Requests (PAR)
* @group JWT Bearer Token Grant Type
* @group SAML 2.0 Bearer Assertion Grant Type
* @group Token Exchange Grant Type
*/
export function parseWwwAuthenticateChallenges(
response: Response,
Expand Down Expand Up @@ -3313,6 +3319,40 @@ export async function clientCredentialsGrantRequest(
)
}

/**
* Performs any Grant request at the {@link AuthorizationServer.token_endpoint `as.token_endpoint`}.
* The purpose is to be able to execute grant requests such as Token Exchange Grant Type, JWT Bearer
* Token Grant Type, or SAML 2.0 Bearer Assertion Grant Type.
*
* @param as Authorization Server Metadata.
* @param client Client Metadata.
* @param grantType Grant Type.
*
* @group JWT Bearer Token Grant Type
* @group SAML 2.0 Bearer Assertion Grant Type
* @group Token Exchange Grant Type
*
* @see {@link https://www.rfc-editor.org/rfc/rfc8693.html Token Exchange Grant Type}
* @see {@link https://www.rfc-editor.org/rfc/rfc7523.html#section-2.1 JWT Bearer Token Grant Type}
* @see {@link https://www.rfc-editor.org/rfc/rfc7522.html#section-2.1 SAML 2.0 Bearer Assertion Grant Type}
*/
export async function genericTokenEndpointRequest(
as: AuthorizationServer,
client: Client,
grantType: string,
parameters: URLSearchParams | Record<string, string> | string[][],
options?: Omit<TokenEndpointRequestOptions, 'additionalParameters'>,
): Promise<Response> {
assertAs(as)
assertClient(client)

if (!validateString(grantType)) {
throw new TypeError('"grantType" must be a non-empty string')
}

return tokenEndpointRequest(as, client, grantType, new URLSearchParams(parameters), options)
}

/**
* Validates Client Credentials Grant {@link !Response} instance to be one coming from the
* {@link AuthorizationServer.token_endpoint `as.token_endpoint`}.
Expand Down
24 changes: 19 additions & 5 deletions tap/end2end-client-credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
import * as lib from '../src/index.js'
import { keys } from './keys.js'

const coinflip = () => !Math.floor(Math.random() * 2)

export default (QUnit: QUnit) => {
const { module, test } = QUnit
module('end2end-client-credentials.ts')
Expand Down Expand Up @@ -98,11 +100,23 @@ export default (QUnit: QUnit) => {
params.set('scope', 'api:write')

{
const clientCredentialsGrantRequest = () =>
lib.clientCredentialsGrantRequest(as, client, params, {
DPoP,
...authenticated,
})
let clientCredentialsGrantRequest: () => ReturnType<
typeof lib.clientCredentialsGrantRequest
>

if (coinflip()) {
clientCredentialsGrantRequest = () =>
lib.clientCredentialsGrantRequest(as, client, params, {
DPoP,
...authenticated,
})
} else {
clientCredentialsGrantRequest = () =>
lib.genericTokenEndpointRequest(as, client, 'client_credentials', params, {
DPoP,
...authenticated,
})
}
let response = await clientCredentialsGrantRequest()

assertNoWwwAuthenticateChallenges(response)
Expand Down

0 comments on commit 2f454b5

Please sign in to comment.