mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Currently when generating a onebox for Discourse topics, some important context is missing such as categories and tags. This patch addresses this issue by introducing a new onebox engine dedicated to display this information when available. Indeed to get this new information, categories and tags are exposed in the topic metadata as opengraph tags.
112 lines
3.5 KiB
Ruby
112 lines
3.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Onebox
|
|
module SanitizeConfig
|
|
HTTP_PROTOCOLS ||= ["http", "https", :relative].freeze
|
|
|
|
ONEBOX ||=
|
|
Sanitize::Config.freeze_config(
|
|
Sanitize::Config.merge(
|
|
Sanitize::Config::RELAXED,
|
|
elements:
|
|
Sanitize::Config::RELAXED[:elements] +
|
|
%w[audio details embed iframe source video svg path use],
|
|
attributes: {
|
|
"a" => Sanitize::Config::RELAXED[:attributes]["a"] + %w[target],
|
|
"audio" => %w[controls controlslist],
|
|
"embed" => %w[height src type width],
|
|
"iframe" => %w[
|
|
allowfullscreen
|
|
frameborder
|
|
height
|
|
scrolling
|
|
src
|
|
width
|
|
data-original-href
|
|
data-unsanitized-src
|
|
],
|
|
"source" => %w[src type],
|
|
"video" => %w[
|
|
controls
|
|
height
|
|
loop
|
|
width
|
|
autoplay
|
|
muted
|
|
poster
|
|
controlslist
|
|
playsinline
|
|
],
|
|
"path" => %w[d fill-rule],
|
|
"svg" => %w[aria-hidden width height viewbox],
|
|
"div" => [:data], # any data-* attributes,
|
|
"span" => [:data], # any data-* attributes,
|
|
"use" => %w[href],
|
|
},
|
|
add_attributes: {
|
|
"iframe" => {
|
|
"seamless" => "seamless",
|
|
"sandbox" =>
|
|
"allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox" \
|
|
" allow-presentation",
|
|
},
|
|
},
|
|
transformers:
|
|
(Sanitize::Config::RELAXED[:transformers] || []) +
|
|
[
|
|
lambda do |env|
|
|
next unless env[:node_name] == "a"
|
|
a_tag = env[:node]
|
|
a_tag["href"] ||= "#"
|
|
if a_tag["href"] =~ %r{^(?:[a-z]+:)?//}
|
|
a_tag["rel"] = "nofollow ugc noopener"
|
|
else
|
|
a_tag.remove_attribute("target")
|
|
end
|
|
end,
|
|
lambda do |env|
|
|
next unless env[:node_name] == "iframe"
|
|
|
|
iframe = env[:node]
|
|
allowed_regexes = env[:config][:allowed_iframe_regexes] || [/.*/]
|
|
|
|
allowed = allowed_regexes.any? { |r| iframe["src"] =~ r }
|
|
|
|
if !allowed
|
|
# add a data attribute with the blocked src. This is not required
|
|
# but makes it much easier to troubleshoot onebox issues
|
|
iframe["data-unsanitized-src"] = iframe["src"]
|
|
iframe.remove_attribute("src")
|
|
end
|
|
end,
|
|
],
|
|
protocols: {
|
|
"embed" => {
|
|
"src" => HTTP_PROTOCOLS,
|
|
},
|
|
"iframe" => {
|
|
"src" => HTTP_PROTOCOLS,
|
|
},
|
|
"source" => {
|
|
"src" => HTTP_PROTOCOLS,
|
|
},
|
|
"use" => {
|
|
"href" => [:relative],
|
|
},
|
|
},
|
|
css: {
|
|
properties: Sanitize::Config::RELAXED[:css][:properties] + %w[--aspect-ratio],
|
|
},
|
|
),
|
|
)
|
|
|
|
DISCOURSE_ONEBOX ||=
|
|
Sanitize::Config.freeze_config(
|
|
Sanitize::Config.merge(
|
|
ONEBOX,
|
|
attributes: Sanitize::Config.merge(ONEBOX[:attributes], "aside" => [:data]),
|
|
),
|
|
)
|
|
end
|
|
end
|