121 lines
3.0 KiB
TypeScript
121 lines
3.0 KiB
TypeScript
import { authenticateWithGoogle } from '$lib/google/auth/client.js';
|
|
|
|
export interface GoogleAuthState {
|
|
isConnected: boolean;
|
|
checking: boolean;
|
|
connecting: boolean;
|
|
showCancelOption: boolean;
|
|
token: string | null;
|
|
error: string | null;
|
|
userEmail: string | null;
|
|
}
|
|
|
|
export function createGoogleAuthState(): GoogleAuthState {
|
|
return {
|
|
isConnected: false,
|
|
checking: false,
|
|
connecting: false,
|
|
showCancelOption: false,
|
|
token: null,
|
|
error: null,
|
|
userEmail: null
|
|
};
|
|
}
|
|
|
|
export class GoogleAuthManager {
|
|
private readonly state: GoogleAuthState;
|
|
private cancelTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
constructor(state: GoogleAuthState) {
|
|
this.state = state;
|
|
}
|
|
|
|
checkConnection(): void {
|
|
this.state.checking = true;
|
|
this.state.error = null;
|
|
|
|
try {
|
|
const token = localStorage.getItem('google_refresh_token');
|
|
const email = localStorage.getItem('google_user_email');
|
|
|
|
this.state.isConnected = !!token;
|
|
this.state.token = token;
|
|
this.state.userEmail = email;
|
|
} catch (error) {
|
|
console.error('Error checking connection:', error);
|
|
this.state.error = 'Failed to check connection status';
|
|
} finally {
|
|
this.state.checking = false;
|
|
}
|
|
}
|
|
|
|
async connectToGoogle(): Promise<void> {
|
|
if (this.state.connecting) return;
|
|
|
|
this.state.connecting = true;
|
|
this.state.error = null;
|
|
this.state.showCancelOption = false;
|
|
|
|
// Show cancel option after 5 seconds
|
|
this.cancelTimeout = setTimeout(() => {
|
|
this.state.showCancelOption = true;
|
|
}, 5000);
|
|
|
|
try {
|
|
const result = await authenticateWithGoogle();
|
|
|
|
if (result.success && result.refreshToken) {
|
|
// Store tokens
|
|
localStorage.setItem('google_refresh_token', result.refreshToken);
|
|
if (result.userEmail) {
|
|
localStorage.setItem('google_user_email', result.userEmail);
|
|
}
|
|
|
|
// Update state
|
|
this.state.isConnected = true;
|
|
this.state.token = result.refreshToken;
|
|
this.state.userEmail = result.userEmail;
|
|
} else {
|
|
throw new Error(result.error ?? 'Authentication failed');
|
|
}
|
|
} catch (error) {
|
|
this.state.error = error instanceof Error ? error.message : 'Failed to connect to Google';
|
|
} finally {
|
|
this.state.connecting = false;
|
|
this.state.showCancelOption = false;
|
|
if (this.cancelTimeout) {
|
|
clearTimeout(this.cancelTimeout);
|
|
this.cancelTimeout = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
cancelGoogleAuth(): void {
|
|
this.state.connecting = false;
|
|
this.state.showCancelOption = false;
|
|
this.state.error = null;
|
|
|
|
if (this.cancelTimeout) {
|
|
clearTimeout(this.cancelTimeout);
|
|
this.cancelTimeout = null;
|
|
}
|
|
}
|
|
|
|
async disconnectGoogle(): Promise<void> {
|
|
try {
|
|
// Clear local storage
|
|
localStorage.removeItem('google_refresh_token');
|
|
localStorage.removeItem('google_user_email');
|
|
|
|
// Reset state
|
|
this.state.isConnected = false;
|
|
this.state.token = null;
|
|
this.state.userEmail = null;
|
|
this.state.error = null;
|
|
} catch (error) {
|
|
console.error('Error disconnecting:', error);
|
|
this.state.error = 'Failed to disconnect';
|
|
}
|
|
}
|
|
}
|