From 6723ba6014a2aa5b45414130cd278511b922d6a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Hanol?= <regis@hanol.fr>
Date: Mon, 1 Jul 2013 02:19:03 +0200
Subject: [PATCH] Add a list of  for file uploads

---
 .../discourse/components/utilities.js         | 29 ++++++++++++++-----
 .../templates/composer.js.handlebars          |  6 ++--
 .../discourse/views/composer_view.js          | 15 +++++-----
 .../stylesheets/application/compose.css.scss  |  4 +--
 app/models/site_setting.rb                    |  1 +
 app/models/upload.rb                          |  2 +-
 config/locales/client.cs.yml                  |  2 --
 config/locales/client.de.yml                  |  2 --
 config/locales/client.en.yml                  |  4 +--
 config/locales/client.fr.yml                  |  4 +--
 config/locales/client.it.yml                  |  3 +-
 config/locales/client.nb_NO.yml               |  3 +-
 config/locales/client.nl.yml                  |  3 +-
 config/locales/client.pseudo.yml              |  3 +-
 config/locales/client.ru.yml                  |  3 +-
 config/locales/client.sv.yml                  |  3 +-
 config/locales/client.zh_CN.yml               |  3 +-
 config/locales/client.zh_TW.yml               |  3 +-
 config/locales/server.en.yml                  |  1 +
 test/javascripts/components/utilities_test.js | 26 ++++++++++++-----
 .../fixtures/site_settings_fixtures.js        |  2 +-
 21 files changed, 69 insertions(+), 53 deletions(-)

diff --git a/app/assets/javascripts/discourse/components/utilities.js b/app/assets/javascripts/discourse/components/utilities.js
index 8da0b1cf9..80ebbb736 100644
--- a/app/assets/javascripts/discourse/components/utilities.js
+++ b/app/assets/javascripts/discourse/components/utilities.js
@@ -158,7 +158,6 @@ Discourse.Utilities = {
     }
   },
 
-
   /**
     Validate a list of files to be uploaded
 
@@ -169,18 +168,19 @@ Discourse.Utilities = {
     if (files) {
       // can only upload one file at a time
       if (files.length > 1) {
-        bootbox.alert(Em.String.i18n('post.errors.upload_too_many_images'));
+        bootbox.alert(Em.String.i18n('post.errors.too_many_uploads'));
         return false;
       } else if (files.length > 0) {
-        // check that the uploaded file is an image
-        // TODO: we should provide support for other types of file
-        if (files[0].type && files[0].type.indexOf('image/') !== 0) {
-          bootbox.alert(Em.String.i18n('post.errors.only_images_are_supported'));
+        var upload = files[0];
+        // check that the uploaded file is authorized
+        if (!Discourse.Utilities.isAuthorizedUpload(upload)) {
+          var extensions = Discourse.SiteSettings.authorized_extensions.replace(/\|/g, ", ");
+          bootbox.alert(Em.String.i18n('post.errors.upload_not_authorized', { authorized_extensions: extensions }));
           return false;
         }
         // check file size
-        if (files[0].size && files[0].size > 0) {
-          var fileSizeInKB = files[0].size / 1024;
+        if (upload.size && upload.size > 0) {
+          var fileSizeInKB = upload.size / 1024;
           if (fileSizeInKB > Discourse.SiteSettings.max_upload_size_kb) {
             bootbox.alert(Em.String.i18n('post.errors.upload_too_large', { max_size_kb: Discourse.SiteSettings.max_upload_size_kb }));
             return false;
@@ -192,6 +192,19 @@ Discourse.Utilities = {
     }
     // there has been an error
     return false;
+  },
+
+  /**
+    Check the extension of the file against the list of authorized extensions
+
+    @method isAuthorizedUpload
+    @param {File} files The file we want to upload
+  **/
+  isAuthorizedUpload: function(file) {
+    var extensions = Discourse.SiteSettings.authorized_extensions;
+    if (!extensions) return false;
+    var regexp = new RegExp("\\.(" + extensions.replace(/\./g, "") + ")$", "i");
+    return file && file.name ? file.name.match(regexp) : false;
   }
 
 };
