solidus_backend 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of solidus_backend might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 02b974645362da82b2400967d919cf00ba57887c
4
- data.tar.gz: edf6dc31425526c2562e5120586525d6c5088f31
3
+ metadata.gz: de5973fabeefe021bc6172c76c6e1a1e02c49394
4
+ data.tar.gz: 05d29540a7e77b7821d80f2ce0511920dec88757
5
5
  SHA512:
6
- metadata.gz: 8e6464351c9e0ad0830445790b9126a0cd7ddf345fb8467971d7a4a90be3db3e19a0442ce4c18c264bb480d34e892b1a89591a5243f1a49fa95d44afe6c7e434
7
- data.tar.gz: 0c253286b3eef6125db0de099e2d64820de97a5194464c58d4d796231bd8f016f18271829489214528cb2e9b1cc4bf260d505069999ee49d9b4b8945097c8fa1
6
+ metadata.gz: 6d97bc9506580584a52f6627dbb70a33fed739686fa72da9ee321c0231a5521e49f79ff93a1b7ffc2cff5f9b42838e13fc93edd903e09344d62cc0a155f771ae
7
+ data.tar.gz: c214582ac6ba0bed1edc3b57a0f694e9342205c9b974574c225f7b6b0ad379949469841c4f7746ee8f5d0129c42270d936873b10a9ad5989823bc58d67ec72b2
@@ -26,7 +26,7 @@ $(document).ready(function() {
26
26
  }
27
27
  },
28
28
  results: function(data, page) {
29
- return { results: data }
29
+ return { results: data.users }
30
30
  }
31
31
  },
32
32
  dropdownCssClass: 'customer_search',
@@ -54,7 +54,7 @@ $(document).ready(function() {
54
54
  });
55
55
  });
56
56
  }
57
- return customer.email;
57
+ return Select2.util.escapeMarkup(customer.email);
58
58
  }
59
59
  })
60
60
  }
@@ -1,6 +1,10 @@
1
1
  $(document).ready(function () {
2
2
  'use strict';
3
3
 
4
+ function formatOptionType(option_type) {
5
+ return Select2.util.escapeMarkup(option_type.presentation + ' (' + option_type.name + ')');
6
+ }
7
+
4
8
  if ($('#product_option_type_ids').length > 0) {
5
9
  $('#product_option_type_ids').select2({
6
10
  placeholder: Spree.translations.option_type_placeholder,
@@ -31,12 +35,8 @@ $(document).ready(function () {
31
35
  };
32
36
  }
33
37
  },
34
- formatResult: function (option_type) {
35
- return option_type.presentation + ' (' + option_type.name + ')';
36
- },
37
- formatSelection: function (option_type) {
38
- return option_type.presentation + ' (' + option_type.name + ')';
39
- }
38
+ formatResult: formatOptionType,
39
+ formatSelection: formatOptionType
40
40
  });
41
41
  }
42
42
  });
@@ -5,6 +5,10 @@ $.fn.productAutocomplete = function (options) {
5
5
  options = options || {}
6
6
  var multiple = typeof(options['multiple']) !== 'undefined' ? options['multiple'] : true
7
7
 
8
+ function formatProduct(product) {
9
+ return Select2.util.escapeMarkup(product.name);
10
+ }
11
+
8
12
  this.select2({
9
13
  minimumInputLength: 3,
10
14
  multiple: multiple,
@@ -37,12 +41,8 @@ $.fn.productAutocomplete = function (options) {
37
41
  };
38
42
  }
39
43
  },
40
- formatResult: function (product) {
41
- return product.name;
42
- },
43
- formatSelection: function (product) {
44
- return product.name;
45
- }
44
+ formatResult: formatProduct,
45
+ formatSelection: formatProduct
46
46
  });
47
47
  };
48
48
 
@@ -17,5 +17,5 @@ jQuery ->
17
17
  return { results: data.stock_items, more: more }
18
18
  formatResult: (stock_item) ->
19
19
  variantTemplate({ variant: stock_item.variant })
20
- formatSelection: (stock_item) ->
21
- "#{stock_item.variant.name} (#{stock_item.variant.options_text})"
20
+ formatSelection: (stock_item, container, excapeMarkup) ->
21
+ Select2.util.escapeMarkup("#{stock_item.variant.name} (#{stock_item.variant.options_text})")
@@ -1,6 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var set_taxon_select = function(){
4
+ function formatTaxon(taxon) {
5
+ return Select2.util.escapeMarkup(taxon.pretty_name);
6
+ }
7
+
4
8
  if ($('#product_taxon_ids').length > 0) {
5
9
  $('#product_taxon_ids').select2({
6
10
  placeholder: Spree.translations.taxon_placeholder,
@@ -37,12 +41,8 @@ var set_taxon_select = function(){
37
41
  };
38
42
  }
39
43
  },
40
- formatResult: function (taxon) {
41
- return taxon.pretty_name;
42
- },
43
- formatSelection: function (taxon) {
44
- return taxon.pretty_name;
45
- }
44
+ formatResult: formatTaxon,
45
+ formatSelection: formatTaxon
46
46
  });
47
47
  }
48
48
  }
@@ -45,6 +45,9 @@ $(document).ready ->
45
45
  sortable.trigger('sortupdate', item: draggable)
46
46
  , 250
47
47
 
48
+ formatTaxon = (taxon) ->
49
+ Select2.util.escapeMarkup(taxon.pretty_name)
50
+
48
51
  $('#taxon_id').select2
49
52
  dropdownCssClass: "taxon_select_box",
50
53
  placeholder: Spree.translations.find_a_taxon,
@@ -59,10 +62,8 @@ $(document).ready ->
59
62
  results: (data) ->
60
63
  results: data['taxons'],
61
64
  more: data.current_page < data.pages
62
- formatResult: (taxon) ->
63
- taxon.pretty_name;
64
- formatSelection: (taxon) ->
65
- taxon.pretty_name;
65
+ formatResult: formatTaxon,
66
+ formatSelection: formatTaxon
66
67
 
67
68
  $('#taxon_id').on "change", (e) ->
68
69
  Spree.ajax
@@ -1,6 +1,10 @@
1
1
  $.fn.userAutocomplete = function () {
2
2
  'use strict';
3
3
 
4
+ function formatUser(user) {
5
+ return Select2.util.escapeMarkup(user.email);
6
+ }
7
+
4
8
  this.select2({
5
9
  minimumInputLength: 1,
6
10
  multiple: true,
@@ -8,7 +12,7 @@ $.fn.userAutocomplete = function () {
8
12
  $.get(Spree.routes.user_search, {
9
13
  ids: element.val()
10
14
  }, function (data) {
11
- callback(data);
15
+ callback(data.users);
12
16
  });
13
17
  },
14
18
  ajax: {
@@ -23,16 +27,12 @@ $.fn.userAutocomplete = function () {
23
27
  },
24
28
  results: function (data) {
25
29
  return {
26
- results: data
30
+ results: data.users
27
31
  };
28
32
  }
29
33
  },
30
- formatResult: function (user) {
31
- return user.email;
32
- },
33
- formatSelection: function (user) {
34
- return user.email;
35
- }
34
+ formatResult: formatUser,
35
+ formatSelection: formatUser
36
36
  });
37
37
  };
38
38
 
@@ -35,8 +35,8 @@ $.fn.variantAutocomplete = (searchOptions = {}) ->
35
35
  results: data["variants"]
36
36
 
37
37
  formatResult: formatVariantResult
38
- formatSelection: (variant) ->
38
+ formatSelection: (variant, container, escapeMarkup) ->
39
39
  if !!variant.options_text
40
- variant.name + " (#{variant.options_text})"
40
+ Select2.util.escapeMarkup("#{variant.name} (#{variant.options_text}")
41
41
  else
42
- variant.name
42
+ Select2.util.escapeMarkup(variant.name)
@@ -27,11 +27,15 @@ module Spree
27
27
  parts << variant.product.name
28
28
  parts << "(#{variant.options_text})" if variant.options_text.present?
29
29
  parts << line_item.display_total
30
- parts.join("<br>").html_safe
30
+ safe_join(parts, "<br />".html_safe)
31
31
  end
32
32
 
33
33
  def display_shipment(shipment)
34
- "#{Spree.t(:shipment)} ##{shipment.number}<br>#{shipment.display_cost}".html_safe
34
+ parts = [
35
+ "#{Spree.t(:shipment)} ##{shipment.number}",
36
+ shipment.display_cost
37
+ ]
38
+ safe_join(parts, "<br />".html_safe)
35
39
  end
