input file does not recognize the type 'application / x-iwork-keynote-sffkey' in Angular 5

0

Hello !, I have a component for input file to load files .cer and .key .

The problem I have is that I do not recognize the extension application / x-iwork-keynote-sffkey and the tipo of the document returns it as a string vacío .

The code is as follows:

onFileChange(event, idDocument) {
    const file = event.target.files[0];

    if (!file) {
      return;
    }

    if (this.validFileType === 'cer' && file.type !== 'application/x-x509-ca-cert') {
      swal('Formato de archivo inválido', 'Sólo puedes subir archivos .cert', 'error');
      return;
    } else if (this.validFileType === 'key' && file.type !== 'application/x-iwork-keynote-sffkey') {
      swal('Formato de archivo inválido', 'Sólo puedes subir archivos .key', 'error');
      return;
    }

    if (file.size > 15000000) {
      swal('Tamaño no permitido', 'Sólo puedes subir archivos con un tamaño máximo de 15MB', 'error');
      return;
    }

    this.filename = file.name;
  }
<div class="form-group mt-3 mb-0 display-inline-block">
  <input type="file" name="{{ name }}" id="{{ name }}" class="inputfile form-control-file display-hidden" (change)="onFileChange($event, name)" accept=".{{ validFileType }}" />
  <a class="{{ style }}" (click)="openFileBrowser($event, name)">
    <span class="text-bold-300">{{ inputMessage }}</span>
  </a>
  {{ filename }}
</div>

However, with the tipo file .cer , it does return the type of extension:

    
asked by Elizabeth Allen 13.08.2018 в 23:34
source

1 answer

0

In my case, using Chrome Beta 68 in Ubuntu 18.04, it does recognize any file with extension .key as application/x-iwork-keynote-sffkey .

That tells you two things

  • The problem depends on your operating system and browser. And if you manage to fix it, it may not work for your end users.
  • If it was enough for me to change the extension of any file for the browser to diagnose that extension, it is because the browser does not validate what you put in the input. Just match the extension with an internal listing.
  • In other words: it would be enough to let it pass if the file has an .key extension.

    Validate the actual mime-type of a file before uploading it

    If you really want to validate the mimetype, you can also, using an object FileReader . You feed the FileReader with the content of the input, you read it as an ArrayBuffer, and once this is done, you detect its "magic numbers", which are the first 4 bytes in hexadecimal. Try the following example:

    document.getElementById("archivo").addEventListener("change", function (event) {
    	var files = document.getElementById("archivo").files;
    	for (var i = 0; i < files.length; i++) {
    		console.log("Filename: " + files[i].name);
    		console.log("Type: " + files[i].type);
    		console.log("Size: " + files[i].size + " bytes");
    	}
    
    	var fileReader = new FileReader();
    	fileReader.onloadend = function (e) {
    		var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
    		var header = [];
    		arr.forEach(function (chunk) {
    			chunk = chunk.toString(16).padStart(2, '0').toUpperCase();
    			header.push(chunk);
    		});
    		console.log('magic numbers', header.join(' '));
    
    
    	};
    	fileReader.readAsArrayBuffer(files[0]);
    
    }, false);
    <input type="file" id="archivo">

    There are databases ( even wikipedia ) where you can find out what each combination of magic numbers means. For example, if you upload a PDF, the magic numbers will be 25 50 44 46 In a JPG, they will be FF D8 FF E0 .

    But here comes the most fucked up:

  • It is not always enough with 4 bytes to diagnose a file
  • A large variety of files that the browser recognizes as distinct have magic numbers that match the signature of a zip file. All ODS, XLSX, DOCX, KMZ and many others are actually zipped files.
  • Do the test by uploading a file .key valid in my example, look at their magic numbers, look for them in google and if they do not fit with a zip, lottery.

        
    answered by 14.08.2018 / 01:35
    source