shopify_app 14.3.0 → 14.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e6d4b068e8936d9c688b668c97ab15fb09647eee15dc066fcb904b24662cb65
4
- data.tar.gz: 289b6e8e1b23b0b633189e5be740c5e32b4e3bfaf8b8c98d8609a8dcf626c12a
3
+ metadata.gz: a3962aefcffacf58b7e57836a66b40a7689d5fe64d754fe1b236081cfeefcda2
4
+ data.tar.gz: 3f7200abedcd9598e08e7fcc816009acd236093c5a3ca011fa1d05684b31a1ed
5
5
  SHA512:
6
- metadata.gz: df4a5e39e099532a7e262e24c51a31ab0ad25023ddab9c0b01a54bf33ffa05b711d71904362c34594fdb54ba68b3ead41ce5c77505e8e22c023daeaf66b2b61d
7
- data.tar.gz: 91e53b6d7111d2833b6ccd88316c7dac3b2f91cbe9bad5f68ee1c7a6b37dee9a4f0bc64b40391ac00ac7db9f7d7b8c3b9a66e9af0db0a8aca1057b85465f3d17
6
+ metadata.gz: a3c2eaf95a630a628de9252be8f1802b35ce57be387a5e5ae3e8047484432b5ed7b1af98b739911c1f6afa74b09c44b5f8589481ad699c6595ef95d5332952de
7
+ data.tar.gz: 312ef3c7dd4013c17696289e9b8890e359d24753501468155cdb3ae63a7ff5a577d4b5f1a3f0606d438e78be655b0df791ccd45406d88485f5386db1a563d9af
@@ -12,3 +12,8 @@ Authentication Issues
12
12
  A great deal of the issues surrounding this repo are around authenticating (installing) the generated app with Shopify.
13
13
 
14
14
  If you are experiencing issues with your app authenticating/installing the best way to get help fast is to create a repo with the minimal amount of code to demonstrate the issue and a clearly documented set of steps you took to arrive there. This will help us solve your problem quicker since we won't need to spend any time figuring out how to reproduce the bug. Please also include your operating system and browser.
15
+
16
+ Security
17
+ --------
18
+
19
+ Please be certain to redact any private information from your logs or code snippets such as Api Keys, Api Secrets, and any authentication tokens such as shop_tokens.
@@ -10,6 +10,7 @@ AllCops:
10
10
  Style/MethodCallWithArgsParentheses:
11
11
  Exclude:
12
12
  - '**/Gemfile'
13
+ - 'test/**/*'
13
14
 
14
15
  Style/ClassAndModuleChildren:
15
16
  Exclude:
@@ -1,3 +1,23 @@
1
+ 14.4.4
2
+ ------
3
+ * Patch to not log params in ShopifyApp jobs [#1086](https://github.com/Shopify/shopify_app/pull/1086)
4
+
5
+ 14.4.3
6
+ ------
7
+ * Fix to ensure post authenticate jobs are run after callback requests [#1079](https://github.com/Shopify/shopify_app/pull/1079)
8
+
9
+ 14.4.2
10
+ ------
11
+ * Add debug logs in sessions controller
12
+
13
+ 14.4.1
14
+ ------
15
+ * Add debug logs for investigating authentication issues
16
+
17
+ 14.4.0
18
+ ------
19
+ * Replace script tags for ITP screens with data attributes
20
+
1
21
  14.3.0
2
22
  ------
3
23
  * Create user session if one does not exist but was expected
data/README.md CHANGED
@@ -26,7 +26,7 @@ Table of Contents
26
26
  - [Troubleshooting](#troubleshooting)
27
27
  - [Testing an embedded app outside the Shopify admin](#testing-an-embedded-app-outside-the-shopify-admin)
28
28
  - [Migration to 13.0.0](#migrating-to-1300)
29
- - [Questions or problems?](#questions-or-problems-)
29
+ - [Questions or problems?](#questions-or-problems)
30
30
  - [Rails 6 Compatibility](#rails-6-compatibility)
31
31
  - [Upgrading from 8.6 to 9.0.0](#upgrading-from-86-to-900)
32
32
 
@@ -105,7 +105,7 @@ Options include:
105
105
  * `application_name` - the name of your app, it can be supplied with or without double-quotes if a whitespace is present. (e.g. `--application_name Example App` or `--application_name "Example App"`)
106
106
  * `scope` - the OAuth access scope required for your app, e.g. **read_products, write_orders**. *Multiple options* need to be delimited by a comma-space and can be supplied with or without double-quotes
107
107
  (e.g. `--scope read_products, write_orders, write_products` or `--scope "read_products, write_orders, write_products"`)
108
- For more information, refer the [docs](http://docs.shopify.com/api/tutorials/oauth).
108
+ For more information, refer to the [docs](http://docs.shopify.com/api/tutorials/oauth).
109
109
  * `embedded` - the default is to generate an [embedded app](http://docs.shopify.com/embedded-app-sdk), if you want a legacy non-embedded app then set this to false, `--embedded false`
110
110
 
111
111
  You can update any of these settings later on easily; the arguments are simply for convenience.
@@ -427,7 +427,7 @@ bin/rails g shopify_app:rotate_shopify_token_job
427
427
 
428
428
  The generated rake task will be found at `lib/tasks/shopify/rotate_shopify_token.rake` and is provided strictly for example purposes. It might not work with your application out of the box without some configuration.
429
429
 
430
- ⚠️ Note: if you are updating `shopify_app` from a version prior to 8.4.2 (and do not wish to run the default/install generator again), you will need to add [the following line](https://github.com/Shopify/shopify_app/blob/4f7e6cca2a472d8f7af44b938bd0fcafe4d8e88a/lib/generators/shopify_app/install/templates/shopify_provider.rb#L18) to `config/intializers/omniauth.rb`:
430
+ ⚠️ Note: if you are updating `shopify_app` from a version prior to 8.4.2 (and do not wish to run the default/install generator again), you will need to add [the following line](https://github.com/Shopify/shopify_app/blob/4f7e6cca2a472d8f7af44b938bd0fcafe4d8e88a/lib/generators/shopify_app/install/templates/shopify_provider.rb#L18) to `config/initializers/omniauth.rb`:
431
431
 
432
432
  ```ruby
433
433
  strategy.options[:old_client_secret] = ShopifyApp.configuration.old_secret
@@ -132,7 +132,8 @@
132
132
 
133
133
  /* ITP 2.0 solution: handles cookie partitioning */
134
134
  StorageAccessHelper.prototype.setUpHelper = function() {
135
- return new ITPHelper({redirectUrl: window.shopOrigin + "/admin/apps/" + window.apiKey + window.returnTo});
135
+ var shopifyData = document.body.dataset;
136
+ return new ITPHelper({redirectUrl: shopifyData.shopOrigin + "/admin/apps/" + shopifyData.apiKey + shopifyData.returnTo});
136
137
  }
137
138
 
138
139
  StorageAccessHelper.prototype.setCookieAndRedirect = function() {
@@ -1,7 +1,7 @@
1
1
  (function() {
2
2
  function setUpTopLevelInteraction() {
3
3
  var TopLevelInteraction = new ITPHelper({
4
- redirectUrl: window.redirectUrl,
4
+ redirectUrl: document.body.dataset.redirectUrl,
5
5
  });
6
6
 
7
7
  TopLevelInteraction.execute();
@@ -6,46 +6,77 @@ module ShopifyApp
6
6
  include ShopifyApp::LoginProtection
7
7
 
8
8
  def callback
9
- unless auth_hash
10
- return respond_with_error
11
- end
9
+ return respond_with_error if invalid_request?
10
+
11
+ store_access_token_and_build_session
12
12
 
13
- if jwt_request? && !valid_jwt_auth?
14
- return respond_with_error
13
+ if start_user_token_flow?
14
+ return respond_with_user_token_flow
15
15
  end
16
16
 
17
+ perform_post_authenticate_jobs
18
+
19
+ respond_successfully
20
+ end
21
+
22
+ private
23
+
24
+ def respond_successfully
17
25
  if jwt_request?
18
- set_shopify_session
19
26
  head(:ok)
20
27
  else
28
+ redirect_to(return_address)
29
+ end
30
+ end
31
+
32
+ def respond_with_user_token_flow
33
+ Rails.logger.debug("[ShopifyApp::CallbackController] Redirecting for user token...")
34
+ redirect_to(login_url_with_optional_shop)
35
+ end
36
+
37
+ def store_access_token_and_build_session
38
+ if native_browser_request?
39
+ Rails.logger.debug("[ShopifyApp::CallbackController] Not a JWT request. Resetting session options...")
21
40
  reset_session_options
22
- set_shopify_session
41
+ else
42
+ Rails.logger.debug("[ShopifyApp::CallbackController] JWT request detected. Setting shopify session...")
43
+ end
44
+ set_shopify_session
45
+ end
23
46
 
24
- if redirect_for_user_token?
25
- return redirect_to(login_url_with_optional_shop)
26
- end
47
+ def invalid_request?
48
+ return true unless auth_hash
27
49
 
28
- install_webhooks
29
- install_scripttags
30
- perform_after_authenticate_job
50
+ jwt_request? && !valid_jwt_auth?
51
+ end
31
52
 
32
- redirect_to(return_address)
33
- end
53
+ def native_browser_request?
54
+ !jwt_request?
34
55
  end
35
56
 
36
- private
57
+ def perform_post_authenticate_jobs
58
+ install_webhooks
59
+ install_scripttags
60
+ perform_after_authenticate_job
61
+ end
37
62
 
38
63
  def respond_with_error
39
64
  if jwt_request?
65
+ Rails.logger.debug("[ShopifyApp::CallbackController] Invalid JWT auth detected.")
40
66
  head(:unauthorized)
41
67
  else
68
+ Rails.logger.debug("[ShopifyApp::CallbackController] Invalid non JWT auth detected.")
42
69
  flash[:error] = I18n.t('could_not_log_in')
43
70
  redirect_to(login_url_with_optional_shop)
44
71
  end
45
72
  end
46
73
 
47
- def redirect_for_user_token?
48
- ShopifyApp::SessionRepository.user_storage.present? && user_session.blank?
74
+ def start_user_token_flow?
75
+ if jwt_request?
76
+ false
77
+ else
78
+ ShopifyApp::SessionRepository.user_storage.present? && user_session.blank?
79
+ end
49
80
  end
50
81
 
51
82
  def jwt_request?
@@ -10,14 +10,19 @@ module ShopifyApp
10
10
  end
11
11
 
12
12
  def new
13
- authenticate if sanitized_shop_name.present?
13
+ if sanitized_shop_name.present?
14
+ Rails.logger.debug("[ShopifyApp::SessionsController] Sanitized shop name present. Authenticating...")
15
+ authenticate
16
+ end
14
17
  end
15
18
 
16
19
  def create
20
+ Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating...")
17
21
  authenticate
18
22
  end
19
23
 
20
24
  def enable_cookies
25
+ Rails.logger.debug("[ShopifyApp::SessionsController] Enabling cookies...")
21
26
  return unless validate_shop_presence
22
27
 
23
28
  render(:enable_cookies, layout: false, locals: {
@@ -40,6 +45,7 @@ module ShopifyApp
40
45
  end
41
46
 
42
47
  def granted_storage_access
48
+ Rails.logger.debug("[ShopifyApp::SessionsController] Granted storage access.")
43
49
  return unless validate_shop_presence
44
50
 
45
51
  session['shopify.granted_storage_access'] = true
@@ -50,6 +56,7 @@ module ShopifyApp
50
56
  end
51
57
 
52
58
  def destroy
59
+ Rails.logger.debug("[ShopifyApp::SessionsController] Resetting session.")
53
60
  reset_session
54
61
  flash[:notice] = I18n.t('.logged_out')
55
62
  redirect_to(login_url_with_optional_shop)
@@ -66,18 +73,23 @@ module ShopifyApp
66
73
  set_user_tokens_option
67
74
 
68
75
  if user_agent_can_partition_cookies
76
+ Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating with partitioning...")
69
77
  authenticate_with_partitioning
70
78
  else
79
+ Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating normally...")
71
80
  authenticate_normally
72
81
  end
73
82
  end
74
83
 
75
84
  def authenticate_normally
76
85
  if request_storage_access?
86
+ Rails.logger.debug("[ShopifyApp::SessionsController] Redirecting to request storage access...")
77
87
  redirect_to_request_storage_access
78
88
  elsif authenticate_in_context?
89
+ Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating in context...")
79
90
  authenticate_in_context
80
91
  else
92
+ Rails.logger.debug("[ShopifyApp::SessionsController] Authenticating at top level...")
81
93
  authenticate_at_top_level
82
94
  end
83
95
  end
@@ -95,6 +107,7 @@ module ShopifyApp
95
107
  # rubocop:disable Lint/SuppressedException
96
108
  def set_user_tokens_option
97
109
  if shop_session.blank?
110
+ Rails.logger.debug("[ShopifyApp::SessionsController] Shop session is blank.")
98
111
  session[:user_tokens] = false
99
112
  return
100
113
  end
@@ -117,6 +130,7 @@ module ShopifyApp
117
130
  def validate_shop_presence
118
131
  @shop = sanitized_shop_name
119
132
  unless @shop
133
+ Rails.logger.debug("[ShopifyApp::SessionsController] Invalid shop detected.")
120
134
  render_invalid_shop_error
121
135
  return false
122
136
  end
@@ -14,15 +14,10 @@
14
14
  display: none;
15
15
  }
16
16
  </style>
17
- <script>
18
- window.apiKey = "<%= ShopifyApp.configuration.api_key %>";
19
- window.shopOrigin = "https://<%= @shop %>";
20
- window.returnTo = "<%= params[:return_to] %>"
21
- </script>
22
17
 
23
18
  <%= javascript_include_tag('shopify_app/enable_cookies', crossorigin: 'anonymous', integrity: true) %>
24
19
  </head>
25
- <body>
20
+ <body data-api-key="<%= ShopifyApp.configuration.api_key %>" data-shop-origin="https://<%= @shop %>" data-redirect-url="<%= @url %>">
26
21
  <%=
27
22
  content_tag(
28
23
  :div, nil,
@@ -15,15 +15,9 @@
15
15
  }
16
16
  </style>
17
17
 
18
- <script>
19
- window.apiKey = "<%= ShopifyApp.configuration.api_key %>";
20
- window.shopOrigin = "https://<%= @shop %>";
21
- window.redirectUrl = "<%= @url %>";
22
- </script>
23
-
24
18
  <%= javascript_include_tag('shopify_app/top_level', crossorigin: 'anonymous', integrity: true) %>
25
19
  </head>
26
- <body>
20
+ <body data-api-key="<%= ShopifyApp.configuration.api_key %>" data-shop-origin="https://<%= @shop %>" data-redirect-url="<%= @url %>">
27
21
  <main id="TopLevelInteractionContent">
28
22
  <div class="Polaris-Page">
29
23
  <div class="Polaris-Page__Content">
@@ -8,7 +8,7 @@ Releasing ShopifyApp
8
8
  - Change the title of the PR to something like: "Packaging for release X.Y.Z"
9
9
  1. Merge your pull request
10
10
  1. Checkout and pull from master so you have the latest version of the shopify_app
11
- 1. Tag the HEAD with the version
11
+ 1. Tag the HEAD with the version
12
12
  ```bash
13
13
  $ git tag -f vX.Y.Z && git push --tags --force
14
14
  ```
@@ -8,7 +8,7 @@ module.exports = function(config) {
8
8
  config.set({
9
9
  mode: 'development',
10
10
  basePath: '',
11
- frameworks: ['mocha-debug', 'mocha', 'chai-sinon'],
11
+ frameworks: ['mocha', 'chai-sinon'],
12
12
  files: [
13
13
  'app/assets/javascripts/**/*.js',
14
14
  'test/javascripts/**/*test.js',
@@ -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
 
@@ -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
 
@@ -13,10 +13,12 @@ module ShopifyApp
13
13
  end
14
14
 
15
15
  def set_top_level_oauth_cookie
16
+ Rails.logger.debug("[ShopifyApp::Itp] Setting top level oauth cookie...")
16
17
  session['shopify.top_level_oauth'] = true
17
18
  end
18
19
 
19
20
  def clear_top_level_oauth_cookie
21
+ Rails.logger.debug("[ShopifyApp::Itp] Clearing top level oauth cookie...")
20
22
  session.delete('shopify.top_level_oauth')
21
23
  end
22
24
 
@@ -18,17 +18,24 @@ module ShopifyApp
18
18
 
19
19
  def activate_shopify_session
20
20
  if user_session_expected? && user_session.blank?
21
+ Rails.logger.debug("[ShopifyApp::LoginProtection] User session required. Redirecting to login...")
21
22
  signal_access_token_required
22
23
  return redirect_to_login
23
24
  end
24
25
 
25
- return redirect_to_login if current_shopify_session.blank?
26
+ if current_shopify_session.blank?
27
+ Rails.logger.debug("[ShopifyApp::LoginProtection] Current shopify session is blank. Redirecting to login...")
28
+ return redirect_to_login
29
+ end
30
+
26
31
  clear_top_level_oauth_cookie
27
32
 
28
33
  begin
34
+ Rails.logger.debug("[ShopifyApp::LoginProtection] Activating session...")
29
35
  ShopifyAPI::Base.activate_session(current_shopify_session)
30
36
  yield
31
37
  ensure
38
+ Rails.logger.debug("[ShopifyApp::LoginProtection] Clearing session...")
32
39
  ShopifyAPI::Base.clear_session
33
40
  end
34
41
  end
@@ -71,8 +78,12 @@ module ShopifyApp
71
78
 
72
79
  def login_again_if_different_user_or_shop
73
80
  if session[:user_session].present? && params[:session].present? # session data was sent/stored correctly
81
+ Rails.logger.debug("[ShopifyApp::LoginProtection] Session data was sent/stored correctly.")
74
82
  clear_session = session[:user_session] != params[:session] # current user is different from stored user
75
-
83
+ if clear_session
84
+ Rails.logger.debug("[ShopifyApp::LoginProtection] Current user is different from stored user.")
85
+ end
86
+ clear_session
76
87
  end
77
88
 
78
89
  if current_shopify_session &&
@@ -82,6 +93,7 @@ module ShopifyApp
82
93
  end
83
94
 
84
95
  if clear_session
96
+ Rails.logger.debug("[ShopifyApp::LoginProtection] Clearing shopify session and redirecting to login...")
85
97
  clear_shopify_session
86
98
  redirect_to_login
87
99
  end
@@ -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
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ShopifyApp
3
- VERSION = '14.3.0'
3
+ VERSION = '14.4.4'
4
4
  end