fetchAccountDetails method

Future<GoogleAccountDetails> fetchAccountDetails(
  1. Session session, {
  2. required String idToken,
})

Returns the account details for the given idToken.

Implementation

Future<GoogleAccountDetails> fetchAccountDetails(
  final Session session, {
  required final String idToken,
}) async {
  final clientSecret = GoogleAccounts.secrets;
  if (clientSecret == null) {
    throw StateError('The server side Google client secret is not loaded.');
  }

  final String clientId = clientSecret.clientId;

  // Verify the ID token with Google's servers.
  final response = await http.get(
    Uri.https(
      'www.googleapis.com',
      '/oauth2/v3/tokeninfo',
      {'id_token': idToken},
    ),
  );

  if (response.statusCode != 200) {
    session.log(
      'Invalid token response status: ${response.statusCode}',
      level: LogLevel.debug,
    );

    throw GoogleIdTokenVerificationException();
  }

  final data = jsonDecode(response.body);
  if (data is! Map<String, dynamic>) {
    session.log(
      'Invalid token response, content was not a Map.',
      level: LogLevel.debug,
    );

    throw GoogleIdTokenVerificationException();
  }

  final issuer = data['iss'] as String?;
  if (issuer != 'accounts.google.com' &&
      issuer != 'https://accounts.google.com') {
    session.log(
      'Invalid token response, unexpected issuer "$issuer"',
      level: LogLevel.debug,
    );

    throw GoogleIdTokenVerificationException();
  }

  if (data['aud'] != clientId) {
    session.log(
      'Invalid token response, client ID does not match',
      level: LogLevel.debug,
    );

    throw GoogleIdTokenVerificationException();
  }

  final userId = data['sub'] as String?;
  final email = data['email'] as String?;
  final verifiedEmail = data['verified_email'] as bool? ??
      ((data['email_verified'] as String?) == 'true');
  final fullName = data['name'] as String?;
  final image = data['picture'] as String?;
  final name = data['given_name'] as String?;

  if (userId == null ||
      email == null ||
      verifiedEmail != true ||
      fullName == null ||
      image == null ||
      name == null) {
    session.log(
      'Invalid token response, missing required data: $data',
      level: LogLevel.debug,
    );

    throw GoogleIdTokenVerificationException();
  }

  return (
    userIdentifier: userId,
    email: email,
    name: name,
    fullName: fullName,
    image: image,
  );
}