1{"version":3,"file":"TokenRequest.js","sourceRoot":"","sources":["../src/TokenRequest.ts"],"names":[],"mappings":"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","sourcesContent":["import invariant from 'invariant';\nimport { Platform } from 'react-native';\n\nimport * as Base64 from './Base64';\nimport * as ServiceConfig from './Discovery';\nimport { ResponseErrorConfig, TokenError } from './Errors';\nimport { Headers, requestAsync } from './Fetch';\nimport {\n  AccessTokenRequestConfig,\n  GrantType,\n  RefreshTokenRequestConfig,\n  RevokeTokenRequestConfig,\n  ServerTokenResponseConfig,\n  TokenRequestConfig,\n  TokenResponseConfig,\n  TokenType,\n  TokenTypeHint,\n} from './TokenRequest.types';\n\n/**\n * Returns the current time in seconds.\n */\nexport function getCurrentTimeInSeconds(): number {\n  return Math.floor(Date.now() / 1000);\n}\n\n/**\n * Token Response.\n *\n * [Section 5.1](https://tools.ietf.org/html/rfc6749#section-5.1)\n */\nexport class TokenResponse implements TokenResponseConfig {\n  /**\n   * Determines whether a token refresh request must be made to refresh the tokens\n   *\n   * @param token\n   * @param secondsMargin\n   */\n  static isTokenFresh(\n    token: Pick<TokenResponse, 'expiresIn' | 'issuedAt'>,\n    /**\n     * -10 minutes in seconds\n     */\n    secondsMargin: number = 60 * 10 * -1\n  ): boolean {\n    if (!token) {\n      return false;\n    }\n    if (token.expiresIn) {\n      const now = getCurrentTimeInSeconds();\n      return now < token.issuedAt + token.expiresIn + secondsMargin;\n    }\n    // if there is no expiration time but we have an access token, it is assumed to never expire\n    return true;\n  }\n  /**\n   * Creates a `TokenResponse` from query parameters returned from an `AuthRequest`.\n   *\n   * @param params\n   */\n  static fromQueryParams(params: Record<string, any>): TokenResponse {\n    return new TokenResponse({\n      accessToken: params.access_token,\n      refreshToken: params.refresh_token,\n      scope: params.scope,\n      state: params.state,\n      idToken: params.id_token,\n      tokenType: params.token_type,\n      expiresIn: params.expires_in,\n      issuedAt: params.issued_at,\n    });\n  }\n\n  accessToken: string;\n  tokenType: TokenType;\n  expiresIn?: number;\n  refreshToken?: string;\n  scope?: string;\n  state?: string;\n  idToken?: string;\n  issuedAt: number;\n\n  constructor(response: TokenResponseConfig) {\n    this.accessToken = response.accessToken;\n    this.tokenType = response.tokenType ?? 'bearer';\n    this.expiresIn = response.expiresIn;\n    this.refreshToken = response.refreshToken;\n    this.scope = response.scope;\n    this.state = response.state;\n    this.idToken = response.idToken;\n    this.issuedAt = response.issuedAt ?? getCurrentTimeInSeconds();\n  }\n\n  private applyResponseConfig(response: TokenResponseConfig) {\n    this.accessToken = response.accessToken ?? this.accessToken;\n    this.tokenType = response.tokenType ?? this.tokenType ?? 'bearer';\n    this.expiresIn = response.expiresIn ?? this.expiresIn;\n    this.refreshToken = response.refreshToken ?? this.refreshToken;\n    this.scope = response.scope ?? this.scope;\n    this.state = response.state ?? this.state;\n    this.idToken = response.idToken ?? this.idToken;\n    this.issuedAt = response.issuedAt ?? this.issuedAt ?? getCurrentTimeInSeconds();\n  }\n\n  getRequestConfig(): TokenResponseConfig {\n    return {\n      accessToken: this.accessToken,\n      idToken: this.idToken,\n      refreshToken: this.refreshToken,\n      scope: this.scope,\n      state: this.state,\n      tokenType: this.tokenType,\n      issuedAt: this.issuedAt,\n      expiresIn: this.expiresIn,\n    };\n  }\n\n  async refreshAsync(\n    config: Omit<TokenRequestConfig, 'grantType' | 'refreshToken'>,\n    discovery: Pick<ServiceConfig.DiscoveryDocument, 'tokenEndpoint'>\n  ): Promise<TokenResponse> {\n    const request = new RefreshTokenRequest({\n      ...config,\n      refreshToken: this.refreshToken,\n    });\n    const response = await request.performAsync(discovery);\n    // Custom: reuse the refresh token if one wasn't returned\n    response.refreshToken = response.refreshToken ?? this.refreshToken;\n    const json = response.getRequestConfig();\n    this.applyResponseConfig(json);\n    return this;\n  }\n\n  shouldRefresh(): boolean {\n    // no refresh token available and token has expired\n    return !(TokenResponse.isTokenFresh(this) || !this.refreshToken);\n  }\n}\n\nclass Request<T, B> {\n  constructor(protected request: T) {}\n\n  async performAsync(discovery: ServiceConfig.DiscoveryDocument): Promise<B> {\n    throw new Error('performAsync must be extended');\n  }\n\n  getRequestConfig(): T {\n    throw new Error('getRequestConfig must be extended');\n  }\n\n  getQueryBody(): Record<string, string> {\n    throw new Error('getQueryBody must be extended');\n  }\n}\n\n/**\n * A generic token request.\n */\nclass TokenRequest<T extends TokenRequestConfig> extends Request<T, TokenResponse> {\n  readonly clientId: string;\n  readonly clientSecret?: string;\n  readonly scopes?: string[];\n  readonly extraParams?: Record<string, string>;\n\n  constructor(\n    request,\n    public grantType: GrantType\n  ) {\n    super(request);\n    this.clientId = request.clientId;\n    this.clientSecret = request.clientSecret;\n    this.extraParams = request.extraParams;\n    this.scopes = request.scopes;\n  }\n\n  getHeaders(): Headers {\n    const headers: Headers = { 'Content-Type': 'application/x-www-form-urlencoded' };\n    if (typeof this.clientSecret !== 'undefined') {\n      // If client secret exists, it should be converted to base64\n      // https://tools.ietf.org/html/rfc6749#section-2.3.1\n      const encodedClientId = encodeURIComponent(this.clientId);\n      const encodedClientSecret = encodeURIComponent(this.clientSecret);\n      const credentials = `${encodedClientId}:${encodedClientSecret}`;\n      const basicAuth = Base64.encodeNoWrap(credentials);\n      headers.Authorization = `Basic ${basicAuth}`;\n    }\n\n    return headers;\n  }\n\n  async performAsync(discovery: Pick<ServiceConfig.DiscoveryDocument, 'tokenEndpoint'>) {\n    // redirect URI must not be nil\n    invariant(\n      discovery.tokenEndpoint,\n      `Cannot invoke \\`performAsync()\\` without a valid tokenEndpoint`\n    );\n    const response = await requestAsync<ServerTokenResponseConfig | ResponseErrorConfig>(\n      discovery.tokenEndpoint,\n      {\n        dataType: 'json',\n        method: 'POST',\n        headers: this.getHeaders(),\n        body: this.getQueryBody(),\n      }\n    );\n\n    if ('error' in response) {\n      throw new TokenError(response);\n    }\n\n    return new TokenResponse({\n      accessToken: response.access_token,\n      tokenType: response.token_type,\n      expiresIn: response.expires_in,\n      refreshToken: response.refresh_token,\n      scope: response.scope,\n      idToken: response.id_token,\n      issuedAt: response.issued_at,\n    });\n  }\n\n  getQueryBody() {\n    const queryBody: Record<string, string> = {\n      grant_type: this.grantType,\n    };\n\n    if (!this.clientSecret) {\n      // Only add the client ID if client secret is not present, otherwise pass the client id with the secret in the request body.\n      queryBody.client_id = this.clientId;\n    }\n\n    if (this.scopes) {\n      queryBody.scope = this.scopes.join(' ');\n    }\n\n    if (this.extraParams) {\n      for (const extra in this.extraParams) {\n        if (extra in this.extraParams && !(extra in queryBody)) {\n          queryBody[extra] = this.extraParams[extra];\n        }\n      }\n    }\n    return queryBody;\n  }\n}\n\n/**\n * Access token request. Exchange an authorization code for a user access token.\n *\n * [Section 4.1.3](https://tools.ietf.org/html/rfc6749#section-4.1.3)\n */\nexport class AccessTokenRequest\n  extends TokenRequest<AccessTokenRequestConfig>\n  implements AccessTokenRequestConfig\n{\n  readonly code: string;\n  readonly redirectUri: string;\n\n  constructor(options: AccessTokenRequestConfig) {\n    invariant(\n      options.redirectUri,\n      `\\`AccessTokenRequest\\` requires a valid \\`redirectUri\\` (it must also match the one used in the auth request). Example: ${Platform.select(\n        {\n          web: 'https://yourwebsite.com/redirect',\n          default: 'myapp://redirect',\n        }\n      )}`\n    );\n\n    invariant(\n      options.code,\n      `\\`AccessTokenRequest\\` requires a valid authorization \\`code\\`. This is what's received from the authorization server after an auth request.`\n    );\n    super(options, GrantType.AuthorizationCode);\n    this.code = options.code;\n    this.redirectUri = options.redirectUri;\n  }\n\n  getQueryBody() {\n    const queryBody: Record<string, string> = super.getQueryBody();\n\n    if (this.redirectUri) {\n      queryBody.redirect_uri = this.redirectUri;\n    }\n\n    if (this.code) {\n      queryBody.code = this.code;\n    }\n\n    return queryBody;\n  }\n\n  getRequestConfig() {\n    return {\n      clientId: this.clientId,\n      clientSecret: this.clientSecret,\n      grantType: this.grantType,\n      code: this.code,\n      redirectUri: this.redirectUri,\n      extraParams: this.extraParams,\n      scopes: this.scopes,\n    };\n  }\n}\n\n/**\n * Refresh request.\n *\n * [Section 6](https://tools.ietf.org/html/rfc6749#section-6)\n */\nexport class RefreshTokenRequest\n  extends TokenRequest<RefreshTokenRequestConfig>\n  implements RefreshTokenRequestConfig\n{\n  readonly refreshToken?: string;\n\n  constructor(options: RefreshTokenRequestConfig) {\n    invariant(options.refreshToken, `\\`RefreshTokenRequest\\` requires a valid \\`refreshToken\\`.`);\n    super(options, GrantType.RefreshToken);\n    this.refreshToken = options.refreshToken;\n  }\n\n  getQueryBody() {\n    const queryBody = super.getQueryBody();\n\n    if (this.refreshToken) {\n      queryBody.refresh_token = this.refreshToken;\n    }\n\n    return queryBody;\n  }\n\n  getRequestConfig() {\n    return {\n      clientId: this.clientId,\n      clientSecret: this.clientSecret,\n      grantType: this.grantType,\n      refreshToken: this.refreshToken,\n      extraParams: this.extraParams,\n      scopes: this.scopes,\n    };\n  }\n}\n\n/**\n * Revocation request for a given token.\n *\n * [Section 2.1](https://tools.ietf.org/html/rfc7009#section-2.1)\n */\nexport class RevokeTokenRequest\n  extends Request<RevokeTokenRequestConfig, boolean>\n  implements RevokeTokenRequestConfig\n{\n  readonly clientId?: string;\n  readonly clientSecret?: string;\n  readonly token: string;\n  readonly tokenTypeHint?: TokenTypeHint;\n\n  constructor(request: RevokeTokenRequestConfig) {\n    super(request);\n    invariant(request.token, `\\`RevokeTokenRequest\\` requires a valid \\`token\\` to revoke.`);\n    this.clientId = request.clientId;\n    this.clientSecret = request.clientSecret;\n    this.token = request.token;\n    this.tokenTypeHint = request.tokenTypeHint;\n  }\n\n  getHeaders(): Headers {\n    const headers: Headers = { 'Content-Type': 'application/x-www-form-urlencoded' };\n    if (typeof this.clientSecret !== 'undefined' && this.clientId) {\n      // If client secret exists, it should be converted to base64\n      // https://tools.ietf.org/html/rfc6749#section-2.3.1\n      const encodedClientId = encodeURIComponent(this.clientId);\n      const encodedClientSecret = encodeURIComponent(this.clientSecret);\n      const credentials = `${encodedClientId}:${encodedClientSecret}`;\n      const basicAuth = Base64.encodeNoWrap(credentials);\n      headers.Authorization = `Basic ${basicAuth}`;\n    }\n\n    return headers;\n  }\n\n  /**\n   * Perform a token revocation request.\n   *\n   * @param discovery The `revocationEndpoint` for a provider.\n   */\n  async performAsync(discovery: Pick<ServiceConfig.DiscoveryDocument, 'revocationEndpoint'>) {\n    invariant(\n      discovery.revocationEndpoint,\n      `Cannot invoke \\`performAsync()\\` without a valid revocationEndpoint`\n    );\n    await requestAsync<boolean>(discovery.revocationEndpoint, {\n      method: 'POST',\n      headers: this.getHeaders(),\n      body: this.getQueryBody(),\n    });\n\n    return true;\n  }\n\n  getRequestConfig() {\n    return {\n      clientId: this.clientId,\n      clientSecret: this.clientSecret,\n      token: this.token,\n      tokenTypeHint: this.tokenTypeHint,\n    };\n  }\n\n  getQueryBody(): Record<string, string> {\n    const queryBody: Record<string, string> = { token: this.token };\n    if (this.tokenTypeHint) {\n      queryBody.token_type_hint = this.tokenTypeHint;\n    }\n    // Include client creds https://tools.ietf.org/html/rfc6749#section-2.3.1\n    if (this.clientId) {\n      queryBody.client_id = this.clientId;\n    }\n    if (this.clientSecret) {\n      queryBody.client_secret = this.clientSecret;\n    }\n    return queryBody;\n  }\n}\n\n// @needsAudit\n/**\n * Exchange an authorization code for an access token that can be used to get data from the provider.\n *\n * @param config Configuration used to exchange the code for a token.\n * @param discovery The `tokenEndpoint` for a provider.\n * @return Returns a discovery document with a valid `tokenEndpoint` URL.\n */\nexport function exchangeCodeAsync(\n  config: AccessTokenRequestConfig,\n  discovery: Pick<ServiceConfig.DiscoveryDocument, 'tokenEndpoint'>\n): Promise<TokenResponse> {\n  const request = new AccessTokenRequest(config);\n  return request.performAsync(discovery);\n}\n\n// @needsAudit\n/**\n * Refresh an access token.\n * - If the provider didn't return a `refresh_token` then the access token may not be refreshed.\n * - If the provider didn't return a `expires_in` then it's assumed that the token does not expire.\n * - Determine if a token needs to be refreshed via `TokenResponse.isTokenFresh()` or `shouldRefresh()` on an instance of `TokenResponse`.\n *\n * @see [Section 6](https://tools.ietf.org/html/rfc6749#section-6).\n *\n * @param config Configuration used to refresh the given access token.\n * @param discovery The `tokenEndpoint` for a provider.\n * @return Returns a discovery document with a valid `tokenEndpoint` URL.\n */\nexport function refreshAsync(\n  config: RefreshTokenRequestConfig,\n  discovery: Pick<ServiceConfig.DiscoveryDocument, 'tokenEndpoint'>\n): Promise<TokenResponse> {\n  const request = new RefreshTokenRequest(config);\n  return request.performAsync(discovery);\n}\n\n// @needsAudit\n/**\n * Revoke a token with a provider. This makes the token unusable, effectively requiring the user to login again.\n *\n * @param config Configuration used to revoke a refresh or access token.\n * @param discovery The `revocationEndpoint` for a provider.\n * @return Returns a discovery document with a valid `revocationEndpoint` URL. Many providers do not support this feature.\n */\nexport function revokeAsync(\n  config: RevokeTokenRequestConfig,\n  discovery: Pick<ServiceConfig.DiscoveryDocument, 'revocationEndpoint'>\n): Promise<boolean> {\n  const request = new RevokeTokenRequest(config);\n  return request.performAsync(discovery);\n}\n\n/**\n * Fetch generic user info from the provider's OpenID Connect `userInfoEndpoint` (if supported).\n *\n * @see [UserInfo](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo).\n *\n * @param config The `accessToken` for a user, returned from a code exchange or auth request.\n * @param discovery The `userInfoEndpoint` for a provider.\n */\nexport function fetchUserInfoAsync(\n  config: Pick<TokenResponse, 'accessToken'>,\n  discovery: Pick<ServiceConfig.DiscoveryDocument, 'userInfoEndpoint'>\n): Promise<Record<string, any>> {\n  if (!discovery.userInfoEndpoint) {\n    throw new Error('User info endpoint is not defined in the service config discovery document');\n  }\n  return requestAsync<Record<string, any>>(discovery.userInfoEndpoint, {\n    headers: {\n      'Content-Type': 'application/x-www-form-urlencoded',\n      Authorization: `Bearer ${config.accessToken}`,\n    },\n    dataType: 'json',\n    method: 'GET',\n  });\n}\n"]}