shopify_app 7.4.0 → 8.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/README.md +15 -15
  4. data/app/controllers/shopify_app/authenticated_controller.rb +2 -4
  5. data/app/controllers/shopify_app/sessions_controller.rb +96 -2
  6. data/app/controllers/shopify_app/webhooks_controller.rb +1 -1
  7. data/lib/generators/shopify_app/home_controller/templates/home_controller.rb +1 -0
  8. data/lib/generators/shopify_app/home_controller/templates/index.html.erb +14 -0
  9. data/lib/generators/shopify_app/home_controller/templates/shopify_app_ready_script.html.erb +1 -5
  10. data/lib/generators/shopify_app/install/install_generator.rb +0 -11
  11. data/lib/generators/shopify_app/install/templates/shopify_app.rb +1 -0
  12. data/lib/generators/shopify_app/install/templates/shopify_provider.rb +3 -3
  13. data/lib/generators/shopify_app/shop_model/shop_model_generator.rb +3 -3
  14. data/lib/generators/shopify_app/shop_model/templates/shop.rb +0 -1
  15. data/lib/shopify_app.rb +20 -17
  16. data/lib/shopify_app/configuration.rb +21 -8
  17. data/lib/shopify_app/{app_proxy_verification.rb → controller_concerns/app_proxy_verification.rb} +0 -0
  18. data/lib/shopify_app/controller_concerns/embedded_app.rb +19 -0
  19. data/lib/shopify_app/{localization.rb → controller_concerns/localization.rb} +6 -0
  20. data/lib/shopify_app/{login_protection.rb → controller_concerns/login_protection.rb} +11 -7
  21. data/lib/shopify_app/{webhook_verification.rb → controller_concerns/webhook_verification.rb} +0 -0
  22. data/lib/shopify_app/{scripttags_manager_job.rb → jobs/scripttags_manager_job.rb} +0 -0
  23. data/lib/shopify_app/{webhooks_manager_job.rb → jobs/webhooks_manager_job.rb} +0 -0
  24. data/lib/shopify_app/{scripttags_manager.rb → managers/scripttags_manager.rb} +0 -0
  25. data/lib/shopify_app/{webhooks_manager.rb → managers/webhooks_manager.rb} +0 -0
  26. data/lib/shopify_app/session/in_memory_session_store.rb +27 -0
  27. data/lib/shopify_app/{shopify_session_repository.rb → session/session_repository.rb} +0 -0
  28. data/lib/shopify_app/{session_storage.rb → session/session_storage.rb} +9 -0
  29. data/lib/shopify_app/version.rb +1 -1
  30. metadata +14 -17
  31. data/lib/generators/shopify_app/install/templates/shopify_session_repository.rb +0 -23
  32. data/lib/generators/shopify_app/shop_model/templates/shopify_session_repository.rb +0 -9
  33. data/lib/shopify_app/in_memory_session_store.rb +0 -25
  34. data/lib/shopify_app/sessions_concern.rb +0 -103
  35. data/lib/shopify_app/shop.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b534fe893fb126d699a8e2a0908cc06aab2ea3e9
4
- data.tar.gz: 7da8663a89439030d2198be0f4d09e947d68ae63
3
+ metadata.gz: 3c17b0036bfc249437b86de35f0ad6a42bae8a74
4
+ data.tar.gz: 4c1840a61918df21033a9492662a5b48810aa4fc
5
5
  SHA512:
6
- metadata.gz: 189dfc0d53bd7eae968b3270151b00a363a9ecd964b38cbabd378824156fa2eaf5aecb93c9932b1fa3fde2323bd35c9a8fcddec3f8b62b2c02cd6bd2001c8e1f
7
- data.tar.gz: 9e11244536e4039e59b1170ab3fcf9717f9f0e53036dbd791cf30e72279d95737cb640cee2a19736e9e74da380c1209a49446aeb32cb2223baf36fe28e8eabcd
6
+ metadata.gz: e9e9c0e4930528ab48b9ea7dfbb3d4722a650dbd97bc97c4e254115398026c462ca25a660aa91a85654a37bde1ecf1195744cb31c8da7facc748f9985bb46b34
7
+ data.tar.gz: bb0726fb075b047ceb02b8a7b10cd04e3b2c925ea7e5efcf14df1465d347b6edc164599ceb894af52aae50cf6ff0cb7448fac7e175e1b8332ffcb22706f4e03e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ 8.0.0
2
+ -----
3
+ * Removed the `shopify_session_repository` initializer. The SessionRepository is now configured through the main ShopifyApp configuration object and the generated initializer
4
+ * Moved InMemorySessionStore into the ShopifyApp namespace
5
+ * Remove ShopifySession concern. This module made the code internal to this engine harder to follow and we want do discourage over-writing the auth code now that we have generic hooks for all extra tasks during install.
6
+ * Changed engine controllers to subclass ActionController::Base to avoid any possible conflict with the parent application
7
+ * Removed the `ShopifyApp::Shop` concern and added its methods to `ShopifyApp::SessionStorage`. To update for this change just remove this concern anywhere it is being used in your application.
8
+ * Add `ShopifyApp::EmbeddedApp` controller concern which handles setting the required headers for the ESDK. Previously this was done by injecting configuration into applicaton.rb which affects the entire app.
9
+ * Add webhooks to generated home controller. This should help new users debug issues.
10
+
1
11
  7.4.0
2
12
  -----
