Skip to content

feat(sso): add social login providers (Google, GitHub, RoboLearn) - #18

Merged
mjunaidca merged 4 commits into
mainfrom
008-social-login-providers
Dec 8, 2025
Merged

feat(sso): add social login providers (Google, GitHub, RoboLearn)#18
mjunaidca merged 4 commits into
mainfrom
008-social-login-providers

Conversation

@mjunaidca

Copy link
Copy Markdown
Owner

Summary

  • Add Google OAuth 2.0 social login via Better Auth built-in socialProviders
  • Add GitHub OAuth social login via Better Auth built-in socialProviders
  • Add RoboLearn SSO via genericOAuth plugin for custom OIDC integration
  • All providers are environment-driven (toggle via env vars, no code changes needed)

Changes

Backend (sso-platform/src/lib/)

  • auth.ts: Add conditional socialProviders block for Google/GitHub, add genericOAuth plugin for RoboLearn OIDC
  • auth-client.ts: Add genericOAuthClient plugin for RoboLearn support

Frontend (sso-platform/src/components/)

  • sign-in-form.tsx: Add social login buttons with SVG icons, handleSocialSignIn handler, loading states, error handling

Configuration

  • .env.example: Add 10 new environment variables for social providers with setup instructions

Documentation

  • docs/social-login-providers.md: Comprehensive guide covering:
    • Redirect URI patterns (different for built-in vs genericOAuth)
    • Setup instructions for each provider
    • Database & account linking behavior
    • Troubleshooting common errors

Key Implementation Details

Provider Type Callback Path
Google Built-in /api/auth/callback/google
GitHub Built-in /api/auth/callback/github
RoboLearn genericOAuth /api/auth/oauth2/callback/robolearn

Test Plan

  • TypeScript compilation passes
  • RoboLearn SSO tested and working
  • Google OAuth (requires credentials)
  • GitHub OAuth (requires credentials)

Environment Variables

# Google
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
NEXT_PUBLIC_GOOGLE_ENABLED=true

# GitHub
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
NEXT_PUBLIC_GITHUB_ENABLED=true

# RoboLearn
ROBOLEARN_CLIENT_ID=...
ROBOLEARN_CLIENT_SECRET=...
ROBOLEARN_SSO_URL=https://robolearn-sso.vercel.app/api/auth
NEXT_PUBLIC_ROBOLEARN_ENABLED=true

🤖 Generated with Claude Code

Implement environment-driven social login with Better Auth:
- Google OAuth 2.0 via built-in socialProviders
- GitHub OAuth via built-in socialProviders
- RoboLearn SSO via genericOAuth plugin (custom OIDC)

Key changes:
- auth.ts: Add conditional socialProviders and genericOAuth config
- auth-client.ts: Add genericOAuthClient plugin
- sign-in-form.tsx: Add social login buttons with icons and handlers
- .env.example: Document all social provider env vars
- docs/social-login-providers.md: Comprehensive setup guide

Features:
- All providers toggle via environment variables (no code changes)
- Account linking for same-email users across providers
- Auto-join default organization for new social sign-ups
- OAuth parameter preservation for SSO flows

Note: genericOAuth uses /api/auth/oauth2/callback/{providerId} path
(different from built-in /api/auth/callback/{provider})

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings December 8, 2025 18:57
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds social login provider support to the Taskflow SSO Platform, enabling users to authenticate via Google OAuth, GitHub OAuth, and RoboLearn SSO (custom OIDC). The implementation leverages Better Auth's built-in socialProviders for Google and GitHub, and the genericOAuth plugin for RoboLearn's OIDC integration. All providers are environment-driven, allowing operators to enable/disable them via environment variables without code changes.

Key Changes:

  • Added conditional social provider configuration to Better Auth using environment variables
  • Implemented social sign-in UI with provider-specific buttons and icons in the sign-in form
  • Created comprehensive documentation covering setup, redirect URIs, database behavior, and troubleshooting

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
sso-platform/src/lib/auth.ts Added socialProviders block for Google/GitHub and conditional genericOAuth plugin for RoboLearn OIDC
sso-platform/src/lib/auth-client.ts Added genericOAuthClient plugin to support RoboLearn on the client side
sso-platform/src/components/sign-in-form.tsx Added social login buttons with SVG icons, handleSocialSignIn handler, OAuth parameter preservation, and error handling
sso-platform/docs/social-login-providers.md Comprehensive guide covering redirect URI patterns, provider setup, database behavior, and troubleshooting
sso-platform/.env.example Added 10 environment variables for social provider configuration with setup instructions
web-dashboard/src/app/page.tsx Unrelated wording change in marketing copy ("revolutionizes" → "rethinks")
specs/008-social-login-providers/* Complete specification, planning, and task tracking documents for the feature
history/prompts/008-social-login-providers/* Prompt history documenting the development process including a redirect URI fix

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +228 to +233
```typescript
accountLinking: {
enabled: true,
trustedProviders: ["google", "github", "robolearn"],
}
```

Copilot AI Dec 8, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation describes an accountLinking configuration with trustedProviders that doesn't exist in the actual auth.ts file. This code block shows a configuration that is not present in the implementation.

Either:

  1. Add the actual accountLinking configuration to auth.ts if account linking is needed
  2. Update the documentation to reflect that Better Auth's default account linking behavior is being used
  3. Clarify whether account linking is actually enabled by default in Better Auth

Without this configuration, the documented behavior (linking accounts with the same email across providers) may not work as described.

Suggested change
```typescript
accountLinking: {
enabled: true,
trustedProviders: ["google", "github", "robolearn"],
}
```
> **Note:** Account linking is enabled by default in Better Auth. If a user logs in with multiple providers (Google, GitHub, RoboLearn) using the same email address, their accounts will be linked to a single user record automatically. No explicit configuration is required.

Copilot uses AI. Check for mistakes.
}
} catch (error) {
console.error(`[SignIn] Social sign-in error (${provider}):`, error);
setErrors({ general: `Failed to sign in with ${provider}. Please try again.` });

Copilot AI Dec 8, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling in handleSocialSignIn only sets setIsLoading(false) in the catch block. However, if the social sign-in redirects successfully (which is the expected behavior), the loading state remains true forever.

While this might not cause visible issues (since the user is redirected away), it's better practice to ensure state cleanup happens in a finally block or remove the manual loading state reset entirely since the component will unmount on redirect.

Consider either:

  1. Removing the setIsLoading(false) from the catch block since the redirect will unmount the component
  2. Adding a finally block with setIsLoading(false) for consistency (though it won't execute on redirect)
Suggested change
setErrors({ general: `Failed to sign in with ${provider}. Please try again.` });
setErrors({ general: `Failed to sign in with ${provider}. Please try again.` });
} finally {

Copilot uses AI. Check for mistakes.
}
} catch (error) {
console.error(`[SignIn] Social sign-in error (${provider}):`, error);
setErrors({ general: `Failed to sign in with ${provider}. Please try again.` });

Copilot AI Dec 8, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message format capitalizes the provider name inconsistently. For example, when the provider is 'google', the error message will read "Failed to sign in with google" instead of "Failed to sign in with Google".

Consider capitalizing the provider name in the error message:

setErrors({ general: `Failed to sign in with ${provider.charAt(0).toUpperCase() + provider.slice(1)}. Please try again.` });

Or create a mapping for display names:

const providerNames = { google: 'Google', github: 'GitHub', robolearn: 'RoboLearn' };
setErrors({ general: `Failed to sign in with ${providerNames[provider]}. Please try again.` });

Copilot uses AI. Check for mistakes.
@mjunaidca
mjunaidca merged commit 6ccb2b0 into main Dec 8, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants