Verifying drag & dropped file extension using JavaScript - javascript

I created a page that would accept drag & drop method of file upload, however, I couldn't get it to verify whether file extension is correct, and as of right now it simply rejects every file fed to it as "not of the right file extension". Can anyone explain to me why that is and what fixes can be done in order to fix my problem?
I'm using Apache to run my website
Here's my script of what I have tried:
const dropArea = document.getElementById("dropArea");
dropArea.addEventListener("dragover", (event)=>{
event.preventDefault();
dropArea.classList.add("active");
});
dropArea.addEventListener("dragleave", ()=>{
dropArea.classList.remove("active");
});
dropArea.addEventListener("drop", (event)=>{
event.preventDefault();
file = event.dataTransfer.files[0];
showFile(); //calling function
});
function showFile(){
const pheil = document.getElementById('TotalFail');
var filePath = file.type;
let validExtensions = ["application/x-java-keystore", "application/pkcs12"]; //adding some valid extensions in array
if(!validExtensions.includes(filePath)){
dropArea.classList.remove("active");
dropArea.classList.add("upload-fail")
var errorMessage = document.createElement("p")
errorMessage.className = "ErrorMsg"
errorMessage.id = "TotalFail"
if(pheil === null){
var errorTxt = document.createTextNode("Maximum file size exceeded or file extension is incorrect")
errorMessage.appendChild(errorTxt)
var errorDiv = document.getElementById("error-message")
errorDiv.appendChild(errorMessage)
} else {
return;
}
file.value = null;
}else{
alert("things are supposed to happen here")
}
}
What current code does:
Rejecting every file extension fed to it, even the one that's supposed to be the correct file extension
What I expect my code to do:
Correctly validate .jks and .pfx files without fault
P.S.:
I could provide a full html page with all the code if needed. Just in case that this doesn't actually look sensible at all.
Could also be that my complication is that I want my javascript to check for .jks and .pfx file extensions (e-key files) which aren't really super common.
What I have tried:
Rewriting code with different ways of verifying file extensions, none of which worked out for me.
Adding .jks and .pfx file extensions to mime.types and .htaccess
Trying other people's codes.

Related

How to use SaveAs function in Adobe Acrobat

I was trying to implement a javascript into a pdf button.Once you click it, it will allow you to .
I know there are security issues which does not allow you to use this function in pdf. And it requires you to put a SaveAs Javascript to make it trusted Functions in the computer. So i have put following code as a trusted function in my computer.
var mySaveAs = app.trustedFunction(
function(oDoc,cPath,cFlName)
{
// Ensure path has trailing "/"
cPath = cPath.replace(/([^/])$/, "$1/");
try{
oDoc.saveAs(cPath + cFlName);
}catch(e){
app.alert("Error During Save");
}
}
);
And i have these codes in my pdf file's button which allows me to saveas another pdf file which name is "123.pdf".
var doc = app.activeDocs;
var aMyPath = this.path.split("/");
aMyPath.pop();
var pathname = aMyPath.join("/")
if(typeof(mySaveAs) == "function"){
mySaveAs(doc,pathname,"345.pdf")
}else{
app.alert("Missing Save Fucntion" + "Please contact forms administrator");
}
i don't know why, but it still gives me an error message saying "Error During Save". Does anyone know the reason? Or there's a easier way to use the SaveAs function using JavaScript in Acrobat. Thanks in advance.
app.activeDocs is an array of Doc objects. Therefore the variable doc (which has not the smartest name, BTW) is an array.
However the save function requires one Doc object to work.
Try whether replacing
mySaveAs(doc,pathname,"345.pdf")
with
mySaveAs(this,pathname,"345.pdf")
would work.
I've an old code for similar thing, and that used the below code for saving the current file in new folder. I had used this in Adobe 6. Check if this works for you.
this.saveAs(destfolder+filename);

Anyway, with js, to find a filename on the server with a wildcard?

I have a js program in which I would like to build a link to a file in a specific directory. However, the js program does not know if the file will be .html, .xls .doc or .docx or others. All it knows is the directory and the first part of the filename. I have control of that directory and there will only be one file there with that first part.
Is there anyway to do this?
No. You can try these different file endings and check if the server returns something or a 404 instead. Otherwise you have the implement some logic on the server to check the directory.
This is not a good practice and I am not recommending it, but sure it can be done: Live demo (click).
//list each file name you want to find
var files = ['some-file', 'some-other-file'];
//list possible extensions
var exts = ['html', 'doc'];
//iterate each file name
$.each(files, function(index, file) {
//attempt to get the file
//pass a copy of the "exts" array so that each function can "shift" through it
getFile(file, exts.slice());
});
function getFile(file, exts) {
//the filename to try (added extension)
var newFile = file+'.'+exts.shift();
//try to get the file
$.get(newFile).then(function(data) {
//found the file - do something with the contents
foo(data);
}, function() {
//file not found
//if there are any extensions left to try
if (exts.length) {
//try again (will shift to next extension)
getFile(file, exts);
}
});
}
function foo(data) {
var div = document.createElement('div');
div.textContent = data;
document.body.appendChild(div);
}
Only with javascript you can't access any files because security reasons reference here,
but you can create an ActiveX for Internet Explorer only.

How to resolve the C:\fakepath?

