UNPKG

auth0

Version:
242 lines 10.8 kB
import { JSONApiResponse, VoidApiResponse, validateRequiredRequestParams, } from '../lib/runtime.js'; import { BaseAuthAPI, grant } from './base-auth-api.js'; import { IDTokenValidator } from './id-token-validator.js'; import { mtlsPrefix } from '../utils.js'; export const TOKEN_FOR_CONNECTION_GRANT_TYPE = 'urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token'; export const TOKEN_FOR_CONNECTION_TOKEN_TYPE = 'urn:ietf:params:oauth:token-type:refresh_token'; export const TOKEN_FOR_CONNECTION_REQUESTED_TOKEN_TYPE = 'http://auth0.com/oauth/token-type/federated-connection-access-token'; export const TOKEN_URL = '/oauth/token'; /** * OAuth 2.0 flows. */ export class OAuth extends BaseAuthAPI { constructor(options) { super({ ...options, domain: options.useMTLS ? `${mtlsPrefix}.${options.domain}` : options.domain, }); this.idTokenValidator = new IDTokenValidator(options); } /** * This is the flow that regular web apps use to access an API. * * Use this endpoint to exchange an Authorization Code for a Token. * * See: https://auth0.com/docs/api/authentication#authorization-code-flow44 * * @example * ```js * const auth0 = new AuthenticationApi({ * domain: 'my-domain.auth0.com', * clientId: 'myClientId', * clientSecret: 'myClientSecret' * }); * * await auth0.oauth.authorizationCodeGrant({ code: 'mycode' }); * ``` */ async authorizationCodeGrant(bodyParameters, options = {}) { validateRequiredRequestParams(bodyParameters, ['code']); return grant('authorization_code', await this.addClientAuthentication(bodyParameters), options, this.clientId, this.idTokenValidator, this.request.bind(this)); } /** * PKCE was originally designed to protect the authorization code flow in mobile apps, * but its ability to prevent authorization code injection makes it useful for every type of OAuth client, * even web apps that use client authentication. * * See: https://auth0.com/docs/api/authentication#authorization-code-flow-with-pkce45 * * @example * ```js * const auth0 = new AuthenticationApi({ * domain: 'my-domain.auth0.com', * clientId: 'myClientId', * clientSecret: 'myClientSecret' * }); * * await auth0.oauth.authorizationCodeGrantWithPKCE({ * code: 'mycode', * code_verifier: 'mycodeverifier' * }); * ``` */ async authorizationCodeGrantWithPKCE(bodyParameters, options = {}) { validateRequiredRequestParams(bodyParameters, ['code', 'code_verifier']); return grant('authorization_code', await this.addClientAuthentication(bodyParameters), options, this.clientId, this.idTokenValidator, this.request.bind(this)); } /** * This is the OAuth 2.0 grant that server processes use to access an API. * * Use this endpoint to directly request an Access Token by using the Client's credentials * (a Client ID and a Client Secret or a Client Assertion). * * See: https://auth0.com/docs/api/authentication#client-credentials-flow * * @example * ```js * const auth0 = new AuthenticationApi({ * domain: 'my-domain.auth0.com', * clientId: 'myClientId', * clientSecret: 'myClientSecret' * }); * * await auth0.oauth.clientCredentialsGrant({ audience: 'myaudience' }); * ``` */ async clientCredentialsGrant(bodyParameters, options = {}) { validateRequiredRequestParams(bodyParameters, ['audience']); return grant('client_credentials', await this.addClientAuthentication(bodyParameters), options, this.clientId, this.idTokenValidator, this.request.bind(this)); } /** * This is the OAuth 2.0 extension that allows to initiate an OAuth flow from the backchannel instead of by building a URL. * * * See: https://www.rfc-editor.org/rfc/rfc9126.html * * @example * ```js * const auth0 = new AuthenticationApi({ * domain: 'my-domain.auth0.com', * clientId: 'myClientId', * clientSecret: 'myClientSecret' * }); * * await auth0.oauth.pushedAuthorization({ response_type: 'id_token', redirect_uri: 'http://localhost' }); * ``` */ async pushedAuthorization(bodyParameters, options = {}) { validateRequiredRequestParams(bodyParameters, ['client_id', 'response_type', 'redirect_uri']); const bodyParametersWithClientAuthentication = await this.addClientAuthentication(bodyParameters); const response = await this.request({ path: '/oauth/par', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ client_id: this.clientId, ...bodyParametersWithClientAuthentication, }), }, options.initOverrides); return JSONApiResponse.fromResponse(response); } /** * This information is typically received from a highly trusted public client like a SPA*. * (<strong>*Note:</string> For single-page applications and native/mobile apps, we recommend using web flows instead.) * * See: https://auth0.com/docs/api/authentication#resource-owner-password * * @example * ```js * const auth0 = new AuthenticationApi({ * domain: 'my-domain.auth0.com', * clientId: 'myClientId' * clientSecret: 'myClientSecret' * }); * * await auth0.oauth.passwordGrant({ * username: 'myusername@example.com', * password: 'mypassword' * }, * { initOverrides: { headers: { 'auth0-forwarded-for': 'END.USER.IP.123' } } } * ); * ``` * * Set the'auth0-forwarded-for' header to the end-user IP as a string value if you want * brute-force protection to work in server-side scenarios. * * See https://auth0.com/docs/get-started/authentication-and-authorization-flow/avoid-common-issues-with-resource-owner-password-flow-and-attack-protection * */ async passwordGrant(bodyParameters, options = {}) { validateRequiredRequestParams(bodyParameters, ['username', 'password']); return grant(bodyParameters.realm ? 'http://auth0.com/oauth/grant-type/password-realm' : 'password', await this.addClientAuthentication(bodyParameters), options, this.clientId, this.idTokenValidator, this.request.bind(this)); } /** * Use this endpoint to refresh an Access Token using the Refresh Token you got during authorization. * * See: https://auth0.com/docs/api/authentication#refresh-token * * @example * ```js * const auth0 = new AuthenticationApi({ * domain: 'my-domain.auth0.com', * clientId: 'myClientId' * clientSecret: 'myClientSecret' * }); * * await auth0.oauth.refreshTokenGrant({ refresh_token: 'myrefreshtoken' }) * ``` */ async refreshTokenGrant(bodyParameters, options = {}) { validateRequiredRequestParams(bodyParameters, ['refresh_token']); return grant('refresh_token', await this.addClientAuthentication(bodyParameters), options, this.clientId, this.idTokenValidator, this.request.bind(this)); } /** * Use this endpoint to invalidate a Refresh Token if it has been compromised. * * The behaviour of this endpoint depends on the state of the <a href="https://auth0.com/docs/secure/tokens/refresh-tokens/revoke-refresh-tokens#refresh-tokens-and-grants">Refresh Token Revocation Deletes Grant</a> toggle. * If this toggle is enabled, then each revocation request invalidates not only the specific token, but all other tokens based on the same authorization grant. * This means that all Refresh Tokens that have been issued for the same user, application, and audience will be revoked. * If this toggle is disabled, then only the refresh token is revoked, while the grant is left intact. * * See: https://auth0.com/docs/api/authentication#revoke-refresh-token * * @example * ```js * const auth0 = new AuthenticationApi({ * domain: 'my-domain.auth0.com', * clientId: 'myClientId' * clientSecret: 'myClientSecret' * }); * * await auth0.oauth.revokeRefreshToken({ token: 'myrefreshtoken' }) * ``` */ async revokeRefreshToken(bodyParameters, options = {}) { validateRequiredRequestParams(bodyParameters, ['token']); const response = await this.request({ path: '/oauth/revoke', method: 'POST', headers: { 'Content-Type': 'application/json', }, body: await this.addClientAuthentication({ client_id: this.clientId, ...bodyParameters }), }, options.initOverrides); return VoidApiResponse.fromResponse(response); } /** * Exchanges a subject token (refresh token in this case) for an access token for the connection. * * The request body includes: * - client_id (and client_secret/client_assertion via addClientAuthentication) * - grant_type set to `urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token` * - subject_token (refresh token) and fixed subject_token_type for refresh tokens (`urn:ietf:params:oauth:token-type:refresh_token`) * - requested_token_type (`http://auth0.com/oauth/token-type/federated-connection-access-token`) indicating that a federated connection access token is desired * - connection name and an optional `login_hint` if provided * * @param bodyParameters - The options to retrieve a token for a connection. * @returns A promise with the token response data. * @throws An error if the exchange fails. */ async tokenForConnection(bodyParameters, options = {}) { validateRequiredRequestParams(bodyParameters, ['connection', 'subject_token']); const body = { ...bodyParameters, grant_type: TOKEN_FOR_CONNECTION_GRANT_TYPE, subject_token_type: TOKEN_FOR_CONNECTION_TOKEN_TYPE, requested_token_type: TOKEN_FOR_CONNECTION_REQUESTED_TOKEN_TYPE, }; await this.addClientAuthentication(body); const response = await this.request({ path: TOKEN_URL, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams(body), }, options.initOverrides); return JSONApiResponse.fromResponse(response); } } //# sourceMappingURL=oauth.js.map