thecore_backend_commons 3.9.0 → 3.9.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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3aa559045828d8dc8ca4981fad05e6ff9ef2f80a7191f2e16db4f45ddcaf1c24
|
|
4
|
+
data.tar.gz: cd8fe33d14e2373a1b01ccd7290ceba1cb75048df57b6591a35c9cb135e077d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2a94d02e27478addb9660b69f693d4c8760e92dd11c5698130a7dc38601e1a745d3ca041ee6103204e4aeb070d138ef64877537debba042153ad5d2125650414
|
|
7
|
+
data.tar.gz: 15fc51c68e34e67042f8a02699639d5fb953e8710fce8e5923c225fa414e6c7c52c6ca5e22d3d618b817b88df09597dff65d31b35935bcbbc884b3678029ae2c
|
|
@@ -13,5 +13,5 @@ Rails.application.config.action_cable.allowed_request_origins = [/http:\/\/*/, /
|
|
|
13
13
|
# and mounts Sidekiq::Web unconditionally (thecore_background_jobs), so ActiveJob should actually
|
|
14
14
|
# route through it rather than defaulting to Rails' in-process :async, which silently drops any
|
|
15
15
|
# job in flight when its process restarts. Production only: :async remains the default in
|
|
16
|
-
# development/test so neither requires a reachable Redis. See docs/adr/0001,
|
|
16
|
+
# development/test so neither requires a reachable Redis. See docs/adr/0001, GLOSSARY.md.
|
|
17
17
|
Rails.application.config.active_job.queue_adapter = :sidekiq if Rails.env.production?
|
|
@@ -11,22 +11,51 @@ module CableConnectionConcern
|
|
|
11
11
|
|
|
12
12
|
protected
|
|
13
13
|
|
|
14
|
-
def find_verified_user
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
14
|
+
def find_verified_user
|
|
15
|
+
# An already-authenticated Devise/Warden session (e.g. RailsAdmin in the browser) is
|
|
16
|
+
# trusted as-is, before looking at any token.
|
|
17
|
+
warden_user = env["warden"]&.user
|
|
18
|
+
return warden_user if warden_user
|
|
19
|
+
|
|
20
|
+
# Looks for a token in the query parameters, or in the "Authorization" header.
|
|
21
|
+
m = request.query_parameters["token"].presence ||
|
|
22
|
+
request.headers["Authorization"].to_s.split(" ").second&.strip
|
|
23
|
+
return reject_unauthorized_connection if m.blank?
|
|
24
|
+
|
|
25
|
+
# Machine-to-machine token (bcrypt-compared against each user's stored token). Guarded by a
|
|
26
|
+
# column check so this generic gem also works in a host without m2m tokens (and so its own
|
|
27
|
+
# dummy app, whose users table has no such column, doesn't abort the transaction).
|
|
28
|
+
if User.column_names.include?("encrypted_access_token")
|
|
29
|
+
m2m_user = User.where.not(encrypted_access_token: nil)
|
|
30
|
+
.find { |u| BCrypt::Password.new(u.encrypted_access_token) == m } rescue nil
|
|
31
|
+
return m2m_user if m2m_user
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# JWT: the signature MUST be verified, exactly like every REST request. Decoding with the
|
|
35
|
+
# verification disabled (the previous behaviour) let a forged token carrying an arbitrary
|
|
36
|
+
# user_id authenticate as any user over the WebSocket — and ActivityLogChannel streams every
|
|
37
|
+
# record change, so that was a full read bypass. See docs/adr and the issue tracker.
|
|
38
|
+
body = decode_verified_jwt(m)
|
|
39
|
+
jwt_user = User.find_by(id: body[:user_id]) if body && body[:user_id]
|
|
40
|
+
return jwt_user if jwt_user
|
|
41
|
+
|
|
42
|
+
# Neither a valid m2m nor a valid JWT token: refuse the connection.
|
|
43
|
+
reject_unauthorized_connection
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Decodes and VERIFIES a JWT. Reuses model_driven_api's JsonWebToken when present, so the
|
|
47
|
+
# WebSocket shares the REST API's signing key, key-rotation and single-session handling;
|
|
48
|
+
# falls back to a signature-verifying decode so this gem still works on its own. Returns nil
|
|
49
|
+
# on any invalid, forged or expired token.
|
|
50
|
+
def decode_verified_jwt(token)
|
|
51
|
+
if defined?(::JsonWebToken)
|
|
52
|
+
::JsonWebToken.decode(token)
|
|
53
|
+
else
|
|
54
|
+
secret = ::Rails.application.credentials.dig(:secret_key_base).presence || ENV["SECRET_KEY_BASE"]
|
|
55
|
+
::HashWithIndifferentAccess.new(::JWT.decode(token, secret, true, algorithm: "HS256")[0])
|
|
56
|
+
end
|
|
57
|
+
rescue StandardError
|
|
58
|
+
nil
|
|
30
59
|
end
|
|
31
60
|
end
|
|
32
61
|
end
|