loadOAuthProfile<TProfile extends Object> function

Future<Map<String, dynamic>> loadOAuthProfile<TProfile extends Object>(
  1. OAuthProvider<TProfile> provider, {
  2. required OAuthTokenResponse token,
  3. required Client httpClient,
  4. String? oidcNonce,
})

Loads a provider profile from userinfo or an ID token payload.

Implementation

Future<Map<String, dynamic>> loadOAuthProfile<TProfile extends Object>(
  OAuthProvider<TProfile> provider, {
  required OAuthTokenResponse token,
  required http.Client httpClient,
  String? oidcNonce,
}) async {
  if (provider.userInfoEndpoint == null) {
    final idToken = token.raw['id_token']?.toString();
    if (provider.type == AuthProviderType.oidc &&
        (idToken == null || idToken.isEmpty)) {
      throw AuthFlowException('oidc_id_token_missing');
    }
    if (idToken != null && idToken.isNotEmpty) {
      final issuer = provider.oidcIssuer;
      final jwksUri = provider.oidcJwksUri;
      if (issuer == null || jwksUri == null) {
        throw AuthFlowException('oidc_validation_unconfigured');
      }
      try {
        final payload = await JwtVerifier(
          options: JwtOptions(
            issuer: issuer.toString(),
            audience: [provider.clientId],
            requiredClaims: const ['sub', 'iss', 'aud', 'exp'],
            jwksUri: jwksUri,
            algorithms: provider.oidcAlgorithms,
          ),
          httpClient: httpClient,
        ).verifyToken(idToken);
        if (oidcNonce == null || payload.claims['nonce'] != oidcNonce) {
          throw AuthFlowException('oidc_nonce_mismatch');
        }
        return payload.claims;
      } on AuthFlowException {
        rethrow;
      } catch (_) {
        throw AuthFlowException('id_token_invalid');
      }
    }
    return <String, dynamic>{};
  }

  if (provider.userInfoRequest != null) {
    try {
      return await Future.sync(
        () => provider.userInfoRequest!(
          token,
          httpClient,
          provider.userInfoEndpoint!,
        ),
      ).timeout(provider.requestTimeout);
    } catch (_) {
      throw AuthFlowException('userinfo_failed');
    }
  }

  try {
    return await oauthClientForProvider(
      provider,
      httpClient: httpClient,
    ).fetchUserInfo(provider.userInfoEndpoint!, token.accessToken);
  } catch (_) {
    throw AuthFlowException('userinfo_failed');
  }
}