CORS ERROR when trying to upload via TUS Direct Creator

There seem to be questions for 3 years in the similar direction. I have the following code that should upload to cloudflare stream via TUS but I get CORS Error some answers mention to use your own server URL in TUS which makes no sense at all in the current setup so I am missing some viat information here. Could someone please help me:

The Backend API:

router.post('/generate-upload-url', async (req, res, next) => {
  try {
    const CLOUDFLARE_ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID; // Taken from environment variables
    const CLOUDFLARE_API_TOKEN = process.env.CLOUDFLARE_API_TOKEN; // Taken from environment variables
    const endpoint = `https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/stream?direct_user=true`;
    const fileSize = req.body.size; // Extracting the size from the request body

    // const uploadLength = Array.isArray(req.headers['upload-length'])
    //   ? req.headers['upload-length'][0]
    //   : req.headers['upload-length'];

    const uploadMetadata = Array.isArray(req.headers['upload-metadata'])
      ? req.headers['upload-metadata'][0]
      : req.headers['upload-metadata'];

    const cloudflareResponse = await fetch(endpoint, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${CLOUDFLARE_API_TOKEN}`,
        'Tus-Resumable': '1.0.0',
        'Upload-Length': fileSize, // Assuming these headers are provided by the client
        'Upload-Metadata': uploadMetadata,
      },
    });

    if (cloudflareResponse.ok) {
      const destination = cloudflareResponse.headers.get('Location');

      res.json({
        message: 'Generated Cloudflare one-time upload URL successfully.',
        uploadURL: destination,
      });
    } else {
      const errorData = await cloudflareResponse.json();
      res.status(400).json({
        error: 'Failed to generate Cloudflare upload URL',
        details: errorData,
      });
    }
  } catch (err) {
    next(err);
  }
});

The call in the client

  const uploadToCloudFlare = async (file) => {
    const fileSize = file.size; // Getting the size of the file in bytes

    const { uploadURL } = await generateUploadURL(fileSize);
    console.log(uploadURL);

    if (!uploadURL) {
      console.error('Could not generate one-time URL');
      return;
    }

    const upload = new Upload(file, {
      endpoint: uploadURL,
      retryDelays: [0, 1000, 3000, 5000],
      chunkSize: 50 * 1024 * 1024,
      metadata: {
        filename: file.name,
        filetype: file.type,
      },
      onError: function (error) {
        console.error('CloudFlare Upload Error:', error);
      },
      onProgress: function (bytesUploaded, bytesTotal) {
        const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
        console.log(percentage);
        setUploadProgress(parseFloat(percentage));
        console.log(bytesUploaded, bytesTotal, percentage + '%');
      },
      onSuccess: function () {
        console.log('Upload finished:', upload.url);
      },
    });

    upload.start();
  };

I got it now working with

  const uploadToCloudFlare = async (file) => {
    const fileSize = file.size; // Getting the size of the file in bytes

    // const response = await generateUploadURL(fileSize);

    // if (!uploadURL) {
    //   console.error('Could not generate one-time URL');
    //   return;
    // }

    console.log(file.name);
    const upload = new Upload(file, {
      endpoint: 'http://localhost:8000/api/v1/team-member/generate-upload-url',

      retryDelays: [0, 1000, 3000, 5000],
      chunkSize: 50 * 1024 * 1024,

      metadata: {
        filename: file.name,
        filetype: file.type,
        name: file.name,
      },

      onBeforeRequest: function (req) {
        const xhr = req.getUnderlyingObject();
        xhr.withCredentials = true;
      },

      onError: function (error) {
        console.error('CloudFlare Upload Error:', error);
      },
      onProgress: function (bytesUploaded, bytesTotal) {
        const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
        console.log(percentage);
        setUploadProgress(parseFloat(percentage));
        console.log(bytesUploaded, bytesTotal, percentage + '%');
      },
      onSuccess: function () {
        console.log('Upload finished:', upload.url);
      },
    });

    upload.start();
  };
router.post('/generate-upload-url', async (req, res, next) => {
  try {
    const CLOUDFLARE_ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID; // Taken from environment variables
    const CLOUDFLARE_API_TOKEN = process.env.CLOUDFLARE_API_TOKEN; // Taken from environment variables
    const endpoint = `https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/stream?direct_user=true`;

    console.log(req.headers['uploadSize']);

    const uploadLength = Array.isArray(req.headers['upload-length'])
      ? req.headers['upload-length'][0]
      : req.headers['upload-length'];

    const uploadMetadata = Array.isArray(req.headers['upload-metadata'])
      ? req.headers['upload-metadata'][0]
      : req.headers['upload-metadata'];

    const cloudflareResponse = await fetch(endpoint, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${CLOUDFLARE_API_TOKEN}`,
        'Tus-Resumable': '1.0.0',
        'Upload-Length': uploadLength, // Assuming these headers are provided by the client
        'Upload-Metadata': uploadMetadata,
      },
    });

    if (cloudflareResponse.ok) {
      const destination = cloudflareResponse.headers.get('Location');
      console.log(cloudflareResponse);
      res.setHeader('Location', destination); // Set the Location header
      res.setHeader('Access-Control-Expose-Headers', 'Location');
      res.setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type'); // Specify headers explicitly instead of '*'
      res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); // Specify the exact origin instead of '*'

      res.json({
        message: 'Generated Cloudflare one-time upload URL successfully.',
        uploadURL: destination,
      });
    } else {
      const errorData = await cloudflareResponse.json();
      res.status(400).json({
        error: 'Failed to generate Cloudflare upload URL',
        details: errorData,
      });
    }
  } catch (err) {
    next(err);
  }
});

But it is not working with protected resources that require JWT or Cokkie to be authenticated , here again I get a Cors error

Access to XMLHttpRequest at 'https://upload.videodelivery.net/tus/[key]?tusv2=true' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Please update also your documentation , it is a great product but it is not a good sign when a service that should make things “easier” takes more time to configure than my whole media pipeline in AWS with S3 → Lamda/FFMPEG) → S3 → Cloudfront

I can get it working with the following way…but sorry this is a hacky approach there must be another way that should be covered in the documentation this is a standard case having a protected API on the backend that is be used to generate one time URL →

const uploadToCloudFlare = async (file) => {
    const fileSize = file.size; // Getting the size of the file in bytes

    // const response = await generateUploadURL(fileSize);

    // if (!uploadURL) {
    //   console.error('Could not generate one-time URL');
    //   return;
    // }

    console.log(file.name);
    const upload = new Upload(file, {
      endpoint: 'http://localhost:8000/api/v1/team-member/generate-upload-url',

      retryDelays: [0, 1000, 3000, 5000],
      chunkSize: 50 * 1024 * 1024,

      metadata: {
        filename: file.name,
        filetype: file.type,
        name: file.name,
      },

      onBeforeRequest: function (req) {
        if (req.getURL() === 'http://localhost:8000/api/v1/team-member/generate-upload-url') {
          const xhr = req.getUnderlyingObject();
          xhr.withCredentials = true;
        }
      },

      onError: function (error) {
        console.error('CloudFlare Upload Error:', error);
      },
      onProgress: function (bytesUploaded, bytesTotal) {
        const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
        console.log(percentage);
        setUploadProgress(parseFloat(percentage));
        console.log(bytesUploaded, bytesTotal, percentage + '%');
      },
      onSuccess: function () {
        console.log('Upload finished:', upload.url);
      },
    });

    upload.start();
  };```