2

I am using a tool called TamperMonkey to modify a webpage for my personal convenience. TamperMonkey lets you modify the client-side HTML etc. by appending JavaScript to the page after it loads.

The webpage has a file chooser, but it doesn't let you drag-and-drop a file. I use this webpage a lot so having drag-and-drop functionality would really help.

This page has a form with a file input type. I've been reading, and there's no way to modify a file input type for security reasons. But, using TamperMonkey, I could change the input type of the file chooser to "hidden," then set the hidden input value to the file contents that I drop on the webpage, right? It's my understanding that the server couldn't tell the difference (if the name attribute is the same).

I don't know how to set the hidden input type to the same data the file chooser would have:

I've got my file here: const file = e.originalEvent.dataTransfer.files[0];

I've got my hidden input type by doing this: const hiddenField = $("iframe").contents().find(".file-input").attr('type','hidden')

I just don't know how to take file and set it on hiddenField. Should this value be base64 encoded? A blob? Regardless, what code would set the data correctly?

The form it's wrapped in looks like this:

<form ... method="post" enctype="multipart/form-data">

Important context for alternative suggestions: this file chooser input isn't on the page at all until you click a button. Then it shows up in an iframe.

I am using firefox.

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356
  • Are you able to share more code? or even the url for the website? – Goldwave Oct 01 '20 at 17:44
  • @Goldwave I can't share the website. I can share code if you tell me what more you are looking for. – Daniel Kaplan Oct 01 '20 at 18:06
  • Have you tried dragging the file onto the select button? the "Select file to upload" button. Or is there no such thing? – Goldwave Oct 01 '20 at 18:11
  • @Goldwave it doesn't work. The select button is in a pop-up and I have to click something before it shows up. – Daniel Kaplan Oct 01 '20 at 18:15
  • Some ideas. 1) In dragover event on document.body change the style of the existing file input so it covers the entire page e.g. add a humongous transparent border and use absolute positioning + z-index 2) replace the submit event of the page and construct the payload yourself using FormData API which can directly use a file blob that you would read from the file's contents in your `drop` event handler. – wOxxOm Oct 01 '20 at 18:39
  • @wOxxOm I think I'm asking how to do #2 – Daniel Kaplan Oct 01 '20 at 19:22

1 Answers1

1

It is possible to modify a file input type with Tampermonkey.

If you are not able to add drag and drop support to the input itself straight away, you can implement drag and drop using another dom element and use them as below.

const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)

dT.items.add(new File([dataURItoBlob(image)], '1.jpg', { type: 'image/jpeg' }));
dT.items.add(new File([dataURItoBlob(image2)], '2.jpg', { type: 'image/jpeg' }));

// then ...
// $("iframe").contents().find(".file-input").get(0).files = dT.files;

That snippet of code was tested working, in a similar setting where a file input was being attached to the page dynamically after clicking a button. The images were drag n dropped onto the page using a different div.

Prasanth
  • 5,230
  • 2
  • 29
  • 61
  • I already have the file: `const file = e.originalEvent.dataTransfer.files[0]; ` I'm going to attempt to use the last line of your answer. – Daniel Kaplan Oct 05 '20 at 22:07
  • 1
    Would be nice to link to [where](https://stackoverflow.com/questions/47119426/how-to-set-file-objects-and-length-property-at-filelist-object-where-the-files-a/47172409#47172409) you pick half of your code... – Kaiido Oct 06 '20 at 02:19