clerk-sdk-ruby 2.0.4 → 2.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e443f464076d7d267af214c5e2d12847aec0bf5bac6e80479736d02fbf92a8ae
4
- data.tar.gz: a3b0457f1402594db56968d7af4e6dcc4674276f248083aad09f278530b22d57
3
+ metadata.gz: 0beece8585345751d91279f43af6fc81ea3bed2274988ffcaf711cd9e6212203
4
+ data.tar.gz: fe3cda34f2c460f9b79a1da4a68d5931c4ca68454e869afa27676c72d68414c3
5
5
  SHA512:
6
- metadata.gz: dfb091cbe8eb5a88881db5294927eb849d20e8f802a6cac697f8c865328a5a29afe69e3467eb1c8aea74265f96ce8d4ca0d93d1533513c0c6f6aad1e32537463
7
- data.tar.gz: 66e0af91ac94339b1b10f4507b936b9c38083cd1f5a9deb69cccfd8177e44c08f65d838e9bc00e8c543ac9396fffa19da7243eeb271ae203c3d2856ee3c5ba5f
6
+ metadata.gz: 94fdbacc63e4af0fc4084aad5db8a17904eda58c42f60b1f951e7dc351b3ea543299b12668bc96fad63a0afed7967f6d8e9eda4053b454a769601f4cee71a03b
7
+ data.tar.gz: 4fe7fee577704f10027ea812cacbbf7482b112b5a7423b041debfd332bb97cbc5cc2a2e026910aff8d7b0559e3d3132d7df4fc048e4c12c9507974a72d2ccec0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## unreleased
2
2
 
