Skip to content

feat(auth): implement Wikimedia OAuth 2.0 authentication - #46

Open
pushpaktiwarii wants to merge 1 commit into
Tiisu:mainfrom
pushpaktiwarii:feat/wikimedia-oauth
Open

feat(auth): implement Wikimedia OAuth 2.0 authentication#46
pushpaktiwarii wants to merge 1 commit into
Tiisu:mainfrom
pushpaktiwarii:feat/wikimedia-oauth

Conversation

@pushpaktiwarii

Copy link
Copy Markdown
Contributor

Description

This PR introduces the 'Sign in with Wikimedia' functionality using the OAuth 2.0 Authorization Code grant flow. It seamlessly integrates alongside the existing local JWT authentication system.

Resolves T431227

Key Changes

  • Backend Auth Controller: Added logic to redirect users to the Wikimedia authorization endpoint and handle the callback code to exchange for access tokens.
  • User Model: Updated the schema to support wikimedia_id and wikimedia_username, making the password field optional for OAuth-based users.
  • Frontend Auth Page: Added a 'Sign in with Wikimedia' button seamlessly integrated into the login UI.
  • Frontend Callback Page: Implemented a new /auth/callback page that safely extracts tokens from the URL and authenticates the user in the React context without double-rendering issues.
  • Environment: Added necessary WIKIMEDIA_* environment variables to .env.example for open-source contributors.

Testing

  • Verified that clicking "Sign in with Wikimedia" correctly redirects to the Wikimedia authorization page.
  • Confirmed that successful authorization properly registers/logs in the user and redirects them to the homepage with a valid session.
  • Ensured local email/password login still works as expected.

@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

@pushpaktiwarii is attempting to deploy a commit to the Tiisu's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI review requested due to automatic review settings July 10, 2026 20:54
Resolves T431227

This commit introduces 'Sign in with Wikimedia' functionality using the OAuth 2.0 Authorization Code grant flow, integrating alongside the existing local JWT authentication.

Key changes:
- Backend Auth Controller: Added logic to redirect users to the Wikimedia authorization endpoint and handle the callback code to exchange for access tokens.
- User Model: Updated schema to support wikimedia_id and wikimedia_username, and made the password field optional for OAuth users.
- Frontend Auth Page: Added a 'Sign in with Wikimedia' button seamlessly integrated into the UI.
- Frontend Callback Page: Implemented a new /auth/callback page that safely extracts tokens from the URL and authenticates the user in the React context without double-rendering issues.
- Environment: Added necessary WIKIMEDIA environment variables to .env.example for open-source contributors.

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 “Sign in with Wikimedia” using an OAuth 2.0 authorization code flow, integrating it alongside the existing JWT-based auth by introducing new backend OAuth endpoints and frontend callback handling.

Changes:

  • Added backend /auth/wikimedia and /auth/wikimedia/callback routes to initiate OAuth and handle the authorization-code exchange + user provisioning.
  • Added frontend /auth/callback route/page to ingest OAuth results and establish an authenticated session in the React auth context.
  • Extended the User model to support Wikimedia-linked accounts and made passwords optional for OAuth-created users.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
frontend/src/pages/OAuthCallback.tsx New callback page to process OAuth redirect results and finalize login in the client.
frontend/src/pages/index.ts Exposes the new OAuthCallback page via the pages barrel export.
frontend/src/pages/AuthPage.tsx Adds a “Sign in with Wikimedia” button and surfaces OAuth errors on the auth page.
frontend/src/lib/auth-context.tsx Adds loginWithTokens for establishing auth state from externally obtained tokens.
frontend/src/App.tsx Registers the new /auth/callback route.
backend/src/routes/authRoutes.js Adds Wikimedia OAuth routes to the auth router.
backend/src/models/User.js Adds Wikimedia identity fields and relaxes password requirements for OAuth users.
backend/src/controllers/authController.js Implements Wikimedia OAuth redirect + callback exchange and user provisioning flow.
backend/.env.example Documents required Wikimedia OAuth configuration variables.

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

Comment on lines +19 to +21
const accessToken = searchParams.get('accessToken');
const refreshToken = searchParams.get('refreshToken');
const error = searchParams.get('error');
Comment on lines +24 to +26
toast.error(`Authentication failed: ${error}`);
navigate('/auth');
return;
Comment on lines +29 to +37
if (accessToken && refreshToken) {
loginWithTokens(accessToken, refreshToken).then(success => {
if (success) {
navigate('/');
} else {
navigate('/auth');
}
});
} else {
Comment on lines +38 to +40
toast.error('Authentication failed: Missing tokens');
navigate('/auth');
}
Comment on lines +20 to +27
useEffect(() => {
// Check for errors from OAuth redirect
const params = new URLSearchParams(window.location.search);
const error = params.get('error');
if (error) {
toast.error(error);
}
}, []);
Comment on lines +208 to +210
if (oauthError || !code) {
return res.redirect(`${process.env.FRONTEND_URL}/auth?error=${oauthError || 'No code provided'}`);
}
Comment on lines +268 to +272
const accessToken = generateAccessToken(user._id);
const refreshToken = generateRefreshToken(user._id);

res.redirect(`${process.env.FRONTEND_URL}/auth/callback?accessToken=${accessToken}&refreshToken=${refreshToken}`);

Comment on lines +192 to +196
const params = new URLSearchParams({
response_type: 'code',
client_id: process.env.WIKIMEDIA_CLIENT_ID,
redirect_uri: process.env.WIKIMEDIA_CALLBACK_URL
});
Comment on lines +20 to +21
router.get('/wikimedia', wikimediaLogin);
router.get('/wikimedia/callback', wikimediaCallback);
Comment on lines 76 to 79
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) {
if (!this.isModified('password') || !this.password) {
return next();
}
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