diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3d9aa0a1..b1ad9e5fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,18 @@ Changelog
All notable changes to this project will be documented in this file.
+## [4.0.2] - 2022-11-15
+### Fixed
+
+- Fix wrong color on mentions hidden behind content warning in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20724))
+- Fix filters from other users being used in the streaming service ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20719))
+- Fix `unsafe-eval` being used when `wasm-unsafe-eval` is enough in Content Security Policy ([Gargron](https://github.com/mastodon/mastodon/pull/20729), [prplecake](https://github.com/mastodon/mastodon/pull/20606))
+
+## [4.0.1] - 2022-11-14
+### Fixed
+
+- Fix nodes order being sometimes mangled when rewriting emoji ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20677))
+
## [4.0.0] - 2022-11-14
Some of the features in this release have been funded through the [NGI0 Discovery](https://nlnet.nl/discovery) Fund, a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 825322.
diff --git a/Gemfile.lock b/Gemfile.lock
index d7ea91e2e..10f3b297f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -412,7 +412,7 @@ GEM
net-ssh (>= 2.6.5, < 8.0.0)
net-ssh (7.0.1)
nio4r (2.5.8)
- nokogiri (1.13.8)
+ nokogiri (1.13.9)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
nsa (0.2.8)
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js
index d26d18cae..9d1367536 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.js
@@ -255,7 +255,7 @@ class StatusContent extends React.PureComponent {
let mentionsPlaceholder = '';
const mentionLinks = status.get('mentions').map(item => (
-
+
@{item.get('username')}
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);
diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js
index 33bebef63..52a8458fb 100644
--- a/app/javascript/mastodon/features/emoji/emoji.js
+++ b/app/javascript/mastodon/features/emoji/emoji.js
@@ -73,8 +73,6 @@ const emojifyTextNode = (node, customEmojis) => {
}
node.textContent = str.slice(0, i);
str = str.slice(rend);
- node = document.createTextNode(str);
- parentElement.append(node);
}
fragment.append(document.createTextNode(str));
diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb
index be4ef50fc..6b62e6f33 100644
--- a/config/initializers/content_security_policy.rb
+++ b/config/initializers/content_security_policy.rb
@@ -36,7 +36,7 @@ Rails.application.config.content_security_policy do |p|
p.worker_src :self, :blob, assets_host
else
p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url
- p.script_src :self, assets_host, :unsafe_eval
+ p.script_src :self, assets_host, "'wasm-unsafe-eval'"
p.child_src :self, :blob, assets_host
p.worker_src :self, :blob, assets_host
end
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index 01797fb2f..1be61b92b 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -13,7 +13,7 @@ module Mastodon
end
def patch
- 0
+ 2
end
def flags
diff --git a/streaming/index.js b/streaming/index.js
index 8d60110f2..b9ddfd1ad 100644
--- a/streaming/index.js
+++ b/streaming/index.js
@@ -688,7 +688,7 @@ const startWorker = async (workerId) => {
}
if (!unpackedPayload.filtered && !req.cachedFilters) {
- queries.push(client.query('SELECT filter.id AS id, filter.phrase AS title, filter.context AS context, filter.expires_at AS expires_at, filter.action AS filter_action, keyword.keyword AS keyword, keyword.whole_word AS whole_word FROM custom_filter_keywords keyword JOIN custom_filters filter ON keyword.custom_filter_id = filter.id WHERE filter.account_id = $1 AND filter.expires_at IS NULL OR filter.expires_at > NOW()', [req.accountId]));
+ queries.push(client.query('SELECT filter.id AS id, filter.phrase AS title, filter.context AS context, filter.expires_at AS expires_at, filter.action AS filter_action, keyword.keyword AS keyword, keyword.whole_word AS whole_word FROM custom_filter_keywords keyword JOIN custom_filters filter ON keyword.custom_filter_id = filter.id WHERE filter.account_id = $1 AND (filter.expires_at IS NULL OR filter.expires_at > NOW())', [req.accountId]));
}
Promise.all(queries).then(values => {