const { BrowserWindow } = require('@electron/remote'); const { v4: uuidv4 } = require('uuid'); // Add this for GUID generation class GraphApiClient { constructor() { this.baseUrl = 'https://graph.microsoft.com/v1.0'; this.clientId = "073204aa-c1e0-4e66-a200-e5815a0aa93d"; this.scopes = "OneDrive.ReadWrite offline_access openid profile"; this.redirectUrl = "https://photos.onedrive.com/auth/login"; } async getAccessToken() { return new Promise((resolve, reject) => { const authWindow = new BrowserWindow({ width: 800, height: 600, show: true, webPreferences: { nodeIntegration: false, contextIsolation: true } }); const authUrl = `https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?` + `client_id=${this.clientId}` + `&nonce=uv.${uuidv4()}` + `&response_mode=form_post` + `&scope=${encodeURIComponent(this.scopes)}` + `&response_type=code` + `&redirect_uri=${encodeURIComponent(this.redirectUrl)}`; console.log('Loading auth URL:', authUrl); authWindow.loadURL(authUrl); // Handle the navigation events authWindow.webContents.on('will-navigate', (event, url) => { console.log('Navigation detected:', url); handleCallback(url); }); authWindow.webContents.on('will-redirect', (event, url) => { console.log('Redirect detected:', url); handleCallback(url); }); const handleCallback = async (callbackUrl) => { // Check if this is our redirect URI if (callbackUrl.startsWith(this.redirectUrl)) { console.log('Redirect URI matched, getting cookies...'); try { // Get all cookies const cookies = await authWindow.webContents.session.cookies.get({}); console.log('Found cookies:', cookies.length); // Find the access token const accessToken = cookies.find( cookie => cookie.name === 'AccessToken-OneDrive.ReadWrite' ); if (accessToken) { console.log('Found access token in cookies'); authWindow.close(); resolve(accessToken.value); } else { console.log('Access token not found in cookies, waiting...'); } } catch (error) { console.error('Error getting cookies:', error); reject(error); } } }; // Handle window closing authWindow.on('closed', () => { console.log('Auth window closed'); reject(new Error('Authentication window was closed')); }); }); } cleanPath(path) { return path .replace(/^\/+|\/+$/g, '') // Remove leading/trailing slashes .split('/') .map(segment => encodeURIComponent(segment)) .join('/'); } async listFolderContents(folderPath) { try { console.log('graphApiClient listFolderContents:', folderPath); const accessToken = await this.getAccessToken(); console.log('graphApiClient Access token:', accessToken); const cleanPath = this.cleanPath(folderPath); console.log('graphApiClient Clean path:', cleanPath); const url = `${this.baseUrl}/me/drive/root:/${cleanPath}:/children`; console.log('Querying OneDrive items from:', url); const response = await fetch(url, { headers: { 'Authorization': `Bearer ${accessToken}`, 'Accept': 'application/json', 'Origin': 'https://onedrive.live.com', 'Referer': 'https://onedrive.live.com/' } }); if (!response.ok) { const errorData = await response.json(); console.error('Graph API error details:', errorData); throw new Error(`Graph API error: ${response.status} ${response.statusText}`); } const data = await response.json(); return data.value; } catch (error) { console.error('Graph API error:', error); throw error; } } } module.exports = new GraphApiClient();