duodealer_app 1.0.0 → 1.0.1

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 (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/controllers/duodealer_app/callback_controller.rb +10 -10
  4. data/app/controllers/duodealer_app/sessions_controller.rb +23 -23
  5. data/app/controllers/duodealer_app/webhooks_controller.rb +1 -1
  6. data/lib/duodealer_app/controller_concerns/login_protection.rb +29 -29
  7. data/lib/duodealer_app/controller_concerns/webhook_verification.rb +2 -2
  8. data/lib/duodealer_app/jobs/scripttags_manager_job.rb +3 -3
  9. data/lib/duodealer_app/jobs/webhooks_manager_job.rb +2 -2
  10. data/lib/duodealer_app/version.rb +1 -1
  11. data/lib/generators/duodealer_app/install/templates/duodealer_provider.rb +0 -2
  12. data/lib/generators/duodealer_app/rotate_duodealer_token_job/templates/rotate_duodealer_token_job.rb +7 -7
  13. metadata +2 -18
  14. data/app/controllers/concerns/duodealer_app/authenticated.rb-e +0 -15
  15. data/app/controllers/duodealer_app/authenticated_controller.rb-e +0 -9
  16. data/app/controllers/duodealer_app/callback_controller.rb-e +0 -104
  17. data/app/controllers/duodealer_app/extension_verification_controller.rb-e +0 -19
  18. data/app/controllers/duodealer_app/sessions_controller.rb-e +0 -159
  19. data/app/controllers/duodealer_app/webhooks_controller.rb-e +0 -37
  20. data/app/views/duodealer_app/partials/_button_styles.html.erb-e +0 -104
  21. data/app/views/duodealer_app/partials/_card_styles.html.erb-e +0 -33
  22. data/app/views/duodealer_app/partials/_empty_state_styles.html.erb-e +0 -129
  23. data/app/views/duodealer_app/partials/_layout_styles.html.erb-e +0 -167
  24. data/app/views/duodealer_app/partials/_typography_styles.html.erb-e +0 -35
  25. data/app/views/duodealer_app/sessions/enable_cookies.html.erb-e +0 -75
  26. data/app/views/duodealer_app/sessions/new.html.erb-e +0 -123
  27. data/app/views/duodealer_app/sessions/request_storage_access.html.erb-e +0 -68
  28. data/app/views/duodealer_app/sessions/top_level_interaction.html.erb-e +0 -64
  29. data/app/views/duodealer_app/shared/redirect.html.erb-e +0 -23
@@ -3,16 +3,16 @@
3
3
  module Duodealer
4
4
  class RotateDuodealerTokenJob < ActiveJob::Base
5
5
  def perform(params)
6
- @shop = Shop.find_by(duodealer_domain: params[:shop_domain])
7
- return unless @shop
6
+ @account = Account.find_by(duodealer_domain: params[:account_domain])
7
+ return unless @account
8
8
 
9
9
  config = DuodealerApp.configuration
10
- uri = URI("https://#{@shop.duodealer_domain}/admin/oauth/access_token")
10
+ uri = URI("https://#{@account.duodealer_domain}/admin/oauth/access_token")
11
11
  post_data = {
12
12
  client_id: config.api_key,
13
13
  client_secret: config.secret,
14
14
  refresh_token: params[:refresh_token],
15
- access_token: @shop.duodealer_token,
15
+ access_token: @account.duodealer_token,
16
16
  }
17
17
 
18
18
  @response = Net::HTTP.post_form(uri, post_data)
@@ -21,7 +21,7 @@ module Duodealer
21
21
  access_token = JSON.parse(@response.body)['access_token']
22
22
  return log_error(no_access_token_error_message) unless access_token
23
23
 
24
- @shop.update(duodealer_token: access_token)
24
+ @account.update(duodealer_token: access_token)
25
25
  end
26
26
 
27
27
  private
@@ -31,11 +31,11 @@ module Duodealer
31
31
  end
32
32
 
33
33
  def no_access_token_error_message
34
- "RotateDuodealerTokenJob response returned no access token for shop: #{@shop.duodealer_domain}"
34
+ "RotateDuodealerTokenJob response returned no access token for account: #{@account.duodealer_domain}"
35
35
  end
36
36
 
37
37
  def response_exception_error_message
38
- "RotateDuodealerTokenJob failed for shop: #{@shop.duodealer_domain}." \
38
+ "RotateDuodealerTokenJob failed for account: #{@account.duodealer_domain}." \
39
39
  "Response returned status: #{@response.code}. Error message: #{@response.message}. "
40
40
  end
41
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duodealer_app
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Raio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-22 00:00:00.000000000 Z
11
+ date: 2020-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: browser_sniffer
@@ -234,37 +234,21 @@ files:
234
234
  - app/assets/javascripts/duodealer_app/top_level.js
235
235
  - app/assets/javascripts/duodealer_app/top_level_interaction.js
236
236
  - app/controllers/concerns/duodealer_app/authenticated.rb
237
- - app/controllers/concerns/duodealer_app/authenticated.rb-e
238
237
  - app/controllers/duodealer_app/authenticated_controller.rb
239
- - app/controllers/duodealer_app/authenticated_controller.rb-e
240
238
  - app/controllers/duodealer_app/callback_controller.rb
241
- - app/controllers/duodealer_app/callback_controller.rb-e
242
239
  - app/controllers/duodealer_app/extension_verification_controller.rb
243
- - app/controllers/duodealer_app/extension_verification_controller.rb-e
244
240
  - app/controllers/duodealer_app/sessions_controller.rb
245
- - app/controllers/duodealer_app/sessions_controller.rb-e
246
241
  - app/controllers/duodealer_app/webhooks_controller.rb
247
- - app/controllers/duodealer_app/webhooks_controller.rb-e
248
242
  - app/views/duodealer_app/partials/_button_styles.html.erb
249
- - app/views/duodealer_app/partials/_button_styles.html.erb-e
250
243
  - app/views/duodealer_app/partials/_card_styles.html.erb
251
- - app/views/duodealer_app/partials/_card_styles.html.erb-e
252
244
  - app/views/duodealer_app/partials/_empty_state_styles.html.erb
253
- - app/views/duodealer_app/partials/_empty_state_styles.html.erb-e
254
245
  - app/views/duodealer_app/partials/_layout_styles.html.erb
255
- - app/views/duodealer_app/partials/_layout_styles.html.erb-e
256
246
  - app/views/duodealer_app/partials/_typography_styles.html.erb
257
- - app/views/duodealer_app/partials/_typography_styles.html.erb-e
258
247
  - app/views/duodealer_app/sessions/enable_cookies.html.erb
259
- - app/views/duodealer_app/sessions/enable_cookies.html.erb-e
260
248
  - app/views/duodealer_app/sessions/new.html.erb
261
- - app/views/duodealer_app/sessions/new.html.erb-e
262
249
  - app/views/duodealer_app/sessions/request_storage_access.html.erb
263
- - app/views/duodealer_app/sessions/request_storage_access.html.erb-e
264
250
  - app/views/duodealer_app/sessions/top_level_interaction.html.erb
265
- - app/views/duodealer_app/sessions/top_level_interaction.html.erb-e
266
251
  - app/views/duodealer_app/shared/redirect.html.erb
267
- - app/views/duodealer_app/shared/redirect.html.erb-e
268
252
  - config/locales/cs.yml
269
253
  - config/locales/da.yml
270
254
  - config/locales/de.yml
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DuodealerApp
4
- module Authenticated
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- include DuodealerApp::Localization
9
- include DuodealerApp::LoginProtection
10
- include DuodealerApp::EmbeddedApp
11
- before_action :login_again_if_different_user_or_shop
12
- around_action :duodealer_session
13
- end
14
- end
15
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DuodealerApp
4
- class AuthenticatedController < ApplicationController
5
- include DuodealerApp::Authenticated
6
-
7
- protect_from_forgery with: :exception
8
- end
9
- end
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DuodealerApp
4
- # Performs login after OAuth completes
5
- class CallbackController < ApplicationController
6
- include DuodealerApp::LoginProtection
7
-
8
- def callback
9
- if auth_hash
10
- login_shop
11
- install_webhooks
12
- install_scripttags
13
- perform_after_authenticate_job
14
-
15
- redirect_to return_address
16
- else
17
- flash[:error] = I18n.t("could_not_log_in")
18
- redirect_to(login_url_with_optional_shop)
19
- end
20
- end
21
-
22
- private
23
- def login_shop
24
- reset_session_options
25
- set_duodealer_session
26
- end
27
-
28
- def auth_hash
29
- request.env["omniauth.auth"]
30
- end
31
-
32
- def shop_name
33
- auth_hash.uid
34
- end
35
-
36
- def associated_user
37
- return if auth_hash["extra"].blank?
38
-
39
- auth_hash["extra"]["associated_user"]
40
- end
41
-
42
- def token
43
- auth_hash["credentials"]["token"]
44
- end
45
-
46
- def reset_session_options
47
- request.session_options[:renew] = true
48
- session.delete(:_csrf_token)
49
- end
50
-
51
- def set_duodealer_session
52
- session_store = DuodealerAPI::Session.new(
53
- domain: shop_name,
54
- token: token,
55
- api_version: DuodealerApp.configuration.api_version
56
- )
57
- session[:duodealer] = DuodealerApp::SessionRepository.store(session_store, user: associated_user)
58
- session[:duodealer_domain] = shop_name
59
- session[:duodealer_user] = associated_user
60
-
61
- if DuodealerApp.configuration.per_user_tokens?
62
- # Adds the user_session to the session to determine if the logged in user has changed
63
- user_session = auth_hash&.extra&.session
64
- raise IndexError, "Missing user session signature" if user_session.nil?
65
- session[:user_session] = user_session
66
- end
67
- end
68
-
69
- def install_webhooks
70
- return unless DuodealerApp.configuration.has_webhooks?
71
-
72
- WebhooksManager.queue(
73
- shop_name,
74
- token,
75
- DuodealerApp.configuration.webhooks
76
- )
77
- end
78
-
79
- def install_scripttags
80
- return unless DuodealerApp.configuration.has_scripttags?
81
-
82
- ScripttagsManager.queue(
83
- shop_name,
84
- token,
85
- DuodealerApp.configuration.scripttags
86
- )
87
- end
88
-
89
- def perform_after_authenticate_job
90
- config = DuodealerApp.configuration.after_authenticate_job
91
-
92
- return unless config && config[:job].present?
93
-
94
- job = config[:job]
95
- job = job.constantize if job.is_a?(String)
96
-
97
- if config[:inline] == true
98
- job.perform_now(shop_domain: session[:duodealer_domain])
99
- else
100
- job.perform_later(shop_domain: session[:duodealer_domain])
101
- end
102
- end
103
- end
104
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DuodealerApp
4
- class ExtensionVerificationController < ApplicationController
5
- protect_from_forgery with: :null_session
6
- before_action :verify_request
7
-
8
- private
9
- def verify_request
10
- hmac_header = request.headers["HTTP_X_DUODEALER_HMAC_SHA256"]
11
- request_body = request.body.read
12
- secret = DuodealerApp.configuration.secret
13
- digest = OpenSSL::Digest.new("sha256")
14
-
15
- expected_hmac = Base64.strict_encode64(OpenSSL::HMAC.digest(digest, secret, request_body))
16
- head(:unauthorized) unless ActiveSupport::SecurityUtils.secure_compare(expected_hmac, hmac_header)
17
- end
18
- end
19
- end
@@ -1,159 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DuodealerApp
4
- class SessionsController < ApplicationController # rubocop:disable Metrics/ClassLength
5
- include DuodealerApp::LoginProtection
6
-
7
- layout false, only: :new
8
- after_action only: [:new, :create] do |controller|
9
- controller.response.headers.except!("X-Frame-Options")
10
- end
11
-
12
- def new
13
- authenticate if sanitized_shop_name.present?
14
- end
15
-
16
- def create
17
- authenticate
18
- end
19
-
20
- def enable_cookies
21
- return unless validate_shop
22
-
23
- render(:enable_cookies, layout: false, locals: {
24
- does_not_have_storage_access_url: top_level_interaction_path(
25
- shop: sanitized_shop_name,
26
- return_to: params[:return_to]
27
- ),
28
- has_storage_access_url: login_url_with_optional_shop(top_level: true),
29
- app_target_url: granted_storage_access_path(
30
- shop: sanitized_shop_name,
31
- return_to: params[:return_to]
32
- ),
33
- current_duodealer_domain: current_duodealer_domain
34
- })
35
- end
36
-
37
- def top_level_interaction
38
- @url = login_url_with_optional_shop(top_level: true)
39
- validate_shop
40
- end
41
-
42
- def granted_storage_access
43
- return unless validate_shop
44
-
45
- session["duodealer.granted_storage_access"] = true
46
-
47
- copy_return_to_param_to_session
48
-
49
- redirect_to(return_address_with_params({ shop: @shop }))
50
- end
51
-
52
- def destroy
53
- reset_session
54
- flash[:notice] = I18n.t(".logged_out")
55
- redirect_to(login_url_with_optional_shop)
56
- end
57
-
58
- private
59
- def authenticate
60
- return render_invalid_shop_error if sanitized_shop_name.blank?
61
- session["duodealer.omniauth_params"] = { shop: sanitized_shop_name }
62
-
63
- copy_return_to_param_to_session
64
-
65
- if user_agent_can_partition_cookies
66
- authenticate_with_partitioning
67
- else
68
- authenticate_normally
69
- end
70
- end
71
-
72
- def authenticate_normally
73
- if request_storage_access?
74
- redirect_to_request_storage_access
75
- elsif authenticate_in_context?
76
- authenticate_in_context
77
- else
78
- authenticate_at_top_level
79
- end
80
- end
81
-
82
- def authenticate_with_partitioning
83
- if session["duodealer.cookies_persist"]
84
- clear_top_level_oauth_cookie
85
- authenticate_in_context
86
- else
87
- set_top_level_oauth_cookie
88
- enable_cookie_access
89
- end
90
- end
91
-
92
- def validate_shop
93
- @shop = sanitized_shop_name
94
- unless @shop
95
- render_invalid_shop_error
96
- return false
97
- end
98
-
99
- true
100
- end
101
-
102
- def copy_return_to_param_to_session
103
- session[:return_to] = params[:return_to] if params[:return_to]
104
- end
105
-
106
- def render_invalid_shop_error
107
- flash[:error] = I18n.t("invalid_shop_url")
108
- redirect_to return_address
109
- end
110
-
111
- def enable_cookie_access
112
- fullpage_redirect_to(enable_cookies_path(
113
- shop: sanitized_shop_name,
114
- return_to: session[:return_to]
115
- ))
116
- end
117
-
118
- def authenticate_in_context
119
- redirect_to "#{main_app.root_path}auth/duodealer"
120
- end
121
-
122
- def authenticate_at_top_level
123
- fullpage_redirect_to(login_url_with_optional_shop(top_level: true))
124
- end
125
-
126
- def authenticate_in_context?
127
- return true unless DuodealerApp.configuration.embedded_app?
128
- params[:top_level]
129
- end
130
-
131
- def request_storage_access?
132
- return false unless DuodealerApp.configuration.embedded_app?
133
- return false if params[:top_level]
134
- return false if user_agent_is_mobile
135
- return false if user_agent_is_pos
136
-
137
- !session["duodealer.granted_storage_access"]
138
- end
139
-
140
- def redirect_to_request_storage_access
141
- render(
142
- :request_storage_access,
143
- layout: false,
144
- locals: {
145
- does_not_have_storage_access_url: top_level_interaction_path(
146
- shop: sanitized_shop_name,
147
- return_to: session[:return_to]
148
- ),
149
- has_storage_access_url: login_url_with_optional_shop(top_level: true),
150
- app_target_url: granted_storage_access_path(
151
- shop: sanitized_shop_name,
152
- return_to: session[:return_to]
153
- ),
154
- current_duodealer_domain: current_duodealer_domain
155
- }
156
- )
157
- end
158
- end
159
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DuodealerApp
4
- class WebhooksController < ApplicationController
5
- include DuodealerApp::WebhookVerification
6
-
7
- class DuodealerApp::MissingWebhookJobError < StandardError; end
8
-
9
- def receive
10
- params.permit!
11
- job_args = { shop_domain: shop_domain, webhook: webhook_params.to_h }
12
- webhook_job_klass.perform_later(job_args)
13
- head :no_content
14
- end
15
-
16
- private
17
- def webhook_params
18
- params.except(:controller, :action, :type)
19
- end
20
-
21
- def webhook_job_klass
22
- webhook_job_klass_name.safe_constantize || raise(DuodealerApp::MissingWebhookJobError)
23
- end
24
-
25
- def webhook_job_klass_name(type = webhook_type)
26
- [webhook_namespace, "#{type}_job"].compact.join("/").classify
27
- end
28
-
29
- def webhook_type
30
- params[:type]
31
- end
32
-
33
- def webhook_namespace
34
- DuodealerApp.configuration.webhook_jobs_namespace
35
- end
36
- end
37
- end