shopify_app 21.6.0 → 22.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE/bug-report.md +23 -18
  4. data/.github/workflows/build.yml +2 -2
  5. data/.github/workflows/release.yml +1 -1
  6. data/.github/workflows/rubocop.yml +1 -2
  7. data/.nvmrc +1 -1
  8. data/.rubocop.yml +0 -1
  9. data/CHANGELOG.md +115 -0
  10. data/CODE_OF_CONDUCT.md +46 -0
  11. data/CONTRIBUTING.md +1 -6
  12. data/Gemfile.lock +99 -96
  13. data/README.md +47 -2
  14. data/app/assets/javascripts/shopify_app/redirect.js +3 -10
  15. data/app/controllers/concerns/shopify_app/ensure_authenticated_links.rb +5 -1
  16. data/app/controllers/concerns/shopify_app/ensure_has_session.rb +11 -5
  17. data/app/controllers/concerns/shopify_app/ensure_installed.rb +10 -4
  18. data/app/controllers/concerns/shopify_app/shop_access_scopes_verification.rb +5 -1
  19. data/app/controllers/shopify_app/callback_controller.rb +39 -18
  20. data/app/controllers/shopify_app/sessions_controller.rb +25 -4
  21. data/app/views/shopify_app/layouts/app_bridge.html.erb +17 -0
  22. data/app/views/shopify_app/sessions/patch_shopify_id_token.html.erb +0 -0
  23. data/app/views/shopify_app/shared/redirect.html.erb +10 -1
  24. data/config/locales/cs.yml +0 -18
  25. data/config/locales/da.yml +0 -15
  26. data/config/locales/de.yml +0 -17
  27. data/config/locales/en.yml +0 -11
  28. data/config/locales/es.yml +0 -17
  29. data/config/locales/fi.yml +0 -15
  30. data/config/locales/fr.yml +0 -18
  31. data/config/locales/it.yml +0 -16
  32. data/config/locales/ja.yml +0 -12
  33. data/config/locales/ko.yml +0 -14
  34. data/config/locales/nb.yml +0 -16
  35. data/config/locales/nl.yml +0 -16
  36. data/config/locales/pl.yml +0 -16
  37. data/config/locales/pt-BR.yml +0 -16
  38. data/config/locales/pt-PT.yml +0 -17
  39. data/config/locales/sv.yml +0 -16
  40. data/config/locales/th.yml +0 -15
  41. data/config/locales/tr.yml +0 -17
  42. data/config/locales/vi.yml +0 -17
  43. data/config/locales/zh-CN.yml +0 -11
  44. data/config/locales/zh-TW.yml +0 -11
  45. data/config/routes.rb +2 -1
  46. data/docs/Quickstart.md +9 -2
  47. data/docs/Troubleshooting.md +0 -23
  48. data/docs/Upgrading.md +64 -1
  49. data/docs/shopify_app/authentication.md +179 -58
  50. data/docs/shopify_app/controller-concerns.md +53 -12
  51. data/docs/shopify_app/generators.md +2 -2
  52. data/docs/shopify_app/sessions.md +358 -0
  53. data/docs/shopify_app/webhooks.md +88 -11
  54. data/karma.conf.js +6 -4
  55. data/lib/generators/shopify_app/add_declarative_webhook/add_declarative_webhook_generator.rb +53 -0
  56. data/lib/generators/shopify_app/add_declarative_webhook/templates/webhook_controller.rb.tt +13 -0
  57. data/lib/generators/shopify_app/add_declarative_webhook/templates/webhook_job.rb.tt +15 -0
  58. data/lib/generators/shopify_app/{add_gdpr_jobs/add_gdpr_jobs_generator.rb → add_privacy_jobs/add_privacy_jobs_generator.rb} +1 -1
  59. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +6 -1
  60. data/lib/generators/shopify_app/add_webhook/templates/webhook_job.rb.tt +1 -0
  61. data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +5 -2
  62. data/lib/generators/shopify_app/shopify_app_generator.rb +1 -1
  63. data/lib/generators/shopify_app/user_model/templates/db/migrate/add_user_expires_at_column.erb +5 -0
  64. data/lib/generators/shopify_app/user_model/user_model_generator.rb +20 -0
  65. data/lib/shopify_app/admin_api/with_token_refetch.rb +27 -0
  66. data/lib/shopify_app/auth/post_authenticate_tasks.rb +48 -0
  67. data/lib/shopify_app/auth/token_exchange.rb +73 -0
  68. data/lib/shopify_app/configuration.rb +69 -1
  69. data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +1 -1
  70. data/lib/shopify_app/controller_concerns/csrf_protection.rb +2 -1
  71. data/lib/shopify_app/controller_concerns/embedded_app.rb +42 -3
  72. data/lib/shopify_app/controller_concerns/ensure_billing.rb +14 -3
  73. data/lib/shopify_app/controller_concerns/frame_ancestors.rb +1 -1
  74. data/lib/shopify_app/controller_concerns/localization.rb +11 -8
  75. data/lib/shopify_app/controller_concerns/login_protection.rb +34 -38
  76. data/lib/shopify_app/controller_concerns/redirect_for_embedded.rb +5 -0
  77. data/lib/shopify_app/controller_concerns/sanitized_params.rb +4 -0
  78. data/lib/shopify_app/controller_concerns/token_exchange.rb +111 -0
  79. data/lib/shopify_app/controller_concerns/with_shopify_id_token.rb +48 -0
  80. data/lib/shopify_app/engine.rb +5 -11
  81. data/lib/shopify_app/managers/webhooks_manager.rb +6 -2
  82. data/lib/shopify_app/middleware/jwt_middleware.rb +13 -9
  83. data/lib/shopify_app/session/in_memory_user_session_store.rb +1 -1
  84. data/lib/shopify_app/session/jwt.rb +9 -0
  85. data/lib/shopify_app/session/session_repository.rb +49 -8
  86. data/lib/shopify_app/session/shop_session_storage.rb +4 -0
  87. data/lib/shopify_app/session/shop_session_storage_with_scopes.rb +4 -0
  88. data/lib/shopify_app/session/user_session_storage.rb +4 -0
  89. data/lib/shopify_app/session/user_session_storage_with_scopes.rb +25 -0
  90. data/lib/shopify_app/test_helpers/shopify_session_helper.rb +1 -0
  91. data/lib/shopify_app/utils.rb +14 -1
  92. data/lib/shopify_app/version.rb +1 -1
  93. data/lib/shopify_app.rb +9 -3
  94. data/package.json +5 -6
  95. data/shopify_app.gemspec +4 -4
  96. data/yarn.lock +2134 -3905
  97. metadata +51 -60
  98. data/.github/workflows/stale.yml +0 -43
  99. data/app/assets/images/storage_access.svg +0 -1
  100. data/app/assets/javascripts/shopify_app/app_bridge_3.1.1.js +0 -10
  101. data/app/assets/javascripts/shopify_app/app_bridge_redirect.js +0 -22
  102. data/app/assets/javascripts/shopify_app/app_bridge_utils_3.1.1.js +0 -1
  103. data/app/controllers/concerns/shopify_app/authenticated.rb +0 -17
  104. data/app/controllers/concerns/shopify_app/require_known_shop.rb +0 -16
  105. data/docs/shopify_app/script-tags.md +0 -28
  106. data/docs/shopify_app/session-repository.md +0 -79
  107. data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +0 -42
  108. data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +0 -63
  109. data/lib/shopify_app/controller_concerns/itp.rb +0 -50
  110. data/lib/shopify_app/jobs/scripttags_manager_job.rb +0 -16
  111. data/lib/shopify_app/managers/scripttags_manager.rb +0 -85
  112. /data/lib/generators/shopify_app/{add_gdpr_jobs → add_privacy_jobs}/templates/customers_data_request_job.rb.tt +0 -0
  113. /data/lib/generators/shopify_app/{add_gdpr_jobs → add_privacy_jobs}/templates/customers_redact_job.rb.tt +0 -0
  114. /data/lib/generators/shopify_app/{add_gdpr_jobs → add_privacy_jobs}/templates/shop_redact_job.rb.tt +0 -0
