From 81a13c0039e657a113f8bd835c0abe4998373152 Mon Sep 17 00:00:00 2001 From: Lyle Schemmerling Date: Wed, 17 Sep 2025 16:47:58 -0600 Subject: [PATCH 1/3] new optional tenant id param added (breaking) --- src/FusionAuthClient.ts | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/FusionAuthClient.ts b/src/FusionAuthClient.ts index f8194f5..1dff06c 100644 --- a/src/FusionAuthClient.ts +++ b/src/FusionAuthClient.ts @@ -106,15 +106,17 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret. This value will be required if client authentication is enabled. * @param {string} token The access token used to identify the user. * @param {string} user_code The end-user verification code. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - approveDevice(client_id: string, client_secret: string, token: string, user_code: string): Promise> { + approveDevice(client_id: string, client_secret: string, token: string, user_code: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('client_id', client_id); body.append('client_secret', client_secret); body.append('token', token); body.append('user_code', user_code); + body.append('tenantId', tenantId); return this.start() .withUri('/oauth2/device/approve') .withFormData(body) @@ -276,15 +278,17 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret used to authenticate this request. * This parameter is optional when Basic Authorization is used to authenticate this request. * @param {string} scope (Optional) This parameter is used to indicate which target entity you are requesting access. To request access to an entity, use the format target-entity:<target-entity-id>:<roles>. Roles are an optional comma separated list. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - clientCredentialsGrant(client_id: string, client_secret: string, scope: string): Promise> { + clientCredentialsGrant(client_id: string, client_secret: string, scope: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('client_id', client_id); body.append('client_secret', client_secret); body.append('grant_type', 'client_credentials'); body.append('scope', scope); + body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1546,9 +1550,10 @@ export class FusionAuthClient { * This parameter is optional when Basic Authorization is used to authenticate this request. * @param {string} client_secret (Optional) The client secret. This value will be required if client authentication is enabled. * @param {string} redirect_uri The URI to redirect to upon a successful request. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - exchangeOAuthCodeForAccessToken(code: string, client_id: string, client_secret: string, redirect_uri: string): Promise> { + exchangeOAuthCodeForAccessToken(code: string, client_id: string, client_secret: string, redirect_uri: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('code', code); @@ -1556,6 +1561,7 @@ export class FusionAuthClient { body.append('client_secret', client_secret); body.append('grant_type', 'authorization_code'); body.append('redirect_uri', redirect_uri); + body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1573,9 +1579,10 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header. * @param {string} redirect_uri The URI to redirect to upon a successful request. * @param {string} code_verifier The random string generated previously. Will be compared with the code_challenge sent previously, which allows the OAuth provider to authenticate your app. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - exchangeOAuthCodeForAccessTokenUsingPKCE(code: string, client_id: string, client_secret: string, redirect_uri: string, code_verifier: string): Promise> { + exchangeOAuthCodeForAccessTokenUsingPKCE(code: string, client_id: string, client_secret: string, redirect_uri: string, code_verifier: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('code', code); @@ -1584,6 +1591,7 @@ export class FusionAuthClient { body.append('grant_type', 'authorization_code'); body.append('redirect_uri', redirect_uri); body.append('code_verifier', code_verifier); + body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1601,9 +1609,10 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header. * @param {string} scope (Optional) This parameter is optional and if omitted, the same scope requested during the authorization request will be used. If provided the scopes must match those requested during the initial authorization request. * @param {string} user_code (Optional) The end-user verification code. This code is required if using this endpoint to approve the Device Authorization. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. Required if the request is for a universal application. * @returns {Promise>} */ - exchangeRefreshTokenForAccessToken(refresh_token: string, client_id: string, client_secret: string, scope: string, user_code: string): Promise> { + exchangeRefreshTokenForAccessToken(refresh_token: string, client_id: string, client_secret: string, scope: string, user_code: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('refresh_token', refresh_token); @@ -1612,6 +1621,7 @@ export class FusionAuthClient { body.append('grant_type', 'refresh_token'); body.append('scope', scope); body.append('user_code', user_code); + body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1644,9 +1654,10 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header. * @param {string} scope (Optional) This parameter is optional and if omitted, the same scope requested during the authorization request will be used. If provided the scopes must match those requested during the initial authorization request. * @param {string} user_code (Optional) The end-user verification code. This code is required if using this endpoint to approve the Device Authorization. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - exchangeUserCredentialsForAccessToken(username: string, password: string, client_id: string, client_secret: string, scope: string, user_code: string): Promise> { + exchangeUserCredentialsForAccessToken(username: string, password: string, client_id: string, client_secret: string, scope: string, user_code: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('username', username); @@ -1656,6 +1667,7 @@ export class FusionAuthClient { body.append('grant_type', 'password'); body.append('scope', scope); body.append('user_code', user_code); + body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1865,13 +1877,15 @@ export class FusionAuthClient { * * @param {string} client_id The unique client identifier. The client Id is the Id of the FusionAuth Application for which this token was generated. * @param {string} token The access token returned by this OAuth provider as the result of a successful client credentials grant. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - introspectAccessToken(client_id: string, token: string): Promise> { + introspectAccessToken(client_id: string, token: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('client_id', client_id); body.append('token', token); + body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/introspect') .withFormData(body) @@ -1883,12 +1897,14 @@ export class FusionAuthClient { * Inspect an access token issued as the result of the Client Credentials Grant. * * @param {string} token The access token returned by this OAuth provider as the result of a successful client credentials grant. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - introspectClientCredentialsAccessToken(token: string): Promise> { + introspectClientCredentialsAccessToken(token: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('token', token); + body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/introspect') .withFormData(body) @@ -3983,9 +3999,10 @@ export class FusionAuthClient { * @param {string} client_id The client Id. * @param {string} client_secret The client Id. * @param {string} user_code The end-user verification code. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - retrieveUserCode(client_id: string, client_secret: string, user_code: string): Promise> { + retrieveUserCode(client_id: string, client_secret: string, user_code: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('client_id', client_id); @@ -3993,6 +4010,7 @@ export class FusionAuthClient { body.append('user_code', user_code); return this.startAnonymous() .withUri('/oauth2/device/user-code') + .withParameter('tenantId', tenantId) .withFormData(body) .withMethod("GET") .go(); @@ -4006,14 +4024,16 @@ export class FusionAuthClient { * This request will require an API key. * * @param {string} user_code The end-user verification code. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - retrieveUserCodeUsingAPIKey(user_code: string): Promise> { + retrieveUserCodeUsingAPIKey(user_code: string, tenantId: UUID): Promise> { let body = new URLSearchParams(); body.append('user_code', user_code); return this.startAnonymous() .withUri('/oauth2/device/user-code') + .withParameter('tenantId', tenantId) .withFormData(body) .withMethod("GET") .go(); @@ -4065,12 +4085,14 @@ export class FusionAuthClient { * Call the UserInfo endpoint to retrieve User Claims from the access token issued by FusionAuth. * * @param {string} encodedJWT The encoded JWT (access token). + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - retrieveUserInfoFromAccessToken(encodedJWT: string): Promise> { + retrieveUserInfoFromAccessToken(encodedJWT: string, tenantId: UUID): Promise> { return this.startAnonymous() .withUri('/oauth2/userinfo') .withAuthorization('Bearer ' + encodedJWT) + .withParameter('tenantId', tenantId) .withMethod("GET") .go(); } @@ -5548,13 +5570,15 @@ export class FusionAuthClient { * * @param {string} user_code The end-user verification code. * @param {string} client_id The client Id. + * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - validateDevice(user_code: string, client_id: string): Promise> { + validateDevice(user_code: string, client_id: string, tenantId: UUID): Promise> { return this.startAnonymous() .withUri('/oauth2/device/validate') .withParameter('user_code', user_code) .withParameter('client_id', client_id) + .withParameter('tenantId', tenantId) .withMethod("GET") .go(); } From a75ff5eed7ea38f554f60d2308fb4c048a540d7d Mon Sep 17 00:00:00 2001 From: Lyle Schemmerling Date: Tue, 23 Sep 2025 12:17:30 -0600 Subject: [PATCH 2/3] validate and libs --- src/FusionAuthClient.ts | 397 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 364 insertions(+), 33 deletions(-) diff --git a/src/FusionAuthClient.ts b/src/FusionAuthClient.ts index 1dff06c..afa8bba 100644 --- a/src/FusionAuthClient.ts +++ b/src/FusionAuthClient.ts @@ -106,17 +106,15 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret. This value will be required if client authentication is enabled. * @param {string} token The access token used to identify the user. * @param {string} user_code The end-user verification code. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - approveDevice(client_id: string, client_secret: string, token: string, user_code: string, tenantId: UUID): Promise> { + approveDevice(client_id: string, client_secret: string, token: string, user_code: string): Promise> { let body = new URLSearchParams(); body.append('client_id', client_id); body.append('client_secret', client_secret); body.append('token', token); body.append('user_code', user_code); - body.append('tenantId', tenantId); return this.start() .withUri('/oauth2/device/approve') .withFormData(body) @@ -124,6 +122,20 @@ export class FusionAuthClient { .go(); } + /** + * Approve a device grant. + * + * @param {DeviceApprovalRequest} request The request object containing the device approval information and optional tenantId. + * @returns {Promise>} + */ + approveDeviceWithRequest(request: DeviceApprovalRequest): Promise> { + return this.start() + .withUri('/oauth2/device/approve') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Cancels the user action. * @@ -278,17 +290,15 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret used to authenticate this request. * This parameter is optional when Basic Authorization is used to authenticate this request. * @param {string} scope (Optional) This parameter is used to indicate which target entity you are requesting access. To request access to an entity, use the format target-entity:<target-entity-id>:<roles>. Roles are an optional comma separated list. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - clientCredentialsGrant(client_id: string, client_secret: string, scope: string, tenantId: UUID): Promise> { + clientCredentialsGrant(client_id: string, client_secret: string, scope: string): Promise> { let body = new URLSearchParams(); body.append('client_id', client_id); body.append('client_secret', client_secret); body.append('grant_type', 'client_credentials'); body.append('scope', scope); - body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -296,6 +306,20 @@ export class FusionAuthClient { .go(); } + /** + * Make a Client Credentials grant request to obtain an access token. + * + * @param {ClientCredentialsGrantRequest} request The client credentials grant request containing client authentication, scope and optional tenantId. + * @returns {Promise>} + */ + clientCredentialsGrantWithRequest(request: ClientCredentialsGrantRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/token') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Adds a comment to the user's account. * @@ -1491,6 +1515,41 @@ export class FusionAuthClient { .go(); } + /** + * Start the Device Authorization flow using form-encoded parameters + * + * @param {string} client_id The unique client identifier. The client Id is the Id of the FusionAuth Application in which you are attempting to authenticate. + * @param {string} client_secret (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header. + * @param {string} scope (Optional) A space-delimited string of the requested scopes. Defaults to all scopes configured in the Application's OAuth configuration. + * @returns {Promise>} + */ + deviceAuthorize(client_id: string, client_secret: string, scope: string): Promise> { + let body = new URLSearchParams(); + + body.append('client_id', client_id); + body.append('client_secret', client_secret); + body.append('scope', scope); + return this.startAnonymous() + .withUri('/oauth2/device_authorize') + .withFormData(body) + .withMethod("POST") + .go(); + } + + /** + * Start the Device Authorization flow using a request body + * + * @param {DeviceAuthorizationRequest} request The device authorization request containing client authentication, scope, and optional device metadata. + * @returns {Promise>} + */ + deviceAuthorizeWithRequest(request: DeviceAuthorizationRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/device_authorize') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Disable two-factor authentication for a user. * @@ -1550,10 +1609,9 @@ export class FusionAuthClient { * This parameter is optional when Basic Authorization is used to authenticate this request. * @param {string} client_secret (Optional) The client secret. This value will be required if client authentication is enabled. * @param {string} redirect_uri The URI to redirect to upon a successful request. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - exchangeOAuthCodeForAccessToken(code: string, client_id: string, client_secret: string, redirect_uri: string, tenantId: UUID): Promise> { + exchangeOAuthCodeForAccessToken(code: string, client_id: string, client_secret: string, redirect_uri: string): Promise> { let body = new URLSearchParams(); body.append('code', code); @@ -1561,7 +1619,6 @@ export class FusionAuthClient { body.append('client_secret', client_secret); body.append('grant_type', 'authorization_code'); body.append('redirect_uri', redirect_uri); - body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1579,10 +1636,9 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header. * @param {string} redirect_uri The URI to redirect to upon a successful request. * @param {string} code_verifier The random string generated previously. Will be compared with the code_challenge sent previously, which allows the OAuth provider to authenticate your app. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - exchangeOAuthCodeForAccessTokenUsingPKCE(code: string, client_id: string, client_secret: string, redirect_uri: string, code_verifier: string, tenantId: UUID): Promise> { + exchangeOAuthCodeForAccessTokenUsingPKCE(code: string, client_id: string, client_secret: string, redirect_uri: string, code_verifier: string): Promise> { let body = new URLSearchParams(); body.append('code', code); @@ -1591,7 +1647,6 @@ export class FusionAuthClient { body.append('grant_type', 'authorization_code'); body.append('redirect_uri', redirect_uri); body.append('code_verifier', code_verifier); - body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1599,6 +1654,36 @@ export class FusionAuthClient { .go(); } + /** + * Exchanges an OAuth authorization code and code_verifier for an access token. + * Makes a request to the Token endpoint to exchange the authorization code returned from the Authorize endpoint and a code_verifier for an access token. + * + * @param {OAuthCodePKCEAccessTokenRequest} request The PKCE OAuth code access token exchange request. + * @returns {Promise>} + */ + exchangeOAuthCodeForAccessTokenUsingPKCEWithRequest(request: OAuthCodePKCEAccessTokenRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/token') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + + /** + * Exchanges an OAuth authorization code for an access token. + * Makes a request to the Token endpoint to exchange the authorization code returned from the Authorize endpoint for an access token. + * + * @param {OAuthCodeAccessTokenRequest} request The OAuth code access token exchange request. + * @returns {Promise>} + */ + exchangeOAuthCodeForAccessTokenWithRequest(request: OAuthCodeAccessTokenRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/token') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Exchange a Refresh Token for an Access Token. * If you will be using the Refresh Token Grant, you will make a request to the Token endpoint to exchange the user’s refresh token for an access token. @@ -1609,10 +1694,9 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header. * @param {string} scope (Optional) This parameter is optional and if omitted, the same scope requested during the authorization request will be used. If provided the scopes must match those requested during the initial authorization request. * @param {string} user_code (Optional) The end-user verification code. This code is required if using this endpoint to approve the Device Authorization. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. Required if the request is for a universal application. * @returns {Promise>} */ - exchangeRefreshTokenForAccessToken(refresh_token: string, client_id: string, client_secret: string, scope: string, user_code: string, tenantId: UUID): Promise> { + exchangeRefreshTokenForAccessToken(refresh_token: string, client_id: string, client_secret: string, scope: string, user_code: string): Promise> { let body = new URLSearchParams(); body.append('refresh_token', refresh_token); @@ -1621,7 +1705,6 @@ export class FusionAuthClient { body.append('grant_type', 'refresh_token'); body.append('scope', scope); body.append('user_code', user_code); - body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1629,6 +1712,21 @@ export class FusionAuthClient { .go(); } + /** + * Exchange a Refresh Token for an Access Token. + * If you will be using the Refresh Token Grant, you will make a request to the Token endpoint to exchange the user’s refresh token for an access token. + * + * @param {RefreshTokenAccessTokenRequest} request The refresh token access token exchange request. + * @returns {Promise>} + */ + exchangeRefreshTokenForAccessTokenWithRequest(request: RefreshTokenAccessTokenRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/token') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Exchange a refresh token for a new JWT. * @@ -1654,10 +1752,9 @@ export class FusionAuthClient { * @param {string} client_secret (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header. * @param {string} scope (Optional) This parameter is optional and if omitted, the same scope requested during the authorization request will be used. If provided the scopes must match those requested during the initial authorization request. * @param {string} user_code (Optional) The end-user verification code. This code is required if using this endpoint to approve the Device Authorization. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - exchangeUserCredentialsForAccessToken(username: string, password: string, client_id: string, client_secret: string, scope: string, user_code: string, tenantId: UUID): Promise> { + exchangeUserCredentialsForAccessToken(username: string, password: string, client_id: string, client_secret: string, scope: string, user_code: string): Promise> { let body = new URLSearchParams(); body.append('username', username); @@ -1667,7 +1764,6 @@ export class FusionAuthClient { body.append('grant_type', 'password'); body.append('scope', scope); body.append('user_code', user_code); - body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/token') .withFormData(body) @@ -1675,6 +1771,21 @@ export class FusionAuthClient { .go(); } + /** + * Exchange User Credentials for a Token. + * If you will be using the Resource Owner Password Credential Grant, you will make a request to the Token endpoint to exchange the user’s email and password for an access token. + * + * @param {UserCredentialsAccessTokenRequest} request The user credentials access token exchange request. + * @returns {Promise>} + */ + exchangeUserCredentialsForAccessTokenWithRequest(request: UserCredentialsAccessTokenRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/token') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Begins the forgot password sequence, which kicks off an email to the user so that they can reset their password. * @@ -1877,15 +1988,13 @@ export class FusionAuthClient { * * @param {string} client_id The unique client identifier. The client Id is the Id of the FusionAuth Application for which this token was generated. * @param {string} token The access token returned by this OAuth provider as the result of a successful client credentials grant. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - introspectAccessToken(client_id: string, token: string, tenantId: UUID): Promise> { + introspectAccessToken(client_id: string, token: string): Promise> { let body = new URLSearchParams(); body.append('client_id', client_id); body.append('token', token); - body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/introspect') .withFormData(body) @@ -1893,18 +2002,30 @@ export class FusionAuthClient { .go(); } + /** + * Inspect an access token issued as the result of the User based grant such as the Authorization Code Grant, Implicit Grant, the User Credentials Grant or the Refresh Grant. + * + * @param {AccessTokenIntrospectRequest} request The access token introspection request. + * @returns {Promise>} + */ + introspectAccessTokenWithRequest(request: AccessTokenIntrospectRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/introspect') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Inspect an access token issued as the result of the Client Credentials Grant. * * @param {string} token The access token returned by this OAuth provider as the result of a successful client credentials grant. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - introspectClientCredentialsAccessToken(token: string, tenantId: UUID): Promise> { + introspectClientCredentialsAccessToken(token: string): Promise> { let body = new URLSearchParams(); body.append('token', token); - body.append('tenantId', tenantId); return this.startAnonymous() .withUri('/oauth2/introspect') .withFormData(body) @@ -1912,6 +2033,20 @@ export class FusionAuthClient { .go(); } + /** + * Inspect an access token issued as the result of the Client Credentials Grant. + * + * @param {ClientCredentialsAccessTokenIntrospectRequest} request The client credentials access token. + * @returns {Promise>} + */ + introspectClientCredentialsAccessTokenWithRequest(request: ClientCredentialsAccessTokenIntrospectRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/introspect') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Issue a new access token (JWT) for the requested Application after ensuring the provided JWT is valid. A valid * access token is properly signed and not expired. @@ -3999,10 +4134,9 @@ export class FusionAuthClient { * @param {string} client_id The client Id. * @param {string} client_secret The client Id. * @param {string} user_code The end-user verification code. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - retrieveUserCode(client_id: string, client_secret: string, user_code: string, tenantId: UUID): Promise> { + retrieveUserCode(client_id: string, client_secret: string, user_code: string): Promise> { let body = new URLSearchParams(); body.append('client_id', client_id); @@ -4010,7 +4144,6 @@ export class FusionAuthClient { body.append('user_code', user_code); return this.startAnonymous() .withUri('/oauth2/device/user-code') - .withParameter('tenantId', tenantId) .withFormData(body) .withMethod("GET") .go(); @@ -4024,21 +4157,53 @@ export class FusionAuthClient { * This request will require an API key. * * @param {string} user_code The end-user verification code. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - retrieveUserCodeUsingAPIKey(user_code: string, tenantId: UUID): Promise> { + retrieveUserCodeUsingAPIKey(user_code: string): Promise> { let body = new URLSearchParams(); body.append('user_code', user_code); return this.startAnonymous() .withUri('/oauth2/device/user-code') - .withParameter('tenantId', tenantId) .withFormData(body) .withMethod("GET") .go(); } + /** + * Retrieve a user_code that is part of an in-progress Device Authorization Grant. + * + * This API is useful if you want to build your own login workflow to complete a device grant. + * + * This request will require an API key. + * + * @param {RetrieveUserCodeUsingAPIKeyRequest} request The user code retrieval request including optional tenantId. + * @returns {Promise>} + */ + retrieveUserCodeUsingAPIKeyWithRequest(request: RetrieveUserCodeUsingAPIKeyRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/device/user-code') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + + /** + * Retrieve a user_code that is part of an in-progress Device Authorization Grant. + * + * This API is useful if you want to build your own login workflow to complete a device grant. + * + * @param {RetrieveUserCodeRequest} request The user code retrieval request. + * @returns {Promise>} + */ + retrieveUserCodeWithRequest(request: RetrieveUserCodeRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/device/user-code') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Retrieves all the comments for the user with the given Id. * @@ -5570,19 +5735,32 @@ export class FusionAuthClient { * * @param {string} user_code The end-user verification code. * @param {string} client_id The client Id. - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - validateDevice(user_code: string, client_id: string, tenantId: UUID): Promise> { + validateDevice(user_code: string, client_id: string): Promise> { return this.startAnonymous() .withUri('/oauth2/device/validate') .withParameter('user_code', user_code) .withParameter('client_id', client_id) - .withParameter('tenantId', tenantId) .withMethod("GET") .go(); } + /** + * Validates the end-user provided user_code from the user-interaction of the Device Authorization Grant. + * If you build your own activation form you should validate the user provided code prior to beginning the Authorization grant. + * + * @param {ValidateDeviceRequest} request The device validation request. + * @returns {Promise>} + */ + validateDeviceWithRequest(request: ValidateDeviceRequest): Promise> { + return this.startAnonymous() + .withUri('/oauth2/device/validate') + .withJSONBody(request) + .withMethod("POST") + .go(); + } + /** * Validates the provided JWT (encoded JWT string) to ensure the token is valid. A valid access token is properly * signed and not expired. @@ -5824,6 +6002,17 @@ export interface AccessToken { userId?: UUID; } +/** + * The request object for introspecting an access token. + * + * @author Lyle Schemmerling + */ +export interface AccessTokenIntrospectRequest { + client_id?: string; + tenantId?: string; + token?: string; +} + /** * The user action request object. * @@ -6700,6 +6889,29 @@ export enum ClientAuthenticationPolicy { NotRequiredWhenUsingPKCE = "NotRequiredWhenUsingPKCE" } +/** + * Contains the parameters used to introspect an access token that was obtained via the client credentials grant. + * + * @author Lyle Schemmerling + */ +export interface ClientCredentialsAccessTokenIntrospectRequest { + tenantId?: string; + token?: string; +} + +/** + * The request object to make a Client Credentials grant request to obtain an access token. + * + * @author Lyle Schemmerling + */ +export interface ClientCredentialsGrantRequest { + client_id?: string; + client_secret?: string; + grant_type?: string; + scope?: string; + tenantId?: string; +} + /** * @author Trevor Smith */ @@ -6904,6 +7116,20 @@ export interface DailyActiveUserReportResponse { total?: number; } +/** + * The request object to approve a device grant. + * + * @author Lyle Schemmerling + */ +export interface DeviceApprovalRequest { + client_id?: string; + client_secret?: string; + metaData?: MetaData; + tenantId?: UUID; + token?: string; + user_code?: string; +} + /** * @author Daniel DeGroff */ @@ -6915,6 +7141,17 @@ export interface DeviceApprovalResponse { userId?: UUID; } +/** + * @author Lyle Schemmerling + */ +export interface DeviceAuthorizationRequest { + client_id?: string; + client_secret?: string; + metaData?: MetaData; + scope?: string; + tenantId?: UUID; +} + /** * @author Daniel DeGroff */ @@ -9493,6 +9730,36 @@ export enum OAuthApplicationRelationship { ThirdParty = "ThirdParty" } +/** + * The request object for exchanging an OAuth authorization code for an access token. + * + * @author Lyle Schemmerling + */ +export interface OAuthCodeAccessTokenRequest { + client_id?: string; + client_secret?: string; + code?: string; + grant_type?: string; + redirect_uri?: string; + tenantId?: string; +} + +/** + * The request object to make a request to the Token endpoint to exchange the authorization code returned from the Authorize endpoint and a + * code_verifier for an access token. + * + * @author Lyle Schemmerling + */ +export interface OAuthCodePKCEAccessTokenRequest { + client_id?: string; + client_secret?: string; + code?: string; + code_verifier?: string; + grant_type?: string; + redirect_uri?: string; + tenantId?: UUID; +} + /** * @author Daniel DeGroff */ @@ -10142,6 +10409,21 @@ export interface MetaData { scopes?: Array; } +/** + * The request object to exchange a Refresh Token for an Access Token. + * + * @author Lyle Schemmerling + */ +export interface RefreshTokenAccessTokenRequest { + client_id?: string; + client_secret?: string; + grant_type?: string; + refresh_token?: string; + scope?: string; + tenantId?: UUID; + user_code?: string; +} + /** * @author Daniel DeGroff */ @@ -10327,6 +10609,28 @@ export enum ResidentKeyRequirement { required = "required" } +/** + * The request object for retrieving a user code that is part of an in-progress Device Authorization Grant. + * + * @author Lyle Schemmerling + */ +export interface RetrieveUserCodeRequest { + client_id?: string; + client_secret?: string; + tenantId?: UUID; + user_code?: string; +} + +/** + * The request object for retrieving a user code that is part of an in-progress Device Authorization Grant using an API key + * + * @author Lyle Schemmerling + */ +export interface RetrieveUserCodeUsingAPIKeyRequest { + tenantId?: UUID; + user_code?: string; +} + /** * @author Brian Pontarelli */ @@ -11777,6 +12081,22 @@ export interface UserCreateCompleteEvent extends BaseUserEvent { export interface UserCreateEvent extends BaseUserEvent { } +/** + * The request object for exchanging user credentials (username and password) for an access token. + * + * @author Lyle Schemmerling + */ +export interface UserCredentialsAccessTokenRequest { + client_id?: string; + client_secret?: string; + grant_type?: string; + password?: string; + scope?: string; + tenantId?: string; + user_code?: string; + username?: string; +} + /** * Models the User Deactivate Event. * @@ -12264,6 +12584,17 @@ export enum UserVerificationRequirement { export interface UserinfoResponse extends Record { } +/** + * The request object for validating an end-user provided user_code from the user-interaction of the Device Authorization Grant + * + * @author Lyle Schemmerling + */ +export interface ValidateDeviceRequest { + client_id?: string; + tenantId?: UUID; + user_code?: string; +} + /** * @author Daniel DeGroff */ From bfb00d0ae3e1c7bf83526d413969ac1cac4d161e Mon Sep 17 00:00:00 2001 From: Lyle Schemmerling Date: Tue, 23 Sep 2025 12:42:52 -0600 Subject: [PATCH 3/3] fix imports and user info --- src/FusionAuthClient.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/FusionAuthClient.ts b/src/FusionAuthClient.ts index afa8bba..2e1d83d 100644 --- a/src/FusionAuthClient.ts +++ b/src/FusionAuthClient.ts @@ -4250,14 +4250,12 @@ export class FusionAuthClient { * Call the UserInfo endpoint to retrieve User Claims from the access token issued by FusionAuth. * * @param {string} encodedJWT The encoded JWT (access token). - * @param {UUID} tenantId (Optional) The Id of the tenant to use for this request. * @returns {Promise>} */ - retrieveUserInfoFromAccessToken(encodedJWT: string, tenantId: UUID): Promise> { + retrieveUserInfoFromAccessToken(encodedJWT: string): Promise> { return this.startAnonymous() .withUri('/oauth2/userinfo') .withAuthorization('Bearer ' + encodedJWT) - .withParameter('tenantId', tenantId) .withMethod("GET") .go(); }