<input type="file" id="file-id" name="file_name" onchange="theimage();">
This is my upload button.
<input type="text" name="file_path" id="file-path">
This is the text field where I have to show the full path of the file.
function theimage(){
var filename = document.getElementById('file-id').value;
document.getElementById('file-path').value = filename;
alert(filename);
}
This is the JavaScript which solve my problem. But in the alert value gives me
C:\fakepath\test.csv
and Mozilla gives me:
test.csv
But I want the local fully qualified file path. How to resolve this issue?
If this is due to browser security issue then what should be the alternate way to do this?
Some browsers have a security feature that prevents JavaScript from knowing your file's local full path. It makes sense - as a client, you don't want the server to know your local machine's filesystem. It would be nice if all browsers did this.
Use
document.getElementById("file-id").files[0].name;
instead of
document.getElementById('file-id').value
I use the object FileReader on the input onchange event for your input file type! This example uses the readAsDataURL function and for that reason you should have an tag. The FileReader object also has readAsBinaryString to get the binary data, which can later be used to create the same file on your server
Example:
var input = document.getElementById("inputFile");
var fReader = new FileReader();
fReader.readAsDataURL(input.files[0]);
fReader.onloadend = function(event){
var img = document.getElementById("yourImgTag");
img.src = event.target.result;
}
If you go to Internet Explorer, Tools, Internet Option, Security, Custom, find the "Include local directory path When uploading files to a server" (it is quite a ways down) and click on "Enable" . This will work
I am happy that browsers care to save us from intrusive scripts and the like. I am not happy with IE putting something into the browser that makes a simple style-fix look like a hack-attack!
I've used a < span > to represent the file-input so that I could apply appropriate styling to the < div > instead of the < input > (once again, because of IE). Now due to this IE want's to show the User a path with a value that's just guaranteed to put them on guard and in the very least apprehensive (if not totally scare them off?!)... MORE IE-CRAP!
Anyhow, thanks to to those who posted the explanation here: IE Browser Security: Appending "fakepath" to file path in input[type="file"], I've put together a minor fixer-upper...
The code below does two things - it fixes a lte IE8 bug where the onChange event doesn't fire until the upload field's onBlur and it updates an element with a cleaned filepath that won't scare the User.
// self-calling lambda to for jQuery shorthand "$" namespace
(function($){
// document onReady wrapper
$().ready(function(){
// check for the nefarious IE
if($.browser.msie) {
// capture the file input fields
var fileInput = $('input[type="file"]');
// add presentational <span> tags "underneath" all file input fields for styling
fileInput.after(
$(document.createElement('span')).addClass('file-underlay')
);
// bind onClick to get the file-path and update the style <div>
fileInput.click(function(){
// need to capture $(this) because setTimeout() is on the
// Window keyword 'this' changes context in it
var fileContext = $(this);
// capture the timer as well as set setTimeout()
// we use setTimeout() because IE pauses timers when a file dialog opens
// in this manner we give ourselves a "pseudo-onChange" handler
var ieBugTimeout = setTimeout(function(){
// set vars
var filePath = fileContext.val(),
fileUnderlay = fileContext.siblings('.file-underlay');
// check for IE's lovely security speil
if(filePath.match(/fakepath/)) {
// update the file-path text using case-insensitive regex
filePath = filePath.replace(/C:\\fakepath\\/i, '');
}
// update the text in the file-underlay <span>
fileUnderlay.text(filePath);
// clear the timer var
clearTimeout(ieBugTimeout);
}, 10);
});
}
});
})(jQuery);
On Chrome/Chromium based apps like electron you can just use the target.files:
(I'm using React JS on this example)
const onChange = (event) => {
const value = event.target.value;
// this will return C:\fakepath\somefile.ext
console.log(value);
const files = event.target.files;
//this will return an ARRAY of File object
console.log(files);
}
return (
<input type="file" onChange={onChange} />
)
The File object I'm talking above looks like this:
{
fullName: "C:\Users\myname\Downloads\somefile.ext"
lastModified: 1593086858659
lastModifiedDate: (the date)
name: "somefile.ext"
size: 10235546
type: ""
webkitRelativePath: ""
}
So then you can just get the fullName if you wanna get the path.
Note that this would only work on chrome/chromium browsers, so if you don't have to support other browsers (like if you're building an electron project) you can use this.
I came accross the same problem. In IE8 it could be worked-around by creating a hidden input after the file input control. The fill this with the value of it's previous sibling. In IE9 this has been fixed aswell.
My reason in wanting to get to know the full path was to create an javascript image preview before uploading. Now I have to upload the file to create a preview of the selected image.
If you really need to send the full path of the uploded file, then you'd probably have to use something like a signed java applet as there isn't any way to get this information if the browser doesn't send it.
Use file readers:
$(document).ready(function() {
$("#input-file").change(function() {
var length = this.files.length;
if (!length) {
return false;
}
useImage(this);
});
});
// Creating the function
function useImage(img) {
var file = img.files[0];
var imagefile = file.type;
var match = ["image/jpeg", "image/png", "image/jpg"];
if (!((imagefile == match[0]) || (imagefile == match[1]) || (imagefile == match[2]))) {
alert("Invalid File Extension");
} else {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(img.files[0]);
}
function imageIsLoaded(e) {
$('div.withBckImage').css({ 'background-image': "url(" + e.target.result + ")" });
}
}
seems you can't find the full path in you localhost by js, but you can hide the fakepath to just show the file name. Use jQuery to get the file input's selected filename without the path
The best solution for this, I've found, is to use a middleware like Multer. Here's a quick rundown:
npm i multer
Add enctype="multipart/form-data" to your html form.
In your backend dock where you're making your post request, require multer (const multer = require('multer'))
In the same dock, set your upload destination: const upload = multer({dest:'uploas/'}). This will automatically create a local folder called 'uploads' where your files will be added. The code I've included shows you how to upload to your local disk storage. If you're using cloud storage (e.g. AWS, Azure, Cloudinary etc.) you can check out the Multer docs to see how to manage that. There aren't too many extra steps though.
in your post request, add 'upload.single' (for one file) or 'upload.array' (for multiple files), like this:
router.post('/new', upload.single('image'), async function(req, res) { //'image' should be the name of the input you're sending in the req.body
console.log(req.file) //note, if you're using 'upload.array', this should be 'req.files'
});
the req.file will have a full path name that you can use in your post request. For more information, check out the Multer docs:
https://www.npmjs.com/package/multer
I hope this helps!
You would be able to get at least temporary created copy of the file path on your machine. The only condition here is your input element should be within a form
What you have to do else is putting in the form an attribute enctype, e.g.:
<form id="formid" enctype="multipart/form-data" method="post" action="{{url('/add_a_note' )}}">...</form>
you can find the path string at the bottom.
It opens stream to file and then deletes it.
Hy there , in my case i am using asp.net development environment, so i was want to upload those data in asynchronus ajax request , in [webMethod] you can not catch the file uploader since it is not static element ,
so i had to make a turnover for such solution by fixing the path , than convert the wanted image into bytes to save it in DB .
Here is my javascript function ,
hope it helps you:
function FixPath(Path)
{
var HiddenPath = Path.toString();
alert(HiddenPath.indexOf("FakePath"));
if (HiddenPath.indexOf("FakePath") > 1)
{
var UnwantedLength = HiddenPath.indexOf("FakePath") + 7;
MainStringLength = HiddenPath.length - UnwantedLength;
var thisArray =[];
var i = 0;
var FinalString= "";
while (i < MainStringLength)
{
thisArray[i] = HiddenPath[UnwantedLength + i + 1];
i++;
}
var j = 0;
while (j < MainStringLength-1)
{
if (thisArray[j] != ",")
{
FinalString += thisArray[j];
}
j++;
}
FinalString = "~" + FinalString;
alert(FinalString);
return FinalString;
}
else
{
return HiddenPath;
}
}
here only for testing :
$(document).ready(function () {
FixPath("hakounaMatata:/7ekmaTa3mahaLaziz/FakePath/EnsaLmadiLiYghiz");
});
// this will give you : ~/EnsaLmadiLiYghiz

