obj-drive-viewer / src /useGoogleDriveAuth.js
hrkjt's picture
Upload folder using huggingface_hub
fcbc624 verified
Raw
History Blame Contribute Delete
2.69 kB
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,
};
}