Class: LexxyVariables::Pipeline

Inherits:
Object
  • Object
show all
Defined in:
lib/lexxy_variables/pipeline.rb

Overview

Turns stored rich text into rendered HTML with attachment chips resolved.

Security invariants (do not weaken):

1. A random per-render nonce guards placeholder tokens, so an author cannot
 forge a substitution by typing the token pattern into the body.
2. Attachments are swapped for nonce tokens BEFORE sanitization and resolved
 values are injected AFTER. :value output is HTML-escaped and therefore
 inert. :fragment output is spliced pre-sanitize so the sanitizer cleans it.
3. Any template-engine escaping (Liquid braces) lives only in that renderer.

Needs a view context (self, from the helper) for Action Text rendering. Build a fresh Pipeline per render, as the helper does. #call stores per-render state on the instance.

Instance Method Summary collapse

Constructor Details

#initialize(view, config = LexxyVariables.config) ⇒ Pipeline

Returns a new instance of Pipeline.



16
17
18
19
# File 'lib/lexxy_variables/pipeline.rb', line 16

def initialize(view, config = LexxyVariables.config)
  @view = view
  @config = config
end

Instance Method Details

#call(rich_text, context: nil, locale: I18n.locale) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/lexxy_variables/pipeline.rb', line 21

def call(rich_text, context: nil, locale: I18n.locale)
  body = rich_text&.body
  return "".html_safe if body.blank?

  @context = context
  @nonce = SecureRandom.hex(8)
  @used_keys = []

  I18n.with_locale(locale || I18n.locale) do
    fragment = substitute(body.fragment, 0)
    html = @view.render_action_text_content(
      ActionText::Content.new(fragment.to_html, canonicalize: false)
    )

    assigns = @config.resolve_assigns(@context, @used_keys.uniq)
    rendered = @config.renderer.render(html, nonce: @nonce, assigns: assigns)

    @view.render(layout: @config.content_layout) { rendered.html_safe }
  end
end