119 lines
4.2 KiB
JavaScript
119 lines
4.2 KiB
JavaScript
let googleClient = null;
|
|
let isSigningIn = false;
|
|
|
|
function waitForGoogleApi() {
|
|
return new Promise((resolve, reject) => {
|
|
if (window.google?.accounts?.oauth2) {
|
|
resolve(window.google);
|
|
return;
|
|
}
|
|
|
|
const maxAttempts = 20;
|
|
let attempts = 0;
|
|
|
|
const checkGoogle = setInterval(() => {
|
|
attempts++;
|
|
if (window.google?.accounts?.oauth2) {
|
|
clearInterval(checkGoogle);
|
|
resolve(window.google);
|
|
} else if (attempts >= maxAttempts) {
|
|
clearInterval(checkGoogle);
|
|
reject(new Error('Google OAuth2 API failed to load within the timeout period'));
|
|
}
|
|
}, 100);
|
|
});
|
|
}
|
|
|
|
async function handleAuthError(error, context = '') {
|
|
const errorMessage = error?.message || error?.type || error?.toString() || 'Unknown error';
|
|
const fullError = `${context}: ${errorMessage}`;
|
|
console.error('Google Auth Error:', { context, error, fullError });
|
|
await DotNet.invokeMethodAsync('BimAI.UI.Shared', 'OnGoogleSignInError', fullError);
|
|
}
|
|
|
|
async function fetchUserInfo(accessToken) {
|
|
const response = await fetch('https://www.googleapis.com/oauth2/v3/userinfo', {
|
|
headers: { 'Authorization': `Bearer ${accessToken}` }
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorText = await response.text();
|
|
console.error('Failed to fetch user info:', errorText);
|
|
await DotNet.invokeMethodAsync('BimAI.UI.Shared', 'OnGoogleSignInError',
|
|
`Failed to fetch user info: HTTP ${response.status}`);
|
|
return null;
|
|
}
|
|
|
|
return await response.json();
|
|
}
|
|
|
|
window.initGoogleSignIn = async function(clientId) {
|
|
if (googleClient) {
|
|
return googleClient;
|
|
}
|
|
|
|
try {
|
|
const google = await waitForGoogleApi();
|
|
|
|
googleClient = google.accounts.oauth2.initTokenClient({
|
|
client_id: clientId,
|
|
scope: 'email profile',
|
|
callback: async (tokenResponse) => {
|
|
try {
|
|
if (tokenResponse.error) {
|
|
console.error('Token response error:', tokenResponse.error);
|
|
await DotNet.invokeMethodAsync('BimAI.UI.Shared', 'OnGoogleSignInError',
|
|
tokenResponse.error);
|
|
return;
|
|
}
|
|
|
|
const userInfo = await fetchUserInfo(tokenResponse.access_token);
|
|
if (!userInfo) return;
|
|
|
|
await DotNet.invokeMethodAsync('BimAI.UI.Shared', 'OnGoogleSignInSuccess',
|
|
tokenResponse.access_token,
|
|
userInfo.name || '',
|
|
userInfo.email || '',
|
|
userInfo.picture || ''
|
|
);
|
|
} catch (error) {
|
|
console.error('Callback error:', error);
|
|
await DotNet.invokeMethodAsync('BimAI.UI.Shared', 'OnGoogleSignInError',
|
|
error.message || 'Unknown callback error');
|
|
} finally {
|
|
isSigningIn = false;
|
|
}
|
|
},
|
|
error_callback: async (error) => {
|
|
console.error('OAuth flow error:', error);
|
|
await DotNet.invokeMethodAsync('BimAI.UI.Shared', 'OnGoogleSignInError',
|
|
error.type || 'OAuth flow error');
|
|
isSigningIn = false;
|
|
}
|
|
});
|
|
|
|
return googleClient;
|
|
} catch (error) {
|
|
console.error('Initiaxcrun xctrace list deviceslization error:', error);
|
|
await DotNet.invokeMethodAsync('BimAI.UI.Shared', 'OnGoogleSignInError',
|
|
error.message || 'Failed to initialize Google Sign-In');
|
|
isSigningIn = false;
|
|
}
|
|
};
|
|
|
|
window.requestGoogleSignIn = async function() {
|
|
if (isSigningIn) {
|
|
console.log('Sign-in already in progress');
|
|
return;
|
|
}
|
|
|
|
if (!googleClient) {
|
|
console.error('Google Sign-In not initialized');
|
|
await DotNet.invokeMethodAsync('BimAI.UI.Shared', 'OnGoogleSignInError',
|
|
'Google Sign-In not initialized. Call initGoogleSignIn first.');
|
|
return;
|
|
}
|
|
|
|
isSigningIn = true;
|
|
googleClient.requestAccessToken();
|
|
}; |