fix: make Google login and session recovery resilient
This commit is contained in:
+37
-27
@@ -1,3 +1,4 @@
|
||||
import {awaitWithAbort} from './abortable.js';
|
||||
/**
|
||||
* Google ile Giriş — frontend istemcisi (GIS ID-token akışı).
|
||||
* Token localStorage'da 'ihaleist_token', kullanıcı 'ihaleist_user' altında saklanır.
|
||||
@@ -25,43 +26,52 @@ export function clearSession() {
|
||||
} catch { /* yoksay */ }
|
||||
}
|
||||
|
||||
export async function getGoogleConfig() {
|
||||
try {
|
||||
const res = await fetch('/api/auth/google/config');
|
||||
if (!res.ok) return { clientId: null };
|
||||
return await res.json();
|
||||
} catch {
|
||||
return { clientId: null };
|
||||
}
|
||||
async function authRequest(url,options={}) {
|
||||
const {signal,...requestOptions}=options,controller=new AbortController();
|
||||
const cancel=()=>controller.abort(signal.reason);
|
||||
if(signal?.aborted)cancel();else signal?.addEventListener('abort',cancel,{once:true});
|
||||
let timeout=false;
|
||||
const timer=setTimeout(()=>{timeout=true;controller.abort();},30000);
|
||||
try{
|
||||
controller.signal.throwIfAborted();
|
||||
const res=await awaitWithAbort(fetch(url,{...requestOptions,signal:controller.signal}),controller.signal);
|
||||
const data=await awaitWithAbort(res.json().catch(error=>{if(res.ok)throw error;return null;}),controller.signal);
|
||||
controller.signal.throwIfAborted();
|
||||
if(!res.ok){const error=new Error(data?.error || 'Giriş hizmetine ulaşılamadı. Yeniden deneyin.');error.status=res.status;throw error;}
|
||||
return data;
|
||||
}catch(error){if(timeout)throw new Error('Giriş hizmeti zamanında yanıt vermedi. Yeniden deneyin.');throw error;}
|
||||
finally{clearTimeout(timer);signal?.removeEventListener('abort',cancel);}
|
||||
}
|
||||
|
||||
export async function loginWithGoogle(credential) {
|
||||
const res = await fetch('/api/auth/google', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ credential }),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!res.ok || !data.success) throw new Error(data.error || 'Giriş başarısız');
|
||||
setSession(data.token, data.user);
|
||||
export async function getGoogleConfig({signal}={}) {
|
||||
const data=await authRequest('/api/auth/google/config',{signal});
|
||||
if(!data || !Object.hasOwn(data,'clientId') || (data.clientId!==null&&typeof data.clientId!=='string'))throw new Error('Giriş yapılandırması doğrulanamadı. Yeniden deneyin.');
|
||||
return data;
|
||||
}
|
||||
export async function loginWithGoogle(credential,{signal}={}) {
|
||||
const data=await authRequest('/api/auth/google',{method:'POST',signal,headers:{'Content-Type':'application/json'},body:JSON.stringify({credential})});
|
||||
if(!data?.success)throw new Error(data?.error || 'Giriş başarısız');
|
||||
if(typeof data.token!=='string'||!data.token||typeof data.user?.email!=='string'||!data.user.email)throw new Error('Giriş yanıtı doğrulanamadı.');
|
||||
signal?.throwIfAborted();
|
||||
setSession(data.token,data.user);
|
||||
if(getToken()!==data.token||getStoredUser()?.email!==data.user.email){clearSession();throw new Error('Tarayıcı oturumu saklayamadı. Site depolama iznini kontrol edip tekrar deneyin.');}
|
||||
return data.user;
|
||||
}
|
||||
|
||||
// Sayfa açılışında saklı token'ı doğrula (opsiyonel; başarısızsa oturum düşer)
|
||||
// Geçici hizmet hatası oturumu silmez; yalnız açık yetki reddi sona erdirir.
|
||||
export async function restoreSession() {
|
||||
const token = getToken();
|
||||
if (!token) return null;
|
||||
try {
|
||||
const res = await fetch('/api/auth/me', { headers: { Authorization: `Bearer ${token}` } });
|
||||
const data = await authRequest('/api/auth/me', { headers: { Authorization: `Bearer ${token}` } });
|
||||
if (getToken() !== token) return getStoredUser();
|
||||
if (!res.ok) { clearSession(); return null; }
|
||||
const data = await res.json();
|
||||
if (data?.success && typeof data.user?.email === 'string' && data.user.email) {
|
||||
setSession(token, data.user);
|
||||
return data.user;
|
||||
}
|
||||
return getStoredUser();
|
||||
} catch (error) {
|
||||
if (getToken() !== token) return getStoredUser();
|
||||
if (data.success) { setSession(token, data.user); return data.user; }
|
||||
clearSession();
|
||||
return null;
|
||||
} catch {
|
||||
// Ağ hatası: saklı kullanıcıyı koru (offline)
|
||||
if (error.status === 401 || error.status === 403) { clearSession(); return null; }
|
||||
return getStoredUser();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user