import { useCallback, useEffect, useState } from 'react'; import { DRIVE_READONLY_SCOPE, GOOGLE_CLIENT_ID } from './config.js'; function decodeJwtPayload(token) { try { const payload = token.split('.')[1]; const normalized = payload.replace(/-/g, '+').replace(/_/g, '/'); const json = decodeURIComponent( window .atob(normalized) .split('') .map((char) => `%${`00${char.charCodeAt(0).toString(16)}`.slice(-2)}`) .join(''), ); return JSON.parse(json); } catch { return null; } } function createNonce() { const bytes = new Uint8Array(16); window.crypto.getRandomValues(bytes); return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join(''); } export function useGoogleDriveAuth() { const [idToken, setIdToken] = useState(''); const [accessToken, setAccessToken] = useState(''); const [user, setUser] = useState(null); const [authReady, setAuthReady] = useState(Boolean(GOOGLE_CLIENT_ID)); const [authError, setAuthError] = useState(''); useEffect(() => { if (!GOOGLE_CLIENT_ID) { setAuthError('GOOGLE_CLIENT_ID is not configured.'); return; } const hashParams = new URLSearchParams(window.location.hash.slice(1)); const tokenFromHash = hashParams.get('access_token'); const idTokenFromHash = hashParams.get('id_token'); const errorFromHash = hashParams.get('error'); if (errorFromHash) { setAuthError(errorFromHash); window.history.replaceState(null, '', window.location.pathname + window.location.search); return; } if (tokenFromHash && idTokenFromHash) { setAuthError(''); setAccessToken(tokenFromHash); setIdToken(idTokenFromHash); setUser(decodeJwtPayload(idTokenFromHash)); window.history.replaceState(null, '', window.location.pathname + window.location.search); } }, []); const signIn = useCallback(() => { if (!GOOGLE_CLIENT_ID) return; const params = new URLSearchParams({ client_id: GOOGLE_CLIENT_ID, redirect_uri: `${window.location.origin}/`, response_type: 'token id_token', scope: `openid email profile ${DRIVE_READONLY_SCOPE}`, include_granted_scopes: 'true', prompt: accessToken && idToken ? '' : 'consent', nonce: createNonce(), hd: 'baby-helmet.com', }); window.location.assign(`https://accounts.google.com/o/oauth2/v2/auth?${params}`); }, [accessToken, idToken]); const signOut = useCallback(() => { setAccessToken(''); setIdToken(''); setUser(null); }, []); return { idToken, accessToken, user, authReady, authError, signIn, signOut, }; }