shopify_app 6.4.2 → 7.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +13 -0
  3. data/ISSUE_TEMPLATE.md +14 -0
  4. data/QUICKSTART.md +6 -7
  5. data/README.md +38 -16
  6. data/Rakefile +2 -6
  7. data/app/controllers/shopify_app/authenticated_controller.rb +7 -0
  8. data/app/controllers/shopify_app/sessions_controller.rb +5 -0
  9. data/app/controllers/shopify_app/webhooks_controller.rb +27 -0
  10. data/app/views/{sessions → shopify_app/sessions}/new.html.erb +0 -0
  11. data/config/routes.rb +4 -0
  12. data/lib/generators/shopify_app/add_webhook/add_webhook_generator.rb +61 -0
  13. data/lib/generators/shopify_app/add_webhook/templates/webhook_job.rb +8 -0
  14. data/lib/generators/shopify_app/controllers/controllers_generator.rb +1 -1
  15. data/lib/generators/shopify_app/home_controller/home_controller_generator.rb +0 -1
  16. data/lib/generators/shopify_app/home_controller/templates/home_controller.rb +1 -1
  17. data/lib/generators/shopify_app/install/install_generator.rb +13 -19
  18. data/lib/generators/shopify_app/install/templates/embedded_app.html.erb +2 -2
  19. data/lib/generators/shopify_app/install/templates/shopify_app.rb +3 -4
  20. data/lib/generators/shopify_app/install/templates/shopify_provider.rb +0 -1
  21. data/lib/generators/shopify_app/routes/templates/routes.rb +4 -0
  22. data/lib/generators/shopify_app/shopify_app_generator.rb +1 -7
  23. data/lib/shopify_app.rb +2 -3
  24. data/lib/shopify_app/configuration.rb +0 -1
  25. data/lib/shopify_app/engine.rb +1 -0
  26. data/lib/shopify_app/login_protection.rb +53 -5
  27. data/lib/shopify_app/{sessions_controller.rb → sessions_concern.rb} +5 -5
  28. data/lib/shopify_app/version.rb +1 -1
  29. data/lib/shopify_app/webhook_verification.rb +35 -0
  30. data/shopify_app.gemspec +1 -1
  31. metadata +11 -43
  32. data/CONTRIBUTING.md +0 -14
  33. data/app/controllers/authenticated_controller.rb +0 -5
  34. data/app/controllers/sessions_controller.rb +0 -3
  35. data/lib/shopify_app/controller.rb +0 -18
  36. data/lib/shopify_app/webhooks_controller.rb +0 -35
  37. data/test/app_templates/app/controllers/application_controller.rb +0 -2
  38. data/test/app_templates/config/application.rb +0 -24
  39. data/test/app_templates/config/initializers/shopify_app.rb +0 -6
  40. data/test/app_templates/config/routes.rb +0 -4
  41. data/test/controllers/sessions_controller_test.rb +0 -122
  42. data/test/controllers/sessions_routes_test.rb +0 -27
  43. data/test/dummy/Rakefile +0 -6
  44. data/test/dummy/app/controllers/application_controller.rb +0 -3
  45. data/test/dummy/app/controllers/home_controller.rb +0 -7
  46. data/test/dummy/config.ru +0 -4
  47. data/test/dummy/config/application.rb +0 -26
  48. data/test/dummy/config/boot.rb +0 -5
  49. data/test/dummy/config/database.yml +0 -25
  50. data/test/dummy/config/environment.rb +0 -5
  51. data/test/dummy/config/environments/test.rb +0 -42
  52. data/test/dummy/config/initializers/shopify_app.rb +0 -6
  53. data/test/dummy/config/routes.rb +0 -10
  54. data/test/dummy/config/secrets.yml +0 -17
  55. data/test/generators/controllers_generator_test.rb +0 -16
  56. data/test/generators/home_controller_generator_test.rb +0 -50
  57. data/test/generators/install_generator_test.rb +0 -87
  58. data/test/generators/routes_generator_test.rb +0 -26
  59. data/test/generators/shop_model_generator_test.rb +0 -39
  60. data/test/generators/shopify_app_generator.rb +0 -15
  61. data/test/generators/views_generator_test.rb +0 -15
  62. data/test/shopify_app/configuration_test.rb +0 -49
  63. data/test/shopify_app/in_memory_session_store_test.rb +0 -35
  64. data/test/shopify_app/login_protection_test.rb +0 -100
  65. data/test/shopify_app/shopify_session_repository_test.rb +0 -73
  66. data/test/shopify_app/utils_test.rb +0 -30
  67. data/test/shopify_app/webhooks_controller_test.rb +0 -50
  68. data/test/shopify_app/webhooks_manager_test.rb +0 -86
  69. data/test/support/generator_test_helpers.rb +0 -29
  70. data/test/test_helper.rb +0 -17
