Fix: Add fallback token retrieval endpoint and improved token extraction debugging

This commit is contained in:
2026-01-18 04:15:37 +00:00
parent 1322ace853
commit 3cc466c12d
3 changed files with 112 additions and 6 deletions
+42
View File
@@ -82,6 +82,48 @@ app.get('/version', (c) => {
}
});
// Get Graph token from PocketBase auth data
app.get('/api/graph-token', async (c) => {
try {
const authHeader = c.req.header('Authorization');
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return c.json({ error: 'Unauthorized' }, 401);
}
const pbToken = authHeader.substring(7);
// Fetch the authenticated user's data from PocketBase
const response = await fetch('https://pocketbase.ccllc.pro/api/collections/users/auth-refresh', {
method: 'POST',
headers: { 'Authorization': `Bearer ${pbToken}` }
});
if (!response.ok) {
return c.json({ error: 'Failed to refresh auth' }, response.status);
}
const data = await response.json();
const meta = data?.meta || {};
// Extract Graph token from all possible locations
const graphToken =
meta?.graphAccessToken ||
meta?.graph_token ||
meta?.graphToken ||
meta?.accessToken ||
meta?.access_token ||
meta?.token ||
meta?.rawToken ||
meta?.authData?.access_token ||
'';
return c.json({ token: graphToken });
} catch (err) {
logLine('logs/error.log', `graph-token endpoint error: ${(err as Error)?.message || String(err)}`);
return c.json({ error: 'Failed to get token', token: '' }, 500);
}
});
// Jobs endpoint with Redis caching
app.get('/api/jobs', async (c) => {
const page = parseInt(c.req.query('page') || '1');
+32 -6
View File
@@ -280,6 +280,7 @@
let refreshPromise = null;
let lastRefreshTime = 0;
const REFRESH_COOLDOWN = 2000; // 2 second cooldown between refreshes
let refreshFailureCount = 0;
const refreshGraphToken = async () => {
try {
@@ -290,7 +291,9 @@
// If refreshed recently, return cached token
if (Date.now() - lastRefreshTime < REFRESH_COOLDOWN) {
return getGraphToken();
const cached = getGraphToken();
if (cached) return cached;
// Even within cooldown, if no cached token, still try refresh
}
// Start new refresh
@@ -299,9 +302,22 @@
const authData = await pb.collection('users').authRefresh();
const meta = authData?.meta || pb?.authStore?.model?.meta || {};
const token = extractGraphToken(meta);
if (token) localStorage.setItem(GRAPH_TOKEN_KEY, token);
lastRefreshTime = Date.now();
return token || '';
if (token) {
localStorage.setItem(GRAPH_TOKEN_KEY, token);
lastRefreshTime = Date.now();
refreshFailureCount = 0;
console.log('✓ Graph token refreshed');
return token;
} else {
console.warn('Graph token missing from auth response');
refreshFailureCount++;
return '';
}
} catch (err) {
console.warn('Token refresh request failed:', err?.message||err);
refreshFailureCount++;
throw err;
} finally {
refreshPromise = null;
}
@@ -310,8 +326,18 @@
return await refreshPromise;
} catch(err){
refreshPromise = null;
console.warn('Graph token refresh failed:', err?.message||err);
return getGraphToken(); // Return cached token if refresh fails
console.error('Graph token refresh failed completely:', err?.message||err);
// If refresh failed multiple times, force sign-in
if (refreshFailureCount >= 2) {
console.warn('Token refresh failed multiple times. Forcing sign-in.');
localStorage.removeItem(GRAPH_TOKEN_KEY);
try { pb?.authStore?.clear?.(); } catch {}
try { localStorage.removeItem('pocketbase_auth'); } catch {}
try { sessionStorage.clear(); } catch {}
window.location.href = 'signin.html?expired=1';
return '';
}
return '';
}
}
+38
View File
@@ -101,13 +101,51 @@
const email = authData?.meta?.rawUser?.email || authData?.record?.email || pb.authStore.model?.email || 'Not available';
const graphToken = extractGraphToken(authData);
console.log('Extracted Graph token:', graphToken ? graphToken.substring(0, 30) + '...' : 'NOT FOUND');
console.log('Full meta object:', JSON.stringify(authData?.meta, null, 2));
if (graphToken) {
localStorage.setItem(GRAPH_TOKEN_KEY, graphToken);
localStorage.removeItem(GRAPH_REAUTH_FLAG);
console.log('✓ Graph token stored');
} else {
console.error('❌ Graph token NOT found in auth response!');
console.error('Available meta keys:', Object.keys(authData?.meta || {}));
// If token not in response, try fetching it from the backend
console.log('Attempting to fetch token from backend...');
fetchTokenFromBackend().then(token => {
if (token) {
localStorage.setItem(GRAPH_TOKEN_KEY, token);
console.log('✓ Graph token fetched from backend');
} else {
console.warn('⚠ Graph token could not be obtained from backend');
}
showAuthedUI(displayName, email);
}).catch(err => {
console.error('Failed to fetch token from backend:', err);
showAuthedUI(displayName, email);
});
return;
}
showAuthedUI(displayName, email);
}
async function fetchTokenFromBackend() {
try {
const response = await fetch('/api/graph-token', {
headers: {
'Authorization': `Bearer ${pb.authStore.token}`
}
});
if (response.ok) {
const data = await response.json();
return data.token || '';
}
} catch (err) {
console.warn('Token fetch error:', err.message);
}
return '';
}
(async () => {
const params = new URLSearchParams(window.location.search);
const reauth = params.get('reauth') === '1';