Revert "Revert "Merge branch 'master' of https://github.com/discourse/discourse""

Revert “Revert “Merge branch ‘master’ of https://github.com/discourse/discourse””

This reverts commit 20780a1eeed56b321daf18ee6bbfe681a51d1bf4.

  • SECURITY: re-adds accidentally reverted commit: 03d26cd6: ensure embed_url contains valid http(s) uri
  • when the merge commit e62a85cf was reverted, git chose the 2660c2e2 parent to land on instead of the 03d26cd6 parent (which contains security fixes)
diff --git a/Gemfile b/Gemfile
index 6c72e48..a80f23d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -127,10 +127,6 @@ gem 'mini_racer'
 # TODO: determine why highline is being held back and upgrade to latest
 gem 'highline', '~> 1.7.0', require: false
 
-# TODO: Upgrading breaks Sidekiq Web
-# This is a bit of a hornets nest cause in an ideal world we much prefer
-# if Sidekiq reused session and CSRF mitigation with Discourse on the
-# _forum_session cookie instead of a rack.session cookie
 gem 'rack', '2.2.2'
 
 gem 'rack-protection' # security
@@ -252,3 +248,5 @@ end
 gem 'webpush', require: false
 gem 'colored2', require: false
 gem 'maxminddb'
+
+gem 'rails_failover', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 752d48c..db4b88d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -195,7 +195,7 @@ GEM
     mini_sql (0.2.5)
     mini_suffix (0.3.0)
       ffi (~> 1.9)
-    minitest (5.14.0)
+    minitest (5.14.1)
     mocha (1.11.2)
     mock_redis (0.23.0)
     msgpack (1.3.3)
@@ -262,7 +262,7 @@ GEM
     pry-rails (0.3.9)
       pry (>= 0.10.4)
     public_suffix (4.0.5)
-    puma (4.3.3)
+    puma (4.3.5)
       nio4r (~> 2.0)
     r2 (0.2.7)
     rack (2.2.2)
@@ -277,6 +277,8 @@ GEM
       nokogiri (>= 1.6)
     rails-html-sanitizer (1.3.0)
       loofah (~> 2.3)
+    rails_failover (0.2.0)
+      redis (~> 4)
     rails_multisite (2.1.2)
       activerecord (> 5.0, < 7)
       railties (> 5.0, < 7)
@@ -294,7 +296,7 @@ GEM
     rb-fsevent (0.10.4)
     rb-inotify (0.10.1)
       ffi (~> 1.0)
-    rbtrace (0.4.12)
+    rbtrace (0.4.13)
       ffi (>= 1.0.6)
       msgpack (>= 0.4.3)
       optimist (>= 3.0.0)
@@ -341,13 +343,16 @@ GEM
       json-schema (~> 2.2)
       railties (>= 3.1, < 7.0)
     rtlit (0.0.5)
-    rubocop (0.83.0)
+    rubocop (0.84.0)
       parallel (~> 1.10)
       parser (>= 2.7.0.1)
       rainbow (>= 2.2.2, < 4.0)
       rexml
+      rubocop-ast (>= 0.0.3)
       ruby-progressbar (~> 1.7)
       unicode-display_width (>= 1.4.0, < 2.0)
+    rubocop-ast (0.0.3)
+      parser (>= 2.7.0.1)
     rubocop-discourse (2.1.2)
       rubocop (>= 0.69.0)
       rubocop-rspec (>= 1.39.0)
@@ -509,6 +514,7 @@ DEPENDENCIES
   rack (= 2.2.2)
   rack-mini-profiler
   rack-protection
+  rails_failover
   rails_multisite
   railties (= 6.0.3)
   rake
diff --git a/app/assets/javascripts/admin/models/admin-user.js b/app/assets/javascripts/admin/models/admin-user.js
index 71b8078..9977fa8 100644
--- a/app/assets/javascripts/admin/models/admin-user.js
+++ b/app/assets/javascripts/admin/models/admin-user.js
@@ -77,12 +77,6 @@ const AdminUser = User.extend({
     });
   },
 
