Files
rxminder/services/oauth.ts
William Valentin e48adbcb00 Initial commit: Complete NodeJS-native setup
- Migrated from Python pre-commit to NodeJS-native solution
- Reorganized documentation structure
- Set up Husky + lint-staged for efficient pre-commit hooks
- Fixed Dockerfile healthcheck issue
- Added comprehensive documentation index
2025-09-06 01:42:48 -07:00

140 lines
4.4 KiB
TypeScript

import { authService } from './auth/auth.service';
import { OAuthProvider, OAuthState, User } from '../types';
import { dbService } from './couchdb.factory';
import { AccountStatus } from './auth/auth.constants';
// Mock OAuth configuration
const GOOGLE_CLIENT_ID = 'mock_google_client_id';
const GITHUB_CLIENT_ID = 'mock_github_client_id';
// Mock OAuth endpoints
const GOOGLE_AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
const GITHUB_AUTH_URL = 'https://github.com/login/oauth/authorize';
// Mock token exchange endpoints
const GOOGLE_TOKEN_URL = 'https://oauth2.googleapis.com/token';
const GITHUB_TOKEN_URL = 'https://github.com/login/oauth/access_token';
// Mock OAuth scopes
const GOOGLE_SCOPES = 'openid email profile';
const GITHUB_SCOPES = 'user:email';
// Mock redirect URI
const REDIRECT_URI = 'http://localhost:3000/auth/callback';
// Mock OAuth state generation
const generateState = () => crypto.randomUUID();
export const googleAuth = () => {
const state = generateState();
const url = new URL(GOOGLE_AUTH_URL);
url.searchParams.append('client_id', GOOGLE_CLIENT_ID);
url.searchParams.append('response_type', 'code');
url.searchParams.append('scope', GOOGLE_SCOPES);
url.searchParams.append('redirect_uri', REDIRECT_URI);
url.searchParams.append('state', state);
// In a real implementation, we would store the state in the session or localStorage
localStorage.setItem('oauth_state', state);
// Redirect to Google's auth endpoint
window.location.href = url.toString();
};
export const githubAuth = () => {
const state = generateState();
const url = new URL(GITHUB_AUTH_URL);
url.searchParams.append('client_id', GITHUB_CLIENT_ID);
url.searchParams.append('response_type', 'code');
url.searchParams.append('scope', GITHUB_SCOPES);
url.searchParams.append('redirect_uri', REDIRECT_URI);
url.searchParams.append('state', state);
// In a real implementation, we would store the state in the session or localStorage
localStorage.setItem('oauth_state', state);
// Redirect to GitHub's auth endpoint
window.location.href = url.toString();
};
// Mock token exchange
const mockExchangeCodeForToken = async (
provider: 'google' | 'github',
code: string
): Promise<string> => {
// In a real implementation, we would make a POST request to the token endpoint
// with the code, client_id, client_secret, and redirect_uri
// For this mock, we'll just return a mock access token
return `mock_${provider}_access_token_${crypto.randomUUID()}`;
};
// Mock user info retrieval
const mockGetUserInfo = async (
provider: 'google' | 'github',
accessToken: string
): Promise<{ email: string; name: string }> => {
// In a real implementation, we would make a GET request to the user info endpoint
// with the access token
// For this mock, we'll return mock user info
return {
email: `mock_${provider}_user_${crypto.randomUUID()}@example.com`,
name: `Mock ${provider.charAt(0).toUpperCase() + provider.slice(1)} User`,
};
};
export const handleGoogleCallback = async () => {
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');
const storedState = localStorage.getItem('oauth_state');
// Verify state to prevent CSRF attacks
if (state !== storedState) {
throw new Error('Invalid OAuth state');
}
// Clear stored state
localStorage.removeItem('oauth_state');
// Exchange code for token
const accessToken = await mockExchangeCodeForToken('google', code);
// Get user info
const userInfo = await mockGetUserInfo('google', accessToken);
// Register or login the user
return authService.loginWithOAuth('google', {
email: userInfo.email,
username: userInfo.name,
});
};
export const handleGithubCallback = async () => {
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');
const storedState = localStorage.getItem('oauth_state');
// Verify state to prevent CSRF attacks
if (state !== storedState) {
throw new Error('Invalid OAuth state');
}
// Clear stored state
localStorage.removeItem('oauth_state');
// Exchange code for token
const accessToken = await mockExchangeCodeForToken('github', code);
// Get user info
const userInfo = await mockGetUserInfo('github', accessToken);
// Register or login the user
return authService.loginWithOAuth('github', {
email: userInfo.email,
username: userInfo.name,
});
};