shopify_app 7.4.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
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