githubProvider function

OAuthProvider<GitHubProfile> githubProvider(
  1. GitHubProviderOptions options
)

GitHub OAuth provider.

Based on GitHub's OAuth documentation and NextAuth's default provider configuration. Retrieves the authenticated user from GET /user and falls back to GET /user/emails if the email is missing.

Resources

Example

final provider = githubProvider(
  GitHubProviderOptions(
    clientId: 'client-id',
    clientSecret: 'client-secret',
    redirectUri: 'https://example.com/auth/callback/github',
  ),
);

Implementation

OAuthProvider<GitHubProfile> githubProvider(GitHubProviderOptions options) {
  final baseUrl = options.enterpriseBaseUrl ?? 'https://github.com';
  final apiBaseUrl = options.enterpriseBaseUrl != null
      ? '${options.enterpriseBaseUrl}/api/v3'
      : 'https://api.github.com';

  return OAuthProvider<GitHubProfile>(
    id: 'github',
    name: 'GitHub',
    clientId: options.clientId,
    clientSecret: options.clientSecret,
    authorizationEndpoint: Uri.parse('$baseUrl/login/oauth/authorize'),
    tokenEndpoint: Uri.parse('$baseUrl/login/oauth/access_token'),
    userInfoEndpoint: Uri.parse('$apiBaseUrl/user'),
    redirectUri: options.redirectUri,
    scopes: options.scopes,
    profileParser: GitHubProfile.fromJson,
    profileSerializer: (profile) => profile.toJson(),
    profile: (profile) {
      return AuthUser(
        id: profile.id.toString(),
        name: profile.name ?? profile.login,
        email: profile.email,
        image: profile.avatarUrl,
        attributes: profile.toJson(),
      );
    },
    profileRequest: (_, _, token, httpClient, profile) async {
      if (profile.email != null && profile.email!.isNotEmpty) {
        return profile;
      }
      final emails = await _loadGitHubEmails(token, httpClient, apiBaseUrl);
      if (emails.isEmpty) return profile;
      final primary = emails.firstWhere(
        (entry) => entry.primary && entry.verified,
        orElse: () => emails.first,
      );
      return profile.copyWith(email: primary.email);
    },
  );
}