foobara-auth 0.0.8 → 0.0.9

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: e1ba58c561a925a0c68b73d09b35bea08bd1547170c3c5cb947c97b6bbbcd91d
4
- data.tar.gz: a9a6ef33b8b8834548034c7852ec4904d1b2161e83c8190b5aacf5c76fe7d38a
3
+ metadata.gz: 625eea5256db4cac1d98cb6b0483b8cbc9c47d91225f0f0736581df8a5a1636c
4
+ data.tar.gz: 0a51402e5ec2ce711ad7c62ef18aadbe23ff03f2ecb775516be35514e78ef89f
5
5
  SHA512:
6
- metadata.gz: de9f66fc29b5d7176198a8b03eb33b2046d0c9cf8c4130d2ecf082a65c7b215996d2c080099b1d7bdffa9f26c89d86513edd5bbab65f9bd9f756eaec983720d2
7
- data.tar.gz: 78a8c4c831f5c808cf4f675ecda90e418803a8c6d5f5d63f08679086a3e5693126f1fb4d9216a1bed7d44ef4f7c96a55d178e0dad5d6dca5cb50ff4e91079971
6
+ metadata.gz: 922de34a2a3343f55152a5d754b0e6a0c1b7e97bc868891e607018f73dcb8aec5dbee9408e3886a100057764de42039676204b5ffac48d2377e2ad5af777695f
7
+ data.tar.gz: 056a01756020a541633ea7467792079f8841c4c8135f7d84054efbab62c0360888b61e9ddf817c8ad67af4ef7a61e9feefae60e348d7c95cbfd0087a2d31c35f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.0.9] - 2025-04-22
2
+
3
+ - Handle malformed jwt tokens
4
+
1
5
  ## [0.0.8] - 2025-04-11
2
6
 
3
7
  - Just seeing if we can successfully push new gems since there's an issue pushing foobara
@@ -0,0 +1,45 @@
1
+ require "securerandom"
2
+
3
+ require_relative "create_token"
4
+
5
+ module Foobara
6
+ module Auth
7
+ class CreateResetPasswordToken < Foobara::Command
8
+ depends_on CreateToken
9
+
10
+ inputs do
11
+ user Types::User, :required
12
+ token_ttl :integer, default: 5 * 60
13
+ end
14
+
15
+ result :string, :sensitive_exposed
16
+
17
+ def execute
18
+ determine_timestamps
19
+
20
+ generate_new_reset_password_token
21
+ save_new_reset_password_token_on_user
22
+
23
+ reset_password_token_secret
24
+ end
25
+
26
+ attr_accessor :expires_at, :reset_password_token_record, :reset_password_token_secret
27
+
28
+ def determine_timestamps
29
+ now = Time.now
30
+ self.expires_at = now + token_ttl
31
+ end
32
+
33
+ def generate_new_reset_password_token
34
+ result = run_subcommand!(CreateToken, expires_at:)
35
+
36
+ self.reset_password_token_record = result[:token_record]
37
+ self.reset_password_token_secret = result[:token_string]
38
+ end
39
+
40
+ def save_new_reset_password_token_on_user
41
+ user.reset_password_token = reset_password_token_record
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,123 @@
1
+ module Foobara
2
+ module Auth
3
+ class ResetPassword < Foobara::Command
4
+ class NoPasswordResetTokenOrOldPasswordGivenError < Foobara::RuntimeError
5
+ context({})
6
+ message "Must give either a password reset token or an old password"
7
+ end
8
+
9
+ class BothPasswordResetTokenAndOldPasswordGivenError < Foobara::RuntimeError
10
+ context({})
11
+ message "Cannot give both a password reset token and an old password"
12
+ end
13
+
14
+ class IncorrectOldPasswordError < Foobara::RuntimeError
15
+ context({})
16
+ message "Incorrect old password"
17
+ end
18
+
19
+ class InvalidResetPasswordTokenError < Foobara::RuntimeError
20
+ context({}) # TODO: make this the default
21
+ message "Invalid password reset token"
22
+ end
23
+
24
+ class UserNotGivenError < Foobara::RuntimeError
25
+ context({})
26
+ message "Must give a user if giving an old password to reset password"
27
+ end
28
+
29
+ class UserNotFoundForResetTokenError < Foobara::RuntimeError
30
+ context({}) # TODO: make this the default?
31
+ message "No user found for reset password token"
32
+ end
33
+
34
+ inputs do
35
+ user Types::User
36
+ old_password :string, :sensitive_exposed
37
+ reset_password_token_secret :string, :sensitive_exposed
38
+ new_password :string, :sensitive, :required
39
+ end
40
+ result Types::User
41
+
42
+ depends_on BuildSecret, VerifyPassword, VerifyToken
43
+
44
+ # TODO: should we enforce certain password requirements?
45
+ def execute
46
+ if old_password_given?
47
+ verify_old_password
48
+ else
49
+ verify_and_use_up_password_reset_token
50
+ load_user
51
+ end
52
+
53
+ build_new_password
54
+ set_password_on_user
55
+
56
+ user
57
+ end
58
+
59
+ def validate
60
+ if old_password_given?
61
+ unless user
62
+ add_runtime_error(UserNotGivenError)
63
+ end
64
+ if reset_password_token_given?
65
+ add_runtime_error(BothPasswordResetTokenAndOldPasswordGivenError)
66
+ end
67
+ else
68
+ unless reset_password_token_given?
69
+ add_runtime_error(NoPasswordResetTokenOrOldPasswordGivenError)
70
+ end
71
+ end
72
+ end
73
+
74
+ attr_accessor :password_secret, :reset_password_token_record
75
+ attr_writer :user
76
+
77
+ def old_password_given?
78
+ !!old_password
79
+ end
80
+
81
+ def reset_password_token_given?
82
+ !!reset_password_token_secret
83
+ end
84
+
85
+ def verify_old_password
86
+ unless run_subcommand!(VerifyPassword, user:, plaintext_password: old_password)
87
+ add_runtime_error(IncorrectOldPasswordError)
88
+ end
89
+ end
90
+
91
+ def verify_and_use_up_password_reset_token
92
+ verified_result = run_subcommand!(VerifyToken, token_string: reset_password_token_secret)
93
+
94
+ unless verified_result[:verified]
95
+ add_runtime_error(InvalidResetPasswordTokenError)
96
+ end
97
+
98
+ self.reset_password_token_record = verified_result[:token_record]
99
+ reset_password_token_record.use_up!
100
+ end
101
+
102
+ def load_user
103
+ self.user = Types::User.that_owns(reset_password_token_record, "reset")
104
+
105
+ unless user
106
+ add_runtime_error(UserNotFoundForResetTokenError)
107
+ end
108
+ end
109
+
110
+ def user
111
+ @user || inputs[:user]
112
+ end
113
+
114
+ def build_new_password
115
+ self.password_secret = run_subcommand!(BuildSecret, secret: new_password)
116
+ end
117
+
118
+ def set_password_on_user
119
+ user.password_secret = password_secret
120
+ end
121
+ end
122
+ end
123
+ end
data/src/types/user.rb CHANGED
@@ -13,6 +13,7 @@ module Foobara
13
13
  api_keys [Types::Token], :sensitive, default: []
