From c89db1bc4c5674cd60292f98b43c56e9a785f1c8 Mon Sep 17 00:00:00 2001 From: Eugen Neuber <eugen.neuber@tugraz.at> Date: Wed, 20 May 2020 13:10:36 +0200 Subject: [PATCH] Deny files not matching required mime types See issue #2 --- packages/file-handling/README.md | 5 +++++ packages/file-handling/src/demo.js | 15 +++++++-------- packages/file-handling/src/fileupload.js | 23 +++++++++++++++++++---- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/packages/file-handling/README.md b/packages/file-handling/README.md index 9b30f26a..7b610c14 100644 --- a/packages/file-handling/README.md +++ b/packages/file-handling/README.md @@ -19,6 +19,11 @@ - `deferred` (optional): if set files will not be uploaded immediately but only queued - use method `uploadFile` or `uploadOneQueuedFile` to really upload the queued file - example `<vpu-fileupload deferred></vpu-fileupload>` +- `allowed-mime-types` (optional): if set accept only files matching mime types + - example `<vpu-fileupload allowed-mime-types='application/pdf'></vpu-fileupload>` ... PDFs only + - example `<vpu-fileupload allowed-mime-types='image/*'></vpu-fileupload>` ... images (of all sub types) only + - example `<vpu-fileupload allowed-mime-types='image/png,text/plain'></vpu-fileupload>` ... PNGs or TXTs only + - example `<vpu-fileupload allowed-mime-types='*/*'></vpu-fileupload>` ... all file types (default) ## Local development diff --git a/packages/file-handling/src/demo.js b/packages/file-handling/src/demo.js index cdbb663a..8089e76f 100644 --- a/packages/file-handling/src/demo.js +++ b/packages/file-handling/src/demo.js @@ -80,18 +80,17 @@ class FileUploadDemo extends ScopedElementsMixin(LitElement) { <div class="content"> <h2 class="subtitle">Send any File to Server</h2> <p>There is no restriction for a specific file type:</p> - <vpu-fileupload lang="de" url="${this.url}"></vpu-fileupload> + <vpu-fileupload lang="de" url="${this.url}" allowed-mime-types="*/*"></vpu-fileupload> <p>Only images are allowed here (JPG, PNG, GIF, TIF, ...):</p> - <vpu-fileupload lang="de" url="${this.url}" accept="image/*" + <vpu-fileupload lang="de" url="${this.url}" allowed-mime-types="image/*" text="Abgabe nur für Bilder "></vpu-fileupload> <p>This is for PDF only:</p> - <vpu-fileupload lang="de" url="${this.url}" accept="application/pdf" + <vpu-fileupload lang="de" url="${this.url}" allowed-mime-types="application/pdf" text="Einreichung als PDF" button-label="PDF auswählen"></vpu-fileupload> - </div> - <div class="content"> - <h2>Log of uploads</h2> - <ul id="log"></ul> - </div> + <p>Text and images (JPG, PNG, GIF, TIF, ...) :</p> + <vpu-fileupload lang="de" url="${this.url}" allowed-mime-types="text/plain,image/*" + text="Abgabe für Text und Bilder "></vpu-fileupload> + </div> </section> `; } diff --git a/packages/file-handling/src/fileupload.js b/packages/file-handling/src/fileupload.js index 88e825aa..de0aeb67 100644 --- a/packages/file-handling/src/fileupload.js +++ b/packages/file-handling/src/fileupload.js @@ -17,7 +17,7 @@ export class FileUpload extends ScopedElementsMixin(VPULitElement) { this.lang = 'de'; this.url = ''; this.dropArea = null; - this.accept = ''; + this.allowedMimeTypes = ''; this.text = ''; this.buttonLabel = ''; this.uploadInProgress = false; @@ -42,7 +42,7 @@ export class FileUpload extends ScopedElementsMixin(VPULitElement) { return { lang: { type: String }, url: { type: String }, - accept: { type: String }, + allowedMimeTypes: { type: String, attribute: 'allowed-mime-types' }, text: { type: String }, buttonLabel: { type: String, attribute: 'button-label'}, uploadInProgress: { type: Boolean, attribute: false}, @@ -150,9 +150,24 @@ export class FileUpload extends ScopedElementsMixin(VPULitElement) { let tempFilesToHandle = []; await commonUtils.asyncArrayForEach(files, async (file) => { if (file.size === 0) { - console.log('file ' + file.name + ' has size=0 and is denied!') + console.log('file \'' + file.name + '\' has size=0 and is denied!') return; } + if (this.allowedMimeTypes) { + // check if file is allowed + const [fileMainType, fileSubType] = file.type.split('/'); + const mimeTypes = this.allowedMimeTypes.split(','); + let deny = true; + mimeTypes.forEach((str) => { + const [mainType, subType] = str.split('/'); + deny = deny && ((mainType !== '*' && mainType !== fileMainType) || (subType !== '*' && subType !== fileSubType)); + }); + if (deny) { + console.log(`mime type ${file.type} of file '${file.name}' is not compatible with ${this.allowedMimeTypes}`); + return; + } + } + tempFilesToHandle.push(file); }); @@ -326,7 +341,7 @@ export class FileUpload extends ScopedElementsMixin(VPULitElement) { <div id="dropArea"> <div class="my-form" title="${this.uploadInProgress ? i18n.t('upload-disabled-title') : ''}"> <p>${this.text || i18n.t('intro')}</p> - <input ?disabled="${this.uploadInProgress}" type="file" id="fileElem" multiple accept="${ifDefined(this.accept)}" name='file'> + <input ?disabled="${this.uploadInProgress}" type="file" id="fileElem" multiple name='file'> <label class="button is-primary" for="fileElem"><vpu-icon style="display: ${this.uploadInProgress ? "inline-block" : "none"}" name="lock"></vpu-icon> ${this.buttonLabel || i18n.t('upload-label')}</label> <vpu-mini-spinner style="display: ${this.multipleUploadInProgress ? "inline-block" : "none"}"></vpu-mini-spinner> </div> -- GitLab