masugadesign / link-vault-craft-cms

The Link Vault download link protection plugin for Craft CMS v3.
Other
5 stars 2 forks source link

Ability to pass options argument to sendFile() via downloadUrl() #25

Closed jrrdnx closed 1 month ago

jrrdnx commented 1 month ago

Craft Version & Installed Plugin Version
Craft: 5.4.1 Plugin: 5.0.1

Is your feature request related to a problem? Please describe.
I'd like to use the generated downloadUrl for the data attribute in an object tag for embedded PDFs.

Describe the solution you'd like
Need a way to pass the options argument to Craft::$app->getResponse()->sendFile() so that inline can be set to false

Additional context
Not sure if there's a way to achieve this currently, but I'd like to use the generated downloadUrl for the data attribute in an object tag for embedded PDFs. However, this currently just prompts the user to download the file.

benjaminkohl commented 1 month ago

I don't believe there is currently a way to do this with the plugin. I want to make sure I am understanding–are you trying to use Link Vault to obfuscate the URL without actually downloading the file?

jrrdnx commented 1 month ago

Sorry, got my wires crossed a bit. I was looking at the download() method (not downloadUrl()) which is what calls sendFile(). It makes more sense to me now to look for mimeType and inline keys in the existing $parameters argument and pass those as the third argument to sendFile() like you're doing with $downloadAs. Also just noticed that a new Variable method would need to be added as well to call download().

Yes, the intent is to obfuscate the URL without actually downloading the file. Just use it as the data attribute for an object tag (or src for embed/iframe, still testing) to embed in the page. This functionality is locked behind permissions logic, so if I understand correctly even if the URL itself were shared it'd be blocked since the blockLeechAttempts setting is set to true.

ryanmasuga commented 1 month ago

What is the use case? What are you trying to accomplish with this functionality?

jrrdnx commented 1 month ago

Embedding a PDF file (hosted on Cloudflare R2 and not publicly accessible) via an object tag:

<object type="application/pdf" data="{{ craft.linkvault.downloadUrl(assetFile) }}" style="width: 100%; height: 1200px;"></object>

This does output the URL to the data attribute as expected, but prompts the user to download the file instead.

benjaminkohl commented 1 month ago

I'm following now. I could see this ability being useful, though the execution may be more complicated than described because the entire point of this plugin is to serve and track downloads so even one small change could cascade into further changes and adding the inline parameter may not function as intended for all possible $file parameter types.

The plugin code is due for some cleaning up so maybe it is something I could look into for a future release but there would definitely need to be a clear distinction between this new functionality and existing download-oriented functionality.

jrrdnx commented 1 month ago

Still doing some testing, but I've noticed that this is only occurring for me in Chromium browsers; Firefox and Safari display the file embedded in the object tag as expected.

Locally, if I change each instance of Craft::$app->getResponse()->sendFile($filePath, $downloadAs) in src/services/GeneralService.php to Craft::$app->getResponse()->sendFile($filePath, $downloadAs, [ 'inline' => true ]), this causes sendFile() to output the value of the Content-Disposition header as 'inline' instead of 'attachment' (the default) and the desired behavior is then seen in Chromium browsers as well.

jrrdnx commented 1 month ago

Have a working test case. PR incoming...

benjaminkohl commented 1 month ago

Okay, I merged it and released it as 5.0.2.

jrrdnx commented 1 month ago

Great, thank you!