Module: Spree::Preferences::Masking

Defined in:
lib/spree/core/preferences/masking.rb

Overview

Masks ‘:password`-typed preferences so secrets (API keys, OAuth tokens, signing secrets, …) never leave the server in plaintext.

The mask token is a bullet sequence followed by the last 4 characters of the original value — Stripe’s “stored, here’s the last 4” pattern.

Constant Summary collapse

TOKEN =
'••••'

Class Method Summary collapse

Class Method Details

.mask(value) ⇒ String?

Returns masked string, or nil if value is blank.

Parameters:

  • value (Object)

    the preference value to mask

Returns:

  • (String, nil)

    masked string, or nil if value is blank



16
17
18
19
20
# File 'lib/spree/core/preferences/masking.rb', line 16

def self.mask(value)
  return nil if value.blank?

  "#{TOKEN}#{value.to_s.last(4)}"
end

.masked?(value) ⇒ Boolean

Returns true if value carries the mask token.

Parameters:

  • value (Object)

    a value previously returned by ‘mask`

Returns:

  • (Boolean)

    true if value carries the mask token



24
25
26
# File 'lib/spree/core/preferences/masking.rb', line 24

def self.masked?(value)
  value.is_a?(String) && value.start_with?(TOKEN)
end

.serialize(preferable) ⇒ Hash{String => Object}

Serializes a Preferable’s ‘preferences` hash for the wire, masking `:password` values. Keys are stringified to match the wire shape expected by JSON clients — schema entries built by `compute_preference_schema` cache `:key_string` to avoid a `to_s` allocation per field per request.

Parameters:

  • preferable (#preferences, #preference_schema, nil)

    any object that includes ‘Spree::Preferences::Preferable` and `Spree::PreferenceSchema`

Returns:

  • (Hash{String => Object})


37
38
39
40
41
42
43
44
# File 'lib/spree/core/preferences/masking.rb', line 37

def self.serialize(preferable)
  return {} if preferable.nil?

  preferable.preference_schema.each_with_object({}) do |field, hash|
    value = preferable.preferences[field[:key]]
    hash[field[:key_string] || field[:key].to_s] = field[:type] == :password ? mask(value) : value
  end
end