fixed request for reauth on clicking show folder

This commit is contained in:
2026-01-10 19:39:57 +00:00
parent c22ada9c7e
commit 221e9d1f53
4 changed files with 44 additions and 35 deletions
+5 -8
View File
@@ -34,9 +34,9 @@ const getGraphToken = (c?: any) => {
const headerToken = c?.req?.header ? c.req.header('x-graph-token') : '';
const envToken = process.env.GRAPH_TOKEN || process.env.MS_GRAPH_TOKEN || '';
const token = headerToken || envToken;
console.log('[getGraphToken] Header token:', headerToken ? headerToken.substring(0, 20) + '...' : 'NONE');
console.log('[getGraphToken] Env token:', envToken ? 'SET' : 'NOT SET');
console.log('[getGraphToken] Using:', token ? token.substring(0, 20) + '...' : 'NONE');
if (!headerToken && !envToken) {
console.warn('[getGraphToken] No token available in header or environment');
}
return token;
};
@@ -120,18 +120,15 @@ const filterByCategory = (items: DriveItem[], category?: string) => {
// List/search job files via Graph using a shared folder link
app.get('/api/job-files', async (c) => {
try {
console.log('[job-files] Request received');
const token = getGraphToken(c);
if (!token) {
console.log('[job-files] No token found');
return c.json({ error: 'GRAPH_TOKEN missing' }, 500);
console.error('[job-files] No Graph token available (not in header or env)');
return c.json({ error: 'Graph access token required. Please sign in again.' }, 401);
}
console.log('[job-files] Token found:', token.substring(0, 20) + '...');
const link = c.req.query('link');
const q = c.req.query('q') || '';
const category = c.req.query('category') || '';
if (!link) return c.json({ error: 'link required' }, 400);
console.log('[job-files] Link:', link);
const { driveId, itemId } = await resolveShareLink(link, token);
+4 -3
View File
@@ -880,7 +880,6 @@
const iframeViewerModal = document.getElementById('iframeViewerModal');
const iframeViewer = document.getElementById('iframeViewer');
const iframeLoader = document.getElementById('iframeLoader');
iframeLoader.style.display = 'none'; // disable loader overlay entirely
const iframeTitle = document.getElementById('iframeTitle');
const iframeBackBtn = document.getElementById('iframeBackBtn');
const iframeCloseBtn = document.getElementById('iframeCloseBtn');
@@ -1354,12 +1353,14 @@
iframeTitle.textContent = job.Job_Number ? `Job# ${job.Job_Number}` : 'Job Files';
fileListContainer.classList.remove('hidden');
iframeViewer.classList.add('hidden');
pdfViewer.classList.add('hidden');
// Check if we have cached files
const cached = fileCache.get(link);
if (cached) {
console.log('Using cached files for job', job.Job_Number);
fileListState.items = cached.items;
iframeLoader.classList.add('hidden');
renderFileGroups(link);
return;
}
@@ -1393,8 +1394,8 @@
}
}
// If still unauthorized or server missing token, prefer stale cache or open-in-new-tab without forcing reauth
if (resp.status === 401 || resp.status === 500) {
// If still unauthorized, prefer stale cache or open-in-new-tab without forcing reauth
if (resp.status === 401) {
const cachedAgain = fileCache.get(link);
if (cachedAgain) {
fileListState.items = cachedAgain.items;
+26
View File
@@ -58,9 +58,35 @@
errorEl.classList.add('hidden');
try {
// Step 1: Authenticate with PocketBase via Microsoft OAuth
const authData = await pb.collection('users').authWithOAuth2({
provider: 'microsoft',
});
// Step 2: Try to get Graph token from PB response
let graphToken = (
authData?.meta?.graphAccessToken ||
authData?.meta?.graph_token ||
authData?.meta?.graphToken ||
authData?.meta?.accessToken ||
authData?.meta?.access_token ||
authData?.meta?.token ||
''
);
// Step 3: If no Graph token from PB, use the OAuth token as the Graph token
// (PB's Microsoft OAuth should return a token that works with Graph API)
if (!graphToken && authData?.meta?.rawUser) {
// The OAuth token from Microsoft should work for Graph API calls
graphToken = authData?.token || authData?.meta?.accessToken || '';
}
if (graphToken) {
const expiresAt = authData?.meta?.graphTokenExpiresAt || new Date(Date.now() + 3600000).toISOString();
await tokenManager.setToken(graphToken, expiresAt);
console.log('[Login] Graph token stored successfully');
}
displayUserInfo(authData);
} catch (error) {
console.error('Login failed:', error);
+9 -24
View File
@@ -136,18 +136,15 @@ class TokenManager {
*/
async refreshToken() {
if (this.isRefreshing) {
console.log('[TokenManager] Refresh already in progress');
return this.token; // Return existing token while refresh ongoing
}
if (!this.pb?.authStore?.isValid) {
console.log('[TokenManager] PB session invalid, cannot refresh');
return null;
}
this.isRefreshing = true;
try {
console.log('[TokenManager] Refreshing token...');
const authData = await this.pb.collection('users').authRefresh();
const meta = authData?.meta || {};
@@ -156,17 +153,16 @@ class TokenManager {
if (newToken) {
await this.setToken(newToken, newExpiry);
console.log('[TokenManager] Token refreshed successfully');
this.retryAttempts = 0; // Reset retry counter on success
this.retryAttempts = 0;
return newToken;
} else {
console.warn('[TokenManager] No token in refresh response');
return null;
// PB authRefresh doesn't return Graph tokens - this is expected
// Token must be obtained during initial OAuth flow
return this.token; // Return existing token if we have one
}
} catch (err) {
console.error('[TokenManager] Refresh failed:', err.message);
this.queueRefreshRetry();
return this.token; // Return stale token while retrying
console.error('[TokenManager] PB authRefresh failed:', err.message);
return this.token; // Return stale token on error
} finally {
this.isRefreshing = false;
}
@@ -176,20 +172,9 @@ class TokenManager {
* Queue retry with exponential backoff
*/
queueRefreshRetry() {
if (this.retryAttempts >= this.maxRetries) {
console.error('[TokenManager] Max refresh retries reached');
return;
}
this.retryAttempts++;
const backoffMs = Math.pow(2, this.retryAttempts - 1) * 1000; // 1s, 2s, 4s, 8s, 16s
console.log(`[TokenManager] Retry ${this.retryAttempts}/${this.maxRetries} in ${backoffMs}ms`);
setTimeout(() => {
this.refreshToken().catch(err => {
console.error('[TokenManager] Retry failed:', err.message);
});
}, backoffMs);
// Disable retry queue since PB authRefresh won't return Graph tokens
// Graph tokens must be obtained through the initial OAuth flow
return;
}
/**