@@ -1,6 +0,0 @@
1
- ShopifyApp.configure do |config|
2
- config.api_key = "key"
3
- config.secret = "secret"
4
- config.scope = 'read_orders, read_products'
5
- config.embedded_app = true
6
- end
@@ -1,4 +0,0 @@
1
- Rails.application.routes.draw do
2
- mount ShopifyApp::Engine, at: '/'
3
- root to: "application#show"
4
- end
@@ -1,122 +0,0 @@
1
- require 'test_helper'
2
-
3
- class SessionsControllerTest < ActionController::TestCase
4
-
5
- setup do
6
- ShopifyApp::SessionRepository.storage = InMemorySessionStore
7
- ShopifyApp.configuration = nil
8
- end
9
-
10
- test "#new should authenticate the shop if the shop param exists" do
11
- ShopifyApp.configuration.embedded_app = true
12
- auth_url = '/auth/shopify?shop=my-shop.myshopify.com'
13
- get :new, shop: 'my-shop'
14
- assert response.body.match(/window\.top\.location\.href = "#{Regexp.escape(auth_url)}"/)
15
- end
16
-
17
- test "#new should authenticate the shop if the shop param exists non embedded" do
18
- ShopifyApp.configuration.embedded_app = false
19
- auth_url = '/auth/shopify?shop=my-shop.myshopify.com'
20
- get :new, shop: 'my-shop'
21
- assert_match "http://test.host/auth/shopify?shop=my-shop.myshopify.com", response.body
22
- end
23
-
24
- test "#new should trust the shop param over the current session" do
25
- ShopifyApp.configuration.embedded_app = true
26
- previously_logged_in_shop_id = 1
27
- session[:shopify] = previously_logged_in_shop_id
28
- new_shop_domain = "new-shop.myshopify.com"
29
- auth_url = "/auth/shopify?shop=#{new_shop_domain}"
30
- get :new, shop: new_shop_domain
31
- assert response.body.match(/window\.top\.location\.href = "#{Regexp.escape(auth_url)}"/)
32
- end
33
-
34
- test "#new should render a full-page if the shop param doesn't exist" do
35
- get :new
36
- assert_response :ok
37
- assert_template :new
38
- end
39
-
40
- ['my-shop', 'my-shop.myshopify.com', 'https://my-shop.myshopify.com', 'http://my-shop.myshopify.com'].each do |good_url|
41
- test "#create should authenticate the shop for the URL (#{good_url})" do
42
- ShopifyApp.configuration.embedded_app = true
43
- auth_url = '/auth/shopify?shop=my-shop.myshopify.com'
44
- post :create, shop: good_url
45
- assert response.body.match(/window\.top\.location\.href = "#{Regexp.escape(auth_url)}"/)
46
- end
47
- end
48
-
49
- ['my-shop', 'my-shop.myshopify.io', 'https://my-shop.myshopify.io', 'http://my-shop.myshopify.io'].each do |good_url|
50
- test "#create should authenticate the shop for the URL (#{good_url}) with custom myshopify_domain" do
51
- ShopifyApp.configuration.embedded_app = true
52
- ShopifyApp.configuration.myshopify_domain = 'myshopify.io'
53
- auth_url = '/auth/shopify?shop=my-shop.myshopify.io'
54
- post :create, shop: good_url
55
- assert response.body.match(/window\.top\.location\.href = "#{Regexp.escape(auth_url)}"/)
56
- end
57
- end
58
-
59
- ['myshop.com', 'myshopify.com', 'shopify.com', 'two words', 'store.myshopify.com.evil.com', '/foo/bar'].each do |bad_url|
60
- test "#create should return an error for a non-myshopify URL (#{bad_url})" do
61
- post :create, shop: bad_url
62
- assert_redirected_to root_url
63
- end
64
- end
65
-
66
- test "#create should render the login page if the shop param doesn't exist" do
67
- post :create
68
- assert_redirected_to root_url
69
- end
70
-
71
- test "#callback should setup a shopify session" do
72
- mock_shopify_omniauth
73
-
74
- get :callback, shop: 'shop'
75
- assert_not_nil session[:shopify]
76
- assert_equal 'shop.myshopify.com', session[:shopify_domain]
77
- end
78
-
79
- test "#callback should start the WebhooksManager if webhooks are configured" do
80
- ShopifyApp.configure do |config|
81
- config.webhooks = [{topic: 'carts/update', address: 'example-app.com/webhooks'}]
82
- end
83
-
84
- ShopifyApp::WebhooksManager.expects(:queue)
85
-
86
- mock_shopify_omniauth
87
- get :callback, shop: 'shop'
88
- end
89
-
90
- test "#callback doesn't run the WebhooksManager if no webhooks are configured" do
91
- ShopifyApp.configure do |config|
92
- config.webhooks = []
93
- end
94
-
95
- ShopifyApp::WebhooksManager.expects(:queue).never
96
-
97
- mock_shopify_omniauth
98
- get :callback, shop: 'shop'
99
- end
100
-
101
- test "#destroy should clear shopify from session and redirect to login with notice" do
102
- shop_id = 1
103
- session[:shopify] = shop_id
104
- session[:shopify_domain] = 'shop1.myshopify.com'
105
-
106
- get :destroy
107
-
108
- assert_nil session[:shopify]
109
- assert_nil session[:shopify_domain]
110
- assert_redirected_to login_path
111
- refute flash[:notice].empty?
112
- end
113
-
114
- private
115
-
116
- def mock_shopify_omniauth
117
- OmniAuth.config.add_mock(:shopify, provider: :shopify, uid: 'shop.myshopify.com', credentials: {token: '1234'})
118
- request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:shopify] if request
119
- request.env['omniauth.params'] = { shop: 'shop.myshopify.com' } if request
120
- end
121
-
122
- end
@@ -1,27 +0,0 @@
1
- require 'test_helper'
2
-
3
- class SessionsRoutesTest < ActionController::TestCase
4
-
5
- setup do
6
- @routes = ShopifyApp::Engine.routes
7
- ShopifyApp::SessionRepository.storage = InMemorySessionStore
8
- ShopifyApp.configuration = nil
9
- end
10
-
11
- test "login routes to sessions#new" do
12
- assert_routing '/login', { controller: "sessions", action: "new" }
13
- end
14
-
15
- test "post login routes to sessions#create" do
16
- assert_routing({method: 'post', path: '/login'}, { controller: "sessions", action: "create" })
17
- end
18
-
19
- test "auth_shopify_callback routes to sessions#callback" do
20
- assert_routing '/auth/shopify/callback', { controller: "sessions", action: "callback" }
21
- end
22
-
23
- test "logout routes to sessions#destroy" do
24
- assert_routing '/logout', { controller: "sessions", action: "destroy" }
25
- end
26
-
27
- end
@@ -1,6 +0,0 @@
1
- # Add your own tasks in files placed in lib/tasks ending in .rake,
2
- # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
-
4
- require File.expand_path('../config/application', __FILE__)
5
-
6
- Rails.application.load_tasks
@@ -1,3 +0,0 @@
1
- class ApplicationController < ActionController::Base
2
- include ShopifyApp::Controller
3
- end
@@ -1,7 +0,0 @@
1
- class HomeController < ApplicationController
2
-
3
- def index
4
- 'index'
5
- end
6
-
7
- end
@@ -1,4 +0,0 @@
1
- # This file is used by Rack-based servers to start the application.
2
-
3
- require ::File.expand_path('../config/environment', __FILE__)
4
- run Rails.application
@@ -1,26 +0,0 @@
1
- require File.expand_path('../boot', __FILE__)
2
-
3
- require 'rails/all'
4
-
5
- Bundler.require(*Rails.groups)
6
- require "shopify_app"
7
-
8
- module Dummy
9
- class Application < Rails::Application
10
- # Settings in config/environments/* take precedence over those specified here.
11
- # Application configuration should go into files in config/initializers
12
- # -- all .rb files in that directory are automatically loaded.
13
-
14
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
15
- # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
16
- # config.time_zone = 'Central Time (US & Canada)'
17
-
18
- # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
19
- # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
20
- # config.i18n.default_locale = :de
21
-
22
- # Do not swallow errors in after_commit/after_rollback callbacks.
23
- config.active_record.raise_in_transactional_callbacks = true
24
- end
25
- end
26
-
@@ -1,5 +0,0 @@
1
- # Set up gems listed in the Gemfile.
2
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
-
4
- require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
5
- $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -1,25 +0,0 @@
1
- # SQLite version 3.x
2
- # gem install sqlite3
3
- #
4
- # Ensure the SQLite 3 gem is defined in your Gemfile
5
- # gem 'sqlite3'
6
- #
7
- default: &default
8
- adapter: sqlite3
9
- pool: 5
10
- timeout: 5000
11
-
12
- development:
13
- <<: *default
14
- database: db/development.sqlite3
15
-
16
- # Warning: The database defined as "test" will be erased and
17
- # re-generated from your development database when you run "rake".
18
- # Do not set this db to the same as development or production.
19
- test:
20
- <<: *default
21
- database: db/test.sqlite3
22
-
23
- production:
24
- <<: *default
25
- database: db/production.sqlite3
@@ -1,5 +0,0 @@
1
- # Load the Rails application.
2
- require File.expand_path('../application', __FILE__)
3
-
4
- # Initialize the Rails application.
5
- Rails.application.initialize!
@@ -1,42 +0,0 @@
1
- Rails.application.configure do
2
- # Settings specified here will take precedence over those in config/application.rb.
3
-
4
- # The test environment is used exclusively to run your application's
5
- # test suite. You never need to work with it otherwise. Remember that
6
- # your test database is "scratch space" for the test suite and is wiped
7
- # and recreated between test runs. Don't rely on the data there!
8
- config.cache_classes = true
9
-
10
- # Do not eager load code on boot. This avoids loading your whole application
11
- # just for the purpose of running a single test. If you are using a tool that
12
- # preloads Rails for running tests, you may have to set it to true.
13
- config.eager_load = false
14
-
15
- # Configure static file server for tests with Cache-Control for performance.
16
- config.serve_static_files = true
17
- config.static_cache_control = 'public, max-age=3600'
18
-
19
- # Show full error reports and disable caching.
20
- config.consider_all_requests_local = true
21
- config.action_controller.perform_caching = false
22
-
23
- # Raise exceptions instead of rendering exception templates.
24
- config.action_dispatch.show_exceptions = false
25
-
26
- # Disable request forgery protection in test environment.
27
- config.action_controller.allow_forgery_protection = false
28
-
29
- # Tell Action Mailer not to deliver emails to the real world.
30
- # The :test delivery method accumulates sent emails in the
31
- # ActionMailer::Base.deliveries array.
32
- config.action_mailer.delivery_method = :test
33
-
34
- # Randomize the order test cases are executed.
35
- config.active_support.test_order = :random
36
-
37
- # Print deprecation notices to the stderr.
38
- config.active_support.deprecation = :stderr
39
-
40
- # Raises error for missing translations
41
- # config.action_view.raise_on_missing_translations = true
42
- end
@@ -1,6 +0,0 @@
1
- ShopifyApp.configure do |config|
2
- config.api_key = "key"
3
- config.secret = "secret"
4
- config.scope = 'read_orders, read_products'
5
- config.embedded_app = true
6
- end
@@ -1,10 +0,0 @@
1
- Rails.application.routes.draw do
2
- root to: 'home#index'
3
-
4
- controller :sessions do
5
- get 'login' => :new, :as => :login
6
- post 'login' => :create, :as => :authenticate
7
- get 'auth/shopify/callback' => :callback
8
- get 'logout' => :destroy, :as => :logout
9
- end
10
- end
@@ -1,17 +0,0 @@
1
- # Be sure to restart your server when you modify this file.
2
-
3
- # Your secret key is used for verifying the integrity of signed cookies.
4
- # If you change this key, all old signed cookies will become invalid!
5
-
6
- # Make sure the secret is at least 30 characters and all random,
7
- # no regular words or you'll be exposed to dictionary attacks.
8
- # You can use `rake secret` to generate a secure secret key.
9
-
10
- # Make sure the secrets in this file are kept private
11
- # if you're sharing your code publicly.
12
-
13
- development:
14
- secret_key_base: aa26a2ea3384f82ea5ae33b4d80fc49ea0cda260418cf65a9c54958d02c4eadfba56e9e26728ee6e339c7f00628f0451abd7f0b0b042f5695097ec8b86b4e135
15
-
16
- test:
17
- secret_key_base: ed1af7104003edfc9f3f55ff6eaa0bc0c4a70c240128ca9c33d2f19d3ac326f63944b40488ef87118b53174601ce488e1ae6075f7f6e18e7968755c6d9decefb
@@ -1,16 +0,0 @@
1
- require 'test_helper'
2
- require 'generators/shopify_app/controllers/controllers_generator'
3
-
4
- class ControllersGeneratorTest < Rails::Generators::TestCase
5
- tests ShopifyApp::Generators::ControllersGenerator
6
- destination File.expand_path("../tmp", File.dirname(__FILE__))
7
- setup :prepare_destination
8
-
9
- test "copies ShopifyApp controllers to the host application" do
10
- run_generator
11
- assert_directory "app/controllers"
12
- assert_file "app/controllers/sessions_controller.rb"
13
- assert_file "app/controllers/authenticated_controller.rb"
14
- end
15
-
16
- end
@@ -1,50 +0,0 @@
1
- require 'test_helper'
2
- require 'generators/shopify_app/home_controller/home_controller_generator'
3
-
4
- class HomeControllerGeneratorTest < Rails::Generators::TestCase
5
- tests ShopifyApp::Generators::HomeControllerGenerator
6
- destination File.expand_path("../tmp", File.dirname(__FILE__))
7
-
8
- setup do
9
- ShopifyApp.configure do |config|
10
- config.embedded_app = true
11
- end
12
-
13
- prepare_destination
14
- provide_existing_application_file
15
- provide_existing_routes_file
16
- provide_existing_application_controller
17
- end
18
-
19
- test "creates the home controller" do
20
- run_generator
21
- assert_file "app/controllers/home_controller.rb"
22
- end
23
-
24
- test "creates the home index view with embedded options" do
25
- run_generator
26
- assert_file "app/views/home/index.html.erb" do |index|
27
- assert_match "ShopifyApp.ready", index
28
- end
29
- end
30
-
31
- test "creates the home index view with embedded false" do
32
- stub_embedded_false
33
- run_generator
34
- assert_file "app/views/home/index.html.erb" do |index|
35
- refute_match "ShopifyApp.ready", index
36
- end
37
- end
38
-
39
- test "adds engine and home route to routes" do
40
- run_generator
41
- assert_file "config/routes.rb" do |routes|
42
- assert_match "mount ShopifyApp::Engine, at: '/'", routes
43
- assert_match "root :to => 'home#index'", routes
44
- end
45
- end
46
-
47
- def stub_embedded_false
48
- ShopifyApp.configuration.embedded_app = false
49
- end
50
- end
@@ -1,87 +0,0 @@
1
- require 'test_helper'
2
- require 'generators/shopify_app/install/install_generator'
3
-
4
- class InstallGeneratorTest < Rails::Generators::TestCase
5
- tests ShopifyApp::Generators::InstallGenerator
6
- destination File.expand_path("../tmp", File.dirname(__FILE__))
7
-
8
- setup do
9
- prepare_destination
10
- provide_existing_application_file
11
- provide_existing_routes_file
12
- provide_existing_application_controller
13
- end
14
-
15
- test "creates the ShopifyApp initializer" do
16
- run_generator
17
- assert_file "config/initializers/shopify_app.rb" do |shopify_app|
18
- assert_match 'config.api_key = "<api_key>"', shopify_app
19
- assert_match 'config.secret = "<secret>"', shopify_app
20
- assert_match 'config.redirect_uri = "http://localhost:3000/auth/shopify/callback"', shopify_app
21
- assert_match 'config.scope = "read_orders, read_products"', shopify_app
22
- assert_match "config.embedded_app = true", shopify_app
23
- end
24
- end
25
-
26
- test "creates the ShopifyApp initializer for non embedded app" do
27
- stub_embedded_false
28
- run_generator
29
-
30
- assert_file "config/initializers/shopify_app.rb" do |shopify_app|
31
- assert_match "config.embedded_app = false", shopify_app
32
- end
33
- end
34
-
35
- test "creats and injects into omniauth initializer" do
36
- run_generator
37
- assert_file "config/initializers/omniauth.rb" do |omniauth|
38
- assert_match "provider :shopify", omniauth
39
- end
40
- end
41
-
42
- test "creates the default shopify_session_repository" do
43
- run_generator
44
- assert_file "config/initializers/shopify_session_repository.rb" do |file|
45
- assert_match "ShopifyApp::SessionRepository.storage = InMemorySessionStore", file
46
- end
47
- end
48
-
49
- test "adds the embedded app options to application.rb" do
50
- run_generator
51
- assert_file "config/application.rb" do |application|
52
- assert_match "config.action_dispatch.default_headers.delete('X-Frame-Options')", application
53
- assert_match "config.action_dispatch.default_headers['P3P'] = 'CP=\"Not used\"'", application
54
- end
55
- end
56
-
57
- test "doesn't add embedd options if -embedded false" do
58
- stub_embedded_false
59
- run_generator
60
- assert_file "config/application.rb" do |application|
61
- refute_match "config.action_dispatch.default_headers.delete('X-Frame-Options')", application
62
- refute_match "config.action_dispatch.default_headers['P3P'] = 'CP=\"Not used\"'", application
63
- end
64
- end
65
-
66
- test "injects into application controller" do
67
- run_generator
68
- assert_file "app/controllers/application_controller.rb" do |controller|
69
- assert_match " include ShopifyApp::Controller\n", controller
70
- end
71
- end
72
-
73
- test "creates the embedded_app layout" do
74
- run_generator
75
- assert_file "app/views/layouts/embedded_app.html.erb"
76
- assert_file "app/views/layouts/_flash_messages.html.erb"
77
- end
78
-
79
- private
80
-
81
- def stub_embedded_false
82
- ShopifyApp::Generators::InstallGenerator.any_instance.stubs(:opts).returns(
83
- {embedded: 'false'}
84
- )
85
- end
86
-
87
- end