shopify_app 14.4.3 → 16.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +5 -0
  3. data/.github/workflows/build.yml +38 -0
  4. data/.github/workflows/rubocop.yml +1 -7
  5. data/.gitignore +0 -2
  6. data/.rubocop.yml +1 -0
  7. data/CHANGELOG.md +21 -0
  8. data/Gemfile.lock +252 -0
  9. data/README.md +22 -6
  10. data/app/assets/images/storage_access.svg +1 -2
  11. data/app/controllers/concerns/shopify_app/ensure_authenticated_links.rb +22 -0
  12. data/app/views/shopify_app/partials/_button_styles.html.erb +41 -36
  13. data/app/views/shopify_app/partials/_card_styles.html.erb +3 -3
  14. data/app/views/shopify_app/partials/_empty_state_styles.html.erb +28 -59
  15. data/app/views/shopify_app/partials/_form_styles.html.erb +56 -0
  16. data/app/views/shopify_app/partials/_layout_styles.html.erb +16 -1
  17. data/app/views/shopify_app/partials/_typography_styles.html.erb +6 -6
  18. data/app/views/shopify_app/sessions/enable_cookies.html.erb +1 -1
  19. data/app/views/shopify_app/sessions/new.html.erb +38 -110
  20. data/app/views/shopify_app/sessions/request_storage_access.html.erb +1 -1
  21. data/app/views/shopify_app/sessions/top_level_interaction.html.erb +20 -15
  22. data/docs/Releasing.md +6 -4
  23. data/lib/generators/shopify_app/controllers/controllers_generator.rb +1 -1
  24. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +16 -7
  25. data/lib/generators/shopify_app/home_controller/templates/index.html.erb +10 -10
  26. data/lib/generators/shopify_app/install/install_generator.rb +6 -1
  27. data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +4 -3
  28. data/lib/generators/shopify_app/views/views_generator.rb +1 -1
  29. data/lib/shopify_app/configuration.rb +3 -0
  30. data/lib/shopify_app/controller_concerns/login_protection.rb +3 -1
  31. data/lib/shopify_app/engine.rb +21 -0
  32. data/lib/shopify_app/session/jwt.rb +3 -1
  33. data/lib/shopify_app/version.rb +1 -1
  34. data/package.json +1 -1
  35. metadata +6 -3
  36. data/.travis.yml +0 -27
@@ -49,7 +49,7 @@
49
49
  </div>
50
50
  </div>
51
51
  <div class="Polaris-Stack__Item">
52
- <div class="Polaris-Stack Polaris-Stack--distributionTrailing">
52
+ <div class="Polaris-Stack Polaris-Stack--distributionTrailing Polaris-Stack--distributionTrailingCustomSpacing">
53
53
  <div class="Polaris-Stack__Item">
54
54
  <button type="button" class="Polaris-Button Polaris-Button--primary" id="TriggerAllowCookiesPrompt">
55
55
  <span class="Polaris-Button__Content"><span><%= I18n.t('request_storage_access_action') %></span></span>
@@ -5,6 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <base target="_top">
7
7
  <title>Redirecting…</title>
8
+ <%= render 'shopify_app/partials/card_styles' %>
8
9
  <%= render 'shopify_app/partials/layout_styles' %>
9
10
  <%= render 'shopify_app/partials/typography_styles' %>
10
11
  <%= render 'shopify_app/partials/button_styles' %>
@@ -25,26 +26,30 @@
25
26
  <div class="Polaris-Layout__Section">
26
27
  <div class="Polaris-Stack Polaris-Stack--vertical">
27
28
  <div class="Polaris-Stack__Item">
28
- <div class="Polaris-EmptyState">
29
- <div class="Polaris-EmptyState__Section">
30
- <div class="Polaris-EmptyState__DetailsContainer">
31
- <div class="Polaris-EmptyState__Details">
32
- <div class="Polaris-TextContainer">
33
- <h1 class="Polaris-DisplayText Polaris-DisplayText--sizeMedium"><%= I18n.t('top_level_interaction_heading', app: ShopifyApp.configuration.application_name) %></h1>
34
- <div class="Polaris-EmptyState__Content">
35
- <p><%= I18n.t('top_level_interaction_body', app: ShopifyApp.configuration.application_name) %></p>
29
+ <div class="Polaris-Card">
30
+ <div class="Polaris-Card__Section">
31
+ <div class="Polaris-EmptyState">
32
+ <div class="Polaris-EmptyState__Section">
33
+ <div class="Polaris-EmptyState__DetailsContainer">
34
+ <div class="Polaris-EmptyState__Details">
35
+ <div class="Polaris-TextContainer">
36
+ <h1 class="Polaris-DisplayText Polaris-DisplayText--sizeSmall"><%= I18n.t('top_level_interaction_heading', app: ShopifyApp.configuration.application_name) %></h1>
37
+ <div class="Polaris-EmptyState__Content">
38
+ <p><%= I18n.t('top_level_interaction_body', app: ShopifyApp.configuration.application_name) %></p>
39
+ </div>
40
+ </div>
41
+ <div class="Polaris-EmptyState__Actions">
42
+ <div class="Polaris-Stack Polaris-Stack--alignmentCenter">
43
+ <div class="Polaris-Stack__Item"><button type="button" id="TopLevelInteractionButton" class="Polaris-Button Polaris-Button--primary Polaris-Button--sizeLarge"><span class="Polaris-Button__Content"><span class="Polaris-Button__Icon"></span><span><%= I18n.t('top_level_interaction_action') %></span></span></button></div>
44
+ </div>
45
+ </div>
36
46
  </div>
37
47
  </div>
38
- <div class="Polaris-EmptyState__Actions">
39
- <div class="Polaris-Stack Polaris-Stack--alignmentCenter">
40
- <div class="Polaris-Stack__Item"><button type="button" id="TopLevelInteractionButton" class="Polaris-Button Polaris-Button--primary Polaris-Button--sizeLarge"><span class="Polaris-Button__Content"><span class="Polaris-Button__Icon"></span><span><%= I18n.t('top_level_interaction_action') %></span></span></button></div>
41
- </div>
48
+ <div class="Polaris-EmptyState__ImageContainer">
49
+ <%= image_tag 'storage_access.svg', role: "presentation", alt: "", class: "Polaris-EmptyState__Image" %>
42
50
  </div>
43
51
  </div>
44
52
  </div>
45
- <div class="Polaris-EmptyState__ImageContainer">
46
- <%= image_tag 'storage_access.svg', role: "presentation", alt: "", class: "Polaris-EmptyState__Image" %>
47
- </div>
48
53
  </div>
49
54
  </div>
50
55
  </div>
@@ -1,18 +1,20 @@
1
- Releasing ShopifyApp
1
+ # Releasing ShopifyApp
2
2
 
3
- 1. Check the Semantic Versioning page for info on how to version the new release: http://semver.org
3
+ 1. Make the code changes in a separate PR that doesn't modify the version.
4
+ 1. After that is merged, check the Semantic Versioning page for info on how to version the new release: http://semver.org
4
5
  1. Create a pull request with the following changes:
5
6
  - Update the version of ShopifyApp in lib/shopify_app/version.rb
6
7
  - Update the version of shopify_app in package.json
8
+ - Run `bundle` to update `Gemfile.lock`
7
9
  - Add a CHANGELOG entry for the new release with the date
8
10
  - Change the title of the PR to something like: "Packaging for release X.Y.Z"
9
11
  1. Merge your pull request
10
12
  1. Checkout and pull from master so you have the latest version of the shopify_app
11
- 1. Tag the HEAD with the version
13
+ 1. Tag the HEAD with the version
12
14
  ```bash
13
15
  $ git tag -f vX.Y.Z && git push --tags --force
14
16
  ```
15
17
  1. Use Shipit to build and push the gem
16
18
 
17
- If you see an error like 'You need to create the vX.Y.X tag first', clear GIT
19
+ If you see an error like 'You need to create the vX.Y.X tag first', clear git
18
20
  cache in Shipit settings
@@ -8,7 +8,7 @@ module ShopifyApp
8
8
 
9
9
  def create_controllers
10
10
  controllers.each do |controller|
11
- copy_file controller
11
+ copy_file(controller)
12
12
  end
13
13
  end
14
14
 
@@ -6,16 +6,15 @@ module ShopifyApp
6
6
  class HomeControllerGenerator < Rails::Generators::Base
7
7
  source_root File.expand_path('../templates', __FILE__)
8
8
 
9
- class_option :with_session_token, type: :boolean, default: false
9
+ class_option :with_cookie_authentication, type: :boolean, default: false
10
+ class_option :embedded, type: :string, default: 'true'
10
11
 
11
12
  def create_home_controller
12
- @with_session_token = options['with_session_token']
13
-
14
13
  template(home_controller_template, 'app/controllers/home_controller.rb')
