shopify_app 13.5.0

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.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/.babelrc +5 -0
  3. data/.github/CODEOWNERS +1 -0
  4. data/.github/ISSUE_TEMPLATE.md +14 -0
  5. data/.github/PULL_REQUEST_TEMPLATE.md +6 -0
  6. data/.github/probots.yml +2 -0
  7. data/.github/workflows/rubocop.yml +28 -0
  8. data/.gitignore +16 -0
  9. data/.nvmrc +1 -0
  10. data/.rubocop.yml +17 -0
  11. data/.ruby-version +1 -0
  12. data/.travis.yml +28 -0
  13. data/CHANGELOG.md +505 -0
  14. data/Gemfile +11 -0
  15. data/LICENSE +19 -0
  16. data/README.md +620 -0
  17. data/Rakefile +7 -0
  18. data/SECURITY.md +59 -0
  19. data/app/assets/images/storage_access.svg +2 -0
  20. data/app/assets/javascripts/shopify_app/enable_cookies.js +3 -0
  21. data/app/assets/javascripts/shopify_app/itp_helper.js +40 -0
  22. data/app/assets/javascripts/shopify_app/partition_cookies.js +8 -0
  23. data/app/assets/javascripts/shopify_app/redirect.js +33 -0
  24. data/app/assets/javascripts/shopify_app/request_storage_access.js +3 -0
  25. data/app/assets/javascripts/shopify_app/storage_access.js +153 -0
  26. data/app/assets/javascripts/shopify_app/storage_access_redirect.js +17 -0
  27. data/app/assets/javascripts/shopify_app/top_level.js +2 -0
  28. data/app/assets/javascripts/shopify_app/top_level_interaction.js +11 -0
  29. data/app/controllers/concerns/shopify_app/authenticated.rb +16 -0
  30. data/app/controllers/concerns/shopify_app/require_known_shop.rb +39 -0
  31. data/app/controllers/shopify_app/authenticated_controller.rb +8 -0
  32. data/app/controllers/shopify_app/callback_controller.rb +140 -0
  33. data/app/controllers/shopify_app/extension_verification_controller.rb +15 -0
  34. data/app/controllers/shopify_app/sessions_controller.rb +184 -0
  35. data/app/controllers/shopify_app/webhooks_controller.rb +37 -0
  36. data/app/views/shopify_app/partials/_button_styles.html.erb +104 -0
  37. data/app/views/shopify_app/partials/_card_styles.html.erb +33 -0
  38. data/app/views/shopify_app/partials/_empty_state_styles.html.erb +129 -0
  39. data/app/views/shopify_app/partials/_layout_styles.html.erb +167 -0
  40. data/app/views/shopify_app/partials/_typography_styles.html.erb +35 -0
  41. data/app/views/shopify_app/sessions/enable_cookies.html.erb +75 -0
  42. data/app/views/shopify_app/sessions/new.html.erb +123 -0
  43. data/app/views/shopify_app/sessions/request_storage_access.html.erb +68 -0
  44. data/app/views/shopify_app/sessions/top_level_interaction.html.erb +64 -0
  45. data/app/views/shopify_app/shared/redirect.html.erb +23 -0
  46. data/config/locales/cs.yml +23 -0
  47. data/config/locales/da.yml +20 -0
  48. data/config/locales/de.yml +22 -0
  49. data/config/locales/en.yml +15 -0
  50. data/config/locales/es.yml +22 -0
  51. data/config/locales/fi.yml +20 -0
  52. data/config/locales/fr.yml +23 -0
  53. data/config/locales/hi.yml +23 -0
  54. data/config/locales/it.yml +21 -0
  55. data/config/locales/ja.yml +17 -0
  56. data/config/locales/ko.yml +19 -0
  57. data/config/locales/ms.yml +22 -0
  58. data/config/locales/nb.yml +21 -0
  59. data/config/locales/nl.yml +21 -0
  60. data/config/locales/pl.yml +21 -0
  61. data/config/locales/pt-BR.yml +21 -0
  62. data/config/locales/pt-PT.yml +22 -0
  63. data/config/locales/sv.yml +21 -0
  64. data/config/locales/th.yml +20 -0
  65. data/config/locales/tr.yml +22 -0
  66. data/config/locales/zh-CN.yml +16 -0
  67. data/config/locales/zh-TW.yml +16 -0
  68. data/config/routes.rb +23 -0
  69. data/docs/Quickstart.md +93 -0
  70. data/docs/Releasing.md +18 -0
  71. data/docs/Troubleshooting.md +16 -0
  72. data/docs/install-on-dev-shop.png +0 -0
  73. data/docs/test-your-app.png +0 -0
  74. data/images/app-proxy-screenshot.png +0 -0
  75. data/karma.conf.js +44 -0
  76. data/lib/generators/shopify_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +47 -0
  77. data/lib/generators/shopify_app/add_after_authenticate_job/templates/after_authenticate_job.rb +11 -0
  78. data/lib/generators/shopify_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +40 -0
  79. data/lib/generators/shopify_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +62 -0
  80. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +69 -0
  81. data/lib/generators/shopify_app/add_webhook/templates/webhook_job.rb.tt +13 -0
  82. data/lib/generators/shopify_app/app_proxy_controller/app_proxy_controller_generator.rb +26 -0
  83. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_controller.rb +8 -0
  84. data/lib/generators/shopify_app/app_proxy_controller/templates/app_proxy_route.rb +11 -0
  85. data/lib/generators/shopify_app/app_proxy_controller/templates/index.html.erb +19 -0
  86. data/lib/generators/shopify_app/authenticated_controller/authenticated_controller_generator.rb +15 -0
  87. data/lib/generators/shopify_app/authenticated_controller/templates/authenticated_controller.rb +5 -0
  88. data/lib/generators/shopify_app/controllers/controllers_generator.rb +30 -0
  89. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +26 -0
  90. data/lib/generators/shopify_app/home_controller/templates/home_controller.rb +8 -0
  91. data/lib/generators/shopify_app/home_controller/templates/index.html.erb +21 -0
  92. data/lib/generators/shopify_app/install/install_generator.rb +83 -0
  93. data/lib/generators/shopify_app/install/templates/_flash_messages.html.erb +3 -0
  94. data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +41 -0
  95. data/lib/generators/shopify_app/install/templates/flash_messages.js +24 -0
  96. data/lib/generators/shopify_app/install/templates/omniauth.rb +3 -0
  97. data/lib/generators/shopify_app/install/templates/session_store.rb +4 -0
  98. data/lib/generators/shopify_app/install/templates/shopify_app.js +15 -0
  99. data/lib/generators/shopify_app/install/templates/shopify_app.rb.tt +15 -0
  100. data/lib/generators/shopify_app/install/templates/shopify_app_index.js +2 -0
  101. data/lib/generators/shopify_app/install/templates/shopify_provider.rb +20 -0
  102. data/lib/generators/shopify_app/install/templates/user_agent.rb +6 -0
  103. data/lib/generators/shopify_app/rotate_shopify_token_job/rotate_shopify_token_job_generator.rb +16 -0
  104. data/lib/generators/shopify_app/rotate_shopify_token_job/templates/rotate_shopify_token.rake +17 -0
  105. data/lib/generators/shopify_app/rotate_shopify_token_job/templates/rotate_shopify_token_job.rb +42 -0
  106. data/lib/generators/shopify_app/routes/routes_generator.rb +32 -0
  107. data/lib/generators/shopify_app/routes/templates/routes.rb +12 -0
  108. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +43 -0
  109. data/lib/generators/shopify_app/shop_model/templates/db/migrate/create_shops.erb +15 -0
  110. data/lib/generators/shopify_app/shop_model/templates/shop.rb +8 -0
  111. data/lib/generators/shopify_app/shop_model/templates/shops.yml +3 -0
  112. data/lib/generators/shopify_app/shopify_app_generator.rb +18 -0
  113. data/lib/generators/shopify_app/user_model/templates/db/migrate/create_users.erb +16 -0
  114. data/lib/generators/shopify_app/user_model/templates/user.rb +8 -0
  115. data/lib/generators/shopify_app/user_model/templates/users.yml +4 -0
  116. data/lib/generators/shopify_app/user_model/user_model_generator.rb +43 -0
  117. data/lib/generators/shopify_app/views/views_generator.rb +30 -0
  118. data/lib/shopify_app.rb +61 -0
  119. data/lib/shopify_app/configuration.rb +94 -0
  120. data/lib/shopify_app/controller_concerns/app_proxy_verification.rb +38 -0
  121. data/lib/shopify_app/controller_concerns/csrf_protection.rb +15 -0
  122. data/lib/shopify_app/controller_concerns/embedded_app.rb +20 -0
  123. data/lib/shopify_app/controller_concerns/itp.rb +45 -0
  124. data/lib/shopify_app/controller_concerns/localization.rb +23 -0
  125. data/lib/shopify_app/controller_concerns/login_protection.rb +231 -0
  126. data/lib/shopify_app/controller_concerns/payload_verification.rb +24 -0
  127. data/lib/shopify_app/controller_concerns/webhook_verification.rb +23 -0
  128. data/lib/shopify_app/engine.rb +25 -0
  129. data/lib/shopify_app/jobs/scripttags_manager_job.rb +16 -0
  130. data/lib/shopify_app/jobs/webhooks_manager_job.rb +16 -0
  131. data/lib/shopify_app/managers/scripttags_manager.rb +78 -0
  132. data/lib/shopify_app/managers/webhooks_manager.rb +62 -0
  133. data/lib/shopify_app/middleware/jwt_middleware.rb +42 -0
  134. data/lib/shopify_app/middleware/same_site_cookie_middleware.rb +34 -0
  135. data/lib/shopify_app/session/in_memory_session_store.rb +31 -0
  136. data/lib/shopify_app/session/in_memory_shop_session_store.rb +14 -0
  137. data/lib/shopify_app/session/in_memory_user_session_store.rb +14 -0
  138. data/lib/shopify_app/session/jwt.rb +61 -0
  139. data/lib/shopify_app/session/null_user_session_store.rb +22 -0
  140. data/lib/shopify_app/session/session_repository.rb +56 -0
  141. data/lib/shopify_app/session/session_storage.rb +20 -0
  142. data/lib/shopify_app/session/shop_session_storage.rb +42 -0
  143. data/lib/shopify_app/session/user_session_storage.rb +42 -0
  144. data/lib/shopify_app/test_helpers/all.rb +2 -0
  145. data/lib/shopify_app/test_helpers/webhook_verification_helper.rb +17 -0
  146. data/lib/shopify_app/utils.rb +24 -0
  147. data/lib/shopify_app/version.rb +4 -0
  148. data/package-lock.json +7177 -0
  149. data/package.json +28 -0
  150. data/service.yml +7 -0
  151. data/shipit.rubygems.yml +4 -0
  152. data/shopify_app.gemspec +37 -0
  153. data/translation.yml +7 -0
  154. data/webpack.config.js +24 -0
  155. data/yarn.lock +5263 -0
  156. metadata +420 -0
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+ require 'rails/generators/base'
3
+
4
+ module ShopifyApp
5
+ module Generators
6
+ class AddWebhookGenerator < Rails::Generators::Base
7
+ source_root File.expand_path('../templates', __FILE__)
8
+ class_option :topic, type: :string, aliases: "-t", required: true
9
+ class_option :address, type: :string, aliases: "-a", required: true
10
+
11
+ hook_for :test_framework, as: :job, in: :rails do |instance, generator|
12
+ instance.invoke(generator, [instance.send(:job_file_name)])
13
+ end
14
+
15
+ def init_webhook_config
16
+ initializer = load_initializer
17
+ return if initializer.include?("config.webhooks")
18
+
19
+ inject_into_file(
20
+ 'config/initializers/shopify_app.rb',
21
+ " config.webhooks = [\n ]\n",
22
+ before: 'end'
23
+ )
24
+ end
25
+
26
+ def inject_webhook_to_shopify_app_initializer
27
+ inject_into_file(
28
+ 'config/initializers/shopify_app.rb',
29
+ webhook_config,
30
+ after: "config.webhooks = ["
31
+ )
32
+
33
+ initializer = load_initializer
34
+
35
+ unless initializer.include?(webhook_config)
36
+ shell.say("Error adding webhook to config. Add this line manually: #{webhook_config}", :red)
37
+ end
38
+ end
39
+
40
+ def add_webhook_job
41
+ @job_file_name = job_file_name + '_job'
42
+ @job_class_name = @job_file_name.classify
43
+ template('webhook_job.rb', "app/jobs/#{@job_file_name}.rb")
44
+ end
45
+
46
+ private
47
+
48
+ def job_file_name
49
+ address.split('/').last
50
+ end
51
+
52
+ def load_initializer
53
+ File.read(File.join(destination_root, 'config/initializers/shopify_app.rb'))
54
+ end
55
+
56
+ def webhook_config
57
+ "\n {topic: '#{topic}', address: '#{address}', format: 'json'},"
58
+ end
59
+
60
+ def topic
61
+ options['topic']
62
+ end
63
+
64
+ def address
65
+ options['address']
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,13 @@
1
+ class <%= @job_class_name %> < ActiveJob::Base
2
+ def perform(shop_domain:, webhook:)
3
+ shop = Shop.find_by(shopify_domain: shop_domain)
4
+
5
+ if shop.nil?
6
+ logger.error("#{self.class} failed: cannot find shop with domain '#{shop_domain}'")
7
+ return
8
+ end
9
+
10
+ shop.with_shopify_session do
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'rails/generators/base'
3
+
4
+ module ShopifyApp
5
+ module Generators
6
+ class AppProxyControllerGenerator < Rails::Generators::Base
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def create_app_proxy_controller
10
+ template('app_proxy_controller.rb', 'app/controllers/app_proxy_controller.rb')
11
+ end
12
+
13
+ def create_app_proxy_index_view
14
+ copy_file('index.html.erb', 'app/views/app_proxy/index.html.erb')
15
+ end
16
+
17
+ def add_app_proxy_route
18
+ inject_into_file(
19
+ 'config/routes.rb',
20
+ File.read(File.expand_path(find_in_source_paths('app_proxy_route.rb'))),
21
+ after: "mount ShopifyApp::Engine, at: '/'\n"
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ class AppProxyController < ApplicationController
3
+ include ShopifyApp::AppProxyVerification
4
+
5
+ def index
6
+ render(layout: false, content_type: 'application/liquid')
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :app_proxy do
4
+ root action: 'index'
5
+ # simple routes without a specified controller will go to AppProxyController
6
+
7
+ # more complex routes will go to controllers in the AppProxy namespace
8
+ # resources :reviews
9
+ # GET /app_proxy/reviews will now be routed to
10
+ # AppProxy::ReviewsController#index, for example
11
+ end
@@ -0,0 +1,19 @@
1
+ <h2>App Proxy Page</h2>
2
+
3
+ <p>Congratulations! You have successfully configured App Proxy for your shopify application.</p>
4
+ <p>Any valid liquid code included in this page will be parsed and rendered by Shopify.</p>
5
+
6
+ <br>
7
+
8
+ <pre>
9
+ Your Shop Details:
10
+ <hr>
11
+ Shop Name : {{ shop.name }}
12
+ myshopify name : {{ shop.permanent_domain }}
13
+ Primary Domain of Shop : {{ shop.domain }}
14
+ Shop URL : {{ shop.url }}
15
+ Shop Currency : {{ shop.currency }}
16
+ No. of products in this shop : {{ shop.products_count }}
17
+ <br>
18
+ <hr>
19
+ </pre>
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module ShopifyApp
6
+ module Generators
7
+ class AuthenticatedControllerGenerator < Rails::Generators::Base
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ def create_home_controller
11
+ template('authenticated_controller.rb', 'app/controllers/authenticated_controller.rb')
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AuthenticatedController < ApplicationController
4
+ include ShopifyApp::Authenticated
5
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ require 'rails/generators/base'
3
+
4
+ module ShopifyApp
5
+ module Generators
6
+ class ControllersGenerator < Rails::Generators::Base
7
+ source_root File.expand_path("../../../../..", __FILE__)
8
+
9
+ def create_controllers
10
+ controllers.each do |controller|
11
+ copy_file controller
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def controllers
18
+ files_within_root('.', 'app/controllers/shopify_app/*.*')
19
+ end
20
+
21
+ def files_within_root(prefix, glob)
22
+ root = "#{self.class.source_root}/#{prefix}"
23
+
24
+ Dir["#{root}/#{glob}"].sort.map do |full_path|
25
+ full_path.sub(root, '.').gsub('/./', '/')
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'rails/generators/base'
3
+
4
+ module ShopifyApp
5
+ module Generators
6
+ class HomeControllerGenerator < Rails::Generators::Base
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def create_home_controller
10
+ template('home_controller.rb', 'app/controllers/home_controller.rb')
11
+ end
12
+
13
+ def create_home_index_view
14
+ copy_file('index.html.erb', 'app/views/home/index.html.erb')
15
+ end
16
+
17
+ def add_home_index_route
18
+ route("root :to => 'home#index'")
19
+ end
20
+
21
+ def embedded_app?
22
+ ShopifyApp.configuration.embedded_app?
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HomeController < AuthenticatedController
4
+ def index
5
+ @products = ShopifyAPI::Product.find(:all, params: { limit: 10 })
6
+ @webhooks = ShopifyAPI::Webhook.find(:all)
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ <h2>Products</h2>
2
+
3
+ <ul>
4
+ <% @products.each do |product| %>
5
+ <li><%= link_to product.title, "https://#{@current_shopify_session.domain}/admin/products/#{product.id}", target: "_top" %></li>
6
+ <% end %>
7
+ </ul>
8
+
9
+ <hr>
10
+
11
+ <h2>Webhooks</h2>
12
+
13
+ <% if @webhooks.present? %>
14
+ <ul>
15
+ <% @webhooks.each do |webhook| %>
16
+ <li><%= webhook.topic %> : <%= webhook.address %></li>
17
+ <% end %>
18
+ </ul>
19
+ <% else %>
20
+ <p>This app has not created any webhooks for this Shop. Add webhooks to your ShopifyApp initializer if you need webhooks</p>
21
+ <% end %>
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+ require 'rails/generators/base'
3
+
4
+ module ShopifyApp
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ class_option :application_name, type: :array, default: ['My', 'Shopify', 'App']
11
+ class_option :scope, type: :array, default: ['read_products']
12
+ class_option :embedded, type: :string, default: 'true'
13
+ class_option :api_version, type: :string, default: nil
14
+
15
+ def create_shopify_app_initializer
16
+ @application_name = format_array_argument(options['application_name'])
17
+ @scope = format_array_argument(options['scope'])
18
+ @api_version = options['api_version'] || ShopifyAPI::Meta.admin_versions.find(&:latest_supported).handle
19
+
20
+ template('shopify_app.rb', 'config/initializers/shopify_app.rb')
21
+ end
22
+
23
+ def create_session_store_initializer
24
+ copy_file('session_store.rb', 'config/initializers/session_store.rb')
25
+ end
26
+
27
+ def create_and_inject_into_omniauth_initializer
28
+ unless File.exist?("config/initializers/omniauth.rb")
29
+ copy_file('omniauth.rb', 'config/initializers/omniauth.rb')
30
+ end
31
+
32
+ inject_into_file(
33
+ 'config/initializers/omniauth.rb',
34
+ File.read(File.expand_path(find_in_source_paths('shopify_provider.rb'))),
35
+ after: "Rails.application.config.middleware.use(OmniAuth::Builder) do\n"
36
+ )
37
+ end
38
+
39
+ def create_embedded_app_layout
40
+ return unless embedded_app?
41
+
42
+ copy_file('embedded_app.html.erb', 'app/views/layouts/embedded_app.html.erb')
43
+ copy_file('_flash_messages.html.erb', 'app/views/layouts/_flash_messages.html.erb')
44
+
45
+ if ShopifyApp.use_webpacker?
46
+ copy_file('shopify_app.js', 'app/javascript/shopify_app/shopify_app.js')
47
+ copy_file('flash_messages.js', 'app/javascript/shopify_app/flash_messages.js')
48
+ copy_file('shopify_app_index.js', 'app/javascript/shopify_app/index.js')
49
+ append_to_file('app/javascript/packs/application.js', "require(\"shopify_app\")\n")
50
+ else
51
+ copy_file('shopify_app.js', 'app/assets/javascripts/shopify_app.js')
52
+ copy_file('flash_messages.js', 'app/assets/javascripts/flash_messages.js')
53
+ end
54
+ end
55
+
56
+ def create_user_agent_initializer
57
+ template('user_agent.rb', 'config/initializers/user_agent.rb')
58
+ end
59
+
60
+ def mount_engine
61
+ route("mount ShopifyApp::Engine, at: '/'")
62
+ end
63
+
64
+ def insert_hosts_into_development_config
65
+ inject_into_file(
66
+ 'config/environments/development.rb',
67
+ " config.hosts = (config.hosts rescue []) << /\\h+.ngrok.io/\n",
68
+ after: "Rails.application.configure do\n"
69
+ )
70
+ end
71
+
72
+ private
73
+
74
+ def embedded_app?
75
+ options['embedded'] == 'true'
76
+ end
77
+
78
+ def format_array_argument(array)
79
+ array.join(' ').tr('"', '')
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,3 @@
1
+ <% content_for :javascript do %>
2
+ <%= content_tag(:div, nil, id: 'shopify-app-flash', data: { flash: { notice: flash[:notice], error: flash[:error] } }) %>
3
+ <% end %>
@@ -0,0 +1,41 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <% application_name = ShopifyApp.configuration.application_name %>
6
+ <title><%= application_name %></title>
7
+ <%= stylesheet_link_tag 'application' %>
8
+ <% if ShopifyApp.use_webpacker? %>
9
+ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
10
+ <% else %>
11
+ <%= javascript_include_tag 'application', "data-turbolinks-track" => true %>
12
+ <% end %>
13
+ <%= csrf_meta_tags %>
14
+ </head>
15
+
16
+ <body>
17
+ <div class="app-wrapper">
18
+ <div class="app-content">
19
+ <main role="main">
20
+ <%= yield %>
21
+ </main>
22
+ </div>
23
+ </div>
24
+
25
+ <%= render 'layouts/flash_messages' %>
26
+
27
+ <script src="https://unpkg.com/@shopify/app-bridge"></script>
28
+
29
+ <%= content_tag(:div, nil, id: 'shopify-app-init', data: {
30
+ api_key: ShopifyApp.configuration.api_key,
31
+ shop_origin: (@current_shopify_session.domain if @current_shopify_session),
32
+ debug: Rails.env.development?
33
+ } ) %>
34
+
35
+ <% if content_for?(:javascript) %>
36
+ <div id="ContentForJavascript" data-turbolinks-temporary>
37
+ <%= yield :javascript %>
38
+ </div>
39
+ <% end %>
40
+ </body>
41
+ </html>
@@ -0,0 +1,24 @@
1
+ var eventName = typeof(Turbolinks) !== 'undefined' ? 'turbolinks:load' : 'DOMContentLoaded';
2
+
3
+ if (!document.documentElement.hasAttribute("data-turbolinks-preview")) {
4
+ document.addEventListener(eventName, function flash() {
5
+ var flashData = JSON.parse(document.getElementById('shopify-app-flash').dataset.flash);
6
+
7
+ var Toast = window['app-bridge'].actions.Toast;
8
+
9
+ if (flashData.notice) {
10
+ Toast.create(app, {
11
+ message: flashData.notice,
12
+ duration: 5000,
13
+ }).dispatch(Toast.Action.SHOW);
14
+ }
15
+
16
+ if (flashData.error) {
17
+ Toast.create(app, {
18
+ message: flashData.error,
19
+ duration: 5000,
20
+ isError: true,
21
+ }).dispatch(Toast.Action.SHOW);
22
+ }
23
+ });
24
+ }
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+ Rails.application.config.middleware.use(OmniAuth::Builder) do
3
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ # Be sure to restart your server when you modify this file.
3
+
4
+ Rails.application.config.session_store(:cookie_store, key: '_example_session', expire_after: 14.days)
@@ -0,0 +1,15 @@
1
+ document.addEventListener('DOMContentLoaded', () => {
2
+ var data = document.getElementById('shopify-app-init').dataset;
3
+ var AppBridge = window['app-bridge'];
4
+ var createApp = AppBridge.default;
5
+ window.app = createApp({
6
+ apiKey: data.apiKey,
7
+ shopOrigin: data.shopOrigin,
8
+ });
9
+
10
+ var actions = AppBridge.actions;
11
+ var TitleBar = actions.TitleBar;
12
+ TitleBar.create(app, {
13
+ title: data.page,
14
+ });
15
+ });