Feat/oauth and GitHub #10
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
OAuth 2.0 and GitHub Authentication Implementation
📋 Overview
This PR introduces a comprehensive OAuth 2.0 authentication system with GitHub provider support. The implementation adds 13 files (+824/-7 lines), delivering an OAuth flow with PKCE protection, token encryption, and state management.
🎯 Summary of Changes
Core OAuth Services
Authentication Infrastructure
Configuration & Dependencies
@better-fetch/fetch,@noble/ciphers,zod🔐 Security Implementation
✅ Implemented Security Measures
httpOnly: true(XSS protection)secure: true(HTTPS only)sameSite: 'lax'(CSRF mitigation)ALLOWED_CALLBACK_HOSTS_ARRAYoauth.js:1🚀 Setup & Configuration
Required Environment Variables
GitHub OAuth (register at github.com/settings/applications)
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GITHUB_CALLBACK_URL=http://localhost:5500/oauth/github/callback
Token Encryption (must be 64 hex characters = 32 bytes)
TOKEN_ENCRYPTION_KEY=
Cookie Security
COOKIE_SECRET=secure-random-string
Server Environment
NODE_ENV=development # or production
Generate TOKEN_ENCRYPTION_KEY:
New Dependencies
@better-fetch/fetch@noble/cipherszodInstall:
Setup Steps
.envwith values from abovenpm installauthentication_providertable/oauth/githubDatabase Schema
New Table:
authentication_provider## File Structure
. ├── constants.js # Allowed callback hosts ├── package.json # New dependencies ├── server/ │ ├── apis/ │ │ └── oauth.js # OAuth sign-in & callback routes (166 lines) │ ├── entities/ │ │ └── authenticationProvider.js # DB schema & entity class (60 lines) │ ├── lib/ │ │ ├── authenticateWithProvider.js # Session creation logic (84 lines) │ │ └── tokenCrypto.js # Encryption utilities (39 lines) │ ├── main.js # Updated with COOKIE_SECRET │ ├── routes/ │ │ └── apis.js # OAuth router registration │ └── services/oauth/ │ ├── OAuthProviderFactory.js # Provider factory pattern (34 lines) │ ├── OAuthService.js # Base OAuth 2.0 class (211 lines) │ ├── SessionStateService.js # State management (97 lines) │ └── providers/ │ └── github.js # GitHub provider (87 lines)🔄 OAuth Flow Diagram
┌─────────────┐
│ User Clicks │
│"Login with │
│ GitHub" │
└──────┬──────┘
│
v
GET /oauth/github
├─ Generate State (32-byte random)
├─ Generate Code Verifier (128-byte random, PKCE)
├─ Set Signed Cookies (state, provider)
└─ Redirect to GitHub Authorization URL
│
v
GitHub Login Page
(User authorizes)
│
v
GitHub Redirects to Callback
/oauth/github/callback?code=X&state=Y
│
v
├─ Validate State vs Cookie
├─ Validate Provider vs Cookie
├─ Exchange Code for Access Token (PKCE S256)
├─ Fetch GitHub User Profile
├─ Create/Update User & Auth Provider Records
├─ Encrypt and Store Access Token
├─ Create Session Token
├─ Set Session Cookie
└─ Redirect to Callback URL (/user)
│
v
✅ User Authenticated
text
## 🏗️ Class Architecture
### OAuthService (Base Class)class OAuthService {
constructor(config) // Validates all required fields
getAuthorizationUrl() // RFC 7636 PKCE S256 code challenge
getAccessToken(code, verifier) // Token exchange with Zod validation
normalizeTokenResponse() // Provider-agnostic token format
refreshAccessToken() // Token refresh support
getUserProfile() // Abstract - provider-specific
#generateCodeChallenge() // Private - code challenge generation
}
githubOAuthProvider (Extends OAuthService)
SessionStateService
💾 Key Implementation Details
State Management
StateStoreinterface (enables Redis swap)Token Encryption
TOKEN_ENCRYPTION_KEYUser Sync Logic
Provider Extension
OAuthService, implementgetUserProfile()🧪 API Endpoints
GET/oauth/:providerPOST/oauth/:providerGET/oauth/:provider/callbackPOST/oauth/:provider/callbackRequest Parameters:
provider(path) - OAuth provider name (e.g., "github")callbackUrl(query/body) - Custom redirect after authenticationResponse:
callbackUrlor/userwith session token/login?error=error_code📚 Supported OAuth Providers
GitHub ✅
read:user,user:emailExtensible
The factory pattern enables adding:
🚨 Known Limitations & Future Work
Recommended Next Steps
✅ Checklist for Reviewers
🤝 How to Test
Setup GitHub OAuth App:
http://localhost:5500/oauth/github/callbackConfigure Environment:
Start Server:
npm startTest OAuth Flow:
GET /oauth/github📝 Notes
🔗 References