- 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
140 lines
4.4 KiB
TypeScript
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,
|
|
});
|
|
};
|