-  revokeApiKey() {
-    return ajax(`/admin/users/${this.id}/revoke_api_key`, {
-      type: "DELETE"
-    }).then(() => this.set("api_key", null));
-  },
-
   deleteAllPosts() {
     let deletedPosts = 0;
     const user = this;
diff --git a/app/assets/javascripts/admin/routes/admin-web-hooks-show.js b/app/assets/javascripts/admin/routes/admin-web-hooks-show.js
index 34aed77..f0860e7 100644
--- a/app/assets/javascripts/admin/routes/admin-web-hooks-show.js
+++ b/app/assets/javascripts/admin/routes/admin-web-hooks-show.js
@@ -1,5 +1,4 @@
 import { get } from "@ember/object";
-import { isEmpty } from "@ember/utils";
 import DiscourseRoute from "discourse/routes/discourse";
 
 export default DiscourseRoute.extend({
@@ -15,7 +14,7 @@ export default DiscourseRoute.extend({
   },
 
   setupController(controller, model) {
-    if (model.get("isNew") || isEmpty(model.get("web_hook_event_types"))) {
+    if (model.get("isNew")) {
       model.set("web_hook_event_types", controller.get("defaultEventTypes"));
     }
 
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 4445fd7..40f1d27 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -1,6 +1,6 @@
 //= require_tree ./discourse-common/addon
 //= require ./polyfills
-//= require_tree ./select-kit/app
+//= require_tree ./select-kit/addon
 //= require ./discourse/app/app
 //= require ./app-boot
 
diff --git a/app/assets/javascripts/discourse-loader.js b/app/assets/javascripts/discourse-loader.js
index d11217a..fc829ae 100644
--- a/app/assets/javascripts/discourse-loader.js
+++ b/app/assets/javascripts/discourse-loader.js
@@ -36,7 +36,6 @@ var define, requirejs;
         default: Ember.Object,
         get: Ember.get,
         getProperties: Ember.getProperties,
-        guidFor: Ember.guidFor,
         set: Ember.set,
         setProperties: Ember.setProperties,
         computed: Ember.computed,
diff --git a/app/assets/javascripts/discourse/app/controllers/preferences/interface.js b/app/assets/javascripts/discourse/app/controllers/preferences/interface.js
index 1ad85b7..2fcc578 100644
--- a/app/assets/javascripts/discourse/app/controllers/preferences/interface.js
+++ b/app/assets/javascripts/discourse/app/controllers/preferences/interface.js
@@ -2,13 +2,10 @@ import I18n from "I18n";
 import { inject } from "@ember/controller";
 import Controller from "@ember/controller";
 import { setDefaultHomepage } from "discourse/lib/utilities";
-import discourseComputed, { observes } from "discourse-common/utils/decorators";
-import {
-  listThemes,
-  previewTheme,
-  setLocalTheme
-} from "discourse/lib/theme-selector";
+import discourseComputed from "discourse-common/utils/decorators";
+import { listThemes, setLocalTheme } from "discourse/lib/theme-selector";
 import { popupAjaxError } from "discourse/lib/ajax-error";
+import pageReloader from "discourse/helpers/page-reloader";
 import {
   safariHacksDisabled,
   isiPad,
@@ -28,6 +25,9 @@ const TEXT_SIZES = ["smaller", "normal", "larger", "largest"];
 const TITLE_COUNT_MODES = ["notifications", "contextual"];
 
 export default Controller.extend({
+  currentThemeId: -1,
+  preferencesController: inject("preferences"),
+
   @discourseComputed("makeThemeDefault")
   saveAttrNames(makeDefault) {
     let attrs = [
@@ -51,8 +51,6 @@ export default Controller.extend({
     return attrs;
   },
 
-  preferencesController: inject("preferences"),
-
   @discourseComputed()
   isiPad() {
     // TODO: remove this preference checkbox when iOS adoption > 90%
@@ -105,10 +103,14 @@ export default Controller.extend({
     return themes && themes.length > 1;
   },
 
-  @observes("themeId")
-  themeIdChanged() {
-    const id = this.themeId;
-    previewTheme([id]);
+  @discourseComputed("themeId")
+  themeIdChanged(themeId) {
+    if (this.currentThemeId === -1) {
+      this.set("currentThemeId", themeId);
+      return false;
+    } else {
+      return this.currentThemeId !== themeId;
+    }
   },
 
   @discourseComputed("model.user_option.theme_ids", "themeId")
@@ -189,6 +191,10 @@ export default Controller.extend({
               this.disableSafariHacks.toString()
             );
           }
+
+          if (this.themeId !== this.currentThemeId) {
+            pageReloader.reload();
+          }
         })
         .catch(popupAjaxError);
     },
diff --git a/app/assets/javascripts/discourse/app/controllers/topic.js b/app/assets/javascripts/discourse/app/controllers/topic.js
index 2c2ebdc..ba7caf5 100644
--- a/app/assets/javascripts/discourse/app/controllers/topic.js
+++ b/app/assets/javascripts/discourse/app/controllers/topic.js
@@ -185,6 +185,13 @@ export default Controller.extend(bufferedProperty("model"), {
     );
   },
 
+  @discourseComputed("model.category")
+  minimumRequiredTags(category) {
+    return category && category.minimum_required_tags > 0
+      ? category.minimum_required_tags
+      : null;
+  },
+
   _forceRefreshPostStream() {
     this.appEvents.trigger("post-stream:refresh", { force: true });
   },
diff --git a/app/assets/javascripts/discourse/app/controllers/user.js b/app/assets/javascripts/discourse/app/controllers/user.js
index cc2db04..b466f08 100644
--- a/app/assets/javascripts/discourse/app/controllers/user.js
+++ b/app/assets/javascripts/discourse/app/controllers/user.js

[... diff too long, it was truncated ...]

GitHub sha: d9a02d13