diff options
-rw-r--r-- | app/javascript/flavours/glitch/components/dropdown_menu.js | 6 | ||||
-rw-r--r-- | app/javascript/flavours/glitch/util/base64.js | 10 | ||||
-rw-r--r-- | app/javascript/flavours/glitch/util/base_polyfills.js | 26 | ||||
-rw-r--r-- | app/javascript/flavours/glitch/util/load_polyfills.js | 8 | ||||
-rw-r--r-- | config/initializers/1_hosts.rb (renamed from config/initializers/ostatus.rb) | 0 | ||||
-rw-r--r-- | config/initializers/content_security_policy.rb | 28 |
6 files changed, 63 insertions, 15 deletions
diff --git a/app/javascript/flavours/glitch/components/dropdown_menu.js b/app/javascript/flavours/glitch/components/dropdown_menu.js index 27b2586e5..1c2b0bf25 100644 --- a/app/javascript/flavours/glitch/components/dropdown_menu.js +++ b/app/javascript/flavours/glitch/components/dropdown_menu.js @@ -225,6 +225,12 @@ export default class Dropdown extends React.PureComponent { return this.target; } + componentWillUnmount = () => { + if (this.state.id === this.props.openDropdownId) { + this.handleClose(); + } + } + render () { const { icon, items, size, ariaLabel, disabled, dropdownPlacement, openDropdownId } = this.props; const open = this.state.id === openDropdownId; diff --git a/app/javascript/flavours/glitch/util/base64.js b/app/javascript/flavours/glitch/util/base64.js new file mode 100644 index 000000000..8226e2c54 --- /dev/null +++ b/app/javascript/flavours/glitch/util/base64.js @@ -0,0 +1,10 @@ +export const decode = base64 => { + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + + return outputArray; +}; diff --git a/app/javascript/flavours/glitch/util/base_polyfills.js b/app/javascript/flavours/glitch/util/base_polyfills.js index 7856b26f9..ad023eb73 100644 --- a/app/javascript/flavours/glitch/util/base_polyfills.js +++ b/app/javascript/flavours/glitch/util/base_polyfills.js @@ -3,7 +3,9 @@ import 'intl/locale-data/jsonp/en'; import 'es6-symbol/implement'; import includes from 'array-includes'; import assign from 'object-assign'; +import values from 'object.values'; import isNaN from 'is-nan'; +import { decode as decodeBase64 } from './base64'; if (!Array.prototype.includes) { includes.shim(); @@ -13,6 +15,30 @@ if (!Object.assign) { Object.assign = assign; } +if (!Object.values) { + values.shim(); +} + if (!Number.isNaN) { Number.isNaN = isNaN; } + +if (!HTMLCanvasElement.prototype.toBlob) { + const BASE64_MARKER = ';base64,'; + + Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { + value(callback, type = 'image/png', quality) { + const dataURL = this.toDataURL(type, quality); + let data; + + if (dataURL.indexOf(BASE64_MARKER) >= 0) { + const [, base64] = dataURL.split(BASE64_MARKER); + data = decodeBase64(base64); + } else { + [, data] = dataURL.split(','); + } + + callback(new Blob([data], { type })); + }, + }); +} diff --git a/app/javascript/flavours/glitch/util/load_polyfills.js b/app/javascript/flavours/glitch/util/load_polyfills.js index 8927b7358..8cb81c1a6 100644 --- a/app/javascript/flavours/glitch/util/load_polyfills.js +++ b/app/javascript/flavours/glitch/util/load_polyfills.js @@ -12,11 +12,13 @@ function importExtraPolyfills() { function loadPolyfills() { const needsBasePolyfills = !( + Array.prototype.includes && + HTMLCanvasElement.prototype.toBlob && window.Intl && - Object.assign && Number.isNaN && - window.Symbol && - Array.prototype.includes + Object.assign && + Object.values && + window.Symbol ); // Latest version of Firefox and Safari do not have IntersectionObserver. diff --git a/config/initializers/ostatus.rb b/config/initializers/1_hosts.rb index 5773b7290..5773b7290 100644 --- a/config/initializers/ostatus.rb +++ b/config/initializers/1_hosts.rb diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 7be45f950..6a649b772 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -2,20 +2,24 @@ # For further information see the following documentation # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy -Rails.application.config.content_security_policy do |p| - p.frame_ancestors :none - p.object_src :none - p.script_src :self - p.base_uri :none -# p.default_src :self, :https -# p.font_src :self, :https, :data -# p.img_src :self, :https, :data -# p.style_src :self, :https, :unsafe_inline -# -# # Specify URI for violation reports -# # p.report_uri "/csp-violation-report-endpoint" +if Rails.env.production? + assets_host = Rails.configuration.action_controller.asset_host || "https://#{ENV['WEB_DOMAIN'] || ENV['LOCAL_DOMAIN']}" + + Rails.application.config.content_security_policy do |p| + p.base_uri :none + p.default_src :none + p.frame_ancestors :none + p.script_src :self, assets_host + p.font_src :self, assets_host + p.img_src :self, :https, :data, :blob + p.style_src :self, :unsafe_inline, assets_host + p.media_src :self, :data, assets_host + p.frame_src :self, :https + p.connect_src :self, assets_host, Rails.configuration.x.streaming_api_base_url + end end + # Report CSP violations to a specified URI # For further information see the following documentation: # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only |