aws-cognito-srp 0.5.0 → 0.6.0

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: 929d703154eb252230b0ec365cf85bb59e632e62a335bcf63d81c0168f6fe3d3
4
- data.tar.gz: 2b857f9bcf58f8363eae7ad056de998758bfaf6458ca478d41e4398b57d34a11
3
+ metadata.gz: 5b685bf22d6f5a6dd977e1b637f84b30fa5630b1f0e14c9e0dfb46c74273be9d
4
+ data.tar.gz: 1e2db6df2d70acb710906b75c119506df3608b52fd78b34e56233af2e480a6c7
5
5
  SHA512:
6
- metadata.gz: 5763f4fac8412527c21ecfb3ae0e283e4cf7be33fc5eadbc94325c83b1b0aa91d34cfc86ebad7895c9f1e1fad93e8c7f8f0f08180f4219d4f78e1ff63d9cf0c1
7
- data.tar.gz: 13e4d566a91689460b4aca21d48b73a3655d336dfc3e07e0e8c505b107606489581b720d045c72e0ebc2aea27d59a79c76eeba5cb3be77965818b69cb259f10d
6
+ metadata.gz: 75e86769e7198362a6e12f05b0e5a137dd62ef3886e122eeb2a7d638169f6dfa856bc12bb13a12616f2663c6b78cf36bf368d615ff617e003446eca7e08372e7
7
+ data.tar.gz: b24ed5925052eae4de68b27ee5fe57dc14bff611576e33748362224b85929ea08a29290919e6d494a2b0ca76cd4ac4db4b073d96de86a6c1a8a51b3496b7187c
data/CHANGELOG.md CHANGED
@@ -1,8 +1,12 @@
1
1
  ## Changelog for aws-cognito-srp-ruby
2
2
 
3
+ ### 0.6.0 (June 20, 2023)
4
+
5
+ * Added support for MFA (@suketa)
6
+
3
7
  ### 0.5.0 (February 14❤︎, 2023)
4
8
 
5
- * Added support for `client_secret`
9
+ * Added support for `client_secret` (@suketa)
6
10
 
7
11
  ### 0.4.0 (October 1, 2021)
8
12
 
@@ -16,6 +20,6 @@
16
20
 
17
21
  * Added custom exception classes and better error messages
18
22
 
19
- ### 0.1.0 (Septembre 17, 2021)
23
+ ### 0.1.0 (September 17, 2021)
20
24
 
21
25
  * Initial release
data/README.md CHANGED
@@ -45,6 +45,8 @@ resp.refresh_token
45
45
  new_tokens = aws_srp.refresh_tokens(resp.refresh_token)
46
46
  ```
47
47
 
48
+ ### `USER_ID_FOR_SRP`
49
+
48
50
  In case you need access to the `USER_ID_FOR_SRP` value from the auth response,
49
51
  you can do so by calling `aws_srp.user_id_for_srp` *after* the initial auth
50
52
  (`aws_srp` being the same as in the code example above).
@@ -58,6 +60,47 @@ new_tokens = aws_srp.refresh_token(resp.refresh_token,
58
60
  user_id_for_srp: your_user_id_for_srp)
59
61
  ```
60
62
 