36
40
 
37
41
  def display_order(order)
@@ -15,8 +15,8 @@ module Spree
15
15
  obj = object.respond_to?(:errors) ? object : instance_variable_get("@#{object}")
16
16
 
17
17
  if obj && obj.errors[method].present?
18
- errors = obj.errors[method].map { |err| h(err) }.join('<br />').html_safe
19
- content_tag(:span, errors, :class => 'formError')
18
+ errors = safe_join(obj.errors[method], "<br />".html_safe)
19
+ content_tag(:span, errors, class: 'formError')
20
20
  else
21
21
  ''
22
22
  end
@@ -132,12 +132,11 @@ module Spree
132
132
 
133
133
  def preference_fields(object, form)
134
134
  return unless object.respond_to?(:preferences)
135
- object.preferences.keys.map{ |key|
136
-
135
+ fields = object.preferences.keys.map { |key|
137
136
  form.label("preferred_#{key}", Spree.t(key) + ": ") +
138
- preference_field_for(form, "preferred_#{key}", :type => object.preference_type(key))
139
-
140
- }.join("<br />").html_safe
137
+ preference_field_for(form, "preferred_#{key}", type: object.preference_type(key))
138
+ }
139
+ safe_join(fields, "<br />".html_safe)
141
140
  end
142
141
 
143
142
  def link_to_add_fields(name, target, options = {})
@@ -74,7 +74,7 @@ module Spree
74
74
  options[:class] = (options[:class].to_s + " fa fa-#{icon_name} icon_link with-tip").strip
75
75
  options[:class] += ' no-text' if options[:no_text]
76
76
  options[:title] = text if options[:no_text]
77
- text = options[:no_text] ? '' : raw("<span class='text'>#{text}</span>")
77
+ text = options[:no_text] ? '' : content_tag(:span, text, class: 'text')
78
78
  options.delete(:no_text)
79
79
  link_to(text, url, options)
80
80
  end
@@ -107,16 +107,10 @@ module Spree
107
107
  if html_options[:icon]
108
108
  html_options[:class] += " fa fa-#{html_options[:icon]}"
109
109
  end
110
- link_to(text_for_button_link(text, html_options), url, html_options)
110
+ link_to(text, url, html_options)
111
111
  end
112
112
  end
113
113
 
114
- def text_for_button_link(text, html_options)
115
- s = ''
116
- s << text
117
- raw(s)
118
- end
119
-
120
114
  def configurations_menu_item(link_text, url, description = '')
121
115
  %(<tr>
122
116
  <td>#{link_to(link_text, url)}</td>
@@ -12,7 +12,7 @@ module Spree
12
12
  :data => { :confirm => Spree.t(:order_sure_want_to, :event => Spree.t(event)) })
13
13
  end
14
14
  end
15
- links.join('&nbsp;').html_safe
15
+ safe_join(links, '&nbsp;'.html_safe)
16
16
  end
17
17
 
18
18
  def line_item_shipment_price(line_item, quantity)
@@ -9,7 +9,8 @@ module Spree
9
9
  :selected => ('selected' if selected)) do
10
10
  (taxon.ancestors.pluck(:name) + [taxon.name]).join(" -> ")
11
11
  end
12
- end.join("").html_safe
12
+ end
13
+ safe_join(options)
13
14
  end
14
15
 
15
16
  def option_types_options_for(product)
@@ -20,7 +21,8 @@ module Spree
20
21
  :selected => ('selected' if selected)) do
21
22
  option_type.name
22
23
  end
23
- end.join("").html_safe
24
+ end
25
+ safe_join(options)
24
26
  end
25
27
  end
26
28
  end
@@ -15,9 +15,9 @@ module Spree
15
15
 
16
16
  def display_variant(stock_movement)
17
17
  variant = stock_movement.stock_item.variant
18
- output = variant.name
19
- output += "<br>(#{variant.options_text})" unless variant.options_text.blank?
20
- output.html_safe
18
+ output = [variant.name]
19
+ output << variant.options_text unless variant.options_text.blank?
20
+ safe_join(output, "<br />".html_safe)
21
21
  end
22
22
  end
23
23
  end
@@ -1,4 +1,4 @@
1
- collection(@users)
1
+ collection(@users => :users)
2
2
  attributes :email, :id
