From 1c38b4abf1fab8d67aaaa4b9f2810add64b709c4 Mon Sep 17 00:00:00 2001 From: Andrei Prigorshnev Date: Thu, 1 Jul 2021 17:13:20 +0400 Subject: [PATCH] FEATURE: pass supported file extensions to the system file picker (#13583) --- .../app/components/composer-editor.js | 17 +++++++++ .../javascripts/discourse/app/lib/uploads.js | 13 +++++-- .../templates/components/composer-editor.hbs | 8 +++- .../acceptance/composer-attachment-test.js | 38 +++++++++++++++++++ .../discourse/tests/unit/lib/uploads-test.js | 5 ++- 5 files changed, 75 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js index 7ce199ce3ad..ae3addd81a9 100644 --- a/app/assets/javascripts/discourse/app/components/composer-editor.js +++ b/app/assets/javascripts/discourse/app/components/composer-editor.js @@ -1,4 +1,6 @@ import { + authorizedExtensions, + authorizesAllExtensions, authorizesOneOrMoreImageExtensions, displayErrorForUpload, getUploadMarkdown, @@ -200,6 +202,21 @@ export default Component.extend({ }); }, + @discourseComputed() + acceptsAllFormats() { + return authorizesAllExtensions(this.currentUser.staff, this.siteSettings); + }, + + @discourseComputed() + acceptedFormats() { + const extensions = authorizedExtensions( + this.currentUser.staff, + this.siteSettings + ); + + return extensions.map((ext) => `.${ext}`).join(); + }, + @on("didInsertElement") _composerEditorInit() { const $input = $(this.element.querySelector(".d-editor-input")); diff --git a/app/assets/javascripts/discourse/app/lib/uploads.js b/app/assets/javascripts/discourse/app/lib/uploads.js index 947035431e1..99d112742ed 100644 --- a/app/assets/javascripts/discourse/app/lib/uploads.js +++ b/app/assets/javascripts/discourse/app/lib/uploads.js @@ -97,7 +97,10 @@ function validateUploadedFile(file, opts) { ) { bootbox.alert( I18n.t("post.errors.upload_not_authorized", { - authorized_extensions: authorizedExtensions(staff, opts.siteSettings), + authorized_extensions: authorizedExtensions( + staff, + opts.siteSettings + ).join(", "), }) ); return false; @@ -177,7 +180,7 @@ export function authorizedExtensions(staff, siteSettings) { const exts = staff ? [...extensions(siteSettings), ...staffExtensions(siteSettings)] : extensions(siteSettings); - return exts.filter((ext) => ext.length > 0).join(", "); + return exts.filter((ext) => ext.length > 0); } function authorizedImagesExtensions(staff, siteSettings) { @@ -230,14 +233,16 @@ function uploadTypeFromFileName(fileName) { export function allowsImages(staff, siteSettings) { return ( authorizesAllExtensions(staff, siteSettings) || - IMAGES_EXTENSIONS_REGEX.test(authorizedExtensions(staff, siteSettings)) + IMAGES_EXTENSIONS_REGEX.test( + authorizedExtensions(staff, siteSettings).join() + ) ); } export function allowsAttachments(staff, siteSettings) { return ( authorizesAllExtensions(staff, siteSettings) || - authorizedExtensions(staff, siteSettings).split(", ").length > + authorizedExtensions(staff, siteSettings).length > imagesExtensions(staff, siteSettings).length ); } diff --git a/app/assets/javascripts/discourse/app/templates/components/composer-editor.hbs b/app/assets/javascripts/discourse/app/templates/components/composer-editor.hbs index 73757105793..1d2aeb755f0 100644 --- a/app/assets/javascripts/discourse/app/templates/components/composer-editor.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/composer-editor.hbs @@ -19,4 +19,10 @@ disabled=disableTextarea outletArgs=(hash composer=composer editorType="composer")}} - +{{#if allowUpload}} + {{#if acceptsAllFormats}} + + {{else}} + + {{/if}} +{{/if}} diff --git a/app/assets/javascripts/discourse/tests/acceptance/composer-attachment-test.js b/app/assets/javascripts/discourse/tests/acceptance/composer-attachment-test.js index 1413cd5c16d..4bd4eec0b87 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/composer-attachment-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/composer-attachment-test.js @@ -1,5 +1,6 @@ import { acceptance, + exists, query, queryAll, } from "discourse/tests/helpers/qunit-helpers"; @@ -253,3 +254,40 @@ acceptance("Composer Attachment - Upload Placeholder", function (needs) { }; } }); + +acceptance("Composer Attachment - File input", function (needs) { + needs.user(); + + test("shouldn't add to DOM the hidden file input if uploads aren't allowed", async function (assert) { + this.siteSettings.authorized_extensions = ""; + await visit("/"); + await click("#create-topic"); + + assert.notOk(exists("input#file-uploader")); + }); + + test("should fill the accept attribute with allowed file extensions", async function (assert) { + this.siteSettings.authorized_extensions = "jpg|jpeg|png"; + await visit("/"); + await click("#create-topic"); + + assert.ok(exists("input#file-uploader"), "An input is rendered"); + assert.equal( + query("input#file-uploader").accept, + ".jpg,.jpeg,.png", + "Accepted values are correct" + ); + }); + + test("the hidden file input shouldn't have the accept attribute if any file extension is allowed", async function (assert) { + this.siteSettings.authorized_extensions = "jpg|jpeg|png|*"; + await visit("/"); + await click("#create-topic"); + + assert.ok(exists("input#file-uploader"), "An input is rendered"); + assert.notOk( + query("input#file-uploader").hasAttribute("accept"), + "The input doesn't contain the accept attribute" + ); + }); +}); diff --git a/app/assets/javascripts/discourse/tests/unit/lib/uploads-test.js b/app/assets/javascripts/discourse/tests/unit/lib/uploads-test.js index 02be685e6b5..8e316cfb673 100644 --- a/app/assets/javascripts/discourse/tests/unit/lib/uploads-test.js +++ b/app/assets/javascripts/discourse/tests/unit/lib/uploads-test.js @@ -110,7 +110,10 @@ discourseModule("Unit | Utility | uploads", function () { assert.ok( bootbox.alert.calledWith( I18n.t("post.errors.upload_not_authorized", { - authorized_extensions: authorizedExtensions(false, this.siteSettings), + authorized_extensions: authorizedExtensions( + false, + this.siteSettings + ).join(", "), }) ) );