lucid-shopify-session 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9ab531b412e4121b375dfc46db8194436b0a00f42d7abc5a92424663fc8db1a5
4
+ data.tar.gz: 174d49b35b6ee27a16c06033950134eca1f1e8b6a9cc0d7d361075108e3b3a31
5
+ SHA512:
6
+ metadata.gz: e3bb3f3cc25fac5b93c9fe49a64c5bdefcb21c37f439bddfe8c81ed5d698bc52d9fa53f4d1dc04da7aae67bca20c5d60b7af132a65e0d688c6f6d6e3712aa168
7
+ data.tar.gz: cdd5992a9d7b7cbde6f8af8b237d4d3420eb08026c427bdb4dbdf72b89432344d9935d2c209547e3a5649038752859c1b455bac59d38e2bee747ef8b0fa28613
@@ -0,0 +1,30 @@
1
+ lucid-shopify-session
2
+ =====================
3
+
4
+ This is [Shopify's new cookieless authentication][0] method for embedded apps,
5
+ which makes use of session tokens provided by App Bridge to identify the shop.
6
+ Session cookies are no longer viable due to browsers (starting with Safari)
7
+ disabling third-party cookies by default. It is possible to work around, but
8
+ quite impractical and harmful to the user experience, so all embedded apps
9
+ should use this new method going forward.
10
+
11
+ This method also replaces CSRF tokens, as the JWT provides the same protection
12
+ considering that the signed JWT must originate from the Shopify admin (with the
13
+ shared secret), so authenticated requests cannot be forged.
14
+
15
+ [0]: https://shopify.dev/tools/app-bridge/authentication
16
+
17
+
18
+ Installation
19
+ ------------
20
+
21
+ Add the gem to your ‘Gemfile’:
22
+
23
+ gem 'lucid-shopify'
24
+ gem 'lucid-shopify-session'
25
+
26
+
27
+ Usage
28
+ -----
29
+
30
+ _WIP_
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lucid/shopify/session'
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lucid
4
+ module Shopify
5
+ module Session
6
+ autoload :Authorise, 'lucid/shopify/session/authorise'
7
+ autoload :DecodeSessionToken, 'lucid/shopify/session/decode_session_token'
8
+ autoload :Middleware, 'lucid/shopify/session/middleware'
9
+ autoload :VERSION, 'lucid/shopify/session/version'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'lucid-shopify-session'
5
+
6
+ module Lucid
7
+ module Shopify
8
+ module Session
9
+ class Authorise
10
+ UnauthorisedError = Class.new(Error)
11
+
12
+ # @param env [Hash]
13
+ #
14
+ # @raise [UnauthorisedError]
15
+ def call(env)
16
+ session_token = env['HTTP_AUTHORIZATION']&.[](/Bearer (\S+)/, 1) || ''
17
+
18
+ env['lucid-shopify-session.shop'] = DecodeSessionToken.new.(session_token)
19
+ rescue DecodeSessionToken::Error
20
+ raise UnauthorisedError
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lucid-shopify'
4
+ require 'jwt'
5
+
6
+ module Lucid
7
+ module Shopify
8
+ module Session
9
+ class DecodeSessionToken
10
+ Error = Class.new(Error)
11
+
12
+ # @param token [String]
13
+ #
14
+ # @return [String] the *.myshopify.com domain of the authenticated shop
15
+ #
16
+ # @raise [Error]
17
+ def call(token)
18
+ payload, _ = JWT.decode(token, Shopify.config.shared_secret, true, algorithm: 'HS256')
19
+
20
+ raise Error unless valid?(payload)
21
+
22
+ myshopify_domain(payload)
23
+ rescue JWT::DecodeError
24
+ raise Error
25
+ end
26
+
27
+ # @param payload [Hash]
28
+ #
29
+ # @return [String]
30
+ private def myshopify_domain(payload)
31
+ payload['dest'].sub('https://', '')
32
+ end
33
+
34
+ # @param payload [Hash]
35
+ #
36
+ # @return [Boolean]
37
+ private def valid?(payload)
38
+ return false unless payload['aud'] == Shopify.config.api_key
39
+ return false unless payload['iss'].start_with?(payload['dest'])
40
+ return true
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'lucid-shopify-session'
5
+
6
+ module Lucid
7
+ module Shopify
8
+ module Session
9
+ class Middleware
10
+ # @param app [#call]
11
+ def initialize(app)
12
+ @app = app
13
+ end
14
+
15
+ # @param env [Hash]
16
+ #
17
+ # @param [Array<Integer, Hash{String => String}, Array<String>]
18
+ def call(env)
19
+ Authorise.new.(env)
20
+
21
+ @app.call(env)
22
+ rescue UnauthorisedError
23
+ Rack::Response.new do |res|
24
+ res.status = 401
25
+ res.set_header('Content-Type', 'application/json')
26
+ res.write({
27
+ error: 'Invalid session token',
28
+ }.to_json)
29
+ end.to_a
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lucid
4
+ module Shopify
5
+ module Session
6
+ VERSION = '0.0.1'
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lucid-shopify-session
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kelsey Judson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.89'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.89'
41
+ - !ruby/object:Gem::Dependency
42
+ name: jwt
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: lucid-shopify
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.64'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.64'
69
+ description:
70
+ email: kelsey@kelseyjudson.dev
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - README.md
76
+ - lib/lucid-shopify-session.rb
77
+ - lib/lucid/shopify/session.rb
78
+ - lib/lucid/shopify/session/authorise.rb
79
+ - lib/lucid/shopify/session/decode_session_token.rb
80
+ - lib/lucid/shopify/session/middleware.rb
81
+ - lib/lucid/shopify/session/version.rb
82
+ homepage: https://github.com/kj/lucid-shopify-session
83
+ licenses:
84
+ - ISC
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubygems_version: 3.1.4
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Shopify client library session token helpers for embedded apps
105
+ test_files: []