14
14
  refresh_tokens [Types::Token], :sensitive, default: []
15
15
  password_secret Types::Secret, :sensitive, :allow_nil
16
+ reset_password_token Types::Token, :sensitive, :allow_nil
16
17
  end
17
18
 
18
19
  primary_key :id
@@ -10,7 +10,7 @@ module Foobara
10
10
 
11
11
  result do
12
12
  verified :boolean, :required
13
- failure_reason :string, :allow_nil, one_of: %w[invalid expired]
13
+ failure_reason :string, :allow_nil, one_of: %w[invalid expired cannot_verify]
14
14
  payload :associative_array, :allow_nil
15
15
  headers :associative_array, :allow_nil
16
16
  end
@@ -27,9 +27,11 @@ module Foobara
27
27
  def decode_access_token
28
28
  self.payload, self.headers = JWT.decode(access_token, jwt_secret)
29
29
  rescue JWT::VerificationError
30
- self.failure_reason = "invalid"
30
+ self.failure_reason = "cannot_verify"
31
31
  rescue JWT::ExpiredSignature
32
32
  self.failure_reason = "expired"
33
+ rescue JWT::DecodeError
34
+ self.failure_reason = "invalid"
33
35
  end
34
36
 
35
37
  def set_verified_flag
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara-auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
@@ -68,6 +68,7 @@ files:
68
68
  - src/build_secret.rb
69
69
  - src/create_api_key.rb
70
70
  - src/create_refresh_token.rb
71
+ - src/create_reset_password_token.rb
71
72
  - src/create_role.rb
72
73
  - src/create_token.rb
73
74
  - src/create_user.rb
@@ -76,6 +77,7 @@ files:
76
77
  - src/logout.rb
77
78
  - src/refresh_login.rb
78
79
  - src/register.rb
80
+ - src/reset_password.rb
79
81
  - src/set_password.rb
80
82
  - src/types/role.rb
81
83
  - src/types/secret.rb