Acrobat Javascript Save & Exit Button

I have a writeable pdf form created in acrobat pro. Now, i added a button which has to change a fields value, save the pdf and close it.
I decided to do this as following:
var fieldX = this.getField("xxxxField");
fieldX.value = 1;
app.execMenuItem("Save");
this.closeDoc(true);
But this doesn't save the pdf.
I don't want to have a confirmation dialog. I saw the saveAs function in the API but how to get the real-path incl. filename of the current editing document? Or do you have any other approaches?
thank you.
But this doesn't save the pdf.
That's because there are security restrictions that prevent app.execMenuItem("Save"); from working. You're not allowed to call Save via JS.
function in the API but how to get the real-path incl. filename of the current editing document? Or do you have any other approaches?
You can use Doc.path to get the path of the current document including its filename (and Doc.documentFilename gives you the filename only).
However, saveAs is also subject to security restrictions, and it can only be called in a "privileged" context (batch or console). So this won't work either.
In short, security restrictions will prevent you from saving documents without asking the user. If you think about it, it's only logical.
See: Acrobat JS API Reference
Client side code to save PDF Data used below link or code. It's Client side trusted function which you need to put in C:\Program Files\Adobe\...\JavaScript\Config.js.
How to Save a PDF with Acrobat JavaScript
1) Code to save data at folder level.
var mySaveAs = app.trustedFunction ( function(oDoc,cPath,cFlName)
{
app.beginPriv();
var flag=false;
cPath = cPath.replace(/([^\/])$/, "$1/");
if(cPath.indexOf("http://") !== -1 || cPath.indexOf("https://") !== -1)
{
cPath = cPath.replace('http://', "\\\\");
cPath = cPath.replace('https://', "\\\\");
while(cPath.indexOf("/") !== -1)
{
cPath = cPath.replace('/', "\\\\");
}
}
if(cPath.indexOf(":") !== -1)
{
cPath = cPath.replace(":","#");
}
try{
oDoc.saveAs(cPath + cFlName);
flag = true;
}catch(e){
app.alert("Error During Save");
}
app.endPriv();
return flag;
});
2) Code to save data at SharePoint.
var mySaveAs = app.trustedFunction ( function(oDoc,cPath,cFlName)
{
app.beginPriv();
var flag=false;
try{
app.execMenuItem("Save");
flag = true;
}catch(e){
app.alert("Error During Save");
}
app.endPriv();
return flag;
});