63
+ ### MFA (multi-factor authentication)
64
+
65
+ If you're using MFA you should check for the challenge after calling
66
+ `#authenticate` and respond accordingly with `#respond_to_mfa_challenge`.
67
+
68
+ ```ruby
69
+ resp = aws_srp.authenticate
70
+
71
+ if resp.respond_to?(:challenge_name) && resp.mfa_challenge?
72
+ user_code = get.chomp # Get MFA code from user
73
+
74
+ resp = aws_srp.respond_to_mfa_challenge(
75
+ user_code,
76
+ auth_response: resp
77
+ )
78
+ end
79
+
80
+ resp.id_token
81
+ resp.access_token
82
+ resp.refresh_token
83
+ ```
84
+
85
+ Note that when `#authenticate` results in a successful authentication it
86
+ returns a `AuthenticationResultType`
87
+ ([AWS SDK docs](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/CognitoIdentityProvider/Types/AuthenticationResultType.html)),
88
+ i.e. an object that responds to `#id_token`, `#access_token`, etc.
89
+
90
+ However, when a MFA challenge step occurs, `#authenticate` instead returns a
91
+ `RespondToAuthChallengeResponse` ([AWS SDK docs](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/CognitoIdentityProvider/Types/RespondToAuthChallengeResponse.html#authentication_result-instance_method)),
92
+ which you can check for with `.respond_to?(:challenge_name)` as in the above
93
+ example. The `RespondToAuthChallengeResponse` object will be extended with the
94
+ convenience methods `#mfa_challenge?`, `#software_token_mfa?` and `#sms_mfa?`.
95
+
96
+ The `#respond_to_mfa_challenge` method can be called with the following
97
+ signatures:
98
+
99
+ ```
100
+ #respond_to_mfa_challenge(user_code, auth_response: [, user_id_for_srp:])
101
+ #respond_to_mfa_challenge(user_code, challenge_name:, session: [, user_id_for_srp:])
102
+ ```
103
+
61
104
  ## Supported rubies
62
105
 
63
106
  This gem is tested against and supports Ruby 2.4 through 3.2, JRuby and
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "aws/cognito_srp/errors"
4
+
5
+ module Aws
6
+ class CognitoSrp
7
+ module ChallengeResponseHelper
8
+ def mfa_challenge?
9
+ software_token_mfa? || sms_mfa?
10
+ end
11
+
12
+ def software_token_mfa?
13
+ challenge_name == SOFTWARE_TOKEN_MFA
14
+ end
15
+
16
+ def sms_mfa?
17
+ challenge_name == SMS_MFA
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aws
4
4
  class CognitoSrp
5
- VERSION = "0.5.0"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
@@ -9,6 +9,7 @@ require "base64"
9
9
 
10
10
  require "aws/cognito_srp/version"
11
11
  require "aws/cognito_srp/errors"
12
+ require "aws/cognito_srp/challenge_response_helper"
12
13
 
13
14
  if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5")
14
15
  module IntegerWithPow
@@ -50,6 +51,8 @@ module Aws
50
51
  PASSWORD_VERIFIER = "PASSWORD_VERIFIER"
51
52
  REFRESH_TOKEN = "REFRESH_TOKEN"
52
53
  USER_SRP_AUTH = "USER_SRP_AUTH"
54
+ SOFTWARE_TOKEN_MFA = "SOFTWARE_TOKEN_MFA"
55
+ SMS_MFA = "SMS_MFA"
53
56
 
54
57
  N_HEX = %w(
55
58
  FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08
@@ -117,6 +120,12 @@ module Aws
117
120
 
118
121
  auth_response = @aws_client.respond_to_auth_challenge(params)
119
122
 
123
+ if auth_response.challenge_name == SOFTWARE_TOKEN_MFA || auth_response.challenge_name == SMS_MFA
124
+ auth_response.extend(ChallengeResponseHelper)
125
+
126
+ return auth_response
127
+ end
128
+
120
129
  if auth_response.challenge_name == NEW_PASSWORD_REQUIRED
121
130
  raise NewPasswordRequired, "Cognito responded to password verifier with a #{NEW_PASSWORD_REQUIRED} challenge"
122
131
  end
@@ -140,6 +149,34 @@ module Aws
140
149
  end
141
150
  alias_method :refresh, :refresh_tokens
142
151
 
152
+ def respond_to_mfa_challenge(user_code, auth_response: nil, challenge_name: auth_response&.challenge_name, session: auth_response&.session, user_id_for_srp: @user_id_for_srp)
153
+ unless auth_response || (challenge_name && session)
154
+ raise ArgumentError, "Either `auth_response' or `challenge_name'+`session' keyword arguments should be given"
155
+ end
156
+
157
+ hash = @client_secret && secret_hash(user_id_for_srp)
158
+
159
+ challenge_responses = {
160
+ USERNAME: user_id_for_srp,
161
+ SECRET_HASH: hash
162
+ }
163
+ if challenge_name == SOFTWARE_TOKEN_MFA
164
+ challenge_responses[:SOFTWARE_TOKEN_MFA_CODE] = user_code
165
+ elsif challenge_name == SMS_MFA
166
+ challenge_responses[:SMS_MFA_CODE] = user_code
167
+ end
168
+
169
+ params = {
170
+ challenge_name: challenge_name,
171
+ session: session,
172
+ client_id: @client_id,
173
+ challenge_responses: challenge_responses.compact
174
+ }.compact
175
+
176
+ resp = @aws_client.respond_to_auth_challenge(params)
177
+ resp.authentication_result
178
+ end
179
+
143
180
  private
144
181
 
145
182
  def generate_random_small_a
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-cognito-srp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Viney
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-02-14 00:00:00.000000000 Z
13
+ date: 2023-06-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws-sdk-cognitoidentityprovider
@@ -117,6 +117,7 @@ files:
117
117
  - bin/setup
118
118
  - lib/aws-cognito-srp.rb
119
119
  - lib/aws/cognito_srp.rb
120
+ - lib/aws/cognito_srp/challenge_response_helper.rb
120
121
  - lib/aws/cognito_srp/errors.rb
121
122
  - lib/aws/cognito_srp/version.rb
122
123
  - lib/aws_cognito_srp.rb