3
13
  * Add an after_authenticate job which will be run once the shop is authenticated. [[#431]](https://github.com/Shopify/shopify_app/pull/432)
data/README.md CHANGED
@@ -142,7 +142,7 @@ After running the `install` generator, you can start your app with `bundle exec
142
142
  $ rails generate shopify_app:shop_model
143
143
  ```
144
144
 
145
- The install generator doesn't create any database models for you and if you are starting a new app its quite likely that you will want one (most of our internally developed apps do!). This generator creates a simple shop model and a migration. It also creates a model called `SessionStorage` which interacts with `ShopifyApp::SessionRepository`. Check out the later section to learn more about `ShopifyApp::SessionRepository`
145
+ The install generator doesn't create any database tables or models for you. If you are starting a new app its quite likely that you will want a shops table and model to store the tokens when your app is installed (most of our internally developed apps do!). This generator creates a shop model and a migration. This model includes the `ShopifyApp::Shop` concern which adds two methods to make it compatible as a `SessionRepository`. After running this generator you'll notice the `session_repository` in your `config/initializers/shopify_app.rb` will be set to the `Shop` model. This means that internally ShopifyApp will try and load tokens from this model.
146
146
 
147
147
  *Note that you will need to run rake db:migrate after this generator*
148
148
 
@@ -172,7 +172,7 @@ The last group of generators are for your convenience if you want to start overr
172
172
  Mounting the Engine
173
173
  -------------------
174
174
 
175
- Mounting the Engine will provide the basic routes to authenticating a shop with your custom application. It will provide:
175
+ Mounting the Engine will provide the basic routes to authenticating a shop with your application. By default it will provide:
176
176
 
177
177
  | Verb | Route | Action |
178
178
  |--------|-------------------------------|------------------------------|
@@ -183,28 +183,28 @@ Mounting the Engine will provide the basic routes to authenticating a shop with
183
183
  |POST |'/webhooks/:type' |Webhook Callback |
184
184
 
185
185
 
186
- The default routes of the Shopify rails engine, which is mounted to the root, can be altered to mount on a different route. The `config/routes.rb` can be modified to put these under a nested route (say `/app-name`) as:
186
+ If required the engine can be mounted at a nested route, eg:
187
187
 
188
188
  ```ruby
189
189
  mount ShopifyApp::Engine, at: '/nested'
190
190
  ```
191
191
 
192
- This will create the Shopify engine routes under the specified subpath, as a result it will redirect new consumers to `/nested/login`. If you mount the engine at a subpath you'll also need to update the omniauth initializer to include a custom `callback_path` e.g:
192
+ This will create the Shopify engine routes under the specified subpath. You'll also need to make some updates to your `shopify_app.rb` and `omniauth.rb` initializers. First update the shopify_app initializer to include a custom `root_url` e.g:
193
193
 
194
194
  ```ruby
195
- provider :shopify,
196
- ShopifyApp.configuration.api_key,
197
- ShopifyApp.configuration.secret,
198
- scope: ShopifyApp.configuration.scope,
199
- callback_path: '/nested/auth/shopify/callback'
195
+ ShopifyApp.configure do |config|
196
+ config.root_url = '/nested'
197
+ end
200
198
  ```
201
199
 
202
- To use named routes with the engine so that it can route between the application and the engine's routes it should be prefixed with `main_app` or `shopify_app`.
200
+ then update the omniauth initializer to include a custom `callback_path` e.g:
203
201
 
204
202
  ```ruby
205
- main_app.login_path # For a named login route on the rails app.
206
-
207
- shopify_app.login_path # For the shopify app store login route.
203
+ provider :shopify,
204
+ ShopifyApp.configuration.api_key,
205
+ ShopifyApp.configuration.secret,
206
+ scope: ShopifyApp.configuration.scope,
207
+ callback_path: '/nested/auth/shopify/callback'
208
208
  ```
209
209
 
210
210
  Managing Api Keys
@@ -327,9 +327,9 @@ bin/rails g shopify_app:add_after_authenticate_job
327
327
  ShopifyApp::SessionRepository
328
328
  -----------------------------
329
329
 
330
- `ShopifyApp::SessionRepository` allows you as a developer to define how your sessions are retrieved and stored for a shop. The `SessionRepository` is configured using the `config/initializers/shopify_session_repository.rb` file and can be set to any object that implements `self.store(shopify_session)` which stores the session and returns a unique identifier and `self.retrieve(id)` which returns a `ShopifyAPI::Session` for the passed id. See either the `InMemorySessionStore` or the `SessionStorage` module for examples.
330
+ `ShopifyApp::SessionRepository` allows you as a developer to define how your sessions are retrieved and stored for a shop. The `SessionRepository` is configured in the `config/initializers/shopify_app.rb` file and can be set to any object that implements `self.store(shopify_session)` which stores the session and returns a unique identifier and `self.retrieve(id)` which returns a `ShopifyAPI::Session` for the passed id. See either the `ShopifyApp::InMemorySessionStore` class or the `ShopifyApp::Shop` concern for examples.
331
331
 
332
- If you only run the install generator then by default you will have an in memory store but it **won't work** on multi-server environments including Heroku. If you ran all the generators including the shop_model generator then the Shop model itself will be the `SessionRepository`. If you look at the implementation of the generated shop model you'll see that this gem provides an activerecord mixin for the `SessionRepository`. You can use this mixin on any model that responds to `shopify_domain` and `shopify_token`.
332
+ If you only run the install generator then by default you will have an in memory store but it **won't work** on multi-server environments including Heroku. If you ran all the generators including the shop_model generator then the `Shop` model itself will be the `SessionRepository`. If you look at the implementation of the generated shop model you'll see that this gem provides a concern for the `SessionRepository`. You can use this concern on any model that responds to `shopify_domain` and `shopify_token`.
333
333
 
334
334
  AuthenticatedController
335
335
  -----------------------
@@ -1,12 +1,10 @@
1
1
  module ShopifyApp
2
- class AuthenticatedController < ApplicationController
2
+ class AuthenticatedController < ActionController::Base
3
3
  include ShopifyApp::Localization
4
4
  include ShopifyApp::LoginProtection
5
+ include ShopifyApp::EmbeddedApp
5
6
 
6
- before_action :set_locale
7
7
  before_action :login_again_if_different_shop
8
8
  around_action :shopify_session
9
-
10
- layout ShopifyApp.configuration.embedded_app? ? 'embedded_app' : 'application'
11
9
  end
12
10
  end
@@ -1,5 +1,99 @@
1
1
  module ShopifyApp
2
- class SessionsController < ApplicationController
3
- include ShopifyApp::SessionsConcern
2
+ class SessionsController < ActionController::Base
3
+ include ShopifyApp::LoginProtection
4
+ layout false, only: :new
5
+
6
+ def new
7
+ authenticate if sanitized_shop_name.present?
8
+ end
9
+
10
+ def create
11
+ authenticate
12
+ end
13
+
14
+ def callback
15
+ if auth_hash
16
+ login_shop
17
+ install_webhooks
18
+ install_scripttags
19
+ perform_after_authenticate_job
20
+
21
+ redirect_to return_address
22
+ else
23
+ flash[:error] = I18n.t('could_not_log_in')
24
+ redirect_to login_url
25
+ end
26
+ end
27
+
28
+ def destroy
29
+ session[:shopify] = nil
30
+ session[:shopify_domain] = nil
31
+ flash[:notice] = I18n.t('.logged_out')
32
+ redirect_to login_url
33
+ end
34
+
35
+ private
36
+
37
+ def authenticate
38
+ if sanitized_shop_name.present?
39
+ fullpage_redirect_to "#{main_app.root_path}auth/shopify?shop=#{sanitized_shop_name}"
40
+ else
41
+ redirect_to return_address
42
+ end
43
+ end
44
+
45
+ def login_shop
46
+ sess = ShopifyAPI::Session.new(shop_name, token)
47
+ session[:shopify] = ShopifyApp::SessionRepository.store(sess)
48
+ session[:shopify_domain] = shop_name
49
+ end
50
+
51
+ def auth_hash
52
+ request.env['omniauth.auth']
53
+ end
54
+
55
+ def shop_name
56
+ auth_hash.uid
57
+ end
58
+
59
+ def token
60
+ auth_hash['credentials']['token']
61
+ end
62
+
63
+ def install_webhooks
64
+ return unless ShopifyApp.configuration.has_webhooks?
65
+
66
+ WebhooksManager.queue(
67
+ shop_name,
68
+ token,
69
+ ShopifyApp.configuration.webhooks
70
+ )
71
+ end
72
+
73
+ def install_scripttags
74
+ return unless ShopifyApp.configuration.has_scripttags?
75
+
76
+ ScripttagsManager.queue(
77
+ shop_name,
78
+ token,
79
+ ShopifyApp.configuration.scripttags
80
+ )
81
+ end
82
+
83
+ def perform_after_authenticate_job
84
+ config = ShopifyApp.configuration.after_authenticate_job
85
+
86
+ return unless config && config[:job].present?
87
+
88
+ if config[:inline] == true
89
+ config[:job].perform_now(shop_domain: session[:shopify_domain])
90
+ else
91
+ config[:job].perform_later(shop_domain: session[:shopify_domain])
92
+ end
93
+ end
94
+
95
+ def return_address
96
+ session.delete(:return_to) || ShopifyApp::configuration.root_url
97
+ end
4
98
  end
5
99
  end
@@ -1,5 +1,5 @@
1
1
  module ShopifyApp
2
- class WebhooksController < ApplicationController
2
+ class WebhooksController < ActionController::Base
3
3
  include ShopifyApp::WebhookVerification
4
4
 
5
5
  class ShopifyApp::MissingWebhookJobError < StandardError; end
@@ -1,5 +1,6 @@
1
1
  class HomeController < ShopifyApp::AuthenticatedController
2
2
  def index
3
3
  @products = ShopifyAPI::Product.find(:all, params: { limit: 10 })
4
+ @webhooks = ShopifyAPI::Webhook.find(:all)
4
5
  end
5
6
  end
@@ -5,3 +5,17 @@
5
5
  <li><%= link_to product.title, "https://#{@shop_session.url}/admin/products/#{product.id}", target: "_top" %></li>
6
6
  <% end %>
7
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 %>
@@ -1,11 +1,7 @@
1
1
  <% content_for :javascript do %>
2
2
  <script type="text/javascript">
3
3
  ShopifyApp.ready(function(){
4
- ShopifyApp.Bar.initialize({
5
- title: "Home",
6
- icon: "<%= asset_path('favicon.ico') %>"
7
- });
4
+ ShopifyApp.Bar.initialize({ title: "Home" });
8
5
  });
9
6
  </script>
10
7
  <% end %>
11
-
@@ -34,17 +34,6 @@ module ShopifyApp
34
34
  )
35
35
  end
36
36
 
37
- def create_shopify_session_repository_initializer
38
- copy_file 'shopify_session_repository.rb', 'config/initializers/shopify_session_repository.rb'
39
- end
40
-
41
- def inject_embedded_app_options_to_application
42
- if embedded_app?
43
- application "config.action_dispatch.default_headers.delete('X-Frame-Options')"
44
- application "config.action_dispatch.default_headers['P3P'] = 'CP=\"Not used\"'"
45
- end
46
- end
47
-
48
37
  def create_embedded_app_layout
49
38
  if embedded_app?
50
39
  copy_file 'embedded_app.html.erb', 'app/views/layouts/embedded_app.html.erb'
@@ -5,4 +5,5 @@ ShopifyApp.configure do |config|
5
5
  config.scope = "<%= @scope %>"
6
6
  config.embedded_app = <%= embedded_app? %>
7
7
  config.after_authenticate_job = false
8
+ config.session_repository = ShopifyApp::InMemorySessionStore
8
9
  end
@@ -1,4 +1,4 @@
1
1
  provider :shopify,
2
- ShopifyApp.configuration.api_key,
3
- ShopifyApp.configuration.secret,
4
- scope: ShopifyApp.configuration.scope
2
+ ShopifyApp.configuration.api_key,
3
+ ShopifyApp.configuration.secret,
4
+ scope: ShopifyApp.configuration.scope
@@ -12,11 +12,11 @@ module ShopifyApp
12
12
  end
13
13
 
14
14
  def create_shop_migration
15
- migration_template "db/migrate/create_shops.erb", "db/migrate/create_shops.rb"
15
+ migration_template 'db/migrate/create_shops.erb', 'db/migrate/create_shops.rb'
16
16
  end
17
17
 
18
- def create_session_storage_initializer
19
- copy_file 'shopify_session_repository.rb', 'config/initializers/shopify_session_repository.rb', force: true
18
+ def update_shopify_app_initializer
19
+ gsub_file 'config/initializers/shopify_app.rb', 'ShopifyApp::InMemorySessionStore', 'Shop'
20
20
  end
21
21
 
22
22
  def create_shop_fixtures
@@ -1,4 +1,3 @@
1
1
  class Shop < ActiveRecord::Base
2
- include ShopifyApp::Shop
3
2
  include ShopifyApp::SessionStorage
4
3
  end
data/lib/shopify_app.rb CHANGED
@@ -10,22 +10,25 @@ require 'shopify_app/configuration'
10
10
  # engine
11
11
  require 'shopify_app/engine'
12
12
 
13
- # jobs
14
- require 'shopify_app/webhooks_manager_job'
15
- require 'shopify_app/scripttags_manager_job'
16
-
17
- # helpers and concerns
18
- require 'shopify_app/shop'
19
- require 'shopify_app/session_storage'
20
- require 'shopify_app/sessions_concern'
21
- require 'shopify_app/localization'
22
- require 'shopify_app/login_protection'
23
- require 'shopify_app/webhooks_manager'
24
- require 'shopify_app/scripttags_manager'
25
- require 'shopify_app/webhook_verification'
26
- require 'shopify_app/app_proxy_verification'
13
+ # utils
27
14
  require 'shopify_app/utils'
28
15
 
29
- # session repository
30
- require 'shopify_app/shopify_session_repository'
31
- require 'shopify_app/in_memory_session_store'
16
+ # controller concerns
17
+ require 'shopify_app/controller_concerns/localization'
18
+ require 'shopify_app/controller_concerns/login_protection'
19
+ require 'shopify_app/controller_concerns/embedded_app'
20
+ require 'shopify_app/controller_concerns/webhook_verification'
21
+ require 'shopify_app/controller_concerns/app_proxy_verification'
22
+
23
+ # jobs
24
+ require 'shopify_app/jobs/webhooks_manager_job'
25
+ require 'shopify_app/jobs/scripttags_manager_job'
26
+
27
+ # managers
28
+ require 'shopify_app/managers/webhooks_manager'
29
+ require 'shopify_app/managers/scripttags_manager'
30
+
31
+ # session
32
+ require 'shopify_app/session/session_storage'
33
+ require 'shopify_app/session/session_repository'
34
+ require 'shopify_app/session/in_memory_session_store'
@@ -13,6 +13,10 @@ module ShopifyApp
13
13
  attr_accessor :webhooks
14
14
  attr_accessor :scripttags
15
15
  attr_accessor :after_authenticate_job
16
+ attr_accessor :session_repository
17
+
18
+ # customise urls
19
+ attr_accessor :root_url
16
20
 
17
21
  # customise ActiveJob queue names
18
22
  attr_accessor :scripttags_manager_queue_name
@@ -22,23 +26,32 @@ module ShopifyApp
22
26
  attr_accessor :myshopify_domain
23
27
 
24
28
  def initialize
29
+ @root_url = '/'
25
30
  @myshopify_domain = 'myshopify.com'
31
+ @scripttags_manager_queue_name = Rails.application.config.active_job.queue_name
32
+ @webhooks_manager_queue_name = Rails.application.config.active_job.queue_name
26
33
  end
27
34
 
28
- def has_webhooks?
29
- webhooks.present?
35
+ def login_url
36
+ File.join(@root_url, 'login')
30
37
  end
31
38
 
32
- def has_scripttags?
33
- scripttags.present?
39
+ def session_repository=(klass)
40
+ if Rails.configuration.cache_classes
41
+ ShopifyApp::SessionRepository.storage = klass
42
+ else
43
+ ActiveSupport::Reloader.to_prepare do
44
+ ShopifyApp::SessionRepository.storage = klass
45
+ end
46
+ end
34
47
  end
35
48
 
36
- def scripttags_manager_queue_name
37
- @scripttags_manager_queue_name ||= Rails.application.config.active_job.queue_name
49
+ def has_webhooks?
50
+ webhooks.present?
38
51
  end
39
52
 
40
- def webhooks_manager_queue_name
41
- @webhooks_manager_queue_name ||= Rails.application.config.active_job.queue_name
53
+ def has_scripttags?
54
+ scripttags.present?
42
55
  end
43
56
  end
44
57
 
@@ -0,0 +1,19 @@
1
+ module ShopifyApp
2
+ module EmbeddedApp
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ if ShopifyApp.configuration.embedded_app?
7
+ after_action :set_esdk_headers
8
+ layout 'embedded_app'
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def set_esdk_headers
15
+ response.set_header('P3P', 'CP="Not used"')
16
+ response.default_headers.delete('X-Frame-Options')
17
+ end
18
+ end
19
+ end
@@ -2,6 +2,12 @@ module ShopifyApp
2
2
  module Localization
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ included do
6
+ before_action :set_locale
7
+ end
8
+
9
+ private
10
+
5
11
  def set_locale
6
12
  if params[:locale]
7
13
  session[:locale] = params[:locale]
@@ -41,20 +41,25 @@ module ShopifyApp
41
41
  head :unauthorized
42
42
  else
43
43
  session[:return_to] = request.fullpath if request.get?
44
- redirect_to main_or_engine_login_url(shop: params[:shop])
44
+ redirect_to login_url
45
45
  end
46
46
  end
47
47
 
48
48
  def close_session
49
49
  session[:shopify] = nil
50
50
  session[:shopify_domain] = nil
51
- redirect_to main_or_engine_login_url(shop: params[:shop])
51
+ redirect_to login_url
52
52
  end
53
53
 
54
- def main_or_engine_login_url(params = {})
55
- main_app.login_url(params)
56
- rescue NoMethodError
57
- shopify_app.login_url(params)
54
+ def login_url
55
+ url = ShopifyApp.configuration.login_url
56
+
57
+ if params[:shop].present?
58
+ query = { shop: params[:shop] }.to_query
59
+ url = "#{url}?#{query}"
60
+ end
61
+
62
+ url
58
63
  end
59
64
 
60
65
  def fullpage_redirect_to(url)
@@ -114,6 +119,5 @@ module ShopifyApp
114
119
  return unless params[:shop].present?
115
120
  ShopifyApp::Utils.sanitize_shop_domain(params[:shop])
116
121
  end
117
-
118
122
  end
119
123
  end
@@ -0,0 +1,27 @@
1
+ module ShopifyApp
2
+ class InMemorySessionStore
3
+ class EnvironmentError < StandardError; end
4
+
5
+ def self.retrieve(id)
6
+ repo[id]
7
+ end
8
+
9
+ def self.store(session)
10
+ id = SecureRandom.uuid
11
+ repo[id] = session
12
+ id
13
+ end
14
+
15
+ def self.clear
16
+ @@repo = nil
17
+ end
18
+
19
+ def self.repo
20
+ if Rails.env.production?
21
+ raise EnvironmentError.new("Cannot use InMemorySessionStore in a Production environment. \
22
+ Please initialize ShopifyApp with a model that can store and retrieve sessions")
23
+ end
24
+ @@repo ||= {}
25
+ end
26
+ end
27
+ end
@@ -2,6 +2,15 @@ module ShopifyApp
2
2
  module SessionStorage
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ included do
6
+ validates :shopify_domain, presence: true, uniqueness: true
7
+ validates :shopify_token, presence: true
8
+ end
9
+
10
+ def with_shopify_session(&block)
11
+ ShopifyAPI::Session.temp(shopify_domain, shopify_token, &block)
12
+ end
13
+
5
14
  class_methods do
6
15
  def store(session)
7
16
  shop = self.find_or_initialize_by(shopify_domain: session.url)
@@ -1,3 +1,3 @@
1
1
  module ShopifyApp
2
- VERSION = '7.4.0'
2
+ VERSION = '8.0.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify_app
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.4.0
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-10 00:00:00.000000000 Z
11
+ date: 2017-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -169,34 +169,31 @@ files:
169
169
  - lib/generators/shopify_app/install/templates/omniauth.rb
170
170
  - lib/generators/shopify_app/install/templates/shopify_app.rb
171
171
  - lib/generators/shopify_app/install/templates/shopify_provider.rb
172
- - lib/generators/shopify_app/install/templates/shopify_session_repository.rb
173
172
  - lib/generators/shopify_app/routes/routes_generator.rb
174
173
  - lib/generators/shopify_app/routes/templates/routes.rb
175
174
  - lib/generators/shopify_app/shop_model/shop_model_generator.rb
176
175
  - lib/generators/shopify_app/shop_model/templates/db/migrate/create_shops.erb
177
176
  - lib/generators/shopify_app/shop_model/templates/shop.rb
178
- - lib/generators/shopify_app/shop_model/templates/shopify_session_repository.rb
179
177
  - lib/generators/shopify_app/shop_model/templates/shops.yml
180
178
  - lib/generators/shopify_app/shopify_app_generator.rb
181
179
  - lib/generators/shopify_app/views/views_generator.rb
182
180
  - lib/shopify_app.rb
183
- - lib/shopify_app/app_proxy_verification.rb
184
181
  - lib/shopify_app/configuration.rb
182
+ - lib/shopify_app/controller_concerns/app_proxy_verification.rb
183
+ - lib/shopify_app/controller_concerns/embedded_app.rb
184
+ - lib/shopify_app/controller_concerns/localization.rb
185
+ - lib/shopify_app/controller_concerns/login_protection.rb
186
+ - lib/shopify_app/controller_concerns/webhook_verification.rb
185
187
  - lib/shopify_app/engine.rb
186
- - lib/shopify_app/in_memory_session_store.rb
187
- - lib/shopify_app/localization.rb
188
- - lib/shopify_app/login_protection.rb
189
- - lib/shopify_app/scripttags_manager.rb
190
- - lib/shopify_app/scripttags_manager_job.rb
191
- - lib/shopify_app/session_storage.rb
192
- - lib/shopify_app/sessions_concern.rb
193
- - lib/shopify_app/shop.rb
194
- - lib/shopify_app/shopify_session_repository.rb
188
+ - lib/shopify_app/jobs/scripttags_manager_job.rb
189
+ - lib/shopify_app/jobs/webhooks_manager_job.rb
190
+ - lib/shopify_app/managers/scripttags_manager.rb
191
+ - lib/shopify_app/managers/webhooks_manager.rb
192
+ - lib/shopify_app/session/in_memory_session_store.rb
193
+ - lib/shopify_app/session/session_repository.rb
194
+ - lib/shopify_app/session/session_storage.rb
195
195
  - lib/shopify_app/utils.rb
196
196
  - lib/shopify_app/version.rb
197
- - lib/shopify_app/webhook_verification.rb
198
- - lib/shopify_app/webhooks_manager.rb
199
- - lib/shopify_app/webhooks_manager_job.rb
200
197
  - shipit.rubygems.yml
201
198
  - shopify_app.gemspec
202
199
  homepage:
@@ -1,23 +0,0 @@
1
- # You should replace InMemorySessionStore with what you will be using
2
- # in Production. For example a model called "Shop":
3
- #
4
- # ShopifySessionRepository.storage = 'Shop'
5
- #
6
- # Interface to implement are self.retrieve(id) and self.store(ShopifyAPI::Session)
7
- # Here is how you would add these functions to an ActiveRecord:
8
- #
9
- # class Shop < ActiveRecord::Base
10
- # def self.store(session)
11
- # shop = self.new(domain: session.url, token: session.token)
12
- # shop.save!
13
- # shop.id
14
- # end
15
- #
16
- # def self.retrieve(id)
17
- # if shop = self.where(id: id).first
18
- # ShopifyAPI::Session.new(shop.domain, shop.token)
19
- # end
20
- # end
21
- # end
22
-
23
- ShopifyApp::SessionRepository.storage = InMemorySessionStore
@@ -1,9 +0,0 @@
1
- if Rails.configuration.cache_classes
2
- ShopifyApp::SessionRepository.storage = Shop
3
- else
4
- reloader = defined?(ActiveSupport::Reloader) ? ActiveSupport::Reloader : ActionDispatch::Reloader
5
-
6
- reloader.to_prepare do
7
- ShopifyApp::SessionRepository.storage = Shop
8
- end
9
- end
@@ -1,25 +0,0 @@
1
- # WARNING - This really only works for development, see README for more details
2
- class InMemorySessionStore
3
- class EnvironmentError < StandardError; end
4
-
5
- def self.retrieve(id)
6
- repo[id]
7
- end
8
-
9
- def self.store(session)
10
- id = SecureRandom.uuid
11
- repo[id] = session
12
- id
13
- end
14
-
15
- def self.clear
16
- @@repo = nil
17
- end
18
-
19
- def self.repo
20
- if Rails.env.production?
21
- raise EnvironmentError.new("Cannot use InMemorySessionStore in a Production environment")
22
- end
23
- @@repo ||= {}
24
- end
25
- end
@@ -1,103 +0,0 @@
1
- module ShopifyApp
2
- module SessionsConcern
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- include ShopifyApp::LoginProtection
7
- layout false, only: :new
8
- end
9
-
10
- def new
11
- authenticate if sanitized_shop_name.present?
12
- end
13
-
14
- def create
15
- authenticate
16
- end
17
-
18
- def callback
19
- if auth_hash
20
- login_shop
21
- install_webhooks
22
- install_scripttags
23
- perform_after_authenticate_job
24
-
25
- redirect_to return_address
26
- else
27
- flash[:error] = I18n.t('could_not_log_in')
28
- redirect_to login_url
29
- end
30
- end
31
-
32
- def destroy
33
- session[:shopify] = nil
34
- session[:shopify_domain] = nil
35
- flash[:notice] = I18n.t('.logged_out')
36
- redirect_to login_url
37
- end
38
-
39
- protected
40
-
41
- def authenticate
42
- if sanitized_shop_name.present?
43
- fullpage_redirect_to "#{main_app.root_path}auth/shopify?shop=#{sanitized_shop_name}"
44
- else
45
- redirect_to return_address
46
- end
47
- end
48
-
49
- def login_shop
50
- sess = ShopifyAPI::Session.new(shop_name, token)
51
- session[:shopify] = ShopifyApp::SessionRepository.store(sess)
52
- session[:shopify_domain] = shop_name
53
- end
54
-
55
- def auth_hash
56
- request.env['omniauth.auth']
57
- end
58
-
59
- def shop_name
60
- auth_hash.uid
61
- end
62
-
63
- def token
64
- auth_hash['credentials']['token']
65
- end
66
-
67
- def install_webhooks
68
- return unless ShopifyApp.configuration.has_webhooks?
69
-
70
- WebhooksManager.queue(
71
- shop_name,
72
- token,
73
- ShopifyApp.configuration.webhooks
74
- )
75
- end
76
-
77
- def install_scripttags
78
- return unless ShopifyApp.configuration.has_scripttags?
79
-
80
- ScripttagsManager.queue(
81
- shop_name,
82
- token,
83
- ShopifyApp.configuration.scripttags
84
- )
85
- end
86
-
87
- def return_address
88
- session.delete(:return_to) || main_app.root_url
89
- end
90
-
91
- def perform_after_authenticate_job
92
- config = ShopifyApp.configuration.after_authenticate_job
93
-
94
- return unless config && config[:job].present?
95
-
96
- if config[:inline] == true
97
- config[:job].perform_now(shop_domain: session[:shopify_domain])
98
- else
99
- config[:job].perform_later(shop_domain: session[:shopify_domain])
100
- end
101
- end
102
- end
103
- end
@@ -1,15 +0,0 @@
1
- module ShopifyApp
2
- module Shop
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- validates :shopify_domain, presence: true, uniqueness: true
7
- validates :shopify_token, presence: true
8
- end
9
-
10
- def with_shopify_session(&block)
11
- ShopifyAPI::Session.temp(shopify_domain, shopify_token, &block)
12
- end
13
-
14
- end
15
- end