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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bfa1fb612c68e9997d4058381ef9c4b6b8d7eb61ddcbb52800fac41ace7fcd0
4
- data.tar.gz: e673fd8edc82b0ae0f1a7c32ecf82bdd6c8368ebe2b8b626dc4e5d1cf6d6b696
3
+ metadata.gz: 67c88ef564275000006548bd40149fb9d8c9c6a28d7b9faf430a8dd6b338147c
4
+ data.tar.gz: 10401cac65cfa9f711640911038c12491acaf73b160f340851becdce92edfbb2
5
5
  SHA512:
6
- metadata.gz: a2b43eeff2fbea68a9b7b908097ca88bf858504035671808c8dac2716b0621d37219c06f92aaed8d9be7eb6571da665a1f8fed95f52cf02f3d02ba4151c29898
7
- data.tar.gz: 927e0f48d3a1d2e4cb492ccefa7cb3bc377468ac7c57b3896abcaaa449a3b85a42cad99392927f0733127b28a7fe612d0f365c55060993b3c545c8c193048606
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:
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aha
4
4
  module Auth
5
- VERSION = "1.0.3"
5
+ VERSION = "1.0.4"
6
6
  end
7
7
  end
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
- params = { client_id: configuration.client_id }
47
- params[:state] = state if state
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
- client.authenticate_with_code(code: code)
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.3
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-01 00:00:00.000000000 Z
11
+ date: 2026-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport