EduShade
Auth Module

OAuth & Social Login

Sign in or register using social providers — currently Google and Facebook in the UI; Apple and GitHub supported by the backend

OAuth & Social Login

EduShade lets users sign in or register using their existing social accounts — eliminating another password to remember and speeding up onboarding.

Supported Providers

There are two layers to be aware of:

ProviderBackend (oauth_service.go)Frontend (UI button on login/register)
Google✅ Implemented✅ Visible
Facebook✅ Implemented✅ Visible
GitHub✅ Implemented❌ No button rendered
Apple✅ Implemented❌ Button code exists but is commented out

What end users actually see today: only Google and Facebook buttons on /auth/login and /auth/register. Apple and GitHub are wired in the backend OAuth handler and can be enabled by uncommenting the Apple button or adding a GitHub button in src/components/auth/oauth-buttons.tsx, plus enabling the provider in config.yaml.

Scopes & Data Retrieved (when enabled)

ProviderTypical ScopesData Retrieved
Googleopenid, email, profileName, Email, Profile Picture, Locale
Facebookemail, public_profileName, Email, Profile Picture
GitHubuser:emailUsername, Email, Name, Avatar
Applename, emailName, Email

Provider availability is also gated by tenant/deployment config — if a provider's client_id and client_secret aren't configured, its endpoint will reject the request even if a button is shown.

How Social Login Works

Step-by-Step Flow

  1. Click the provider button on the login or register page.
  2. Frontend calls GET /v1/oauth/{provider} and receives a redirect_url.
  3. Browser navigates to the provider's authorization page.
  4. User grants EduShade permission to access their basic profile.
  5. Provider redirects back to /auth/oauth/{provider}/callback?code=...&state=....
  6. Frontend posts the code and state to POST /v1/oauth/{provider}/callback.
  7. Backend resolves the account:
    • Provider ID already linked → log in
    • Email matches an existing account → link provider, then log in
    • Neither → create new account, then log in
  8. Tokens are returned and stored; the user is redirected to their dashboard (or the intended URL captured before the OAuth flow).

What Gets Auto-Populated on First Sign-Up

FieldSource
NameSocial profile
EmailSocial profile (auto-verified if the provider confirms it)
AvatarProfile picture URL
Provider IDStored as google_id, facebook_id, github_id, or apple_id for future logins

Security

State Parameter Protection

The OAuth flow uses an encrypted state parameter to prevent CSRF and replay attacks. The state encodes: tenant ID, provider, a cryptographic token, and an expiry timestamp. On callback the state is validated for:

  • Correct tenant (prevents cross-tenant attacks)
  • Untampered token
  • Not expired (prevents replay)

Email Auto-Verification

If the provider confirms the email is verified (e.g. Google), EduShade marks the user's email as verified automatically — the user skips the email verification step.

Intent Preservation

Before redirecting to the provider, the frontend stores any intended query param in sessionStorage under es_auth_oauth_intended so the user lands on the page they originally tried to reach after signing in.

Linking Social Accounts

You can link multiple social accounts to one EduShade account.

  1. Log in to EduShade.
  2. Go to Account Settings → connected accounts section.
  3. Click Connect next to a provider.
  4. Complete the provider's authorization screen.

Backend endpoint: POST /v1/oauth/link/{provider} (authenticated).

  1. Go to Account Settings → connected accounts.
  2. Click Disconnect next to the provider.

Backend endpoint: DELETE /v1/oauth/unlink/{provider} (authenticated).

You must always have at least one login method available (a password or another linked provider) before unlinking — otherwise you would lock yourself out.

Admin-Initiated Linking

The auth-service exposes admin link/unlink endpoints (POST /v1/users/:user_id/oauth/link and POST /v1/users/:user_id/oauth/unlink, both requiring user.update). These accept a provider_user_id and are designed primarily for service-to-service or scripted account migration — admins typically don't have a user's raw provider ID at hand, so there is no general-purpose UI for arbitrary linking.

Troubleshooting

IssueSolution
"Authorization failed"The provider denied access. Try again and make sure to click "Allow"
"Invalid state"The OAuth session expired or the state was tampered. Restart the login flow
"Email already registered"An account with this email exists but isn't linked to this provider. Log in with your password (or another linked provider) first, then link this provider from settings
Provider button not showingOnly Google and Facebook are visible by default. Apple/GitHub require enabling in the frontend buttons component plus provider config
Profile picture not updatingAvatars are pulled at first sign-up. Update your avatar manually in account settings

On this page