aha_builder_core 1.0.3 → 1.0.4
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 +4 -4
- data/README.md +3 -1
- data/lib/aha/auth/version.rb +1 -1
- data/lib/aha/auth.rb +45 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 67c88ef564275000006548bd40149fb9d8c9c6a28d7b9faf430a8dd6b338147c
|
|
4
|
+
data.tar.gz: 10401cac65cfa9f711640911038c12491acaf73b160f340851becdce92edfbb2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f8c526217a495e3e9ec239c4d169eb0848f9bcc6f876ba92f02f114a420f0220313e7960ef1a56b1271c0d270f2906480a5524510e988ecda939eca8491e3f10
|
|
7
|
+
data.tar.gz: 1eb5ccd35517e18df03ea87a2c93b4eadea3152d79023f440ee19c9930f600543085c6c6ab2e45fccbfb3ee0df1a1bd14b0223ca11315e8826e2d655f5df5880
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Aha Builder Core Client
|
|
2
2
|
|
|
3
|
-
Ruby client for Aha! Builder core authentication services.
|
|
3
|
+
Ruby client for Aha! Builder core authentication services which provides login and signup using email/password, social logins (Google, Github, Microsoft), SAML SSO and password reset.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -18,6 +18,8 @@ No configuration is necessary and no environment variables are necessary.
|
|
|
18
18
|
|
|
19
19
|
The authentication UI is provided completely by the core system. During authentication the user is redirected to the login page, and will return (via HTTP redirect) to the `/callback` URL when authentication is complete. Your application must implement a callback action at `/callback` to receive the code. Any value passed in as `state` is returned verbatim to the callback.
|
|
20
20
|
|
|
21
|
+
Protection against CSRF atacks is handled internally by the Aha::Auth library and there is no need to use a nonce in the state parameter.
|
|
22
|
+
|
|
21
23
|
### Generate Login URL
|
|
22
24
|
|
|
23
25
|
Redirect users to the authentication and signup UI:
|
data/lib/aha/auth/version.rb
CHANGED
data/lib/aha/auth.rb
CHANGED
|
@@ -4,6 +4,8 @@ require "faraday"
|
|
|
4
4
|
require "faraday/retry"
|
|
5
5
|
require "jwt"
|
|
6
6
|
require "concurrent"
|
|
7
|
+
require "active_support"
|
|
8
|
+
require "active_support/core_ext"
|
|
7
9
|
|
|
8
10
|
require_relative "auth/version"
|
|
9
11
|
require_relative "auth/errors"
|
|
@@ -40,11 +42,28 @@ module Aha
|
|
|
40
42
|
|
|
41
43
|
# Generate login URL for redirecting users to the auth server
|
|
42
44
|
#
|
|
45
|
+
# @param session [Hash] Session hash to store the nonce for CSRF verification
|
|
43
46
|
# @param state [String] Optional state parameter to pass through the auth flow
|
|
44
47
|
# @return [String] The login URL
|
|
45
|
-
def login_url(state: nil)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
def login_url(session:, state: nil)
|
|
49
|
+
# Generate a nonce for CSRF protection
|
|
50
|
+
nonce = SecureRandom.hex(10)
|
|
51
|
+
|
|
52
|
+
# Store nonce in the client's session if provided
|
|
53
|
+
session[:auth_nonce] = nonce if session
|
|
54
|
+
|
|
55
|
+
# Encode the state with nonce
|
|
56
|
+
state_data = {
|
|
57
|
+
tunneled_state: state,
|
|
58
|
+
nonce: nonce,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
encoded_state = Base64.urlsafe_encode64(state_data.to_json, padding: false)
|
|
62
|
+
|
|
63
|
+
params = {
|
|
64
|
+
client_id: configuration.client_id,
|
|
65
|
+
state: encoded_state
|
|
66
|
+
}
|
|
48
67
|
|
|
49
68
|
query = URI.encode_www_form(params)
|
|
50
69
|
"#{configuration.server_url}/auth_ui/start?#{query}"
|
|
@@ -52,10 +71,30 @@ module Aha
|
|
|
52
71
|
|
|
53
72
|
# Exchange an authorization code for tokens
|
|
54
73
|
#
|
|
55
|
-
# @param code [String] The authorization code from the callback
|
|
74
|
+
# @param code [String] The authorization code from the callback (may include nonce)
|
|
75
|
+
# @param session [Hash] Session hash containing the nonce for CSRF verification
|
|
56
76
|
# @return [Hash] Token response with :session_token, :refresh_token, :expires_at, :user
|
|
57
|
-
def authenticate_with_code(code:)
|
|
58
|
-
|
|
77
|
+
def authenticate_with_code(code:, session:)
|
|
78
|
+
# Split the code and nonce if present
|
|
79
|
+
actual_code, nonce = code.split(".", 2)
|
|
80
|
+
|
|
81
|
+
# Verify CSRF protection if nonce is present
|
|
82
|
+
if nonce
|
|
83
|
+
session_nonce = session[:auth_nonce]
|
|
84
|
+
|
|
85
|
+
# Verify nonce matches
|
|
86
|
+
if session_nonce.blank? || session_nonce != nonce
|
|
87
|
+
raise "CSRF verification failed: nonce mismatch"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Clear the nonce from session after verification
|
|
91
|
+
session.delete(:auth_nonce)
|
|
92
|
+
else
|
|
93
|
+
# If we fon't have a none, we can't verify CSRF.
|
|
94
|
+
raise "CSRF verification failed: unable to verify nonce"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
client.authenticate_with_code(code: actual_code)
|
|
59
98
|
end
|
|
60
99
|
|
|
61
100
|
# Refresh tokens using a refresh token
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aha_builder_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aha! Labs Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|