Is robust javascript-only upload of file possible

I want a robust way to upload a file. That means that I want to be able to handle interruptions, error and pauses.
So my question is: Is something like the following possible using javascript only on the client.
If so I would like pointers to libraries, tutorials, books or implementations.
If not I would like an explanation to why it's not possible.
Scenario:
Open a large file
Split it into parts
For each part I would like to
Create checksum and append to data
Post data to server (the server would check if data uploaded correctly)
Check a web page on server to see if upload is ok
If yes upload next part if no retry
Assume all posts to server is accompanied by relevant meta data (sessionid and whatnot).
No. You can, through a certain amount of hackery, begin a file upload with AJAX, in which case you'll be able to tell when it's finished uploading. That's it.
JavaScript does not have any direct access to files on the visitor's computer for security reasons. The most you'll be able to see from within your script is the filename.
Firefox 3.5 adds support for DOM progress event monitoring of XMLHttpRequest transfers which allow you to keep track of at least upload status as well as completion and cancellation of uploads.
It's also possible to simulate progress tracking with iframes in clients that don't support this newer XMLHTTPRequest additions.
For an example of script that does just this, take a look at NoSWFUpload. I've been using it succesfully for about few months now.
It's possible in Firefox 3 to open a local file as chosen by a file upload field and read it into a JavaScript variable using the field's files array. That would allow you to do your own chunking, hashing and sending by AJAX.
There is some talk of getting something like this standardised by W3, but for the immediate future no other browser supports this.
Yes. Please look at the following file -
function Upload() {
var self = this;
this.btnUpload;
this.frmUpload;
this.inputFile;
this.divUploadArea;
this.upload = function(event, target) {
event.stopPropagation();
if (!$('.upload-button').length) {
return false;
}
if (!$('.form').length) {
return false;
}
self.btnUpload = target;
self.frmUpload = $(self.btnUpload).parents('form:first');
self.inputFile = $(self.btnUpload).prev('.upload-input');
self.divUploadArea = $(self.btnUpload).next('.uploaded-area');
var target = $(self.frmUpload).attr('target');
var action = $(self.frmUpload).attr('action');
$(self.frmUpload).attr('target', 'upload_target'); //change the form's target to the iframe's id
$(self.frmUpload).attr('action', '/trnUpload/upload'); //change the form's action to the upload iframe function page
$(self.frmUpload).parent("div").prepend(self.iframe);
$('#upload_target').load(function(event){
if (!$("#upload_target").contents().find('.upload-success:first').length) {
$('#upload_target').remove();
return false;
} else if($("#upload_target").contents().find('.upload-success:first') == 'false') {
$('#upload_target').remove();
return false;
}
var fid = $("#upload_target").contents().find('.fid:first').html();
var filename = $("#upload_target").contents().find('.filename:first').html();
var filetype = $("#upload_target").contents().find('.filetype:first').html();
var filesize = $("#upload_target").contents().find('.filesize:first').html();
$(self.frmUpload).attr('target', target); //change the form's target to the iframe's id
$(self.frmUpload).attr('action', action); //change the form's
$('#upload_target').remove();
self.insertUploadLink(fid, filename, filetype, filesize);
});
};
this.iframe = '' +
'false' +
'';
this.insertUploadLink = function (fid, filename, filetype, filesize) {
$('#upload-value').attr('value', fid);
}
}
$(document).ready(event) {
var myupload = new Upload();
myupload.upload(event, event.target);
}
With also using PHP's APC to query the status of how much of the file has been uploaded, you can do a progress bar with a periodical updater (I would use jQuery, which the above class requires also). You can use PHP to output both the periodical results, and the results of the upload in the iframe that is temporarily created.
This is hackish. You will need to spend a lot of time to get it to work. You will need admin access to whatever server you want to run it on so you can install APC. You will also need to setup the HTML form to correspond to the js Upload class. A reference on how to do this can be found here http://www.ultramegatech.com/blog/2008/12/creating-upload-progress-bar-php/

Categories

Resources