duodealer_app 1.0.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 (212) hide show
  1. checksums.yaml +7 -0
  2. data/.!66854!duodealer_app.gemspec +0 -0
  3. data/.babelrc +5 -0
  4. data/.gitignore +16 -0
  5. data/.nvmrc +1 -0
  6. data/.rubocop.yml +263 -0
  7. data/.ruby-version +1 -0
  8. data/.travis.yml +27 -0
  9. data/Gemfile +8 -0
  10. data/LICENSE +19 -0
  11. data/README.md +553 -0
  12. data/Rakefile +6 -0
  13. data/app/assets/images/storage_access.svg +2 -0
  14. data/app/assets/javascripts/duodealer_app/enable_cookies.js +3 -0
  15. data/app/assets/javascripts/duodealer_app/itp_helper.js +40 -0
  16. data/app/assets/javascripts/duodealer_app/partition_cookies.js +8 -0
  17. data/app/assets/javascripts/duodealer_app/redirect.js +33 -0
  18. data/app/assets/javascripts/duodealer_app/request_storage_access.js +3 -0
  19. data/app/assets/javascripts/duodealer_app/storage_access.js +153 -0
  20. data/app/assets/javascripts/duodealer_app/storage_access_redirect.js +17 -0
  21. data/app/assets/javascripts/duodealer_app/top_level.js +2 -0
  22. data/app/assets/javascripts/duodealer_app/top_level_interaction.js +11 -0
  23. data/app/controllers/concerns/duodealer_app/authenticated.rb +15 -0
  24. data/app/controllers/concerns/duodealer_app/authenticated.rb-e +15 -0
  25. data/app/controllers/duodealer_app/authenticated_controller.rb +9 -0
  26. data/app/controllers/duodealer_app/authenticated_controller.rb-e +9 -0
  27. data/app/controllers/duodealer_app/callback_controller.rb +104 -0
  28. data/app/controllers/duodealer_app/callback_controller.rb-e +104 -0
  29. data/app/controllers/duodealer_app/extension_verification_controller.rb +19 -0
  30. data/app/controllers/duodealer_app/extension_verification_controller.rb-e +19 -0
  31. data/app/controllers/duodealer_app/sessions_controller.rb +159 -0
  32. data/app/controllers/duodealer_app/sessions_controller.rb-e +159 -0
  33. data/app/controllers/duodealer_app/webhooks_controller.rb +37 -0
  34. data/app/controllers/duodealer_app/webhooks_controller.rb-e +37 -0
  35. data/app/views/duodealer_app/partials/_button_styles.html.erb +104 -0
  36. data/app/views/duodealer_app/partials/_button_styles.html.erb-e +104 -0
  37. data/app/views/duodealer_app/partials/_card_styles.html.erb +33 -0
  38. data/app/views/duodealer_app/partials/_card_styles.html.erb-e +33 -0
  39. data/app/views/duodealer_app/partials/_empty_state_styles.html.erb +129 -0
  40. data/app/views/duodealer_app/partials/_empty_state_styles.html.erb-e +129 -0
  41. data/app/views/duodealer_app/partials/_layout_styles.html.erb +167 -0
  42. data/app/views/duodealer_app/partials/_layout_styles.html.erb-e +167 -0
  43. data/app/views/duodealer_app/partials/_typography_styles.html.erb +35 -0
  44. data/app/views/duodealer_app/partials/_typography_styles.html.erb-e +35 -0
  45. data/app/views/duodealer_app/sessions/enable_cookies.html.erb +75 -0
  46. data/app/views/duodealer_app/sessions/enable_cookies.html.erb-e +75 -0
  47. data/app/views/duodealer_app/sessions/new.html.erb +123 -0
  48. data/app/views/duodealer_app/sessions/new.html.erb-e +123 -0
  49. data/app/views/duodealer_app/sessions/request_storage_access.html.erb +68 -0
  50. data/app/views/duodealer_app/sessions/request_storage_access.html.erb-e +68 -0
  51. data/app/views/duodealer_app/sessions/top_level_interaction.html.erb +64 -0
  52. data/app/views/duodealer_app/sessions/top_level_interaction.html.erb-e +64 -0
  53. data/app/views/duodealer_app/shared/redirect.html.erb +23 -0
  54. data/app/views/duodealer_app/shared/redirect.html.erb-e +23 -0
  55. data/config/locales/cs.yml +23 -0
  56. data/config/locales/da.yml +20 -0
  57. data/config/locales/de.yml +22 -0
  58. data/config/locales/en.yml +15 -0
  59. data/config/locales/es.yml +22 -0
  60. data/config/locales/fi.yml +20 -0
  61. data/config/locales/fr.yml +23 -0
  62. data/config/locales/hi.yml +23 -0
  63. data/config/locales/it.yml +21 -0
  64. data/config/locales/ja.yml +17 -0
  65. data/config/locales/ko.yml +19 -0
  66. data/config/locales/ms.yml +22 -0
  67. data/config/locales/nb.yml +21 -0
  68. data/config/locales/nl.yml +21 -0
  69. data/config/locales/pl.yml +21 -0
  70. data/config/locales/pt-BR.yml +21 -0
  71. data/config/locales/pt-PT.yml +22 -0
  72. data/config/locales/sv.yml +21 -0
  73. data/config/locales/th.yml +20 -0
  74. data/config/locales/tr.yml +22 -0
  75. data/config/locales/zh-CN.yml +16 -0
  76. data/config/locales/zh-TW.yml +16 -0
  77. data/config/routes.rb +22 -0
  78. data/docs/.!20385!test-your-app.png +0 -0
  79. data/docs/.!20388!install-on-dev-shop.png +0 -0
  80. data/docs/.!62511!test-your-app.png +0 -0
  81. data/docs/.!62512!install-on-dev-shop.png +0 -0
  82. data/docs/.!62763!test-your-app.png +0 -0
  83. data/docs/.!62765!install-on-dev-shop.png +0 -0
  84. data/docs/.!63018!test-your-app.png +0 -0
  85. data/docs/.!63020!install-on-dev-shop.png +0 -0
  86. data/docs/.!63289!test-your-app.png +0 -0
  87. data/docs/.!63291!install-on-dev-shop.png +0 -0
  88. data/docs/.!63562!test-your-app.png +0 -0
  89. data/docs/.!63564!install-on-dev-shop.png +0 -0
  90. data/docs/.!63872!test-your-app.png +0 -0
  91. data/docs/.!63874!install-on-dev-shop.png +0 -0
  92. data/docs/.!64151!test-your-app.png +0 -0
  93. data/docs/.!64153!install-on-dev-shop.png +0 -0
  94. data/docs/.!64428!test-your-app.png +0 -0
  95. data/docs/.!64431!install-on-dev-shop.png +0 -0
  96. data/docs/.!64737!test-your-app.png +0 -0
  97. data/docs/.!64740!install-on-dev-shop.png +0 -0
  98. data/docs/.!65025!test-your-app.png +0 -0
  99. data/docs/.!65028!install-on-dev-shop.png +0 -0
  100. data/docs/.!65324!test-your-app.png +0 -0
  101. data/docs/.!65327!install-on-dev-shop.png +0 -0
  102. data/docs/.!65626!test-your-app.png +0 -0
  103. data/docs/.!65629!install-on-dev-shop.png +0 -0
  104. data/docs/.!65942!test-your-app.png +0 -0
  105. data/docs/.!65945!install-on-dev-shop.png +0 -0
  106. data/docs/.!66760!test-your-app.png +0 -0
  107. data/docs/.!66763!install-on-dev-shop.png +0 -0
  108. data/docs/.!67028!test-your-app.png +0 -0
  109. data/docs/.!67031!install-on-dev-shop.png +0 -0
  110. data/docs/.!67657!test-your-app.png +0 -0
  111. data/docs/.!67660!install-on-dev-shop.png +0 -0
  112. data/docs/.!68031!test-your-app.png +0 -0
  113. data/docs/.!68034!install-on-dev-shop.png +0 -0
  114. data/docs/.!68363!test-your-app.png +0 -0
  115. data/docs/.!68366!install-on-dev-shop.png +0 -0
  116. data/docs/Quickstart.md +103 -0
  117. data/docs/Releasing.md +17 -0
  118. data/docs/Troubleshooting.md +16 -0
  119. data/docs/install-on-dev-shop.png +0 -0
  120. data/docs/test-your-app.png +0 -0
  121. data/duodealer_app.gemspec +34 -0
  122. data/images/.!20334!app-proxy-screenshot.png +0 -0
  123. data/images/.!62504!app-proxy-screenshot.png +0 -0
  124. data/images/.!62754!app-proxy-screenshot.png +0 -0
  125. data/images/.!63008!app-proxy-screenshot.png +0 -0
  126. data/images/.!63277!app-proxy-screenshot.png +0 -0
  127. data/images/.!63548!app-proxy-screenshot.png +0 -0
  128. data/images/.!63855!app-proxy-screenshot.png +0 -0
  129. data/images/.!64132!app-proxy-screenshot.png +0 -0
  130. data/images/.!64407!app-proxy-screenshot.png +0 -0
  131. data/images/.!64714!app-proxy-screenshot.png +0 -0
  132. data/images/.!65000!app-proxy-screenshot.png +0 -0
  133. data/images/.!65296!app-proxy-screenshot.png +0 -0
  134. data/images/.!65594!app-proxy-screenshot.png +0 -0
  135. data/images/.!65908!app-proxy-screenshot.png +0 -0
  136. data/images/.!66724!app-proxy-screenshot.png +0 -0
  137. data/images/.!66989!app-proxy-screenshot.png +0 -0
  138. data/images/.!67614!app-proxy-screenshot.png +0 -0
  139. data/images/.!67986!app-proxy-screenshot.png +0 -0
  140. data/images/.!68314!app-proxy-screenshot.png +0 -0
  141. data/images/app-proxy-screenshot.png +0 -0
  142. data/karma.conf.js +44 -0
  143. data/lib/duodealer_app.rb +54 -0
  144. data/lib/duodealer_app/configuration.rb +85 -0
  145. data/lib/duodealer_app/controller_concerns/app_proxy_verification.rb +39 -0
  146. data/lib/duodealer_app/controller_concerns/embedded_app.rb +20 -0
  147. data/lib/duodealer_app/controller_concerns/itp.rb +44 -0
  148. data/lib/duodealer_app/controller_concerns/localization.rb +23 -0
  149. data/lib/duodealer_app/controller_concerns/login_protection.rb +180 -0
  150. data/lib/duodealer_app/controller_concerns/webhook_verification.rb +39 -0
  151. data/lib/duodealer_app/engine.rb +22 -0
  152. data/lib/duodealer_app/jobs/scripttags_manager_job.rb +17 -0
  153. data/lib/duodealer_app/jobs/webhooks_manager_job.rb +17 -0
  154. data/lib/duodealer_app/managers/scripttags_manager.rb +78 -0
  155. data/lib/duodealer_app/managers/webhooks_manager.rb +62 -0
  156. data/lib/duodealer_app/middleware/same_site_cookie_middleware.rb +69 -0
  157. data/lib/duodealer_app/session/in_memory_session_store.rb +29 -0
  158. data/lib/duodealer_app/session/session_repository.rb +33 -0
  159. data/lib/duodealer_app/session/session_storage.rb +31 -0
  160. data/lib/duodealer_app/session/storage_strategies/shop_storage_strategy.rb +25 -0
  161. data/lib/duodealer_app/session/storage_strategies/user_storage_strategy.rb +26 -0
  162. data/lib/duodealer_app/utils.rb +24 -0
  163. data/lib/duodealer_app/version.rb +5 -0
  164. data/lib/generators/duodealer_app/add_after_authenticate_job/add_after_authenticate_job_generator.rb +46 -0
  165. data/lib/generators/duodealer_app/add_after_authenticate_job/templates/after_authenticate_job.rb +10 -0
  166. data/lib/generators/duodealer_app/add_marketing_activity_extension/add_marketing_activity_extension_generator.rb +40 -0
  167. data/lib/generators/duodealer_app/add_marketing_activity_extension/templates/marketing_activities_controller.rb +62 -0
  168. data/lib/generators/duodealer_app/add_webhook/add_webhook_generator.rb +69 -0
  169. data/lib/generators/duodealer_app/add_webhook/templates/webhook_job.rb +8 -0
  170. data/lib/generators/duodealer_app/app_proxy_controller/app_proxy_controller_generator.rb +27 -0
  171. data/lib/generators/duodealer_app/app_proxy_controller/templates/app_proxy_controller.rb +9 -0
  172. data/lib/generators/duodealer_app/app_proxy_controller/templates/app_proxy_route.rb +10 -0
  173. data/lib/generators/duodealer_app/app_proxy_controller/templates/index.html.erb +19 -0
  174. data/lib/generators/duodealer_app/authenticated_controller/authenticated_controller_generator.rb +15 -0
  175. data/lib/generators/duodealer_app/authenticated_controller/templates/authenticated_controller.rb +5 -0
  176. data/lib/generators/duodealer_app/controllers/controllers_generator.rb +30 -0
  177. data/lib/generators/duodealer_app/duodealer_app_generator.rb +19 -0
  178. data/lib/generators/duodealer_app/home_controller/home_controller_generator.rb +27 -0
  179. data/lib/generators/duodealer_app/home_controller/templates/home_controller.rb +8 -0
  180. data/lib/generators/duodealer_app/home_controller/templates/index.html.erb +21 -0
  181. data/lib/generators/duodealer_app/install/install_generator.rb +83 -0
  182. data/lib/generators/duodealer_app/install/templates/_flash_messages.html.erb +3 -0
  183. data/lib/generators/duodealer_app/install/templates/duodealer_app.js +15 -0
  184. data/lib/generators/duodealer_app/install/templates/duodealer_app.rb +15 -0
  185. data/lib/generators/duodealer_app/install/templates/duodealer_app_index.js +2 -0
  186. data/lib/generators/duodealer_app/install/templates/duodealer_provider.rb +20 -0
  187. data/lib/generators/duodealer_app/install/templates/embedded_app.html.erb +41 -0
  188. data/lib/generators/duodealer_app/install/templates/flash_messages.js +26 -0
  189. data/lib/generators/duodealer_app/install/templates/omniauth.rb +2 -0
  190. data/lib/generators/duodealer_app/install/templates/session_store.rb +4 -0
  191. data/lib/generators/duodealer_app/install/templates/user_agent.rb +5 -0
  192. data/lib/generators/duodealer_app/rotate_duodealer_token_job/rotate_duodealer_token_job_generator.rb +16 -0
  193. data/lib/generators/duodealer_app/rotate_duodealer_token_job/templates/rotate_duodealer_token.rake +17 -0
  194. data/lib/generators/duodealer_app/rotate_duodealer_token_job/templates/rotate_duodealer_token_job.rb +42 -0
  195. data/lib/generators/duodealer_app/routes/routes_generator.rb +32 -0
  196. data/lib/generators/duodealer_app/routes/templates/routes.rb +11 -0
  197. data/lib/generators/duodealer_app/shop_model/shop_model_generator.rb +39 -0
  198. data/lib/generators/duodealer_app/shop_model/templates/db/migrate/create_shops.erb +15 -0
  199. data/lib/generators/duodealer_app/shop_model/templates/shop.rb +7 -0
  200. data/lib/generators/duodealer_app/shop_model/templates/shops.yml +3 -0
  201. data/lib/generators/duodealer_app/user_model/templates/db/migrate/create_users.erb +16 -0
  202. data/lib/generators/duodealer_app/user_model/templates/user.rb +7 -0
  203. data/lib/generators/duodealer_app/user_model/templates/users.yml +4 -0
  204. data/lib/generators/duodealer_app/user_model/user_model_generator.rb +39 -0
  205. data/lib/generators/duodealer_app/views/views_generator.rb +30 -0
  206. data/package-lock.json +7224 -0
  207. data/package.json +28 -0
  208. data/shipit.rubygems.yml +4 -0
  209. data/translation.yml +7 -0
  210. data/webpack.config.js +24 -0
  211. data/yarn.lock +5263 -0
  212. metadata +447 -0
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module DuodealerApp
6
+ module Generators
7
+ class AddWebhookGenerator < Rails::Generators::Base
8
+ source_root File.expand_path("../templates", __FILE__)
9
+ class_option :topic, type: :string, aliases: "-t", required: true
10
+ class_option :address, type: :string, aliases: "-a", required: true
11
+
12
+ hook_for :test_framework, as: :job, in: :rails do |instance, generator|
13
+ instance.invoke generator, [ instance.send(:job_file_name) ]
14
+ end
15
+
16
+ def init_webhook_config
17
+ initializer = load_initializer
18
+ return if initializer.include?("config.webhooks")
19
+
20
+ inject_into_file(
21
+ "config/initializers/duodealer_app.rb",
22
+ " config.webhooks = [\n ]\n",
23
+ before: "end"
24
+ )
25
+ end
26
+
27
+ def inject_webhook_to_duodealer_app_initializer
28
+ inject_into_file(
29
+ "config/initializers/duodealer_app.rb",
30
+ webhook_config,
31
+ after: "config.webhooks = ["
32
+ )
33
+
34
+ initializer = load_initializer
35
+
36
+ unless initializer.include?(webhook_config)
37
+ shell.say "Error adding webhook to config. Add this line manually: #{webhook_config}", :red
38
+ end
39
+ end
40
+
41
+ def add_webhook_job
42
+ @job_file_name = job_file_name + "_job"
43
+ @job_class_name = @job_file_name.classify
44
+ template "webhook_job.rb", "app/jobs/#{@job_file_name}.rb"
45
+ end
46
+
47
+ private
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/duodealer_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,8 @@
1
+ class <%= @job_class_name %> < ActiveJob::Base
2
+ def perform(shop_domain:, webhook:)
3
+ shop = Shop.find_by(duodealer_domain: shop_domain)
4
+
5
+ shop.with_duodealer_session do
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module DuodealerApp
6
+ module Generators
7
+ class AppProxyControllerGenerator < Rails::Generators::Base
8
+ source_root File.expand_path("../templates", __FILE__)
9
+
10
+ def create_app_proxy_controller
11
+ template "app_proxy_controller.rb", "app/controllers/app_proxy_controller.rb"
12
+ end
13
+
14
+ def create_app_proxy_index_view
15
+ copy_file "index.html.erb", "app/views/app_proxy/index.html.erb"
16
+ end
17
+
18
+ def add_app_proxy_route
19
+ inject_into_file(
20
+ "config/routes.rb",
21
+ File.read(File.expand_path(find_in_source_paths("app_proxy_route.rb"))),
22
+ after: "mount DuodealerApp::Engine, at: '/'\n"
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AppProxyController < ApplicationController
4
+ include DuodealerApp::AppProxyVerification
5
+
6
+ def index
7
+ render layout: false, content_type: "application/liquid"
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+
2
+ namespace :app_proxy do
3
+ root action: 'index'
4
+ # simple routes without a specified controller will go to AppProxyController
5
+
6
+ # more complex routes will go to controllers in the AppProxy namespace
7
+ # resources :reviews
8
+ # GET /app_proxy/reviews will now be routed to
9
+ # AppProxy::ReviewsController#index, for example
10
+ end
@@ -0,0 +1,19 @@
1
+ <h2>App Proxy Page</h2>
2
+
3
+ <p>Congratulations! You have successfully configured App Proxy for your duodealer application.</p>
4
+ <p>Any valid liquid code included in this page will be parsed and rendered by Duo Dealer.</p>
5
+
6
+ <br>
7
+
8
+ <pre>
9
+ Your Shop Details:
10
+ <hr>
11
+ Shop Name : {{ shop.name }}
12
+ duodealer 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 DuodealerApp
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 DuodealerApp::Authenticated
5
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module DuodealerApp
6
+ module Generators
7
+ class ControllersGenerator < Rails::Generators::Base
8
+ source_root File.expand_path("../../../../..", __FILE__)
9
+
10
+ def create_controllers
11
+ controllers.each do |controller|
12
+ copy_file controller
13
+ end
14
+ end
15
+
16
+ private
17
+ def controllers
18
+ files_within_root(".", "app/controllers/duodealer_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,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DuodealerApp
4
+ module Generators
5
+ class DuodealerAppGenerator < Rails::Generators::Base
6
+ def initialize(args, *options)
7
+ @opts = options.first
8
+ super(args, *options)
9
+ end
10
+
11
+ def run_all_generators
12
+ generate "duodealer_app:install #{@opts.join(' ')}"
13
+ generate "duodealer_app:shop_model"
14
+ generate("duodealer_app:authenticated_controller")
15
+ generate "duodealer_app:home_controller"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module DuodealerApp
6
+ module Generators
7
+ class HomeControllerGenerator < Rails::Generators::Base
8
+ source_root File.expand_path("../templates", __FILE__)
9
+
10
+ def create_home_controller
11
+ template "home_controller.rb", "app/controllers/home_controller.rb"
12
+ end
13
+
14
+ def create_home_index_view
15
+ copy_file "index.html.erb", "app/views/home/index.html.erb"
16
+ end
17
+
18
+ def add_home_index_route
19
+ route "root :to => 'home#index'"
20
+ end
21
+
22
+ def embedded_app?
23
+ DuodealerApp.configuration.embedded_app?
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HomeController < AuthenticatedController
4
+ def index
5
+ @products = DuodealerAPI::Product.find(:all, params: { limit: 10 })
6
+ @webhooks = DuodealerAPI::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://#{@shop_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 DuodealerApp initializer if you need webhooks</p>
21
+ <% end %>
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module DuodealerApp
6
+ module Generators
7
+ class InstallGenerator < Rails::Generators::Base
8
+ include Rails::Generators::Migration
9
+ source_root File.expand_path("../templates", __FILE__)
10
+
11
+ class_option :application_name, type: :array, default: ["My", "DuoDealer", "App"]
12
+ class_option :scope, type: :array, default: ["read_products"]
13
+ class_option :embedded, type: :string, default: "true"
14
+ class_option :api_version, type: :string, default: nil
15
+
16
+ def create_duodealer_app_initializer
17
+ @application_name = format_array_argument(options["application_name"])
18
+ @scope = format_array_argument(options["scope"])
19
+ @api_version = options["api_version"] || DuodealerAPI::Meta.admin_versions.find(&:latest_supported).handle
20
+
21
+ template "duodealer_app.rb", "config/initializers/duodealer_app.rb"
22
+ end
23
+
24
+ def create_session_store_initializer
25
+ copy_file("session_store.rb", "config/initializers/session_store.rb")
26
+ end
27
+
28
+ def create_and_inject_into_omniauth_initializer
29
+ unless File.exist? "config/initializers/omniauth.rb"
30
+ copy_file "omniauth.rb", "config/initializers/omniauth.rb"
31
+ end
32
+
33
+ inject_into_file(
34
+ "config/initializers/omniauth.rb",
35
+ File.read(File.expand_path(find_in_source_paths("duodealer_provider.rb"))),
36
+ after: "Rails.application.config.middleware.use OmniAuth::Builder do\n"
37
+ )
38
+ end
39
+
40
+ def create_embedded_app_layout
41
+ return unless embedded_app?
42
+
43
+ copy_file "embedded_app.html.erb", "app/views/layouts/embedded_app.html.erb"
44
+ copy_file "_flash_messages.html.erb", "app/views/layouts/_flash_messages.html.erb"
45
+
46
+ if DuodealerApp.use_webpacker?
47
+ copy_file("duodealer_app.js", "app/javascript/duodealer_app/duodealer_app.js")
48
+ copy_file("flash_messages.js", "app/javascript/duodealer_app/flash_messages.js")
49
+ copy_file("duodealer_app_index.js", "app/javascript/duodealer_app/index.js")
50
+ append_to_file("app/javascript/packs/application.js", 'require("duodealer_app")')
51
+ else
52
+ copy_file("duodealer_app.js", "app/assets/javascripts/duodealer_app.js")
53
+ copy_file("flash_messages.js", "app/assets/javascripts/flash_messages.js")
54
+ end
55
+ end
56
+
57
+ def create_user_agent_initializer
58
+ template "user_agent.rb", "config/initializers/user_agent.rb"
59
+ end
60
+
61
+ def mount_engine
62
+ route "mount DuodealerApp::Engine, at: '/'"
63
+ end
64
+
65
+ def insert_hosts_into_development_config
66
+ inject_into_file(
67
+ "config/environments/development.rb",
68
+ " config.hosts = (config.hosts rescue []) << /\\h+.ngrok.io/\n",
69
+ after: "Rails.application.configure do\n"
70
+ )
71
+ end
72
+
73
+ private
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: 'duodealer-app-flash', data: { flash: { notice: flash[:notice], error: flash[:error] } }) %>
3
+ <% end %>
@@ -0,0 +1,15 @@
1
+ document.addEventListener('DOMContentLoaded', () => {
2
+ var data = document.getElementById('duodealer-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
+ });
@@ -0,0 +1,15 @@
1
+ DuodealerApp.configure do |config|
2
+ config.application_name = "<%= @application_name %>"
3
+ config.api_key = ENV['DUODEALER_API_KEY']
4
+ config.secret = ENV['DUODEALER_API_SECRET']
5
+ config.old_secret = "<%= @old_secret %>"
6
+ config.scope = "<%= @scope %>" # Consult this page for more scope options:
7
+ # https://help.duodealer.com/en/api/getting-started/authentication/oauth/scopes
8
+ config.embedded_app = <%= embedded_app? %>
9
+ config.after_authenticate_job = false
10
+ config.api_version = "<%= @api_version %>"
11
+ config.session_repository = 'DuodealerApp::InMemorySessionStore'
12
+ end
13
+
14
+ # DuodealerApp::Utils.fetch_known_api_versions # Uncomment to fetch known api versions from duodealer servers on boot
15
+ # DuodealerAPI::ApiVersion.version_lookup_mode = :raise_on_unknown # Uncomment to raise an error if attempting to use an api version that was not previously known
@@ -0,0 +1,2 @@
1
+ require('./duodealer_app')
2
+ require('./flash_messages')
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ provider :duodealer,
4
+ DuodealerApp.configuration.api_key,
5
+ DuodealerApp.configuration.secret,
6
+ scope: DuodealerApp.configuration.scope,
7
+ per_user_permissions: DuodealerApp.configuration.per_user_tokens,
8
+ setup: lambda { |env|
9
+ strategy = env['omniauth.strategy']
10
+
11
+ duodealer_auth_params = strategy.session['duodealer.omniauth_params']&.with_indifferent_access
12
+ shop = if duodealer_auth_params.present?
13
+ "https://#{duodealer_auth_params[:shop]}"
14
+ else
15
+ ''
16
+ end
17
+
18
+ strategy.options[:client_options][:site] = shop
19
+ strategy.options[:old_client_secret] = DuodealerApp.configuration.old_secret
20
+ }
@@ -0,0 +1,41 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <% application_name = DuodealerApp.configuration.application_name %>
6
+ <title><%= application_name %></title>
7
+ <%= stylesheet_link_tag 'application' %>
8
+ <% if DuodealerApp.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/@duodealer/app-bridge"></script>
28
+
29
+ <%= content_tag(:div, nil, id: 'duodealer-app-init', data: {
30
+ api_key: DuodealerApp.configuration.api_key,
31
+ shop_origin: (@shop_session.domain if @shop_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>