3
3
  address_fields = [:firstname, :lastname,
4
4
  :address1, :address2,
@@ -172,6 +172,18 @@ describe "New Order", :type => :feature do
172
172
  end
173
173
  end
174
174
 
175
+ context "customer with attempted XSS", js: true do
176
+ let(:xss_string) { %(<script>throw("XSS")</script>) }
177
+ before do
178
+ user.update!(email: xss_string)
179
+ end
180
+ it "displays the user's email escaped without executing" do
181
+ click_on "Customer Details"
182
+ targetted_select2_search user.email, from: "#s2id_customer_search"
183
+ expect(page).to have_field("Email", with: xss_string)
184
+ end
185
+ end
186
+
175
187
  def fill_in_address(kind = "bill")
176
188
  fill_in "First Name", with: "John 99"
177
189
  fill_in "Last Name", with: "Doe"
@@ -11,15 +11,16 @@ describe "Product Taxons", :type => :feature do
11
11
  Capybara.ignore_hidden_elements = false
12
12
  end
13
13
 
14
- context "managing taxons" do
14
+ context "managing taxons", js: true do
15
15
  def selected_taxons
16
16
  find("#product_taxon_ids").value.split(',').map(&:to_i).uniq
17
17
  end
18
18
 
19
- it "should allow an admin to manage taxons", :js => true do
19
+ let(:product) { create(:product) }
20
+
21
+ it "should allow an admin to manage taxons" do
20
22
  taxon_1 = create(:taxon)
21
- taxon_2 = create(:taxon, :name => 'Clothing')
22
- product = create(:product)
23
+ taxon_2 = create(:taxon, name: 'Clothing')
23
24
  product.taxons << taxon_1
24
25
 
25
26
  visit spree.admin_path
@@ -39,5 +40,17 @@ describe "Product Taxons", :type => :feature do
39
40
  expect(page).to have_css(".select2-search-choice", text: taxon_1.name)
40
41
  expect(page).to have_css(".select2-search-choice", text: taxon_2.name)
41
42
  end
43
+
44
+ context "with an XSS attempt" do
45
+ let(:taxon_name) { %(<script>throw("XSS")</script>) }
46
+ let!(:taxon) { create(:taxon, name: taxon_name) }
47
+ it "displays the escaped HTML without executing it" do
48
+ visit spree.edit_admin_product_path(product)
49
+
50
+ select2_search "<script>", from: "Taxons"
51
+
52
+ expect(page).to have_content(taxon_name)
53
+ end
54
+ end
42
55
  end
43
56
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Promotion with user rule', js: true do
4
+ stub_authorization!
5
+
6
+ given(:promotion) { create :promotion }
7
+
8
+ background do
9
+ visit spree.edit_admin_promotion_path(promotion)
10
+ end
11
+
12
+ context "with an attempted XSS" do
13
+ let(:xss_string) { %(<script>throw("XSS")</script>) }
14
+ given!(:user) { create(:user, email: xss_string) }
15
+
16
+ scenario "adding an option value rule" do
17
+ select2 "User", from: "Add rule of type"
18
+ within("#rules_container") { click_button "Add" }
19
+
20
+ select2_search "<script>", from: "Choose users"
21
+
22
+ expect(page).to have_content(xss_string)
23
+ end
24
+ end
25
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_backend
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solidus Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-22 00:00:00.000000000 Z
11
+ date: 2016-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: solidus_api
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.4
19
+ version: 1.0.5
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.4
26
+ version: 1.0.5
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: solidus_core
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.4
33
+ version: 1.0.5
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 1.0.4
40
+ version: 1.0.5
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bourbon
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -639,6 +639,7 @@ files:
639
639
  - spec/features/admin/products/variant_spec.rb
640
640
  - spec/features/admin/promotion_adjustments_spec.rb
641
641
  - spec/features/admin/promotions/tiered_calculator_spec.rb
642
+ - spec/features/admin/promotions/user_rule_spec.rb
642
643
  - spec/features/admin/reports_spec.rb
643
644
  - spec/features/admin/stock_transfer_spec.rb
644
645
  - spec/features/admin/store_credits_spec.rb
@@ -712,3 +713,4 @@ signing_key:
712
713
  specification_version: 4
713
714
  summary: Admin interface for the Solidus e-commerce framework.
714
715
  test_files: []
716
+ has_rdoc: