Skip to content

Conversation

@kuhe
Copy link
Contributor

@kuhe kuhe commented Oct 17, 2025

Issue

#7428
and related to #7237

Description

in the cloudfront signer, encode search params contained in the base URL. This is more consistent with the URL object normalization that was occurring earlier.

Testing

unit tests

Checklist

  • If the PR is a feature, add integration tests (*.integ.spec.ts).
    • unit tests are able to exercise the full public API of the signer
  • If you wrote E2E tests, are they resilient to concurrent I/O?
  • If adding new public functions, did you add the @public tag and enable doc generation on the package?

@kuhe kuhe merged commit 8458bab into main Oct 17, 2025
7 checks passed
@kuhe kuhe deleted the fix/cloudfront-signer branch October 17, 2025 19:42
@eliocapella
Copy link

eliocapella commented Oct 30, 2025

It seems this change broke the ability to set filename*= in the content disposition

function encodeRFC5987ValueChars(str) {
  return encodeURIComponent(str)
    .replace(/['()]/g, escape)
    .replace(/\*/g, "%2A")
    .replace(/%(?:7C|60|5E)/g, unescape);
}

/**
 * @param {string} key file data key
 * @param {object} options
 * @param {false | string} [options.download=false] filename if we want to force download on the browser
 * @returns {Shared.URL}
 */
exports.url = function (key, { download = false } = {}) {
  let url = `${env.AWS_CLOUDFRONT_BASE_URL}/${encodeURI(key)}`;
  if (download) {
    const encName = encodeRFC5987ValueChars(download);
    url += `?response-content-disposition=${encodeURIComponent(
      `attachment; filename=${encName}; filename*=UTF-8''${encName}`,
    )}`;
  }
  return /** @type {Shared.URL} */ (url);
};

/**
 * @param {string} key file data key
 * @param {object} options
 * @param {number} [options.hoursToExpire=24]
 * @param {false | string} [options.download=false] filename if we want to force download on the browser
 * @returns {Shared.URL}
 */
exports.signedUrl = function (
  key,
  { hoursToExpire = 24, download = false } = {},
) {
  return /** @type {Shared.URL} */ (
    getSignedCloudfrontUrl({
      url: exports.url(key, { download }),
      keyPairId: env.AWS_CLOUDFRONT_KEY_ID,
      privateKey: env.AWS_CLOUDFRONT_PRIVATE_KEY,
      dateLessThan: new Date(
        Date.now() + hoursToExpire * 60 * 60 * 1000,
      ).toISOString(),
    })
  );
};

this code stopped working after upgrading, it seems Cloudfront needs the * in filename* not to be encoded for the URLs not to work and now that isn't possible anymore.

I ended up implementing my own Cloudwatch signer

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 14, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants