clerk-sdk-ruby 2.0.2 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14a199089622ba34863506e79d0dc93dfe86f88c7d1d2c2543bb6b15fb5fd927
4
- data.tar.gz: 58e580b74208bcc0da98492257975c9d155c39b0e1c9c1704fae04e9cbeec57e
3
+ metadata.gz: 8a1b17c701d86ec55c4519f72231005a5b83efc07af4180ae98a292a63e422a5
4
+ data.tar.gz: 204eb5ac27340d5d4fc64c7edfc93287c293b9c3d973977b5aa1f87e3ba53ea9
5
5
  SHA512:
6
- metadata.gz: 2dec6b419ca2398552cfb9806b046acee03a5440d122e53fac73446863f52c04d1ffc5009fa3458d88774092b79de2d603b10fc5beb7b3ab6124a0137e2aa679
7
- data.tar.gz: d92a5e3dbf790b9ad0459f3c209ab2721077075bd9c574523b4ce6f7b2f8d7b1023fcf33aa9f21572215db63eb270c1f68e51cd2d5ed501206ff664c1e5d6e25
6
+ metadata.gz: af8693eb43e6f61133966fc47d3ee884697df94c1415fd05d921e6ff35f66807c47e65fba24d51d09db2f9e6177c0624267181ac42f0ea566c580c4c503c95fd
7
+ data.tar.gz: b46bd350059257dcb2b8f8b6d164ead13b563921417ea766b1a4d9847ed5aaa992755f21445ba899503b4f5587b95493121ff3d1a0c7206634f21125611d34ed
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## unreleased
2
2
 
3
+ ## 2.1.1 - 2022-02-24
4
+
5
+ - fix: Make Authv2 middleware thread-safe
6
+
3
7
  ## 2.0.0 - 2021-10-21
4
8
 
5
9
  This release introduces the new networkless middleware which works with the new
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
 
@@ -1,93 +1,103 @@
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"]&.strip
70
- @cookie_token = @req.cookies["__session"]
71
- @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"]
72
73
 
73
74
  ##########################################################################
74
75
  # #
75
76
  # HEADER AUTHENTICATION #
76
77
  # #
77
78
  ##########################################################################
78
- if @header_token
79
- return signed_out if !sdk.decode_token(@header_token) # malformed JWT
79
+ if header_token
80
+ return signed_out(env) if !sdk.decode_token(header_token) # malformed JWT
80
81
 
81
- token = verify_token(@header_token)
82
- return signed_in(token, @header_token) if token
82
+ token = verify_token(header_token)
83
+ return signed_in(env, token, header_token) if token
83
84
 
84
85
  # Clerk.js should refresh the token and retry
85
86
  return unknown(interstitial: false)
86
87
  end
87
88
 
88
89
  # in cross-origin XHRs the use of Authorization header is mandatory.
89
- if cross_origin_request?(@req)
90
- return signed_out
90
+ if cross_origin_request?(req)
91
+ return signed_out(env)
92
+ end
93
+
94
+ if development_or_staging? && !browser_request?(req)
95
+ # the interstitial won't work if the user agent is not a browser, so
96
+ # short-circuit and avoid rendering it
97
+ #
98
+ # We only limit this to dev/stg because we're not yet sure how robust
99
+ # this strategy is, yet. In the future, we might enable it for prod too.
100
+ return signed_out(env)
91
101
  end
92
102
 
93
103
  ##########################################################################
@@ -95,22 +105,22 @@ module Clerk
95
105
  # COOKIE AUTHENTICATION #
96
106
  # #
97
107
  ##########################################################################
98
- if development_or_staging? && (@req.referrer.nil? || cross_origin_request?(@req))
108
+ if development_or_staging? && (req.referrer.nil? || cross_origin_request?(req))
99
109
  return unknown(interstitial: true)
100
110
  end
101
111
 
102
- if production? && @client_uat.nil?
103
- return signed_out
112
+ if production? && client_uat.nil?
113
+ return signed_out(env)
104
114
  end
105
115
 
106
- if @client_uat == "0"
107
- return signed_out
116
+ if client_uat == "0"
117
+ return signed_out(env)
108
118
  end
109
119
 
110
- token = verify_token(@cookie_token)
120
+ token = verify_token(cookie_token)
111
121
 
112
- if token && token["iat"] && @client_uat && Integer(@client_uat) <= token["iat"]
113
- return signed_in(token, @cookie_token)
122
+ if token && token["iat"] && client_uat && Integer(client_uat) <= token["iat"]
123
+ return signed_in(env, token, cookie_token)
114
124
  end
115
125
 
116
126
  unknown(interstitial: true)
@@ -119,15 +129,15 @@ module Clerk
119
129
  private
120
130
 
121
131
  # Outcome A
122
- def signed_in(claims, token)
123
- @env["clerk"] = ProxyV2.new(session_claims: claims, session_token: token)
132
+ def signed_in(env, claims, token)
133
+ env["clerk"] = ProxyV2.new(session_claims: claims, session_token: token)
124
134
 
125
- @app.call(@env)
135
+ @app.call(env)
126
136
  end
127
137
 
128
138
  # Outcome B
129
- def signed_out
130
- @app.call(@env)
139
+ def signed_out(env)
140
+ @app.call(env)
131
141
  end
132
142
 
133
143
  # Outcome C
@@ -153,7 +163,7 @@ module Clerk
153
163
  return false if origin.nil?
154
164
 
155
165
  # strip scheme
156
- origin = origin.strip.sub(/(^\w+:|^)\/\//, '')
166
+ origin = origin.strip.sub(/\A(\w+:)?\/\//, '')
157
167
  return false if origin.empty?
158
168
 
159
169
  # Rack's host and port helpers are reverse-proxy-aware; that
@@ -161,21 +171,27 @@ module Clerk
161
171
  request_host = req.host
162
172
  request_host << ":#{req.port}" if req.port != 80 && req.port != 443
163
173
 
164
- origin == request_host
174
+ origin != request_host
175
+ end
176
+
177
+ def browser_request?(req)
178
+ user_agent = req.env["HTTP_USER_AGENT"]
179
+
180
+ !user_agent.nil? && user_agent.starts_with?("Mozilla/")
165
181
  end
166
182
 
167
183
  def verify_token(token)
168
184
  return false if token.nil? || token.strip.empty?
169
185
 
170
186
  begin
171
- @session = sdk.verify_token(token)
187
+ sdk.verify_token(token)
172
188
  rescue JWT::DecodeError, JWT::RequiredDependencyError => e
173
189
  false
174
190
  end
175
191
  end
176
192
 
177
193
  def sdk
178
- @sdk ||= Clerk::SDK.new
194
+ Clerk::SDK.new
179
195
  end
180
196
  end
181
197
  end
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.2"
4
+ VERSION = "2.1.1"
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.2
4
+ version: 2.1.1
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-22 00:00:00.000000000 Z
11
+ date: 2022-02-24 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.15
131
131
  signing_key:
132
132
  specification_version: 4
133
133
  summary: Clerk SDK for Ruby.