fetchAccountDetails method
Future<GitHubAccountDetails>
fetchAccountDetails(
- Session session, {
- required String accessToken,
Returns the account details for the given accessToken.
This method calls GitHub's user API.
Throws GitHubAccessTokenVerificationException if the user info retrieval fails.
Implementation
Future<GitHubAccountDetails> fetchAccountDetails(
final Session session, {
required final String accessToken,
}) async {
// More info on the user API:
// https://docs.github.com/en/rest/users/users#get-the-authenticated-user
final response = await http.get(
Uri.https('api.github.com', '/user'),
headers: {
'Authorization': 'Bearer $accessToken',
'Accept': 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
},
);
if (response.statusCode != 200) {
session.logAndThrow(
'Failed to verify access token from GitHub: ${response.statusCode}',
);
}
Map<String, dynamic> data;
try {
data = jsonDecode(response.body) as Map<String, dynamic>;
} catch (e) {
session.logAndThrow('Invalid user info from GitHub: $e');
}
if (data['email'] == null) {
final emailResponse = await http.get(
Uri.https('api.github.com', '/user/emails'),
headers: {
'Authorization': 'Bearer $accessToken',
'Accept': 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
},
);
if (emailResponse.statusCode == 200) {
try {
final emails = (jsonDecode(emailResponse.body) as List)
.cast<Map<String, dynamic>>();
final primary = emails.firstWhere(
(final e) => e['primary'] == true && e['verified'] == true,
orElse: () => <String, dynamic>{},
);
if (primary['email'] is String) {
data['email'] = primary['email'];
}
} catch (e) {
session.log(
'Failed to fetch primary email from GitHub: $e',
level: LogLevel.debug,
exception: e,
);
}
}
}
GitHubAccountDetails details;
try {
details = _parseAccountDetails(data);
} catch (e) {
session.logAndThrow('Invalid user info from GitHub: $e');
}
return details;
}