/** * Google OAuth Login Guard * Only authorized Google accounts can access the application */ class AuthGuard { constructor(config) { this.clientId = config.clientId; this.onSuccess = config.onSuccess || (() => { }); this.onError = config.onError || ((error) => console.error(error)); this.user = null; this.isAuthenticated = false; } /** * Initialize Google Sign-In */ init() { return new Promise((resolve, reject) => { // Load Google Identity Services const script = document.createElement('script'); script.src = 'https://accounts.google.com/gsi/client'; script.async = true; script.defer = true; script.onload = () => { this.initializeGoogleAuth(); resolve(); }; script.onerror = () => { reject(new Error('Failed to load Google Identity Services')); }; document.head.appendChild(script); }); } /** * Initialize Google OAuth */ initializeGoogleAuth() { google.accounts.id.initialize({ client_id: this.clientId, callback: this.handleCredentialResponse.bind(this), auto_select: true, cancel_on_tap_outside: false }); // Check if already logged in this.checkExistingSession(); } /** * Check locally stored session */ checkExistingSession() { const savedUser = localStorage.getItem('auth_user'); const savedToken = localStorage.getItem('auth_token'); if (savedUser && savedToken) { try { const user = JSON.parse(savedUser); // Verify if token is expired const tokenData = this.parseJwt(savedToken); if (tokenData.exp * 1000 > Date.now()) { this.user = user; this.isAuthenticated = true; this.onSuccess(user); this.hideLoginUI(); return; } } catch (e) { console.error('Invalid session data:', e); } } // No valid session, show login UI this.showLoginUI(); } /** * Handle Google login response */ handleCredentialResponse(response) { try { const credential = response.credential; const userData = this.parseJwt(credential); // Save user info and token this.user = { email: userData.email, name: userData.name, picture: userData.picture, sub: userData.sub }; this.isAuthenticated = true; localStorage.setItem('auth_user', JSON.stringify(this.user)); localStorage.setItem('auth_token', credential); this.hideLoginUI(); this.onSuccess(this.user); // Reload page to initialize the application location.reload(); } catch (error) { this.onError({ type: 'AUTH_ERROR', message: 'Authentication failed', error }); } } /** * Show login UI */ showLoginUI() { const loginContainer = document.createElement('div'); loginContainer.id = 'auth-container'; loginContainer.innerHTML = `
Sign in with your authorized Google account to continue