/files/{id}/download CORS (╯°□°)╯︵ ┻━┻

Hey all,

I’m using ReactJS and Fetch to try and create a download button for users for their files and I’m getting the wonderful CORS issue. I’ve tried everything from Access-Control-Allow-Origin, mode: no-cors, credentials, include, a few proxies… nothing seems to work any advice?

fetch(
      `${pipedriveBaseURI}files/${eightEightTwoOne.id}/download?${pipedriveToken}`,
      {
        credentials: "include",
        method: "GET",
        headers: {
          "Access-Control-Allow-Origin": "*",
        },
      }
    )
      .then((response) => response.blob())
      .then((blob) => console.log(blob))
      .catch((error) => console.log("error", error));

Of course using postman to test works as always but it looks like it’s creating a temporary cookie

var myHeaders = new Headers();
myHeaders.append("Cookie", "__cf_bm=cnKihp4eR1NdJBLkItzOTC8fbNRF0BlpH2jzj7IxaPo-1676962333-0-AdDpKOnVhueLibdH9x0kOKDflOVwMUbZQ/Ph0JOuA7MhC1A4cqWwsZBnd1BWyvHWqz4G7M3EHr9JdeLQnSPv190=");

var requestOptions = {
  method: 'GET',
  headers: myHeaders,
  redirect: 'follow'
};

fetch("https://api.pipedrive.com/v1/files/173/download?api_token=********************", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

The API token works fine, it’s being used in multiple places to make requests for both GET and POST.

Thanks in advance

Hey @starshards
Welcome to the community :wave: and for sharing the details :slight_smile:

You are making the call directly from the front-end client and, as a result, running into the CORs issue. This also leads to security vulnerability issues since you would expose the API token. The API call has to be initiated from a backend.

This means you need a Node.js middleware (could be other runtimes like Java / Python) or a proxy that initiates the API call. This would also protect the API tokens from being exposed.

I’m using firebase cloud functions to make the api calls, and I’m still getting the same error :cry:

Every API calls work except for downloading files

Server functions

const functions = require("firebase-functions");
const fetch = require("node-fetch");

const pipedriveAPIKEY = "************************";

exports.downloadFile = functions.https.onCall(async (data, context) => {
  const fileId = data.fileId;
  const fileName = data.fileName;

  try {
    const response = await fetch(
      `https://api.pipedrive.com/v1/files/${fileId}/download?api_token=${pipedriveAPIKEY}`,
      { method: "GET", "X-Requested-With": "XMLHttpRequest" }
    );
    if (!response.ok) {
      throw new Error(
        `Failed to download file (HTTP status code ${response.status})`
      );
    }

    const fileBuffer = await response.buffer();
    return {
      file: fileBuffer.toString("base64"),
      filename: fileName,
      contentType: "application/pdf",
    };
  } catch (error) {
    console.error("Error downloading file", error);
    throw new functions.https.HttpsError("internal", "Error downloading file");
  }
});

I’ve also tried a proxy prepend the pipedrive API call, still the same thing

Access to fetch at 'https://us-central1-osc-consulting.cloudfunctions.net/downloadFile' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Hi @starshards
Thanks for being patient and for sharing the snippet. Firebase cloud functions should do the job as they initiate the call from the server side. You don’t have to use the X-Requested-With header. What is the error message that you get for the call initiated from the cloud function?

Also, is the file you are downloading in Pipedrive natively or in Google drive? You might have to append direct_download=1 depending on that.