309 lines
8.5 KiB
Markdown
309 lines
8.5 KiB
Markdown
# Good PR Example
|
|
|
|
This example demonstrates a well-structured pull request that follows best practices for open source contributions.
|
|
|
|
---
|
|
|
|
## Example: Adding OAuth2 Authentication
|
|
|
|
### PR Title
|
|
```
|
|
feat(auth): add OAuth2 support for Google and GitHub providers
|
|
```
|
|
|
|
**Why it's good:**
|
|
- ✅ Uses Conventional Commits format (feat)
|
|
- ✅ Includes scope (auth)
|
|
- ✅ Clear, specific description
|
|
- ✅ Under 50 characters
|
|
- ✅ Imperative mood
|
|
|
|
---
|
|
|
|
### PR Description
|
|
|
|
```markdown
|
|
## What?
|
|
Add OAuth2 authentication support for Google and GitHub providers, allowing users to sign in with their social accounts.
|
|
|
|
## Why?
|
|
Multiple users have requested social login to reduce friction during signup (issues #234, #156). This addresses a key pain point: 40% of attempted signups are abandoned at the password creation step according to our analytics.
|
|
|
|
This implements Key Result 2 of Q4 OKR1: "Reduce signup friction by 30%"
|
|
|
|
## How?
|
|
- Implemented OAuth2 flow using passport.js strategy pattern
|
|
- Added provider configuration via environment variables (no hardcoded secrets)
|
|
- Created callback routes for each provider:
|
|
- `/auth/google/callback`
|
|
- `/auth/github/callback`
|
|
- Updated user model to link social accounts with existing email-based accounts
|
|
- Added middleware to automatically merge accounts if user already exists with same email
|
|
- Implemented proper error handling for failed OAuth attempts
|
|
|
|
## Testing
|
|
|
|
### Setup
|
|
1. Create OAuth apps in developer consoles:
|
|
- Google: https://console.cloud.google.com/apis/credentials
|
|
- GitHub: https://github.com/settings/developers
|
|
2. Add credentials to `.env` file (see `.env.example` for required variables)
|
|
3. Run `npm install` to ensure passport dependencies are installed
|
|
|
|
### Manual Testing Steps
|
|
1. Start server: `npm start`
|
|
2. Navigate to `http://localhost:3000/login`
|
|
3. Click "Login with Google" button
|
|
4. Verify OAuth flow redirects to Google consent screen
|
|
5. Grant permissions
|
|
6. Verify redirect back to app with user logged in
|
|
7. Check user profile shows data from Google (name, email, avatar)
|
|
8. Repeat steps 3-7 for GitHub provider
|
|
|
|
### Test Cases Covered
|
|
- ✅ New user signup via OAuth
|
|
- ✅ Existing user login via OAuth
|
|
- ✅ Account merging (same email, different provider)
|
|
- ✅ Error handling (user denies permissions)
|
|
- ✅ Error handling (OAuth provider timeout)
|
|
- ✅ Security: CSRF token validation
|
|
|
|
### Automated Tests
|
|
```bash
|
|
npm test -- tests/auth/oauth.test.js
|
|
```
|
|
|
|
All 15 test cases pass, including edge cases.
|
|
|
|
## Checklist
|
|
- [x] Tests added/updated (tests/auth/oauth.test.js)
|
|
- [x] Documentation updated:
|
|
- [x] README.md (setup instructions)
|
|
- [x] docs/authentication.md (OAuth flow documentation)
|
|
- [x] .env.example (required environment variables)
|
|
- [x] CI passing (all checks green)
|
|
- [x] No breaking changes
|
|
- [x] Follows existing code style
|
|
- [x] Security review completed (no secrets committed)
|
|
|
|
## Related Issues
|
|
Closes #234
|
|
Relates to #156 (social login epic)
|
|
|
|
## Screenshots
|
|
|
|
### Login Page with OAuth Buttons
|
|

|
|
*New social login buttons integrated into existing login page*
|
|
|
|
### OAuth Consent Screen (Google)
|
|

|
|
*User experience during Google OAuth flow*
|
|
|
|
## Breaking Changes
|
|
None - this is additive functionality that doesn't affect existing authentication methods.
|
|
|
|
## Security Considerations
|
|
- OAuth tokens are stored securely using bcrypt hashing
|
|
- CSRF protection implemented for all OAuth routes
|
|
- State parameter used to prevent CSRF attacks
|
|
- No secrets committed to repository (all in .env)
|
|
- Rate limiting applied to OAuth endpoints
|
|
|
|
## Additional Notes
|
|
|
|
### Design Decisions
|
|
- **Chose passport.js** over custom implementation for security, maintenance, and community support
|
|
- **Used strategy pattern** to make adding new OAuth providers easier in future
|
|
- **Account merging** happens automatically based on email address (primary key)
|
|
- **No email verification required** for OAuth signups (providers already verify emails)
|
|
|
|
### Future Improvements
|
|
Consider in follow-up PRs:
|
|
- Add more providers (Twitter, LinkedIn, Microsoft)
|
|
- Implement OAuth token refresh logic
|
|
- Add rate limiting for OAuth endpoints
|
|
- Add admin dashboard for managing OAuth apps
|
|
|
|
### Migration Notes
|
|
No migration needed - existing users can continue using password authentication. OAuth is an additional option.
|
|
|
|
### Dependencies Added
|
|
- passport v0.6.0
|
|
- passport-google-oauth20 v2.0.0
|
|
- passport-github2 v0.1.12
|
|
|
|
All dependencies are actively maintained and have good security track records.
|
|
```
|
|
|
|
---
|
|
|
|
### Files Changed (Clean!)
|
|
|
|
```
|
|
.env.example # Environment variable examples (no secrets!)
|
|
README.md # Updated setup instructions
|
|
docs/authentication.md # OAuth documentation
|
|
package.json # Added passport dependencies
|
|
src/routes/auth.js # OAuth routes
|
|
src/middleware/authenticate.js # OAuth middleware
|
|
src/models/user.js # Updated user model
|
|
tests/auth/oauth.test.js # OAuth tests
|
|
tests/fixtures/users.json # Test fixtures
|
|
```
|
|
|
|
**What's NOT included:**
|
|
- ❌ No SESSION.md or notes files
|
|
- ❌ No planning/ directory
|
|
- ❌ No debug screenshots (only feature demos)
|
|
- ❌ No temporary test files
|
|
- ❌ No .env file (only .env.example)
|
|
- ❌ No personal artifacts
|
|
|
|
---
|
|
|
|
### Commit History (Clean!)
|
|
|
|
```
|
|
feat(auth): add OAuth2 support for Google and GitHub
|
|
|
|
Implemented OAuth2 authentication flow using passport.js.
|
|
Users can now sign in with Google or GitHub accounts.
|
|
Accounts are automatically merged if email matches existing user.
|
|
|
|
- Added OAuth routes and callbacks
|
|
- Updated user model to support social accounts
|
|
- Added comprehensive tests for OAuth flow
|
|
- Documented setup and usage
|
|
|
|
Closes #234
|
|
```
|
|
|
|
**Why it's good:**
|
|
- ✅ Single, focused commit
|
|
- ✅ Clear commit message
|
|
- ✅ Explains what and why
|
|
- ✅ Links issue
|
|
- ✅ Follows Conventional Commits
|
|
|
|
---
|
|
|
|
### Communication During Review
|
|
|
|
**Initial Comment (When Submitting):**
|
|
```
|
|
Hi @maintainer! 👋
|
|
|
|
I've implemented OAuth2 support as discussed in #234. I went with passport.js over a custom implementation because:
|
|
1. Battle-tested security
|
|
2. Well-maintained by the community
|
|
3. Easy to add more providers in future
|
|
|
|
I've tested this locally for the past week and also deployed to staging for integration testing. All existing auth flows remain unchanged - this is purely additive.
|
|
|
|
Ready for review when you have time! Happy to make any changes you'd like.
|
|
```
|
|
|
|
**Response to Feedback:**
|
|
```
|
|
> Could you add rate limiting to these endpoints?
|
|
|
|
Good idea! I've added rate limiting in commit abc1234:
|
|
- Max 5 OAuth attempts per IP per minute
|
|
- Returns 429 with Retry-After header
|
|
- Uses existing rate limiting middleware
|
|
|
|
Let me know if you'd prefer different limits!
|
|
```
|
|
|
|
**After Changes:**
|
|
```
|
|
@maintainer I've addressed all your feedback:
|
|
- ✅ Added rate limiting (commit abc1234)
|
|
- ✅ Updated docs with security considerations (commit def5678)
|
|
- ✅ Refactored callback logic as suggested (commit ghi9012)
|
|
|
|
Marked all conversations as resolved. Ready for re-review!
|
|
|
|
Thanks for the thorough feedback - the rate limiting suggestion was spot-on.
|
|
```
|
|
|
|
---
|
|
|
|
### PR Metrics
|
|
|
|
**Size:**
|
|
- Lines changed: 180
|
|
- Files changed: 9
|
|
- Commits: 1
|
|
|
|
**Result:**
|
|
- ✅ Ideal size for review
|
|
- ✅ Focused on one feature
|
|
- ✅ Easy to understand
|
|
- ✅ Quick to review
|
|
|
|
**Timeline:**
|
|
- Submitted: Day 1
|
|
- First review: Day 2
|
|
- Changes made: Day 2
|
|
- Approved: Day 3
|
|
- Merged: Day 3
|
|
|
|
**Why it was quick:**
|
|
- Clean, focused PR
|
|
- Comprehensive testing
|
|
- Good documentation
|
|
- Responsive to feedback
|
|
- No surprises or issues
|
|
|
|
---
|
|
|
|
## Key Takeaways
|
|
|
|
This PR demonstrates:
|
|
|
|
1. **Clear Communication**
|
|
- What/Why/How structure
|
|
- Testing instructions
|
|
- Design decisions explained
|
|
- Security considerations noted
|
|
|
|
2. **Proper Scope**
|
|
- One feature
|
|
- ~180 lines changed
|
|
- No unrelated changes
|
|
- Easy to review
|
|
|
|
3. **Complete Documentation**
|
|
- Updated README
|
|
- Added OAuth docs
|
|
- Included .env.example
|
|
- Comprehensive inline comments
|
|
|
|
4. **Thorough Testing**
|
|
- Automated tests
|
|
- Manual test steps
|
|
- Edge cases covered
|
|
- Deployed to staging first
|
|
|
|
5. **Professional Artifacts**
|
|
- No personal files
|
|
- No secrets
|
|
- Clean commit history
|
|
- Proper branch naming
|
|
|
|
6. **Excellent Communication**
|
|
- Polite and respectful
|
|
- Responsive to feedback
|
|
- Explains decisions
|
|
- Thanks reviewers
|
|
|
|
7. **Security Conscious**
|
|
- No secrets committed
|
|
- CSRF protection
|
|
- Rate limiting
|
|
- Security considerations documented
|
|
|
|
This is the standard to aim for in your pull requests!
|