15
14
  end
16
15
 
17
16
  def create_products_controller
18
- generate("shopify_app:products_controller") if with_session_token?
17
+ generate("shopify_app:products_controller") unless with_cookie_authentication?
19
18
  end
20
19
 
21
20
  def create_home_index_view
@@ -28,16 +27,26 @@ module ShopifyApp
28
27
 
29
28
  private
30
29
 
30
+ def embedded?
31
+ options['embedded'] == 'true'
32
+ end
33
+
31
34
  def embedded_app?
32
35
  ShopifyApp.configuration.embedded_app?
33
36
  end
34
37
 
35
- def with_session_token?
36
- @with_session_token
38
+ def with_cookie_authentication?
39
+ options['with_cookie_authentication']
37
40
  end
38
41
 
39
42
  def home_controller_template
40
- with_session_token? ? 'unauthenticated_home_controller.rb' : 'home_controller.rb'
43
+ return 'unauthenticated_home_controller.rb' unless authenticated_home_controller_required?
44
+
45
+ 'home_controller.rb'
46
+ end
47
+
48
+ def authenticated_home_controller_required?
49
+ with_cookie_authentication? || !embedded? || !embedded_app?
41
50
  end
42
51
  end
43
52
  end
@@ -7,7 +7,7 @@
7
7
  rel="stylesheet"
8
8
  href="https://unpkg.com/@shopify/polaris@4.25.0/styles.min.css"
9
9
  />
