mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-06-18 18:54:34 +08:00
Previously, the `className` passed via `DiscourseEmbed` was applied to the iframe document's `<html>` element in classic embed mode but silently ignored in full app mode — the param was dropped during the `/embed/comments` redirect and the full app's layout never applied it. This change forwards `class_name` through the redirect and applies it to `html_classes` when embed mode is allowed, validated against `/\A[a-zA-Z0-9\-_ ]+\z/` to prevent attribute injection, matching classic embed behaviour.
35 lines
1.2 KiB
Ruby
Vendored
35 lines
1.2 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
# Shared embed-mode handling for controllers that render the full app inside an
|
|
# embedding iframe (see EmbedController). Including controllers are expected to
|
|
# register the filters with the appropriate actions, e.g.:
|
|
#
|
|
# before_action :set_embed_class, only: :show
|
|
# after_action :allow_embed_mode, only: :show
|
|
module EmbedModeHandler
|
|
# Drops X-Frame-Options so the page can be framed by an allowed embedding host.
|
|
def allow_embed_mode
|
|
response.headers.delete("X-Frame-Options") if embed_mode_allowed?
|
|
end
|
|
|
|
# Applies the `class_name` passed by the embedding page to the `<html>`
|
|
# element of the full app (via `html_classes`), mirroring classic embed mode.
|
|
def set_embed_class
|
|
return unless embed_mode_allowed?
|
|
return if params[:class_name].blank?
|
|
return unless params[:class_name].match?(/\A[a-zA-Z0-9\-_ ]+\z/)
|
|
|
|
@embed_class = params[:class_name]
|
|
end
|
|
|
|
def embed_mode_allowed?
|
|
return @embed_mode_allowed if defined?(@embed_mode_allowed)
|
|
|
|
@embed_mode_allowed =
|
|
if params[:embed_mode].blank? || !SiteSetting.embed_full_app
|
|
false
|
|
else
|
|
SiteSetting.embed_any_origin? || EmbeddableHost.record_for_url(request.referer).present?
|
|
end
|
|
end
|
|
end
|