3
+ ## 2.1.2 - 2022-08-26
4
+
5
+ - fix: Gracefully handle invalid JSON in Authorization header [https://github.com/clerkinc/clerk-sdk-ruby/pull/16]
6
+
7
+ ## 2.1.1 - 2022-02-24
8
+
9
+ - fix: Make Authv2 middleware thread-safe
10
+
3
11
  ## 2.0.0 - 2021-10-21
4
12
 
5
13
  This release introduces the new networkless middleware which works with the new
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- clerk-sdk-ruby (1.0.3)
4
+ clerk-sdk-ruby (2.2.0)
5
5
  faraday (~> 1.4.1)
6
6
  jwt (~> 2.2)
7
7
 
@@ -22,9 +22,9 @@ GEM
22
22
  faraday-excon (1.1.0)
23
23
  faraday-net_http (1.0.1)
24
24
  faraday-net_http_persistent (1.2.0)
25
- jwt (2.2.3)
25
+ jwt (2.5.0)
26
26
  minitest (5.14.2)
27
- multipart-post (2.1.1)
27
+ multipart-post (2.2.3)
28
28
  rake (13.0.3)
29
29
  ruby2_keywords (0.0.5)
30
30
  timecop (0.9.4)
@@ -40,4 +40,4 @@ DEPENDENCIES
40
40
  timecop (~> 0.9.4)
41
41
 
42
42
  BUNDLED WITH
43
- 2.2.24
43
+ 2.2.32
data/README.md CHANGED
@@ -1,20 +1,25 @@
1
1
  # Clerk Ruby SDK
2
2
 
3
+
3
4
  Thank you for choosing [Clerk](https://clerk.dev/) for your authentication,
4
5
  session & user management needs!
5
6
 
6
7
  This SDK allows you to call the Clerk Backend API from Ruby code without having
7
8
  to implement the calls yourself.
8
9
 
9
- ---------
10
-
11
- **Note**: This is the v2 branch, which requires that you use [Auth
10
+ **Note**: You're looking at the main branch, which requires that you use [Auth
12
11
  v2](https://docs.clerk.dev/main-concepts/auth-v2).
13
12
 
14
- If you're looking for the legacy authentication scheme (Auth v1), refer to the
15
- [`main`](https://github.com/clerkinc/clerk-sdk-ruby/tree/main) branch.
13
+ If you're looking for the legacy authentication scheme, refer to the
14
+ [`v1`](https://github.com/clerkinc/clerk-sdk-ruby/tree/v1) branch.
15
+
16
+ ---
17
+
18
+ **Clerk is Hiring!**
19
+
20
+ Would you like to work on Open Source software and help maintain this repository? Apply today https://apply.workable.com/clerk-dev/.
16
21
 
17
- ----------
22
+ ---
18
23
 
19
24
  ## Installation
20
25
 
@@ -10,7 +10,7 @@ module Clerk
10
10
  # the Session object. Subsequent calls to this method will return the cached
11
11
  # Session object.
12
12
  #
13
- # NOTE: For better performance, you can instead use `#clerk_session_claims`
13
+ # NOTE: For better performance, you can instead use `#clerk_verified_session_claims`
14
14
  # which already contains the verified claims as retrieved from the session
15
15
  # token.
16
16
  def clerk_session
@@ -20,7 +20,7 @@ module Clerk
20
20
  # Makes a request to the Clerk API to verify the session again. Returns the
21
21
  # session object as fetched from the API.
22
22
  #
23
- # NOTE: For better performance, you can instead use `#clerk_session_claims`
23
+ # NOTE: For better performance, you can instead use `#clerk_verified_session_claims`
24
24
  # which already contains the verified claims as retrieved from the session
25
25
  # token.
26
26
  #
@@ -1,94 +1,107 @@
1
1
  require "clerk"
2
2
 
3
3
  module Clerk
4
- class RackMiddlewareV2
5
- class ProxyV2
6
- CACHE_TTL = 60 # seconds
4
+ class ProxyV2
5
+ CACHE_TTL = 60 # seconds
7
6
 
8
- attr_reader :session_claims, :session_token
7
+ attr_reader :session_claims, :session_token
9
8
 
10
- def initialize(session_claims: nil, session_token: nil)
11
- @session_claims = session_claims
12
- @session_token = session_token
13
- @session = nil
14
- end
9
+ def initialize(session_claims: nil, session_token: nil)
10
+ @session_claims = session_claims
11
+ @session_token = session_token
12
+ @session = nil
13
+ end
15
14
 
16
- def session
17
- return nil if @session_claims.nil?
15
+ def session
16
+ return nil if @session_claims.nil?
18
17
 
19
- @session ||= verify_session
20
- end
18
+ @session ||= verify_session
19
+ end
21
20
 
22
- def verify_session
23
- return nil if @session_claims.nil?
21
+ def verify_session
22
+ return nil if @session_claims.nil?
24
23
 
25
- sdk.sessions.verify_token(@session_claims["sid"], @session_token)
26
- end
24
+ sdk.sessions.verify_token(@session_claims["sid"], @session_token)
25
+ end
27
26
 
28
- def user
29
- return nil if user_id.nil?
27
+ def user
28
+ return nil if user_id.nil?
30
29
 
31
- @user ||= fetch_user(user_id)
32
- end
30
+ @user ||= fetch_user(user_id)
31
+ end
33
32
 
34
- def user_id
35
- return nil if @session_claims.nil?
33
+ def user_id
34
+ return nil if @session_claims.nil?
36
35
 
37
- @session_claims["sub"]
38
- end
36
+ @session_claims["sub"]
37
+ end
39
38
 
40
- private
39
+ private
41
40
 
42
- def fetch_user(user_id)
43
- cached_fetch("clerk_user:#{user_id}") do
44
- sdk.users.find(user_id)
45
- end
41
+ def fetch_user(user_id)
42
+ cached_fetch("clerk_user:#{user_id}") do
43
+ sdk.users.find(user_id)
46
44
  end
45
+ end
47
46
 
48
- def cached_fetch(key, &block)
49
- if store = Clerk.configuration.middleware_cache_store
50
- store.fetch(key, expires_in: CACHE_TTL, &block)
51
- else
52
- yield
53
- end
47
+ def cached_fetch(key, &block)
48
+ if store = Clerk.configuration.middleware_cache_store
49
+ store.fetch(key, expires_in: CACHE_TTL, &block)
50
+ else
51
+ yield
54
52
  end
53
+ end
55
54
 
56
- def sdk
57
- @sdk ||= Clerk::SDK.new
58
- end
55
+ def sdk
56
+ @sdk ||= Clerk::SDK.new
59
57
  end
58
+ end
60
59
 
60
+ class RackMiddlewareV2
61
61
  def initialize(app)
62
62
  @app = app
63
63
  end
64
64
 
65
65
  def call(env)
66
- @env = env
67
- @req = Rack::Request.new(env)
68
- @env["clerk"] = ProxyV2.new
69
- @header_token = @req.env["HTTP_AUTHORIZATION"]
70
- @header_token = @header_token.strip.sub(/\ABearer /, '') if @header_token
71
- @cookie_token = @req.cookies["__session"]
72
- @client_uat = @req.cookies["__client_uat"]
66
+ env = env
67
+ req = Rack::Request.new(env)
68
+ env["clerk"] = Clerk::ProxyV2.new
69
+ header_token = req.env["HTTP_AUTHORIZATION"]
70
+ header_token = header_token.strip.sub(/\ABearer /, '') if header_token
71
+ cookie_token = req.cookies["__session"]
72
+ client_uat = req.cookies["__client_uat"]
73
73
 
74
74
  ##########################################################################
75
75
  # #
76
76
  # HEADER AUTHENTICATION #
77
77
  # #
78
78
  ##########################################################################
79
- if @header_token
80
- return signed_out if !sdk.decode_token(@header_token) # malformed JWT
81
-
82
- token = verify_token(@header_token)
83
- return signed_in(token, @header_token) if token
79
+ if header_token
80
+ begin
81
+ return signed_out(env) if !sdk.decode_token(header_token) # malformed JWT
82
+ rescue JWT::DecodeError
83
+ return signed_out(env) # malformed JSON authorization header
84
+ end
85
+
86
+ token = verify_token(header_token)
87
+ return signed_in(env, token, header_token) if token
84
88
 
85
89
  # Clerk.js should refresh the token and retry
86
90
  return unknown(interstitial: false)
87
91
  end
88
92
 
89
93
  # in cross-origin XHRs the use of Authorization header is mandatory.
90
- if cross_origin_request?(@req)
91
- return signed_out
94
+ if cross_origin_request?(req)
95
+ return signed_out(env)
96
+ end
97
+
98
+ if development_or_staging? && !browser_request?(req)
99
+ # the interstitial won't work if the user agent is not a browser, so
100
+ # short-circuit and avoid rendering it
101
+ #
102
+ # We only limit this to dev/stg because we're not yet sure how robust
103
+ # this strategy is, yet. In the future, we might enable it for prod too.
104
+ return signed_out(env)
92
105
  end
93
106
 
94
107
  ##########################################################################
@@ -96,22 +109,22 @@ module Clerk
96
109
  # COOKIE AUTHENTICATION #
97
110
  # #
98
111
  ##########################################################################
99
- if development_or_staging? && (@req.referrer.nil? || cross_origin_request?(@req))
112
+ if development_or_staging? && (req.referrer.nil? || cross_origin_request?(req))
100
113
  return unknown(interstitial: true)
101
114
  end
102
115
 
103
- if production? && @client_uat.nil?
104
- return signed_out
116
+ if production? && client_uat.nil?
117
+ return signed_out(env)
105
118
  end
106
119
 
107
- if @client_uat == "0"
108
- return signed_out
120
+ if client_uat == "0"
121
+ return signed_out(env)
109
122
  end
110
123
 
111
- token = verify_token(@cookie_token)
124
+ token = verify_token(cookie_token)
112
125
 
113
- if token && token["iat"] && @client_uat && Integer(@client_uat) <= token["iat"]
114
- return signed_in(token, @cookie_token)
126
+ if token && token["iat"] && client_uat && Integer(client_uat) <= token["iat"]
127
+ return signed_in(env, token, cookie_token)
115
128
  end
116
129
 
117
130
  unknown(interstitial: true)
@@ -120,15 +133,15 @@ module Clerk
120
133
  private
121
134
 
122
135
  # Outcome A
123
- def signed_in(claims, token)
124
- @env["clerk"] = ProxyV2.new(session_claims: claims, session_token: token)
136
+ def signed_in(env, claims, token)
137
+ env["clerk"] = ProxyV2.new(session_claims: claims, session_token: token)
125
138
 
126
- @app.call(@env)
139
+ @app.call(env)
127
140
  end
128
141
 
129
142
  # Outcome B
130
- def signed_out
131
- @app.call(@env)
143
+ def signed_out(env)
144
+ @app.call(env)
132
145
  end
133
146
 
134
147
  # Outcome C
@@ -165,18 +178,24 @@ module Clerk
165
178
  origin != request_host
166
179
  end
167
180
 
181
+ def browser_request?(req)
182
+ user_agent = req.env["HTTP_USER_AGENT"]
183
+
184
+ !user_agent.nil? && user_agent.starts_with?("Mozilla/")
185
+ end
186
+
168
187
  def verify_token(token)
169
188
  return false if token.nil? || token.strip.empty?
170
189
 
171
190
  begin
172
- @session = sdk.verify_token(token)
191
+ sdk.verify_token(token)
173
192
  rescue JWT::DecodeError, JWT::RequiredDependencyError => e
174
193
  false
175
194
  end
176
195
  end
177
196
 
178
197
  def sdk
179
- @sdk ||= Clerk::SDK.new
198
+ Clerk::SDK.new
180
199
  end
181
200
  end
182
201
  end
@@ -11,7 +11,7 @@ module Clerk
11
11
  @resource = PluralResource.new(client, "users")
12
12
  end
13
13
 
14
- def_delegators :@resource, :all, :find, :update, :delete
14
+ def_delegators :@resource, :all, :find, :create, :update, :delete
15
15
 
16
16
  def oauth_access_token(user_id, provider)
17
17
  @client.request(:get, "#{@resource.resource_path(user_id)}/oauth_access_tokens/#{provider}")
data/lib/clerk/sdk.rb CHANGED
@@ -20,7 +20,8 @@ require_relative "errors"
20
20
  module Clerk
21
21
  class SDK
22
22
  DEFAULT_HEADERS = {
23
- "User-Agent" => "Clerk/#{Clerk::VERSION}; Faraday/#{Faraday::VERSION}; Ruby/#{RUBY_VERSION}"
23
+ "User-Agent" => "Clerk/#{Clerk::VERSION}; Faraday/#{Faraday::VERSION}; Ruby/#{RUBY_VERSION}",
24
+ "X-Clerk-SDK" => "ruby/#{Clerk::VERSION}"
24
25
  }
25
26
 
26
27
  # How often (in seconds) should JWKs be refreshed
data/lib/clerk/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Clerk
4
- VERSION = "2.0.4"
4
+ VERSION = "2.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clerk-sdk-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clerk
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-25 00:00:00.000000000 Z
11
+ date: 2022-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  - !ruby/object:Gem::Version
128
128
  version: '0'
129
129
  requirements: []
130
- rubygems_version: 3.2.5
130
+ rubygems_version: 3.2.32
131
131
  signing_key:
132
132
  specification_version: 4
133
133
  summary: Clerk SDK for Ruby.