UNPKG

@rsweeten/dropbox-sync

Version:

Reusable Dropbox synchronization module with framework adapters

85 lines (84 loc) 3.77 kB
export function createAuthMethods(getClient, credentials, setAccessToken) { return { /** * Generate an authentication URL for Dropbox OAuth flow */ async getAuthUrl(redirectUri, state) { const dropbox = getClient(); const randomState = state || Math.random().toString(36).substring(2, 15); // Cast to extended auth type to access missing methods const auth = dropbox.auth; // Generate the authentication URL const authUrl = auth.getAuthenticationUrl(redirectUri, randomState, 'code', // Use authorization code flow 'offline', // Request a refresh token for long-lived access undefined, // No scope specified, request full access undefined, // No include_granted_scopes true // Force reapproval to ensure we get fresh tokens ); return authUrl; }, /** * Exchange authorization code for access token */ async exchangeCodeForToken(code, redirectUri) { const dropbox = getClient(); // Cast to extended auth type to access missing methods const auth = dropbox.auth; // Exchange the code for an access token const response = await auth.getAccessTokenFromCode(redirectUri, code); const tokenResponse = { accessToken: response.result.access_token, refreshToken: response.result.refresh_token, expiresAt: response.result.expires_in ? Date.now() + response.result.expires_in * 1000 : undefined, }; // Update the client with the new token setAccessToken(tokenResponse.accessToken); return tokenResponse; }, /** * Refresh an expired access token using the refresh token */ async refreshAccessToken() { if (!credentials.refreshToken || !credentials.clientId || !credentials.clientSecret) { throw new Error('Refresh token, client ID, and client secret are required to refresh access token'); } // Dropbox API endpoint for token refresh const tokenUrl = 'https://api.dropboxapi.com/oauth2/token'; // Prepare the form data for the token request const formData = new URLSearchParams({ grant_type: 'refresh_token', refresh_token: credentials.refreshToken, client_id: credentials.clientId, client_secret: credentials.clientSecret, }); // Make the request to refresh the token const response = await fetch(tokenUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: formData.toString(), }); if (!response.ok) { await response.text(); // Consume the response body throw new Error(`Failed to refresh token: ${response.status} ${response.statusText}`); } // Parse the response const data = await response.json(); const tokenResponse = { accessToken: data.access_token, refreshToken: data.refresh_token || credentials.refreshToken, expiresAt: data.expires_in ? Date.now() + data.expires_in * 1000 : undefined, }; // Update the client with the new token setAccessToken(tokenResponse.accessToken); return tokenResponse; }, }; }