diff --git a/app/assets/javascripts/discourse/templates/composer.js.handlebars b/app/assets/javascripts/discourse/templates/composer.js.handlebars
index 01556f05e..5449295de 100644
--- a/app/assets/javascripts/discourse/templates/composer.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/composer.js.handlebars
@@ -75,9 +75,9 @@
           {{#if currentUser}}
             <a href="#" {{action togglePreview}} class='toggle-preview'>{{{content.toggleText}}}</a>
             <div id='draft-status'></div>
-            {{#if view.loadingImage}}
-              <div id="image-uploading">
-                {{i18n image_selector.uploading_image}} {{view.uploadProgress}}% <a id="cancel-image-upload">{{i18n cancel}}</a>
+            {{#if view.isUploading}}
+              <div id="file-uploading">
+                {{i18n image_selector.uploading_image}} {{view.uploadProgress}}% <a id="cancel-file-upload">{{i18n cancel}}</a>
               </div>
             {{/if}}
           {{/if}}
diff --git a/app/assets/javascripts/discourse/views/composer_view.js b/app/assets/javascripts/discourse/views/composer_view.js
index c531dfa85..ab2ccec26 100644
--- a/app/assets/javascripts/discourse/views/composer_view.js
+++ b/app/assets/javascripts/discourse/views/composer_view.js
@@ -249,20 +249,20 @@ Discourse.ComposerView = Discourse.View.extend({
     $uploadTarget.on('fileuploadsubmit', function (e, data) {
       var result = Discourse.Utilities.validateFilesForUpload(data.files);
       // reset upload status when everything is ok
-      if (result) composerView.setProperties({ uploadProgress: 0, loadingImage: true });
+      if (result) composerView.setProperties({ uploadProgress: 0, isUploading: true });
       return result;
     });
 
     // send - this event is triggered when the upload request is about to start
     $uploadTarget.on('fileuploadsend', function (e, data) {
-      // hide the "image selector" modal
+      // hide the "file selector" modal
       composerView.get('controller').send('closeModal');
       // cf. https://github.com/blueimp/jQuery-File-Upload/wiki/API#how-to-cancel-an-upload
       var jqXHR = data.xhr();
       // need to wait for the link to show up in the DOM
       Em.run.schedule('afterRender', function() {
         // bind on the click event on the cancel link
-        $('#cancel-image-upload').on('click', function() {
+        $('#cancel-file-upload').on('click', function() {
           // cancel the upload
           // NOTE: this will trigger a 'fileuploadfail' event with status = 0
           if (jqXHR) jqXHR.abort();
@@ -283,13 +283,13 @@ Discourse.ComposerView = Discourse.View.extend({
       var upload = data.result;
       var html = "<img src=\"" + upload.url + "\" width=\"" + upload.width + "\" height=\"" + upload.height + "\">";
       composerView.addMarkdown(html);
-      composerView.set('loadingImage', false);
+      composerView.set('isUploading', false);
     });
 
     // fail
     $uploadTarget.on('fileuploadfail', function (e, data) {
       // hide upload status
-      composerView.set('loadingImage', false);
+      composerView.set('isUploading', false);
       // deal with meaningful errors first
       if (data.jqXHR) {
         switch (data.jqXHR.status) {
@@ -299,9 +299,10 @@ Discourse.ComposerView = Discourse.View.extend({
           case 413:
             bootbox.alert(Em.String.i18n('post.errors.upload_too_large', {max_size_kb: Discourse.SiteSettings.max_upload_size_kb}));
             return;
-          // 415 == media type not recognized (ie. not an image)
+          // 415 == media type not authorized
           case 415:
-            bootbox.alert(Em.String.i18n('post.errors.only_images_are_supported'));
+            var extensions = Discourse.SiteSettings.authorized_extensions.replace(/\|/g, ", ");
+            bootbox.alert(Em.String.i18n('post.errors.upload_not_authorized', { authorized_extensions: extensions }));
             return;
           // 422 == there has been an error on the server (mostly due to FastImage)
           case 422:
diff --git a/app/assets/stylesheets/application/compose.css.scss b/app/assets/stylesheets/application/compose.css.scss
index f837593a8..27cbad424 100644
--- a/app/assets/stylesheets/application/compose.css.scss
+++ b/app/assets/stylesheets/application/compose.css.scss
@@ -104,7 +104,7 @@
 }
 
 #reply-control {
-  .toggle-preview, #draft-status, #image-uploading {
+  .toggle-preview, #draft-status, #file-uploading {
     position: absolute;
     bottom: -31px;
     margin-top: 0px;
@@ -113,7 +113,7 @@
     right: 5px;
     text-decoration: underline;
   }
-  #image-uploading {
+  #file-uploading {
     left: 51%;
     font-size: 12px;
     color: darken($gray, 40);
diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index b814c357e..ac303ca7b 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -51,6 +51,7 @@ class SiteSetting < ActiveRecord::Base
   setting(:title_prettify, true)
 
   client_setting(:max_upload_size_kb, 1024)
+  client_setting(:authorized_extensions, '.jpg|.jpeg|.png|.gif')
 
   # settings only available server side
   setting(:auto_track_topics_after, 240000)
diff --git a/app/models/upload.rb b/app/models/upload.rb
index 20edfa37e..81731a89c 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -69,7 +69,7 @@ class Upload < ActiveRecord::Base
       # make sure we're at the beginning of the file (FastImage is moving the pointer)
       file.rewind
       # store the file and update its url
-    upload.url = Upload.store_file(file, sha1, image_info, upload.id)
+      upload.url = Upload.store_file(file, sha1, image_info, upload.id)
       # save the url
       upload.save
     end
diff --git a/config/locales/client.cs.yml b/config/locales/client.cs.yml
index 6ce7c6d50..936582da6 100644
--- a/config/locales/client.cs.yml
+++ b/config/locales/client.cs.yml
@@ -773,8 +773,6 @@ cs:
         edit: "Bohužel nastala chyba při editaci příspěvku. Prosím zkuste to znovu."
         upload: "Bohužel nastala chyba při nahrávání příspěvku. Prosím zkuste to znovu."
         upload_too_large: "Soubor, který se snažíte nahrát je bohužel příliš velký (maximální velikost je {{max_size_kb}}kb). Prosím zmenšete ho zkuste to znovu."
-        upload_too_many_images: "Bohužel, najednou smíte nahrát pouze jeden obrázek."
-        only_images_are_supported: "Bohužel, smíte nahrávat pouze obrázky."
 
       abandon: "Opravdu chcete opustit váš příspěvek?"
 
diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml
index d3b88c9fd..2ac51c2af 100644
--- a/config/locales/client.de.yml
+++ b/config/locales/client.de.yml
@@ -744,8 +744,6 @@ de:
         edit: "Entschuldige, es gab einen Fehler beim Bearbeiten des Beitrags. Bitte versuche es noch einmal."
         upload: "Entschuldige, es gab einen Fehler beim Hochladen der Datei. Bitte versuche es noch einmal."
         upload_too_large: "Entschuldige, die Datei die du hochladen wolltest ist zu groß (Maximalgröße {{max_size_kb}}kb), bitte reduziere die Dateigröße und versuche es nochmal."
-        upload_too_many_images: "Entschuldige, du kannst nur ein Bild gleichzeitig hochladen."
-        only_images_are_supported: "Entschuldige, du kannst nur Bilder hochladen."
 
       abandon: "Willst Du diesen Beitrag wirklich verwerfen?"
 
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 6a4898438..f2e4326cb 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -744,8 +744,8 @@ en:
         edit: "Sorry, there was an error editing your post. Please try again."
         upload: "Sorry, there was an error uploading that file. Please try again."
         upload_too_large: "Sorry, the file you are trying to upload is too big (maximum size is {{max_size_kb}}kb), please resize it and try again."
-        upload_too_many_images: "Sorry, you can only upload one image at a time."
-        only_images_are_supported: "Sorry, you can only upload images."
+        too_many_uploads: "Sorry, you can only upload one file at a time."
+        upload_not_authorized: "Sorry, the file you are trying to upload is not authorized (authorized extension: {{authorized_extensions}})."
 
       abandon: "Are you sure you want to abandon your post?"
 
diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml
index 73a0df775..ccc0e2189 100644
--- a/config/locales/client.fr.yml
+++ b/config/locales/client.fr.yml
@@ -727,8 +727,8 @@ fr:
         edit: "Désolé, il y a eu une erreur lors de l'édition de votre message. Merci de réessayer."
         upload: "Désolé, il y a eu une erreur lors de l'envoi du fichier. Merci de réessayer."
         upload_too_large: "Désolé, le fichier que vous êtes en train d'envoyer est trop grand (maximum {{max_size_kb}}Kb). Merci de le redimensionner et de réessayer."
-        upload_too_many_images: "Désolé, vous ne pouvez envoyer qu'une seule image à la fois."
-        only_images_are_supported: "Désolé, seulement l'envoi d'image est supporté."
+        too_many_uploads: "Désolé, vous ne pouvez envoyer qu'un seul fichier à la fois."
+        upload_not_authorized: "Désole, le fichier que vous êtes en train d'uploader n'est pas autorisé (extensions autorisées : {{authorized_extensions}})."
 
       abandon: "Voulez-vous vraiment abandonner ce message ?"
 
diff --git a/config/locales/client.it.yml b/config/locales/client.it.yml
index b8b61080e..4db228d76 100644
--- a/config/locales/client.it.yml
+++ b/config/locales/client.it.yml
@@ -652,8 +652,7 @@ it:
         edit: "Spiacenti, si è verificato un errore durante la modifica del tuo post. Per favore, prova di nuovo."
         upload: "Spiacenti, si è verificato un errore durante il caricamento del file. Per favore, prova di nuovo."
         upload_too_large: "Spiacenti, il file che stai cercando di caricare è troppo grande (la dimensione massima è {{max_size_kb}}kb), per favore ridimensionalo e prova di nuovo."
-        upload_too_many_images: "Spiacenti, puoi caricare un'immagine per volta."
-        only_images_are_supported: "Spiacenti, puoi caricare solo immagini."
+        too_many_uploads: "Spiacenti, puoi caricare un'immagine per volta."
 
       abandon: "Sei sicuro di voler abbandonare il tuo post?"
 
diff --git a/config/locales/client.nb_NO.yml b/config/locales/client.nb_NO.yml
index dd02a8c2f..cb6e8caa7 100644
--- a/config/locales/client.nb_NO.yml
+++ b/config/locales/client.nb_NO.yml
@@ -672,8 +672,7 @@ nb_NO:
         edit: "Sorry, there was an error editing your post. Please try again."
         upload: "Sorry, there was an error uploading that file. Please try again."
         upload_too_large: "Sorry, the file you are trying to upload is too big (maximum size is {{max_size_kb}}kb), please resize it and try again."
-        upload_too_many_images: "Sorry, you can only upload one image at a time."
-        only_images_are_supported: "Sorry, you can only upload images."
+        too_many_uploads: "Sorry, you can only upload one image at a time."
 
       abandon: "Are you sure you want to abandon your post?"
 
diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml
index 7ff6149bb..792281395 100644
--- a/config/locales/client.nl.yml
+++ b/config/locales/client.nl.yml
@@ -748,8 +748,7 @@ nl:
         edit: "Sorry, er is iets misgegaan bij het bewerken van je bericht. Probeer het nog eens."
         upload: "Sorry, er is iets misgegaan bij het uploaden van je bestand. Probeer het nog eens."
         upload_too_large: "Sorry, het bestand dat je wil uploaden is te groot (maximum grootte is {{max_size_kb}}kb), verklein het bestand en probeer het opnieuw."
-        upload_too_many_images: "Sorry, je kan maar één afbeelding tegelijk uploaden."
-        only_images_are_supported: "Sorry, je kan alleen afbeeldingen uploaden."
+        too_many_uploads: "Sorry, je kan maar één afbeelding tegelijk uploaden."
 
       abandon: Weet je zeker dat je het schrijven van dit bericht wil afbreken?
 
diff --git a/config/locales/client.pseudo.yml b/config/locales/client.pseudo.yml
index 25ecb826c..4324019f0 100644
--- a/config/locales/client.pseudo.yml
+++ b/config/locales/client.pseudo.yml
@@ -633,9 +633,8 @@ pseudo:
           ]]'
         upload_too_large: '[[ Šóřřý, ťĥé ƒíłé ýóů ářé ťřýíɳǧ ťó ůƿłóáď íš ťóó ƀíǧ
           (ɱáхíɱůɱ šížé íš {{max_size_kb}}ǩƀ), ƿłéášé řéšížé íť áɳď ťřý áǧáíɳ. ]]'
-        upload_too_many_images: '[[ Šóřřý, ýóů čáɳ óɳłý ůƿłóáď óɳé íɱáǧé áť á ťíɱé.
+        too_many_uploads: '[[ Šóřřý, ýóů čáɳ óɳłý ůƿłóáď óɳé íɱáǧé áť á ťíɱé.
           ]]'
-        only_images_are_supported: '[[ Šóřřý, ýóů čáɳ óɳłý ůƿłóáď íɱáǧéš. ]]'
       abandon: '[[ Ářé ýóů šůřé ýóů ŵáɳť ťó áƀáɳďóɳ ýóůř ƿóšť? ]]'
       archetypes:
         save: '[[ Šáνé Óƿťíóɳš ]]'
diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml
index d125d7171..7c0319bb0 100644
--- a/config/locales/client.ru.yml
+++ b/config/locales/client.ru.yml
@@ -729,8 +729,7 @@ ru:
         edit: К сожалению, не удалось изменить сообщение. Попробуйте еще раз.
         upload: К сожалению, не удалось загрузить файл. Попробуйте еще раз.
         upload_too_large: 'Превышен допустимый размер ({{max_size_kb}}kb) файла. Уменьшите размер изображения и повторите попытку.'
-        upload_too_many_images: К сожалению, за один раз можно загрузить только одно изображение.
-        only_images_are_supported: К сожалению, можно загружать только изображения.
+        too_many_uploads: К сожалению, за один раз можно загрузить только одно изображение.
       abandon: Удалить сохраненный черновик?
       archetypes:
         save: Параметры сохранения
diff --git a/config/locales/client.sv.yml b/config/locales/client.sv.yml
index 159bb0bfc..2e5cccda0 100644
--- a/config/locales/client.sv.yml
+++ b/config/locales/client.sv.yml
@@ -570,8 +570,7 @@ sv:
         edit: "Tyvärr, det uppstod ett fel under ändringen av ditt inlägg. Var god försök igen."
         upload: "Tyvärr, det uppstod ett fel under uppladdandet av den filen. Vad god försök igen."
         upload_too_large: "Tyvärr, filen som du försöker ladda upp är för stor (maxstorlek är {{max_size_kb}}kb), var god ändra storlek och försök igen."
-        upload_too_many_images: "Tyvärr, du kan bara ladda upp en bild i taget."
-        only_images_are_supported: "Tyvärr, du kan bara ladda upp bilder."
+        too_many_uploads: "Tyvärr, du kan bara ladda upp en bild i taget."
 
       abandon: "Är du säker på att du vill överge ditt inlägg?"
 
diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml
index 154d0708b..d26ce90bd 100644
--- a/config/locales/client.zh_CN.yml
+++ b/config/locales/client.zh_CN.yml
@@ -711,8 +711,7 @@ zh_CN:
         edit: "抱歉,在编辑你的帖子时发生了错误。请重试。"
         upload: "抱歉,在上传文件时发生了错误。请重试。"
         upload_too_large: "抱歉,你上传的文件太大了(最大不能超过 {{max_size_kb}}kb),请调整文件大小后重新上传。"
-        upload_too_many_images: "抱歉, 你只能一次上传一张图片。"
-        only_images_are_supported: "抱歉,你只能上传图片。"
+        too_many_uploads: "抱歉, 你只能一次上传一张图片。"
 
       abandon: "你确定要丢弃你的帖子吗?"
 
diff --git a/config/locales/client.zh_TW.yml b/config/locales/client.zh_TW.yml
index 0a3534b33..4fa756907 100644
--- a/config/locales/client.zh_TW.yml
+++ b/config/locales/client.zh_TW.yml
@@ -652,8 +652,7 @@ zh_TW:
         edit: "抱歉,在編輯你的帖子時發生了錯誤。請重試。"
         upload: "抱歉,在上傳文件時發生了錯誤。請重試。"
         upload_too_large: "抱歉,你上傳的文件太大了(最大不能超過 {{max_size_kb}}kb),請調整文件大小後重新上傳。"
-        upload_too_many_images: "抱歉, 你只能一次上傳一張圖片。"
-        only_images_are_supported: "抱歉,你只能上傳圖片。"
+        too_many_uploads: "抱歉, 你只能一次上傳一張圖片。"
 
       abandon: "你確定要丟棄你的帖子嗎?"
 
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 954053deb..1fa3fa204 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -610,6 +610,7 @@ en:
 
     category_colors: "A pipe (|) separated list of hexadecimal color values allowed for categories"
     max_upload_size_kb: "The maximum size of files we allow users to upload in kB - be sure to configure the limit in nginx (client_max_body_size) / apache or proxy as well."
+    authorized_extensions: "A pipe (|) separated list of file extensions allowed for upload"
     max_similar_results: "How many similar topics to show a user while they are composing a new topic"
 
     title_prettify: "Prevent common title typos and errors, including all caps, lowercase first character, multiple ! and ?, extra . at end, etc."
diff --git a/test/javascripts/components/utilities_test.js b/test/javascripts/components/utilities_test.js
index 2f1d8ef10..35078481e 100644
--- a/test/javascripts/components/utilities_test.js
+++ b/test/javascripts/components/utilities_test.js
@@ -20,31 +20,43 @@ test("uploading one file", function() {
   this.stub(bootbox, "alert");
 
   ok(!validUpload([1, 2]));
-  ok(bootbox.alert.calledOnce);
+  ok(bootbox.alert.calledWith(Em.String.i18n('post.errors.too_many_uploads')));
 });
 
-test("ensures an image upload", function() {
-  var html = { type: "text/html" };
+test("ensures an authorized upload", function() {
+  var html = { name: "unauthorized.html" };
+  var extensions = Discourse.SiteSettings.authorized_extensions.replace(/\|/g, ", ");
   this.stub(bootbox, "alert");
 
   ok(!validUpload([html]));
-  ok(bootbox.alert.calledOnce);
+  ok(bootbox.alert.calledWith(Em.String.i18n('post.errors.upload_not_authorized', { authorized_extensions: extensions })));
 });
 
 test("prevents files that are too big from being uploaded", function() {
-  var image = { type: "image/png", size: 10 * 1024 };
+  var image = { name: "image.png", size: 10 * 1024 };
   Discourse.SiteSettings.max_upload_size_kb = 5;
   this.stub(bootbox, "alert");
 
   ok(!validUpload([image]));
-  ok(bootbox.alert.calledOnce);
+  ok(bootbox.alert.calledWith(Em.String.i18n('post.errors.upload_too_large', { max_size_kb: 5 })));
 });
 
 test("allows valid uploads to go through", function() {
-  var image = { type: "image/png", size: 10 * 1024 };
+  var image = { name: "image.png", size: 10 * 1024 };
   Discourse.SiteSettings.max_upload_size_kb = 15;
   this.stub(bootbox, "alert");
 
   ok(validUpload([image]));
   ok(!bootbox.alert.calledOnce);
 });
+
+var isAuthorized = function (filename) {
+  return utils.isAuthorizedUpload({ name: filename });
+};
+
+test("isAuthorizedUpload", function() {
+  ok(isAuthorized("image.png"));
+  ok(isAuthorized("image.jpg"));
+  ok(!isAuthorized("image.txt"));
+  ok(!isAuthorized(""));
+});
diff --git a/test/javascripts/fixtures/site_settings_fixtures.js b/test/javascripts/fixtures/site_settings_fixtures.js
index e2f7486e1..64df70b37 100644
--- a/test/javascripts/fixtures/site_settings_fixtures.js
+++ b/test/javascripts/fixtures/site_settings_fixtures.js
@@ -1,2 +1,2 @@
 /*jshint maxlen:10000000 */
-Discourse.SiteSettings = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","traditional_markdown_linebreaks":false,"top_menu":"latest|new|unread|read|favorited|categories","post_menu":"like|edit|flag|delete|share|bookmark|reply","share_links":"twitter|facebook|google+|email","track_external_right_clicks":false,"must_approve_users":false,"ga_tracking_code":"UA-33736483-2","ga_domain_name":"","enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"min_post_length":20,"max_post_length":16000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_search_term_length":3,"flush_timings_secs":5,"suppress_reply_directly_below":true,"email_domains_blacklist":"mailinator.com","email_domains_whitelist":null,"version_checks":true,"min_title_similar_length":10,"min_body_similar_length":15,"category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","max_upload_size_kb":1024,"category_featured_topics":6,"favicon_url":"/assets/favicon.ico","dynamic_favicon":false,"uncategorized_name":"uncategorized","uncategorized_color":"AB9364","uncategorized_text_color":"FFFFFF","invite_only":false,"login_required":false,"enable_local_logins":true,"enable_local_account_create":true,"enable_google_logins":true,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_cas_logins":false,"enable_github_logins":true,"enable_persona_logins":true,"educate_until_posts":2,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000,"min_private_message_post_length":5,"faq_url":"","tos_url":"","privacy_policy_url":""};
+Discourse.SiteSettings = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","traditional_markdown_linebreaks":false,"top_menu":"latest|new|unread|read|favorited|categories","post_menu":"like|edit|flag|delete|share|bookmark|reply","share_links":"twitter|facebook|google+|email","track_external_right_clicks":false,"must_approve_users":false,"ga_tracking_code":"UA-33736483-2","ga_domain_name":"","enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"min_post_length":20,"max_post_length":16000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_search_term_length":3,"flush_timings_secs":5,"suppress_reply_directly_below":true,"email_domains_blacklist":"mailinator.com","email_domains_whitelist":null,"version_checks":true,"min_title_similar_length":10,"min_body_similar_length":15,"category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","max_upload_size_kb":1024,"category_featured_topics":6,"favicon_url":"/assets/favicon.ico","dynamic_favicon":false,"uncategorized_name":"uncategorized","uncategorized_color":"AB9364","uncategorized_text_color":"FFFFFF","invite_only":false,"login_required":false,"enable_local_logins":true,"enable_local_account_create":true,"enable_google_logins":true,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_cas_logins":false,"enable_github_logins":true,"enable_persona_logins":true,"educate_until_posts":2,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000,"min_private_message_post_length":5,"faq_url":"","tos_url":"","privacy_policy_url":"","authorized_extensions":".jpg|.jpeg|.png|.gif"};