10
- <% if @with_session_token %> <script>
10
+ <% unless with_cookie_authentication? %> <script>
11
11
  document.addEventListener("DOMContentLoaded", async function() {
12
12
  var SessionToken = window["app-bridge"].actions.SessionToken
13
13
  var app = window.app;
@@ -47,7 +47,7 @@
47
47
  <% end %> </head>
48
48
  <body>
49
49
  <h2>Products</h2>
50
- <% if @with_session_token %> <div id="products"><br>Loading...</div><% else %>
50
+ <% unless with_cookie_authentication? %> <div id="products"><br>Loading...</div><% else %>
51
51
  <ul>
52
52
  <%% @products.each do |product| %>
53
53
  <li><%%= link_to product.title, "https://#{@current_shopify_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
@@ -55,17 +55,17 @@
55
55
  </ul>
56
56
 
57
57
  <hr>
58
-
58
+ <% end %>
59
59
  <h2>Webhooks</h2>
60
60
 
61
61
  <%% if @webhooks.present? %>
62
- <ul>
63
- <%% @webhooks.each do |webhook| %>
64
- <li><%%= webhook.topic %> : <%%= webhook.address %></li>
65
- <%% end %>
66
- </ul>
62
+ <ul>
63
+ <%% @webhooks.each do |webhook| %>
64
+ <li><%%= webhook.topic %> : <%%= webhook.address %></li>
65
+ <%% end %>
66
+ </ul>
67
67
  <%% else %>
68
- <p>This app has not created any webhooks for this Shop. Add webhooks to your ShopifyApp initializer if you need webhooks</p>
69
- <%% end %><% end %>
68
+ <p>This app has not created any webhooks for this Shop. Add webhooks to your ShopifyApp initializer if you need webhooks</p>
69
+ <%% end %>
70
70
  </body>
71
71
  </html>
@@ -11,6 +11,7 @@ module ShopifyApp
11
11
  class_option :scope, type: :array, default: ['read_products']
12
12
  class_option :embedded, type: :string, default: 'true'
13
13
  class_option :api_version, type: :string, default: nil
14
+ class_option :with_cookie_authentication, type: :boolean, default: false
14
15
 
15
16
  def create_shopify_app_initializer
16
17
  @application_name = format_array_argument(options['application_name'])
@@ -64,7 +65,7 @@ module ShopifyApp
64
65
  def insert_hosts_into_development_config
65
66
  inject_into_file(
66
67
  'config/environments/development.rb',
67
- " config.hosts = (config.hosts rescue []) << /\\h+.ngrok.io/\n",
68
+ " config.hosts = (config.hosts rescue []) << /\\w+\\.ngrok\\.io/\n",
68
69
  after: "Rails.application.configure do\n"
69
70
  )
70
71
  end
@@ -78,6 +79,10 @@ module ShopifyApp
78
79
  def format_array_argument(array)
79
80
  array.join(' ').tr('"', '')
80
81
  end
82
+
83
+ def with_cookie_authentication?
84
+ options['with_cookie_authentication'] || !embedded_app?
85
+ end
81
86
  end
82
87
  end
83
88
  end
@@ -1,7 +1,7 @@
1
1
  ShopifyApp.configure do |config|
2
2
  config.application_name = "<%= @application_name %>"
3
- config.api_key = ENV['SHOPIFY_API_KEY']
4
- config.secret = ENV['SHOPIFY_API_SECRET']
3
+ config.api_key = ENV.fetch('SHOPIFY_API_KEY', '').presence || raise('Missing SHOPIFY_API_KEY')
4
+ config.secret = ENV.fetch('SHOPIFY_API_SECRET', '').presence || raise('Missing SHOPIFY_API_SECRET')
5
5
  config.old_secret = "<%= @old_secret %>"
6
6
  config.scope = "<%= @scope %>" # Consult this page for more scope options:
7
7
  # https://help.shopify.com/en/api/getting-started/authentication/oauth/scopes
@@ -9,7 +9,8 @@ ShopifyApp.configure do |config|
9
9
  config.after_authenticate_job = false
10
10
  config.api_version = "<%= @api_version %>"
11
11
  config.shop_session_repository = 'Shop'
12
- config.allow_jwt_authentication = true
12
+ config.allow_jwt_authentication = <%= !with_cookie_authentication? %>
13
+ config.allow_cookie_authentication = <%= with_cookie_authentication? %>
13
14
  end
14
15
 
15
16
  # ShopifyApp::Utils.fetch_known_api_versions # Uncomment to fetch known api versions from shopify servers on boot
@@ -8,7 +8,7 @@ module ShopifyApp
8
8
 
9
9
  def create_views
10
10
  views.each do |view|
11
- copy_file view
11
+ copy_file(view)
12
12
  end
13
13
  end
14
14
 
@@ -39,12 +39,15 @@ module ShopifyApp
39
39
  # allow enabling jwt headers for authentication
40
40
  attr_accessor :allow_jwt_authentication
41
41
 
42
+ attr_accessor :allow_cookie_authentication
43
+
42
44
  def initialize
43
45
  @root_url = '/'
44
46
  @myshopify_domain = 'myshopify.com'
45
47
  @scripttags_manager_queue_name = Rails.application.config.active_job.queue_name
46
48
  @webhooks_manager_queue_name = Rails.application.config.active_job.queue_name
47
49
  @disable_webpacker = ENV['SHOPIFY_APP_DISABLE_WEBPACKER'].present?
50
+ @allow_cookie_authentication = true
48
51
  end
49
52
 
50
53
  def login_url
@@ -57,6 +57,7 @@ module ShopifyApp
57
57
  end
58
58
 
59
59
  def user_session_by_cookie
60
+ return unless ShopifyApp.configuration.allow_cookie_authentication
60
61
  return unless session[:user_id].present?
61
62
  ShopifyApp::SessionRepository.retrieve_user_session(session[:user_id])
62
63
  end
@@ -72,6 +73,7 @@ module ShopifyApp
72
73
  end
73
74
 
74
75
  def shop_session_by_cookie
76
+ return unless ShopifyApp.configuration.allow_cookie_authentication
75
77
  return unless session[:shop_id].present?
76
78
  ShopifyApp::SessionRepository.retrieve_shop_session(session[:shop_id])
77
79
  end
@@ -100,7 +102,7 @@ module ShopifyApp
100
102
  end
101
103
 
102
104
  def signal_access_token_required
103
- response.set_header(ACCESS_TOKEN_REQUIRED_HEADER, true)
105
+ response.set_header(ACCESS_TOKEN_REQUIRED_HEADER, "true")
104
106
  end
105
107
 
106
108
  protected
@@ -1,5 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
  module ShopifyApp
3
+ module RedactJobParams
4
+ private
5
+
6
+ def args_info(job)
7
+ log_disabled_classes = %w(ShopifyApp::ScripttagsManagerJob ShopifyApp::WebhooksManagerJob)
8
+ return "" if log_disabled_classes.include?(job.class.name)
9
+ super
10
+ end
11
+ end
12
+
3
13
  class Engine < Rails::Engine
4
14
  engine_name 'shopify_app'
5
15
  isolate_namespace ShopifyApp
@@ -21,5 +31,16 @@ module ShopifyApp
21
31
  app.config.middleware.insert_after(ShopifyApp::SameSiteCookieMiddleware, ShopifyApp::JWTMiddleware)
22
32
  end
23
33
  end
34
+
35
+ initializer "shopify_app.redact_job_params" do
36
+ ActiveSupport.on_load(:active_job) do
37
+ if ActiveJob::Base.respond_to?(:log_arguments?)
38
+ WebhooksManagerJob.log_arguments = false
39
+ ScripttagsManagerJob.log_arguments = false
40
+ elsif ActiveJob::Logging::LogSubscriber.private_method_defined?(:args_info)
41
+ ActiveJob::Logging::LogSubscriber.prepend(RedactJobParams)
42
+ end
43
+ end
44
+ end
24
45
  end
25
46
  end
@@ -2,7 +2,9 @@
2
2
  module ShopifyApp
3
3
  class JWT
4
4
  class InvalidDestinationError < StandardError; end
5
+
5
6
  class MismatchedHostsError < StandardError; end
7
+
6
8
  class InvalidAudienceError < StandardError; end
7
9
 
8
10
  WARN_EXCEPTIONS = [
@@ -25,7 +27,7 @@ module ShopifyApp
25
27
  end
26
28
 
27
29
  def shopify_user_id
28
- @payload && @payload['sub']
30
+ @payload['sub'].to_i if @payload && @payload['sub']
29
31
  end
30
32
 
31
33
  private
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ShopifyApp
3
- VERSION = '14.4.3'
3
+ VERSION = '16.1.0'
4
4
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shopify_app",
3
- "version": "14.4.3",
3
+ "version": "16.1.0",
4
4
  "repository": "git@github.com:Shopify/shopify_app.git",
5
5
  "author": "Shopify",
6
6
  "license": "MIT",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify_app
3
3
  version: !ruby/object:Gem::Version
4
- version: 14.4.3
4
+ version: 16.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-23 00:00:00.000000000 Z
11
+ date: 2020-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: browser_sniffer
@@ -245,14 +245,15 @@ files:
245
245
  - ".github/ISSUE_TEMPLATE.md"
246
246
  - ".github/PULL_REQUEST_TEMPLATE.md"
247
247
  - ".github/probots.yml"
248
+ - ".github/workflows/build.yml"
248
249
  - ".github/workflows/rubocop.yml"
249
250
  - ".gitignore"
250
251
  - ".nvmrc"
251
252
  - ".rubocop.yml"
252
253
  - ".ruby-version"
253
- - ".travis.yml"
254
254
  - CHANGELOG.md
255
255
  - Gemfile
256
+ - Gemfile.lock
256
257
  - LICENSE
257
258
  - README.md
258
259
  - Rakefile
@@ -268,6 +269,7 @@ files:
268
269
  - app/assets/javascripts/shopify_app/top_level.js
269
270
  - app/assets/javascripts/shopify_app/top_level_interaction.js
270
271
  - app/controllers/concerns/shopify_app/authenticated.rb
272
+ - app/controllers/concerns/shopify_app/ensure_authenticated_links.rb
271
273
  - app/controllers/concerns/shopify_app/require_known_shop.rb
272
274
  - app/controllers/shopify_app/authenticated_controller.rb
273
275
  - app/controllers/shopify_app/callback_controller.rb
@@ -277,6 +279,7 @@ files:
277
279
  - app/views/shopify_app/partials/_button_styles.html.erb
278
280
  - app/views/shopify_app/partials/_card_styles.html.erb
279
281
  - app/views/shopify_app/partials/_empty_state_styles.html.erb
282
+ - app/views/shopify_app/partials/_form_styles.html.erb
280
283
  - app/views/shopify_app/partials/_layout_styles.html.erb
281
284
  - app/views/shopify_app/partials/_typography_styles.html.erb
282
285
  - app/views/shopify_app/sessions/enable_cookies.html.erb
@@ -1,27 +0,0 @@
1
- sudo: required
2
- dist: trusty
3
- addons:
4
- chrome: stable
5
- before_script:
6
- - "sudo chown root /opt/google/chrome/chrome-sandbox"
7
- - "sudo chmod 4755 /opt/google/chrome/chrome-sandbox"
8
- language: ruby
9
- cache:
10
- bundler: true
11
- directories:
12
- - node_modules
13
- yarn: true
14
-
15
- rvm:
16
- - 2.5
17
- - 2.6
18
- - 2.7
19
-
20
- install:
21
- - bundle install
22
- - nvm install node
23
- - yarn
24
-
25
- script:
26
- - yarn test
27
- - bundle exec rake test