standard_id 0.1.0 → 0.1.2

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +347 -7
  3. data/app/controllers/standard_id/api/providers_controller.rb +15 -16
  4. data/app/controllers/standard_id/web/verify_email/base_controller.rb +9 -0
  5. data/app/controllers/standard_id/web/verify_email/confirm_controller.rb +41 -0
  6. data/app/controllers/standard_id/web/verify_email/start_controller.rb +39 -0
  7. data/app/controllers/standard_id/web/verify_phone/base_controller.rb +9 -0
  8. data/app/controllers/standard_id/web/verify_phone/confirm_controller.rb +41 -0
  9. data/app/controllers/standard_id/web/verify_phone/start_controller.rb +39 -0
  10. data/app/forms/standard_id/web/signup_form.rb +3 -14
  11. data/app/models/standard_id/client_application.rb +2 -1
  12. data/app/models/standard_id/{passwordless_challenge.rb → code_challenge.rb} +9 -5
  13. data/app/models/standard_id/email_identifier.rb +2 -0
  14. data/app/models/standard_id/identifier.rb +17 -0
  15. data/app/models/standard_id/phone_number_identifier.rb +2 -0
  16. data/app/models/standard_id/username_identifier.rb +2 -0
  17. data/config/routes/web.rb +12 -0
  18. data/db/migrate/20250830000000_create_standard_id_client_applications.rb +3 -3
  19. data/db/migrate/20250830232800_create_standard_id_identifiers.rb +1 -1
  20. data/db/migrate/20250831075703_create_standard_id_credentials.rb +2 -2
  21. data/db/migrate/20250831154635_create_standard_id_sessions.rb +2 -2
  22. data/db/migrate/20250901134520_create_standard_id_client_secret_credentials.rb +2 -2
  23. data/db/migrate/20250907090000_create_standard_id_code_challenges.rb +29 -0
  24. data/lib/generators/standard_id/install/templates/standard_id.rb +36 -3
  25. data/lib/{standard_id → standard_config}/config.rb +1 -1
  26. data/lib/standard_config/config_provider.rb +82 -0
  27. data/lib/standard_config/manager.rb +86 -0
  28. data/lib/standard_config/schema.rb +137 -0
  29. data/lib/standard_config.rb +38 -0
  30. data/lib/standard_id/api/session_manager.rb +1 -1
  31. data/lib/standard_id/config/schema.rb +49 -0
  32. data/lib/standard_id/oauth/client_credentials_flow.rb +1 -5
  33. data/lib/standard_id/oauth/implicit_authorization_flow.rb +1 -1
  34. data/lib/standard_id/oauth/password_flow.rb +0 -4
  35. data/lib/standard_id/oauth/passwordless_otp_flow.rb +7 -10
  36. data/lib/standard_id/oauth/token_grant_flow.rb +6 -2
  37. data/lib/standard_id/oauth/token_lifetime_resolver.rb +50 -0
  38. data/lib/standard_id/passwordless/base_strategy.rb +8 -4
  39. data/lib/standard_id/version.rb +1 -1
  40. data/lib/standard_id.rb +13 -4
  41. metadata +16 -4
  42. data/db/migrate/20250903135906_create_standard_id_passwordless_challenges.rb +0 -22
@@ -7,12 +7,12 @@ module StandardId
7
7
  def authenticate!
8
8
  validate_client_secret!(params[:client_id], params[:client_secret]) if params[:client_secret].present?
9
9
 
10
- raise StandardId::InvalidGrantError, "Invalid or expired verification code" if passwordless_challenge.blank?
10
+ raise StandardId::InvalidGrantError, "Invalid or expired verification code" if code_challenge.blank?
11
11
  raise StandardId::InvalidGrantError, "Unable to authenticate user" if account.blank?
12
12
 
13
13
  validate_requested_scope!
14
14
 
15
- passwordless_challenge.use!
15
+ code_challenge.use!
16
16
  end
17
17
 
18
18
  private
@@ -41,14 +41,11 @@ module StandardId
41
41
  true
42
42
  end
43
43
 
44
- def token_expiry
45
- 1.hour
46
- end
47
-
48
- def passwordless_challenge
49
- @passwordless_challenge ||= StandardId::PasswordlessChallenge.active.find_by(
50
- connection_type: params[:connection],
51
- username: params[:username],
44
+ def code_challenge
45
+ @code_challenge ||= StandardId::CodeChallenge.active.find_by(
46
+ realm: "authentication",
47
+ channel: params[:connection],
48
+ target: params[:username],
52
49
  code: params[:otp]
53
50
  )
54
51
  end
@@ -62,7 +62,7 @@ module StandardId
62
62
  end
63
63
 
64
64
  def token_expiry
65
- 1.hour
65
+ TokenLifetimeResolver.access_token_for(token_lifetime_key)
66
66
  end
67
67
 
68
68
  def supports_refresh_token?
@@ -80,7 +80,11 @@ module StandardId
80
80
  end
81
81
 
82
82
  def refresh_token_expiry
83
- 30.days
83
+ TokenLifetimeResolver.refresh_token_lifetime
84
+ end
85
+
86
+ def token_lifetime_key
87
+ grant_type&.to_sym
84
88
  end
85
89
 
86
90
  def subject_id
@@ -0,0 +1,50 @@
1
+ module StandardId
2
+ module Oauth
3
+ class TokenLifetimeResolver
4
+ class << self
5
+ DEFAULT_ACCESS_TOKEN_LIFETIME = 1.hour.to_i
6
+ DEFAULT_REFRESH_TOKEN_LIFETIME = 30.days.to_i
7
+
8
+ def access_token_for(flow_key)
9
+ configured = lookup_token_lifetime(flow_key)
10
+ positive_seconds(configured, default_access_token_lifetime)
11
+ end
12
+
13
+ def refresh_token_lifetime
14
+ positive_seconds(oauth_config.refresh_token_lifetime, DEFAULT_REFRESH_TOKEN_LIFETIME)
15
+ end
16
+
17
+ private
18
+
19
+ def default_access_token_lifetime
20
+ positive_seconds(oauth_config.default_token_lifetime, DEFAULT_ACCESS_TOKEN_LIFETIME)
21
+ end
22
+
23
+ def lookup_token_lifetime(flow_key)
24
+ config = oauth_config
25
+ return nil unless config.respond_to?(:token_lifetimes)
26
+
27
+ lifetimes = config.token_lifetimes || {}
28
+ lifetimes[flow_key.to_sym] || lifetimes[flow_key.to_s] if flow_key
29
+ end
30
+
31
+ def positive_seconds(value, fallback_value)
32
+ normalized_value = case value
33
+ when ActiveSupport::Duration
34
+ value.to_i
35
+ when Numeric, String
36
+ value.to_i
37
+ else
38
+ 0
39
+ end
40
+
41
+ (normalized_value.positive? ? normalized_value : fallback_value).seconds
42
+ end
43
+
44
+ def oauth_config
45
+ StandardId.config.oauth
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -24,14 +24,18 @@ module StandardId
24
24
  protected
25
25
 
26
26
  def create_challenge!(username)
27
- StandardId::PasswordlessChallenge.create!(
28
- connection_type: connection_type,
29
- username: username,
30
- code: generate_otp_code,
27
+ code = generate_otp_code
28
+
29
+ cc = StandardId::CodeChallenge.create!(
30
+ realm: "authentication",
31
+ channel: connection_type,
32
+ target: username,
33
+ code: code,
31
34
  expires_at: 10.minutes.from_now,
32
35
  ip_address: request.remote_ip,
33
36
  user_agent: request.user_agent
34
37
  )
38
+ cc
35
39
  end
36
40
 
37
41
  def generate_otp_code
@@ -1,3 +1,3 @@
1
1
  module StandardId
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/standard_id.rb CHANGED
@@ -2,7 +2,7 @@ require "standard_id/version"
2
2
  require "standard_id/engine"
3
3
  require "standard_id/web_engine"
4
4
  require "standard_id/api_engine"
5
- require "standard_id/config"
5
+ require "standard_id/config/schema"
6
6
  require "standard_id/errors"
7
7
  require "standard_id/jwt_service"
8
8
  require "standard_id/web/session_manager"
@@ -12,6 +12,7 @@ require "standard_id/api/session_manager"
12
12
  require "standard_id/api/token_manager"
13
13
  require "standard_id/api/authentication_guard"
14
14
  require "standard_id/oauth/base_request_flow"
15
+ require "standard_id/oauth/token_lifetime_resolver"
15
16
  require "standard_id/oauth/token_grant_flow"
16
17
  require "standard_id/oauth/client_credentials_flow"
17
18
  require "standard_id/oauth/authorization_code_flow"
@@ -30,12 +31,16 @@ require "standard_id/passwordless/sms_strategy"
30
31
 
31
32
  module StandardId
32
33
  class << self
33
- def configure
34
- yield config
34
+ def configure(&block)
35
+ StandardConfig.configure(&block)
36
+ end
37
+
38
+ def register(scope_name, resolver_proc)
39
+ StandardConfig.config.register(scope_name, resolver_proc)
35
40
  end
36
41
 
37
42
  def config
38
- @config ||= StandardId::Config.new
43
+ StandardConfig.config
39
44
  end
40
45
 
41
46
  def cache_store
@@ -45,5 +50,9 @@ module StandardId
45
50
  def logger
46
51
  @logger ||= config.logger || Rails.logger
47
52
  end
53
+
54
+ def account_class
55
+ config.account_class_name.constantize
56
+ end
48
57
  end
49
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standard_id
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaryl Sim
@@ -83,6 +83,12 @@ files:
83
83
  - app/controllers/standard_id/web/reset_password/start_controller.rb
84
84
  - app/controllers/standard_id/web/sessions_controller.rb
85
85
  - app/controllers/standard_id/web/signup_controller.rb
86
+ - app/controllers/standard_id/web/verify_email/base_controller.rb
87
+ - app/controllers/standard_id/web/verify_email/confirm_controller.rb
88
+ - app/controllers/standard_id/web/verify_email/start_controller.rb
89
+ - app/controllers/standard_id/web/verify_phone/base_controller.rb
90
+ - app/controllers/standard_id/web/verify_phone/confirm_controller.rb
91
+ - app/controllers/standard_id/web/verify_phone/start_controller.rb
86
92
  - app/forms/standard_id/web/reset_password_confirm_form.rb
87
93
  - app/forms/standard_id/web/reset_password_start_form.rb
88
94
  - app/forms/standard_id/web/signup_form.rb
@@ -96,12 +102,12 @@ files:
96
102
  - app/models/standard_id/browser_session.rb
97
103
  - app/models/standard_id/client_application.rb
98
104
  - app/models/standard_id/client_secret_credential.rb
105
+ - app/models/standard_id/code_challenge.rb
99
106
  - app/models/standard_id/credential.rb
100
107
  - app/models/standard_id/device_session.rb
101
108
  - app/models/standard_id/email_identifier.rb
102
109
  - app/models/standard_id/identifier.rb
103
110
  - app/models/standard_id/password_credential.rb
104
- - app/models/standard_id/passwordless_challenge.rb
105
111
  - app/models/standard_id/phone_number_identifier.rb
106
112
  - app/models/standard_id/service_session.rb
107
113
  - app/models/standard_id/session.rb
@@ -124,15 +130,20 @@ files:
124
130
  - db/migrate/20250831154635_create_standard_id_sessions.rb
125
131
  - db/migrate/20250901134520_create_standard_id_client_secret_credentials.rb
126
132
  - db/migrate/20250903063000_create_standard_id_authorization_codes.rb
127
- - db/migrate/20250903135906_create_standard_id_passwordless_challenges.rb
133
+ - db/migrate/20250907090000_create_standard_id_code_challenges.rb
128
134
  - lib/generators/standard_id/install/install_generator.rb
129
135
  - lib/generators/standard_id/install/templates/standard_id.rb
136
+ - lib/standard_config.rb
137
+ - lib/standard_config/config.rb
138
+ - lib/standard_config/config_provider.rb
139
+ - lib/standard_config/manager.rb
140
+ - lib/standard_config/schema.rb
130
141
  - lib/standard_id.rb
131
142
  - lib/standard_id/api/authentication_guard.rb
132
143
  - lib/standard_id/api/session_manager.rb
133
144
  - lib/standard_id/api/token_manager.rb
134
145
  - lib/standard_id/api_engine.rb
135
- - lib/standard_id/config.rb
146
+ - lib/standard_id/config/schema.rb
136
147
  - lib/standard_id/engine.rb
137
148
  - lib/standard_id/errors.rb
138
149
  - lib/standard_id/jwt_service.rb
@@ -149,6 +160,7 @@ files:
149
160
  - lib/standard_id/oauth/subflows/social_login_grant.rb
150
161
  - lib/standard_id/oauth/subflows/traditional_code_grant.rb
151
162
  - lib/standard_id/oauth/token_grant_flow.rb
163
+ - lib/standard_id/oauth/token_lifetime_resolver.rb
152
164
  - lib/standard_id/passwordless/base_strategy.rb
153
165
  - lib/standard_id/passwordless/email_strategy.rb
154
166
  - lib/standard_id/passwordless/sms_strategy.rb
@@ -1,22 +0,0 @@
1
- class CreateStandardIdPasswordlessChallenges < ActiveRecord::Migration[8.0]
2
- def change
3
- create_table :standard_id_passwordless_challenges do |t|
4
- t.string :connection_type, null: false
5
-
6
- t.string :username, null: false
7
- t.string :code, null: false
8
-
9
- t.datetime :expires_at, null: false
10
- t.datetime :used_at
11
-
12
- t.string :ip_address
13
- t.text :user_agent
14
-
15
- t.timestamps
16
- end
17
-
18
- add_index :standard_id_passwordless_challenges, [:connection_type, :username, :code], name: "index_passwordless_challenges_on_lookup"
19
- add_index :standard_id_passwordless_challenges, :expires_at
20
- add_index :standard_id_passwordless_challenges, :used_at
21
- end
22
- end