data/README.md CHANGED
@@ -106,8 +106,7 @@ You can find documentation on gem usage, concepts, mixins, installation, and mor
106
106
  * [Engine](/docs/shopify_app/engine.md)
107
107
  * [Controller Concerns](/docs/shopify_app/controller-concerns.md)
108
108
  * [Generators](/docs/shopify_app/generators.md)
109
- * [ScriptTags](/docs/shopify_app/script-tags.md)
110
- * [Session repository](/docs/shopify_app/session-repository.md)
109
+ * [Sessions](/docs/shopify_app/sessions.md)
111
110
  * [Handling changes in access scopes](/docs/shopify_app/handling-access-scopes-changes.md)
112
111
  * [Testing](/docs/shopify_app/testing.md)
113
112
  * [Webhooks](/docs/shopify_app/webhooks.md)
@@ -130,6 +129,52 @@ These routes are configurable. See the more detailed [*Engine*](/docs/shopify_ap
130
129
 
131
130
  To learn more about how this gem authenticates with Shopify, see [*Authentication*](/docs/shopify_app/authentication.md).
132
131
 
132
+ ### New embedded app authorization strategy (Token Exchange)
133
+
134
+ > [!TIP]
135
+ > If you are building an embedded app, we **strongly** recommend using [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
136
+ > with [token exchange](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange) instead of the legacy authorization code grant flow.
137
+
138
+ We've introduced a new installation and authorization strategy for **embedded apps** that
139
+ eliminates the redirects that were previously necessary.
140
+ It replaces the existing [installation and authorization code grant flow](https://shopify.dev/docs/apps/auth/get-access-tokens/authorization-code-grant).
141
+
142
+ This is achieved by using [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
143
+ to handle automatic app installations and scope updates, while utilizing
144
+ [token exchange](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange) to retrieve an access token for
145
+ authenticated API access.
146
+
147
+ ##### Enabling this new strategy in your app
148
+
149
+ 1. Enable [Shopify managed installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation)
150
+ by configuring your scopes [through the Shopify CLI](https://shopify.dev/docs/apps/tools/cli/configuration).
151
+ > [!NOTE]
152
+ > Ensure you don't have `use_legacy_install_flow = true` in your `shopify.app.toml` configuration file. If `use_legacy_install_flow` is true, Shopify will not manage the installation process for your app.
153
+ > You should remove the `use_legacy_install_flow` line from your `shopify.app.toml` configuration file or set it to `false`.
154
+
155
+ 2. Enable the new auth strategy in your app's ShopifyApp configuration file.
156
+
157
+ ```ruby
158
+ # config/initializers/shopify_app.rb
159
+ ShopifyApp.configure do |config|
160
+ #.....
161
+ config.embedded_app = true
162
+ config.new_embedded_auth_strategy = true
163
+
164
+ # If your app is configured to use online sessions, you can enable session expiry date check so a new access token
165
+ # is fetched automatically when the session expires.
166
+ # See expiry date check docs: https://github.com/Shopify/shopify_app/blob/main/docs/shopify_app/sessions.md#expiry-date
167
+ config.check_session_expiry_date = true
168
+ ...
169
+ end
170
+
171
+ ```
172
+ 3. Handle special callback logic. If your app has overridden the OAuth CallbackController to run special tasks post authorization,
173
+ you'll need to create and configure a custom PostAuthenticateTasks class to run these tasks after the token exchange. The original
174
+ OAuth CallbackController will not be triggered anymore. See [Post Authenticate Tasks documentation](/docs/shopify_app/authentication.md#post-authenticate-tasks) for more information.
175
+ 4. Make sure your `embedded_app` layout is correct. If your app has any controller which includes `ShopifyApp::EnsureInstalled`, they will now also include the `ShopifyApp::EmbeddedApp` concern, which sets `layout 'embedded_app'` for the current controller by default. In cases where the controller originally looked for another layout file, this can cause unexpected behavior. See [`EmbeddedApp` concern's documentation](/docs/shopify_app/controller-concerns.md#embeddedapp) for more information on the effects of this concern and how to disable the layout change if needed.
176
+ 5. Enjoy a smoother and faster app installation process.
177
+
133
178
  ### API Versioning
134
179
 
135
180
  [Shopify's API is versioned](https://shopify.dev/concepts/about-apis/versioning). With Shopify App `v1.11.0`, the included Shopify API gem allows developers to specify and update the Shopify API version they want their app or service to use. The Shopify API gem also surfaces warnings to Rails apps about [deprecated endpoints, GraphQL fields and more](https://shopify.dev/concepts/about-apis/versioning#deprecation-practices).
@@ -1,6 +1,3 @@
1
- //= require ./app_bridge_redirect.js
2
- //= require ./app_bridge_utils_3.1.1.js
3
-
4
1
  (function () {
5
2
  function redirect() {
6
3
  var redirectTargetElement = document.getElementById("redirection-target");
@@ -10,14 +7,10 @@
10
7
  }
11
8
 
12
9
  var targetInfo = JSON.parse(redirectTargetElement.dataset.target);
10
+ var normalizedLink = document.createElement('a');
11
+ normalizedLink.href = targetInfo.url;
13
12
 
14
- var appBridgeUtils = window['app-bridge-utils'];
15
-
16
- if (appBridgeUtils.isShopifyEmbedded()) {
17
- window.appBridgeRedirect(targetInfo.url);
18
- } else {
19
- window.top.location.href = targetInfo.url;
20
- }
13
+ open(normalizedLink.href, '_top');
21
14
  }
22
15
 
23
16
  document.addEventListener("DOMContentLoaded", redirect);
@@ -20,11 +20,15 @@ module ShopifyApp
20
20
  end
21
21
 
22
22
  def splash_page_with_params(params)
23
- uri = URI(root_path)
23
+ uri = URI(base_url)
24
24
  uri.query = params.compact.to_query
25
25
  uri.to_s
26
26
  end
27
27
 
28
+ def base_url
29
+ ShopifyApp.configuration.root_url.presence || root_path
30
+ end
31
+
28
32
  def redirect_to_splash_page
29
33
  redirect_to(splash_page)
30
34
  rescue ::ShopifyApp::ShopifyDomainNotFound => error
@@ -6,14 +6,20 @@ module ShopifyApp
6
6
 
7
7
  included do
8
8
  include ShopifyApp::Localization
9
- include ShopifyApp::LoginProtection
9
+
10
+ if ShopifyApp.configuration.use_new_embedded_auth_strategy?
11
+ include ShopifyApp::TokenExchange
12
+ around_action :activate_shopify_session
13
+ else
14
+ include ShopifyApp::LoginProtection
15
+ before_action :login_again_if_different_user_or_shop
16
+ around_action :activate_shopify_session
17
+ after_action :add_top_level_redirection_headers
18
+ end
19
+
10
20
  include ShopifyApp::CsrfProtection
11
21
  include ShopifyApp::EmbeddedApp
12
22
  include ShopifyApp::EnsureBilling
13
-
14
- before_action :login_again_if_different_user_or_shop
15
- around_action :activate_shopify_session
16
- after_action :add_top_level_redirection_headers
17
23
  end
18
24
  end
19
25
  end
@@ -9,15 +9,21 @@ module ShopifyApp
9
9
  if defined?(ShopifyApp::LoginProtection) && ancestors.include?(ShopifyApp::LoginProtection)
10
10
  message = <<~EOS
11
11
  We detected the use of incompatible concerns (EnsureInstalled and LoginProtection) in #{name},
12
- which may lead to unpredictable behavior. In a future release of this library this will raise an error.
12
+ which leads to unpredictable behavior. You cannot include both concerns in the same controller.
13
13
  EOS
14
14
 
15
- ShopifyApp::Logger.deprecated(message, "22.0.0")
15
+ raise message
16
16
  end
17
17
 
18
18
  before_action :check_shop_domain
19
- before_action :check_shop_known
20
- before_action :validate_non_embedded_session
19
+
20
+ if ShopifyApp.configuration.use_new_embedded_auth_strategy?
21
+ include ShopifyApp::TokenExchange
22
+ around_action :activate_shopify_session
23
+ else
24
+ before_action :check_shop_known
25
+ before_action :validate_non_embedded_session
26
+ end
21
27
  end
22
28
 
23
29
  def current_shopify_domain
@@ -6,7 +6,11 @@ module ShopifyApp
6
6
  include ShopifyApp::RedirectForEmbedded
7
7
 
8
8
  included do
9
- before_action :login_on_scope_changes
9
+ # Embedded auth strategy uses Shopify managed install to ensure latest access scopes,
10
+ # This will be handled automatically through token exchange
11
+ unless ShopifyApp.configuration.use_new_embedded_auth_strategy?
12
+ before_action :login_on_scope_changes
13
+ end
10
14
  end
11
15
 
12
16
  protected
@@ -10,8 +10,12 @@ module ShopifyApp
10
10
  begin
11
11
  api_session, cookie = validated_auth_objects
12
12
  rescue => error
13
- deprecate_callback_rescue(error) unless error.class.module_parent == ShopifyAPI::Errors
14
- return respond_with_error
13
+ if error.class.module_parent == ShopifyAPI::Errors
14
+ callback_rescue(error)
15
+ return respond_with_error
16
+ else
17
+ raise error
18
+ end
15
19
  end
16
20
 
17
21
  save_session(api_session) if api_session
@@ -19,12 +23,25 @@ module ShopifyApp
19
23
 
20
24
  return respond_with_user_token_flow if start_user_token_flow?(api_session)
21
25
 
22
- perform_post_authenticate_jobs(api_session)
26
+ if ShopifyApp::VERSION < "23.0"
27
+ # deprecated in 23.0
28
+ if ShopifyApp.configuration.custom_post_authenticate_tasks.present?
29
+ ShopifyApp.configuration.post_authenticate_tasks.perform(api_session)
30
+ else
31
+ perform_post_authenticate_jobs(api_session)
32
+ end
33
+ else
34
+ ShopifyApp.configuration.post_authenticate_tasks.perform(api_session)
35
+ end
23
36
  redirect_to_app if check_billing(api_session)
24
37
  end
25
38
 
26
39
  private
27
40
 
41
+ def callback_rescue(error)
42
+ ShopifyApp::Logger.debug("#{error.class} was rescued and redirected to login_url_with_optional_shop")
43
+ end
44
+
28
45
  def deprecate_callback_rescue(error)
29
46
  message = <<~EOS
30
47
  An error of type #{error.class} was rescued. This is not part of `ShopifyAPI::Errors`, which could indicate a
@@ -70,14 +87,25 @@ module ShopifyApp
70
87
 
71
88
  def redirect_to_app
72
89
  if ShopifyAPI::Context.embedded?
73
- return_to = "#{decoded_host}#{session.delete(:return_to)}"
74
- return_to = ShopifyApp.configuration.root_url if deduced_phishing_attack?
75
- redirect_to(return_to, allow_other_host: true)
90
+ return_to = session.delete(:return_to)
91
+ redirect_to = if fully_formed_url?(return_to)
92
+ return_to
93
+ else
94
+ "#{decoded_host}#{return_to}"
95
+ end
96
+
97
+ redirect_to = ShopifyApp.configuration.root_url if deduced_phishing_attack?
98
+ redirect_to(redirect_to, allow_other_host: true)
76
99
  else
77
100
  redirect_to(return_address)
78
101
  end
79
102
  end
80
103
 
104
+ def fully_formed_url?(return_to)
105
+ uri = Addressable::URI.parse(return_to)
106
+ uri.present? && uri.scheme.present? && uri.host.present?
107
+ end
108
+
81
109
  def decoded_host
82
110
  @decoded_host ||= ShopifyAPI::Auth.embedded_app_url(params[:host])
83
111
  end
@@ -119,8 +147,11 @@ module ShopifyApp
119
147
  end
120
148
 
121
149
  def perform_post_authenticate_jobs(session)
122
- install_webhooks(session)
123
- install_scripttags(session)
150
+ # Ensure we use the shop session to install webhooks
151
+ session_for_shop = session.online? ? shop_session : session
152
+
153
+ install_webhooks(session_for_shop)
154
+
124
155
  perform_after_authenticate_job(session)
125
156
  end
126
157
 
@@ -130,16 +161,6 @@ module ShopifyApp
130
161
  WebhooksManager.queue(session.shop, session.access_token)
131
162
  end
132
163
 
133
- def install_scripttags(session)
134
- return unless ShopifyApp.configuration.has_scripttags?
135
-
136
- ScripttagsManager.queue(
137
- session.shop,
138
- session.access_token,
139
- ShopifyApp.configuration.scripttags,
140
- )
141
- end
142
-
143
164
  def perform_after_authenticate_job(session)
144
165
  config = ShopifyApp.configuration.after_authenticate_job
145
166
 
@@ -7,7 +7,7 @@ module ShopifyApp
7
7
 
8
8
  layout false, only: :new
9
9
 
10
- after_action only: [:new, :create] do |controller|
10
+ after_action only: [:new, :create, :patch_shopify_id_token] do |controller|
11
11
  controller.response.headers.except!("X-Frame-Options")
12
12
  end
13
13
 
@@ -19,6 +19,10 @@ module ShopifyApp
19
19
  authenticate
20
20
  end
21
21
 
22
+ def patch_shopify_id_token
23
+ render(layout: "shopify_app/layouts/app_bridge")
24
+ end
25
+
22
26
  def top_level_interaction
23
27
  @url = login_url_with_optional_shop(top_level: true)
24
28
  validate_shop_presence
@@ -37,6 +41,23 @@ module ShopifyApp
37
41
  def authenticate
38
42
  return render_invalid_shop_error unless sanitized_shop_name.present?
39
43
 
44
+ if ShopifyApp.configuration.use_new_embedded_auth_strategy?
45
+ ShopifyApp::Logger.debug("Starting OAuth - Redirecting to Shopify managed install")
46
+ start_install
47
+ else
48
+ ShopifyApp::Logger.debug("Starting OAuth - Redirecting to begin auth")
49
+ start_oauth
50
+ end
51
+ end
52
+
53
+ def start_install
54
+ shop_name = sanitized_shop_name.split(".").first
55
+ unified_admin_path = ShopifyApp::Utils.unified_admin_path(shop_name)
56
+ install_path = "#{unified_admin_path}/oauth/install?client_id=#{ShopifyApp.configuration.api_key}"
57
+ redirect_to(install_path, allow_other_host: true)
58
+ end
59
+
60
+ def start_oauth
40
61
  copy_return_to_param_to_session
41
62
 
42
63
  if embedded_redirect_url?
@@ -44,16 +65,16 @@ module ShopifyApp
44
65
  if embedded_param?
45
66
  redirect_for_embedded
46
67
  else
47
- start_oauth
68
+ redirect_to_begin_oauth
48
69
  end
49
70
  elsif top_level?
50
- start_oauth
71
+ redirect_to_begin_oauth
51
72
  else
52
73
  redirect_auth_to_top_level
53
74
  end
54
75
  end
55
76
 
56
- def start_oauth
77
+ def redirect_to_begin_oauth
57
78
  callback_url = ShopifyApp.configuration.login_callback_url.gsub(%r{^/}, "")
58
79
  ShopifyApp::Logger.debug("Starting OAuth with the following callback URL: #{callback_url}")
59
80
 
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title><%= ShopifyApp.configuration.application_name %></title>
6
+ <%= yield :head %>
7
+ <script
8
+ data-api-key="<%= ShopifyApp.configuration.api_key %>"
9
+ src="https://cdn.shopify.com/shopifycloud/app-bridge.js">
10
+ </script>
11
+ <%= csrf_meta_tags %>
12
+ </head>
13
+
14
+ <body>
15
+ <%= yield %>
16
+ </body>
17
+ </html>
@@ -5,9 +5,18 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <base target="_top">
7
7
  <title>Redirecting…</title>
8
+
9
+ <%
10
+ is_iframe = local_assigns.key?(:is_iframe) ? is_iframe : true
11
+ if is_iframe
12
+ %>
13
+ <meta name="shopify-api-key" content="<%= ShopifyApp.configuration.api_key %>">
14
+ <%= javascript_include_tag "https://cdn.shopify.com/shopifycloud/app-bridge.js" %>
15
+ <% end %>
16
+
8
17
  <%= javascript_include_tag('shopify_app/redirect', crossorigin: 'anonymous', integrity: true) %>
9
18
  </head>
10
- <body data-api-key="<%= ShopifyApp.configuration.api_key %>" data-shop-origin="<%= current_shopify_domain %>" data-host="<%= params[:host] %>" >
19
+ <body>
11
20
  <%=
12
21
  content_tag(:div, nil,
13
22
  id: 'redirection-target',
@@ -3,21 +3,3 @@ cs:
3
3
  logged_out: Odhlášení proběhlo úspěšně
4
4
  could_not_log_in: Nelze se přihlásit do obchodu Shopify
5
5
  invalid_shop_url: Neplatná doména obchodu
6
- enable_cookies_heading: Zapnout soubory cookie z aplikace %{app}
7
- enable_cookies_body: Pokud chcete v Shopify používat aplikaci %{app}, musíte soubory
8
- cookie v tomto prohlížeči povolit ručně.
9
- enable_cookies_footer: Soubory cookie umožňují, aby vás aplikace ověřila pomocí
10
- dočasného uchování preferencí a osobních údajů. Jejich platnost vyprší po 30 dnech.
11
- enable_cookies_action: Povolit soubory cookie
12
- top_level_interaction_heading: Váš prohlížeč potřebuje ověřit aplikaci %{app}
13
- top_level_interaction_body: Váš prohlížeč vyžaduje, aby si od vás aplikace, jako
14
- je %{app}, nejdřív vyžádaly přístup k souborům cookie, než je pro vás Shopify
15
- otevře.
16
- top_level_interaction_action: Pokračovat
17
- request_storage_access_heading: Aplikace %{app} potřebuje získat přístup k souborům
18
- cookie
19
- request_storage_access_body: Tato aplikace vám umožní ověření prostřednictvím dočasného
20
- uchování vašich osobních údajů. Pokud chcete používat tuto aplikaci, klikněte
21
- na tlačítko Pokračovat a povolte soubory cookie.
22
- request_storage_access_footer: Platnost souborů cookie vyprší po 30 dnech.
23
- request_storage_access_action: Pokračovat
@@ -3,18 +3,3 @@ da:
3
3
  logged_out: Logget ud
4
4
  could_not_log_in: Kunne ikke logge ind på Shopify-butik
5
5
  invalid_shop_url: Ugyldig butiksdomæne
6
- enable_cookies_heading: Aktivér cookies fra %{app}
7
- enable_cookies_body: Du skal manuelt aktivere cookies i denne browser for at kunne
8
- bruge %{app} i Shopify.
9
- enable_cookies_footer: Cookies lader appen godkende dig ved at gemme dine præferencer
10
- og personlige oplysninger midlertidigt. De udløber efter 30 dage.
11
- enable_cookies_action: Aktivér cookies
12
- top_level_interaction_heading: Din browser skal godkende %{app}
13
- top_level_interaction_body: Din browser kræver, at apps som f.eks. %{app} spørger
14
- dig om adgang til cookies, inden Shopify kan åbne den for dig.
15
- top_level_interaction_action: Fortsæt
16
- request_storage_access_heading: "%{app} skal have adgang til cookies"
17
- request_storage_access_body: Det lader appen godkende dig ved at gemme dine personlige
18
- oplysninger midlertidigt. Klik på forsæt, og tillad cookies for at bruge appen.
19
- request_storage_access_footer: Cookies udløber efter 30 dage.
20
- request_storage_access_action: Fortsæt
@@ -3,20 +3,3 @@ de:
3
3
  logged_out: Erfolgreich ausgelogt
4
4
  could_not_log_in: Shopify Store Login fehlgeschlagen
5
5
  invalid_shop_url: Ungültige Shop-Domain
6
- enable_cookies_heading: Cookies von %{app} aktivieren
7
- enable_cookies_body: Du musst Cookies in diesem Browser manuell aktivieren, um %{app}
8
- in Shopify verwenden zu können.
9
- enable_cookies_footer: Mithilfe von Cookies kann die App dich authentifizieren,
10
- indem deine Einstellungen und personenbezogenen Daten vorübergehend gespeichert
11
- werden. Sie laufen nach 30 Tagen ab.
12
- enable_cookies_action: Cookies aktivieren
13
- top_level_interaction_heading: Dein Browser muss %{app} authentifizieren
14
- top_level_interaction_body: Dein Browser verlangt, dass Apps wie %{app} dich um
15
- Zugriff auf Cookies bitten, bevor Shopify sie für dich öffnen kann.
16
- top_level_interaction_action: Weiter
17
- request_storage_access_heading: "%{app} braucht Zugriff auf Cookies"
18
- request_storage_access_body: Damit kann die App dich authentifizieren, indem deine
19
- Einstellungen und personenbezogenen Daten vorübergehend gespeichert werden. Klicke
20
- auf "Weiter" und erlaube Cookies, um die App zu verwenden.
21
- request_storage_access_footer: Cookies laufen nach 30 Tagen ab.
22
- request_storage_access_action: Weiter
@@ -2,14 +2,3 @@ en:
2
2
  logged_out: 'Successfully logged out'
3
3
  could_not_log_in: 'Could not log in to Shopify store'
4
4
  invalid_shop_url: 'Invalid shop domain'
5
- enable_cookies_heading: "Enable cookies from %{app}"
6
- enable_cookies_body: "You must manually enable cookies in this browser in order to use %{app} within Shopify."
7
- enable_cookies_footer: 'Cookies let the app authenticate you by temporarily storing your preferences and personal information. They expire after 30 days.'
8
- enable_cookies_action: 'Enable cookies'
9
- top_level_interaction_heading: "Your browser needs to authenticate %{app}"
10
- top_level_interaction_body: "Your browser requires apps like %{app} to ask you for access to cookies before Shopify can open it for you."
11
- top_level_interaction_action: 'Continue'
12
- request_storage_access_heading: "%{app} needs access to cookies"
13
- request_storage_access_body: "This lets the app authenticate you by temporarily storing your personal information. Click continue and allow cookies to use the app."
14
- request_storage_access_footer: 'Cookies expire after 30 days.'
15
- request_storage_access_action: 'Continue'
@@ -3,20 +3,3 @@ es:
3
3
  logged_out: Cerrar sesión
4
4
  could_not_log_in: No se pudo iniciar sesión en tu tienda Shopify
5
5
  invalid_shop_url: Dominio de tienda inválido
6
- enable_cookies_heading: Habilitar cookies de %{app}
7
- enable_cookies_body: Debes habilitar manualmente las cookies en este navegador para
8
- usar %{app} en Shopify.
9
- enable_cookies_footer: Las cookies permiten que la aplicación te autentique almacenando
10
- temporalmente tus preferencias y datos personales. Las cookies expiran al cabo
11
- de 30 días.
12
- enable_cookies_action: Habilitar cookies
13
- top_level_interaction_heading: Tu navegador necesita autenticar %{app}
14
- top_level_interaction_body: Tu navegador requiere aplicaciones como %{app} para
15
- solicitarte acceso a cookies antes de que Shopify pueda abrirlo por ti.
16
- top_level_interaction_action: Continuar
17
- request_storage_access_heading: "%{app} necesita acceso a las cookies"
18
- request_storage_access_body: Esto permite que la aplicación te autentique almacenando
19
- temporalmente tus datos personales. Haz clic en continuar y permite que las cookies
20
- utilicen la aplicación.
21
- request_storage_access_footer: Las cookies expiran a los 30 días.
22
- request_storage_access_action: Continuar
@@ -3,18 +3,3 @@ fi:
3
3
  logged_out: Olet kirjautunut ulos
4
4
  could_not_log_in: Kirjautuminen Shopify-kauppaan ei onnistunut
5
5
  invalid_shop_url: Virheellinen kaupan verkkotunnus
6
- enable_cookies_heading: Ota käyttöön sovelluksen %{app} evästeet
7
- enable_cookies_body: Sinun on otettava evästeet käyttöön manuaalisesti tässä selaimessa,
8
- jotta voit käyttää sovellusta %{app} Shopifyssa.
9
- enable_cookies_footer: Evästeiden avulla sovellus voi todentaa sinut tallentamalla
10
- asetuksesi ja henkilötietosi tilapäisesti. Ne vanhenevat 30 päivän kuluttua.
11
- enable_cookies_action: Ota evästeet käyttöön
12
- top_level_interaction_heading: Selaimesi täytyy todentaa %{app}
13
- top_level_interaction_body: Selaimesi vaatii sovelluksia, kuten %{app}, pyytämään
14
- sinulta luvan evästeiden käyttöön, ennen kuin Shopify voi avata sovelluksen.
15
- top_level_interaction_action: Jatka
16
- request_storage_access_heading: "%{app} edellyttää evästeiden käyttöä"
17
- request_storage_access_body: Näin sovellus voi todentaa sinut tallentamalla henkilötietosi
18
- tilapäisesti. Klikkaa Jatka ja salli evästeet sovelluksen käyttämiseksi.
19
- request_storage_access_footer: Evästeet vanhenevat 30 päivän kuluttua.
20
- request_storage_access_action: Jatka
@@ -3,21 +3,3 @@ fr:
3
3
  logged_out: Vous êtes déconnecté(e)
4
4
  could_not_log_in: Impossible de se connecter à la boutique Shopify
5
5
  invalid_shop_url: Url invalide
6
- enable_cookies_heading: Activer les cookies de %{app}
7
- enable_cookies_body: Vous devez manuellement activer les cookies dans ce navigateur
8
- pour utiliser %{app} dans Shopify.
9
- enable_cookies_footer: Les cookies permettent à l'application de vous authentifier
10
- en stockant temporairement vos préférences et informations personnelles. Celles-ci
11
- expirent après 30 jours.
12
- enable_cookies_action: Activer les cookies
13
- top_level_interaction_heading: Votre navigateur doit s'authentifier %{app}
14
- top_level_interaction_body: Votre navigateur nécessite des applications telles que
15
- %{app} pour vous demander l'accès aux cookies avant que Shopify ne puisse l'ouvrir
16
- pour vous.
17
- top_level_interaction_action: Continuer
18
- request_storage_access_heading: "%{app} a besoin d'accéder aux cookies"
19
- request_storage_access_body: Cela permet à l'application de vous authentifier en
20
- stockant temporairement vos informations personnelles. Cliquez pour continuer
21
- et autorisez les cookies à utiliser l'application.
22
- request_storage_access_footer: Les cookies expirent après 30 jours.
23
- request_storage_access_action: Continuer
@@ -3,19 +3,3 @@ it:
3
3
  logged_out: Disconnessione effettuata correttamente
4
4
  could_not_log_in: Impossibile accedere al negozio Shopify
5
5
  invalid_shop_url: Dominio negozio non valido
6
- enable_cookies_heading: Abilita i cookie di %{app}
7
- enable_cookies_body: Devi abilitare manualmente i cookie in questo browser per poter
8
- utilizzare %{app} da Shopify.
9
- enable_cookies_footer: I cookie consentono all'app di autenticarti memorizzando
10
- temporaneamente le tue preferenze e informazioni personali. Scadono dopo 30 giorni.
11
- enable_cookies_action: Abilita i cookie
12
- top_level_interaction_heading: Il tuo browser deve autenticare %{app}
13
- top_level_interaction_body: Il tuo browser richiede che app come %{app} ti chiedano
14
- l'accesso ai cookie prima dell'apertura automatica da parte di Shopify.
15
- top_level_interaction_action: Continua
16
- request_storage_access_heading: "%{app} deve accedere ai cookie"
17
- request_storage_access_body: L'app potrà così autenticarti memorizzando temporaneamente
18
- le tue informazioni personali. Clicca su Continua e consenti ai cookie di utilizzare
19
- l'app.
20
- request_storage_access_footer: I cookie scadono dopo 30 giorni.
21
- request_storage_access_action: Continua
@@ -3,15 +3,3 @@ ja:
3
3
  logged_out: ログアウトに成功しました
4
4
  could_not_log_in: Shopifyストアにログインできませんでした
5
5
  invalid_shop_url: ショップのドメインが無効です
6
- enable_cookies_heading: "%{app}からのCookieを有効にする"
7
- enable_cookies_body: Shopifyで%{app}を使用できるようにするためには、このブラウザのCookieを手動で有効にする必要があります。
8
- enable_cookies_footer: Cookieを使用すると、各種設定や個人情報を一時的に保存することで、アプリ認証を受けることができます。30日後に有効期限が切れます。
9
- enable_cookies_action: Cookieを有効にする
10
- top_level_interaction_heading: お使いのブラウザを更新する必要があります%{app}
11
- top_level_interaction_body: Shopifyがアプリを開けるように、ブラウザはCookieにアクセスするための%{app}のようなアプリが必要です。
12
- top_level_interaction_action: 続ける
13
- request_storage_access_heading: "%{app}はCookieへのアクセス許可が必要です"
14
- request_storage_access_body: Cookieを使用すると、個人情報を一時的に保存することで、アプリ認証を受けることができます。[続ける]
15
- をクリックすると、アプリはCookieを利用します。
16
- request_storage_access_footer: Cookieは30日後に有効期限が切れます。
17
- request_storage_access_action: 続ける
@@ -3,17 +3,3 @@ ko:
3
3
  logged_out: 성공적으로 로그아웃 되었습니다.
4
4
  could_not_log_in: Shopify 스토어에 로그인할 수 없습니다.
5
5
  invalid_shop_url: 유효하지 않은 상점 도메인
6
- enable_cookies_heading: "%{app}에서 쿠키를 사용 가능"
7
- enable_cookies_body: Shopify 내에서 %{app} 을 사용하기 위해 이 브라우저에서 쿠키를 수동으로 사용할 수 있습니다.
8
- enable_cookies_footer: 쿠키를 사용하면 개인의 선호나 정보를 임시로 저장하여 앱에서 사용자를 인증할 수 있습니다. 쿠키는 30일
9
- 후에 만료됩니다.
10
- enable_cookies_action: 쿠리 사용 가능
11
- top_level_interaction_heading: 브라우저에서 %{app} 을 인증해야 합니다.
12
- top_level_interaction_body: Shopify를 열기 전 쿠키에 엑세스하려면 %{app} 과 같은 앱 들이 브라우저에 설치되어야
13
- 합니다.
14
- top_level_interaction_action: 계속
15
- request_storage_access_heading: "%{app}에서 쿠키에 접근해야 합니다."
16
- request_storage_access_body: 이를 통해 개인 정보를 임시로 저장하여 앱에서 사용자를 인증할 수 있습니다. 계속 클릭하여
17
- 쿠키로 앱을 사용하세요.
18
- request_storage_access_footer: 쿠키는 30일 후에 만료됩니다.
19
- request_storage_access_action: 계속
@@ -3,19 +3,3 @@ nb:
3
3
  logged_out: Logget ut
4
4
  could_not_log_in: Kunne ikke logge på Shopify-butikken
5
5
  invalid_shop_url: Ugyldig butikkdomene
6
- enable_cookies_heading: Aktiver informasjonskapsler fra %{app}
7
- enable_cookies_body: Du kan manuelt aktivere informasjonskapsler i denne nettleseren
8
- for å kunne bruke %{app} i Shopify.
9
- enable_cookies_footer: Informasjonskapsler lar appen autentisere deg ved å midlertidig
10
- lagre innstillingene og personopplysningene dine. De går ut etter 30 dager.
11
- enable_cookies_action: Aktiver informasjonskapsler
12
- top_level_interaction_heading: Nettleseren din må autentisere %{app}
13
- top_level_interaction_body: Nettleseren din krever apper som %{app} for å spørre
14
- deg om tilgang til informasjonskapsler før Shopify kan åpne den for deg.
15
- top_level_interaction_action: Fortsett
16
- request_storage_access_heading: "%{app} må ha tilgang til informasjonskapsler"
17
- request_storage_access_body: Informasjonskapsler lar appen autentisere deg ved å
18
- midlertidig lagre personopplysningene dine. Klikk på Fortsett og gi informasjonskapsler
19
- tillatelse til å bruke appen.
20
- request_storage_access_footer: Informasjonskapslene går ut etter 30 dager.
21
- request_storage_access_action: Fortsett
@@ -3,19 +3,3 @@ nl:
3
3
  logged_out: Je bent afgemeld
4
4
  could_not_log_in: Kon niet inloggen bij Shopify-winkel
5
5
  invalid_shop_url: Ongeldig winkeldomein
6
- enable_cookies_heading: Schakel cookies in van %{app}
7
- enable_cookies_body: Je moet cookies in deze browser handmatig inschakelen om %{app}
8
- binnen Shopify te gebruiken.
9
- enable_cookies_footer: Met cookies kan de app je verifiëren door je voorkeuren en
10
- persoonlijke informatie tijdelijk op te slaan. Ze vervallen na 30 dagen.
11
- enable_cookies_action: Schakel cookies in
12
- top_level_interaction_heading: Je browser moet %{app} verifiëren
13
- top_level_interaction_body: Je browser heeft apps nodig zoals %{app} om je toegang
14
- te vragen tot cookies voordat Shopify het voor je kan openen.
15
- top_level_interaction_action: Doorgaan
16
- request_storage_access_heading: "%{app} heeft toegang tot cookies nodig"
17
- request_storage_access_body: Hiermee kan de app je verifiëren door je persoonlijke
18
- gegevens tijdelijk op te slaan. Klik op Doorgaan en sta cookies toe om de app
19
- te gebruiken.
20
- request_storage_access_footer: Cookies verlopen na 30 dagen.
21
- request_storage_access_action: Doorgaan
@@ -3,19 +3,3 @@ pl:
3
3
  logged_out: Pomyślne wylogowanie
4
4
  could_not_log_in: Nie można zalogować się do sklepu Shopify
5
5
  invalid_shop_url: Nieprawidłowa domena sklepu
6
- enable_cookies_heading: Włącz korzystanie z plików cookie z %{app}
7
- enable_cookies_body: Aby móc korzystać z %{app} w Shopify, musisz ręcznie włączyć
8
- korzystanie z plików cookie w tej przeglądarce.
9
- enable_cookies_footer: Pliki cookie umożliwiają uwierzytelnianie aplikacji przez
10
- tymczasowe przechowywanie preferencji i danych osobowych. Wygasają one po 30 dniach.
11
- enable_cookies_action: Włącz korzystanie z plików cookie
12
- top_level_interaction_heading: Twoja przeglądarka wymaga uwierzytelnienia %{app}
13
- top_level_interaction_body: Twoja przeglądarka wymaga takich aplikacji jak %{app},
14
- aby poprosić o dostęp do plików cookie, zanim Shopify będzie mógł ją otworzyć.
15
- top_level_interaction_action: Kontynuuj
16
- request_storage_access_heading: "%{app} potrzebuje dostępu do plików cookie"
17
- request_storage_access_body: Dzięki temu aplikacja może Cię uwierzytelniać, tymczasowo,
18
- przechowując Twoje dane osobowe. Kliknij przycisk Kontynuuj i zezwalaj na pliki
19
- cookie, aby korzystać z aplikacji.
20
- request_storage_access_footer: Pliki cookie wygasają po 30 dniach.
21
- request_storage_access_action: Kontynuuj