shopify_app 6.4.2 → 7.0.0

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