standard_id 0.7.1 → 0.8.0
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/app/controllers/concerns/standard_id/inertia_rendering.rb +16 -1
- data/app/controllers/concerns/standard_id/lifecycle_hooks.rb +72 -0
- data/app/controllers/concerns/standard_id/web_mechanism_gate.rb +28 -0
- data/app/controllers/standard_id/web/auth/callback/providers_controller.rb +20 -4
- data/app/controllers/standard_id/web/base_controller.rb +1 -0
- data/app/controllers/standard_id/web/login_controller.rb +10 -2
- data/app/controllers/standard_id/web/login_verify_controller.rb +16 -11
- data/app/controllers/standard_id/web/reset_password/confirm_controller.rb +1 -0
- data/app/controllers/standard_id/web/reset_password/start_controller.rb +1 -0
- data/app/controllers/standard_id/web/sessions_controller.rb +1 -0
- data/app/controllers/standard_id/web/signup_controller.rb +10 -2
- data/app/controllers/standard_id/web/verify_email/base_controller.rb +1 -0
- data/app/controllers/standard_id/web/verify_phone/base_controller.rb +1 -0
- data/config/brakeman.ignore +10 -10
- data/lib/standard_id/config/schema.rb +27 -0
- data/lib/standard_id/errors.rb +3 -0
- data/lib/standard_id/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 112cdb26b4fc96d4be1830bde78fada616b87a79f6d7adff9657df72d8942a57
|
|
4
|
+
data.tar.gz: 4efeaf6a5f3f5bfdaf3747bebc0f5f9c3ccf22b02642c69e7b59c8a3d4aec74a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eea26565c62749d409acbdf38a282f63edf16ed907872d9673fea58057ede62ea679adb1765cd1e55855a48ca67cdabc5baeb7fa52277529828366c560462e7e
|
|
7
|
+
data.tar.gz: c250360c48f34dc9d52b6f1391e7816735dd1d3e9be63d7d80a0e8ae9b87d7ee178f8c78867eead4b7c792ac62b6a753ea90be73caf9e1f60e4c94415c57f1fd
|
|
@@ -42,8 +42,23 @@ module StandardId
|
|
|
42
42
|
social_providers: {
|
|
43
43
|
google_enabled: StandardId.config.google_client_id.present?,
|
|
44
44
|
apple_enabled: StandardId.config.apple_client_id.present?
|
|
45
|
-
}
|
|
45
|
+
},
|
|
46
|
+
enabled_mechanisms: web_enabled_mechanisms
|
|
46
47
|
}.deep_merge(additional_props)
|
|
47
48
|
end
|
|
49
|
+
|
|
50
|
+
def web_enabled_mechanisms
|
|
51
|
+
web = StandardId.config.web
|
|
52
|
+
{
|
|
53
|
+
password_login: web.password_login,
|
|
54
|
+
signup: web.signup,
|
|
55
|
+
passwordless_login: web.passwordless_login,
|
|
56
|
+
social_login: web.social_login,
|
|
57
|
+
password_reset: web.password_reset,
|
|
58
|
+
email_verification: web.email_verification,
|
|
59
|
+
phone_verification: web.phone_verification,
|
|
60
|
+
sessions_management: web.sessions_management
|
|
61
|
+
}
|
|
62
|
+
end
|
|
48
63
|
end
|
|
49
64
|
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module StandardId
|
|
2
|
+
module LifecycleHooks
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
# Invoke the after_sign_in hook if configured.
|
|
8
|
+
#
|
|
9
|
+
# @param account [Object] the authenticated account
|
|
10
|
+
# @param context [Hash] context about the sign-in
|
|
11
|
+
# - :connection [String] "email", "password", or "social"
|
|
12
|
+
# - :provider [String, nil] e.g. "google", "apple", or nil
|
|
13
|
+
# - :first_sign_in [Boolean] whether this is the account's first browser session
|
|
14
|
+
# @return [String, nil] redirect path override, or nil for default
|
|
15
|
+
# @raise [StandardId::AuthenticationDenied] to reject the sign-in
|
|
16
|
+
def invoke_after_sign_in(account, context)
|
|
17
|
+
hook = StandardId.config.after_sign_in
|
|
18
|
+
return nil unless hook.respond_to?(:call)
|
|
19
|
+
|
|
20
|
+
context = context.merge(first_sign_in: first_sign_in?(account))
|
|
21
|
+
hook.call(account, request, context)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Invoke the after_account_created hook if configured.
|
|
25
|
+
#
|
|
26
|
+
# @param account [Object] the newly created account
|
|
27
|
+
# @param context [Hash] context about the creation
|
|
28
|
+
# - :mechanism [String] "passwordless", "social", or "signup"
|
|
29
|
+
# - :provider [String, nil] e.g. "google", "apple", or nil
|
|
30
|
+
# @return [void]
|
|
31
|
+
def invoke_after_account_created(account, context)
|
|
32
|
+
hook = StandardId.config.after_account_created
|
|
33
|
+
return unless hook.respond_to?(:call)
|
|
34
|
+
|
|
35
|
+
hook.call(account, request, context)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Determine if this is the account's first browser session.
|
|
39
|
+
# A count of 1 means the session just created is the only one.
|
|
40
|
+
def first_sign_in?(account)
|
|
41
|
+
account.sessions.where(type: "StandardId::BrowserSession").active.count <= 1
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Handle AuthenticationDenied by revoking the session and redirecting to login.
|
|
45
|
+
# If the account was just created, clean it up to avoid orphaned records.
|
|
46
|
+
#
|
|
47
|
+
# @param error [StandardId::AuthenticationDenied] the denial error
|
|
48
|
+
# @param account [Object, nil] the account to clean up if newly created
|
|
49
|
+
# @param newly_created [Boolean] whether the account was created during this request
|
|
50
|
+
def handle_authentication_denied(error, account: nil, newly_created: false)
|
|
51
|
+
session_manager.revoke_current_session!
|
|
52
|
+
destroy_newly_created_account(account) if newly_created
|
|
53
|
+
message = error.message
|
|
54
|
+
# When raised without arguments, StandardError#message returns the class name
|
|
55
|
+
message = "Sign-in was denied" if message.blank? || message == error.class.name
|
|
56
|
+
redirect_to StandardId::WebEngine.routes.url_helpers.login_path, alert: message
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Destroy a newly created account and all its dependents.
|
|
60
|
+
# Used when after_sign_in rejects a just-created account to avoid orphans.
|
|
61
|
+
def destroy_newly_created_account(account)
|
|
62
|
+
return unless account&.persisted?
|
|
63
|
+
|
|
64
|
+
ActiveRecord::Base.transaction do
|
|
65
|
+
account.sessions.destroy_all
|
|
66
|
+
account.identifiers.each { |i| i.credentials.destroy_all }
|
|
67
|
+
account.identifiers.destroy_all
|
|
68
|
+
account.destroy
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module StandardId
|
|
2
|
+
module WebMechanismGate
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
class_methods do
|
|
6
|
+
# Declares which web mechanism this controller requires.
|
|
7
|
+
# If the mechanism is disabled via config, requests return 404.
|
|
8
|
+
#
|
|
9
|
+
# class SignupController < BaseController
|
|
10
|
+
# requires_web_mechanism :signup
|
|
11
|
+
# end
|
|
12
|
+
def requires_web_mechanism(mechanism_name)
|
|
13
|
+
before_action -> { enforce_web_mechanism!(mechanism_name) }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def enforce_web_mechanism!(mechanism_name)
|
|
20
|
+
unless StandardId.config.web.respond_to?(mechanism_name)
|
|
21
|
+
raise ArgumentError, "Unknown web mechanism: #{mechanism_name.inspect}. " \
|
|
22
|
+
"Valid mechanisms: #{StandardId.config.web.class.instance_methods(false).grep_v(/=/).sort.join(', ')}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
head :not_found unless StandardId.config.web.public_send(mechanism_name)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -4,10 +4,12 @@ module StandardId
|
|
|
4
4
|
module Callback
|
|
5
5
|
class ProvidersController < StandardId::Web::BaseController
|
|
6
6
|
public_controller
|
|
7
|
+
requires_web_mechanism :social_login
|
|
7
8
|
|
|
8
9
|
include StandardId::WebAuthentication
|
|
9
10
|
include StandardId::SocialAuthentication
|
|
10
11
|
include StandardId::Web::SocialLoginParams
|
|
12
|
+
include StandardId::LifecycleHooks
|
|
11
13
|
|
|
12
14
|
# Social callbacks must be accessible without an existing browser session
|
|
13
15
|
# because they create/sign-in the session upon successful callback.
|
|
@@ -28,21 +30,35 @@ module StandardId
|
|
|
28
30
|
provider_response = get_user_info_from_provider(redirect_uri:, nonce:)
|
|
29
31
|
social_info = provider_response[:user_info]
|
|
30
32
|
provider_tokens = provider_response[:tokens]
|
|
31
|
-
|
|
33
|
+
begin
|
|
34
|
+
account = find_or_create_account_from_social(social_info)
|
|
35
|
+
rescue ActiveRecord::RecordNotUnique
|
|
36
|
+
# Race condition: concurrent request created the account first — retry to find it
|
|
37
|
+
account = find_or_create_account_from_social(social_info)
|
|
38
|
+
end
|
|
39
|
+
newly_created = account.previously_new_record?
|
|
32
40
|
session_manager.sign_in_account(account)
|
|
33
41
|
|
|
42
|
+
provider_name = provider.provider_name
|
|
43
|
+
invoke_after_account_created(account, { mechanism: "social", provider: provider_name }) if newly_created
|
|
44
|
+
|
|
34
45
|
run_social_callback(
|
|
35
|
-
provider:
|
|
46
|
+
provider: provider_name,
|
|
36
47
|
social_info: social_info,
|
|
37
48
|
provider_tokens: provider_tokens,
|
|
38
49
|
account: account,
|
|
39
50
|
original_request_params: state_data
|
|
40
51
|
)
|
|
41
52
|
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
context = { connection: "social", provider: provider_name }
|
|
54
|
+
redirect_override = invoke_after_sign_in(account, context)
|
|
55
|
+
|
|
56
|
+
destination = redirect_override || state_data["redirect_uri"]
|
|
57
|
+
redirect_options = { notice: "Successfully signed in with #{provider_name.humanize}" }
|
|
44
58
|
redirect_options[:allow_other_host] = true if allow_other_host_redirect?(destination)
|
|
45
59
|
redirect_to destination, redirect_options
|
|
60
|
+
rescue StandardId::AuthenticationDenied => e
|
|
61
|
+
handle_authentication_denied(e, account: account, newly_created: newly_created)
|
|
46
62
|
rescue StandardId::OAuthError => e
|
|
47
63
|
redirect_to StandardId::WebEngine.routes.url_helpers.login_path(redirect_uri: state_data&.dig("redirect_uri")), alert: "Authentication failed: #{e.message}"
|
|
48
64
|
end
|
|
@@ -4,6 +4,7 @@ module StandardId
|
|
|
4
4
|
include StandardId::ControllerPolicy
|
|
5
5
|
include StandardId::WebAuthentication
|
|
6
6
|
include StandardId::SetCurrentRequestDetails
|
|
7
|
+
include StandardId::WebMechanismGate
|
|
7
8
|
|
|
8
9
|
include StandardId::WebEngine.routes.url_helpers
|
|
9
10
|
helper StandardId::WebEngine.routes.url_helpers
|
|
@@ -6,6 +6,7 @@ module StandardId
|
|
|
6
6
|
include StandardId::InertiaRendering
|
|
7
7
|
include StandardId::Web::SocialLoginParams
|
|
8
8
|
include StandardId::PasswordlessStrategy
|
|
9
|
+
include StandardId::LifecycleHooks
|
|
9
10
|
|
|
10
11
|
layout "public"
|
|
11
12
|
|
|
@@ -32,16 +33,23 @@ module StandardId
|
|
|
32
33
|
private
|
|
33
34
|
|
|
34
35
|
def passwordless_enabled?
|
|
35
|
-
StandardId.config.
|
|
36
|
+
StandardId.config.web.passwordless_login
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
def handle_password_login
|
|
40
|
+
return head(:not_found) unless StandardId.config.web.password_login
|
|
41
|
+
|
|
39
42
|
if sign_in_account(login_params)
|
|
40
|
-
|
|
43
|
+
context = { connection: "password", provider: nil }
|
|
44
|
+
redirect_override = invoke_after_sign_in(current_account, context)
|
|
45
|
+
destination = redirect_override || params[:redirect_uri] || after_authentication_url
|
|
46
|
+
redirect_to destination, status: :see_other, notice: "Successfully signed in"
|
|
41
47
|
else
|
|
42
48
|
flash.now[:alert] = "Invalid email or password"
|
|
43
49
|
render_with_inertia action: :show, props: auth_page_props(passwordless_enabled: passwordless_enabled?), status: :unprocessable_content
|
|
44
50
|
end
|
|
51
|
+
rescue StandardId::AuthenticationDenied => e
|
|
52
|
+
handle_authentication_denied(e)
|
|
45
53
|
end
|
|
46
54
|
|
|
47
55
|
def handle_passwordless_login
|
|
@@ -2,14 +2,14 @@ module StandardId
|
|
|
2
2
|
module Web
|
|
3
3
|
class LoginVerifyController < BaseController
|
|
4
4
|
public_controller
|
|
5
|
+
requires_web_mechanism :passwordless_login
|
|
5
6
|
|
|
6
7
|
include StandardId::InertiaRendering
|
|
8
|
+
include StandardId::LifecycleHooks
|
|
7
9
|
|
|
8
10
|
layout "public"
|
|
9
11
|
|
|
10
12
|
skip_before_action :require_browser_session!, only: [:show, :update]
|
|
11
|
-
|
|
12
|
-
before_action :ensure_passwordless_enabled!
|
|
13
13
|
before_action :redirect_if_authenticated, only: [:show]
|
|
14
14
|
before_action :require_otp_payload!
|
|
15
15
|
|
|
@@ -39,23 +39,28 @@ module StandardId
|
|
|
39
39
|
return
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
account = result.account
|
|
43
|
+
newly_created = account.previously_new_record?
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
session_manager.sign_in_account(account)
|
|
46
|
+
emit_authentication_succeeded(account)
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
end
|
|
48
|
+
invoke_after_account_created(account, { mechanism: "passwordless", provider: nil }) if newly_created
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
context = { connection: @otp_data[:connection], provider: nil }
|
|
51
|
+
redirect_override = invoke_after_sign_in(account, context)
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
return if StandardId.config.passwordless.enabled
|
|
53
|
+
session.delete(:standard_id_otp_payload)
|
|
54
54
|
|
|
55
|
+
destination = redirect_override || after_authentication_url
|
|
56
|
+
redirect_to destination, status: :see_other, notice: "Successfully signed in"
|
|
57
|
+
rescue StandardId::AuthenticationDenied => e
|
|
55
58
|
session.delete(:standard_id_otp_payload)
|
|
56
|
-
|
|
59
|
+
handle_authentication_denied(e, account: account, newly_created: newly_created)
|
|
57
60
|
end
|
|
58
61
|
|
|
62
|
+
private
|
|
63
|
+
|
|
59
64
|
def redirect_if_authenticated
|
|
60
65
|
redirect_to after_authentication_url, status: :see_other if authenticated?
|
|
61
66
|
end
|
|
@@ -2,8 +2,10 @@ module StandardId
|
|
|
2
2
|
module Web
|
|
3
3
|
class SignupController < BaseController
|
|
4
4
|
public_controller
|
|
5
|
+
requires_web_mechanism :signup
|
|
5
6
|
|
|
6
7
|
include StandardId::InertiaRendering
|
|
8
|
+
include StandardId::LifecycleHooks
|
|
7
9
|
|
|
8
10
|
layout "public"
|
|
9
11
|
|
|
@@ -38,14 +40,20 @@ module StandardId
|
|
|
38
40
|
|
|
39
41
|
if form.submit
|
|
40
42
|
session_manager.sign_in_account(form.account)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
invoke_after_account_created(form.account, { mechanism: "signup", provider: nil })
|
|
44
|
+
|
|
45
|
+
context = { connection: "password", provider: nil }
|
|
46
|
+
redirect_override = invoke_after_sign_in(form.account, context)
|
|
47
|
+
destination = redirect_override || params[:redirect_uri] || after_authentication_url
|
|
48
|
+
redirect_to destination, notice: "Account created successfully"
|
|
43
49
|
else
|
|
44
50
|
@redirect_uri = params[:redirect_uri] || after_authentication_url
|
|
45
51
|
@connection = params[:connection]
|
|
46
52
|
flash.now[:alert] = form.errors.full_messages.join(", ")
|
|
47
53
|
render_with_inertia action: :show, props: auth_page_props(errors: form.errors.to_hash), status: :unprocessable_content
|
|
48
54
|
end
|
|
55
|
+
rescue StandardId::AuthenticationDenied => e
|
|
56
|
+
handle_authentication_denied(e, account: form.account, newly_created: form.account&.previously_new_record?)
|
|
49
57
|
end
|
|
50
58
|
|
|
51
59
|
def social_signup_url
|
data/config/brakeman.ignore
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"ignored_warnings": [
|
|
3
|
-
{
|
|
4
|
-
"fingerprint": "24fc02735a2ad863d6bf1171a4a329b208e9e7c41841fa0149d8e6878d4ce299",
|
|
5
|
-
"note": "Auth engine intentionally redirects to params[:redirect_uri] after signup for OAuth/post-auth flow"
|
|
6
|
-
},
|
|
7
3
|
{
|
|
8
4
|
"fingerprint": "6b35e9906d62a9b9cd0dff9cf53924d40e74bc4f96cfccf27e67e93551113243",
|
|
9
5
|
"note": "Auth engine intentionally redirects to params[:redirect_uri] after logout for OAuth/post-auth flow"
|
|
@@ -16,15 +12,19 @@
|
|
|
16
12
|
"fingerprint": "bdbc72619da2ba771b1185ccf16acce801066689bf51adf116eab8c8714b39af",
|
|
17
13
|
"note": "HEAD vs GET distinction is inconsequential here; storing return URL on GET-only is safe"
|
|
18
14
|
},
|
|
19
|
-
{
|
|
20
|
-
"fingerprint": "16bd6ec7c3fa130eb80c15fc90c87f9859d89b37258807bfaffe4101366611a6",
|
|
21
|
-
"note": "Auth engine intentionally redirects to params[:redirect_uri] after login for OAuth/post-auth flow"
|
|
22
|
-
},
|
|
23
15
|
{
|
|
24
16
|
"fingerprint": "e4f96cb212c73c3165c3db6eaa6368c29d362b61264f034e80c9fa6705d72e5b",
|
|
25
17
|
"note": "Auth engine intentionally redirects to params[:redirect_uri] when user is not authenticated"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"fingerprint": "68be03a57d3ef2cfb68582fc78ac2eb6b96aaa0a9897a9a975c24b889fdbb2aa",
|
|
21
|
+
"note": "after_sign_in hook redirect is controlled by the host app configuration, not user input"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"fingerprint": "277cf277d1c94f46d0abaeba9c51312d1d17e6f62c2e8d457dda47a6aad422aa",
|
|
25
|
+
"note": "after_sign_in hook redirect is controlled by the host app configuration, not user input"
|
|
26
26
|
}
|
|
27
27
|
],
|
|
28
|
-
"updated": "2026-
|
|
29
|
-
"brakeman_version": "8.0.
|
|
28
|
+
"updated": "2026-03-21",
|
|
29
|
+
"brakeman_version": "8.0.4"
|
|
30
30
|
}
|
|
@@ -21,6 +21,20 @@ StandardConfig.schema.draw do
|
|
|
21
21
|
# Callable (lambda/proc) that returns a Hash of extra Sentry user context fields.
|
|
22
22
|
# Receives (account, session) where session may be nil. Non-callable values are ignored.
|
|
23
23
|
field :sentry_context, type: :any, default: nil
|
|
24
|
+
|
|
25
|
+
# Post-authentication lifecycle hooks (synchronous, WebEngine only)
|
|
26
|
+
#
|
|
27
|
+
# after_sign_in: Called after successful sign-in, before redirect.
|
|
28
|
+
# Receives: (account, request, context)
|
|
29
|
+
# Context: { first_sign_in: bool, connection: "email"/"password"/"social", provider: nil/"google"/"apple" }
|
|
30
|
+
# Return: nil (default redirect) or a path string (override redirect)
|
|
31
|
+
# Raise StandardId::AuthenticationDenied.new("message") to reject sign-in.
|
|
32
|
+
field :after_sign_in, type: :any, default: nil
|
|
33
|
+
|
|
34
|
+
# after_account_created: Called after a new account is created via any mechanism.
|
|
35
|
+
# Receives: (account, request, context)
|
|
36
|
+
# Context: { mechanism: "passwordless"/"social"/"signup", provider: nil/"google"/"apple" }
|
|
37
|
+
field :after_account_created, type: :any, default: nil
|
|
24
38
|
end
|
|
25
39
|
|
|
26
40
|
scope :events do
|
|
@@ -28,6 +42,8 @@ StandardConfig.schema.draw do
|
|
|
28
42
|
end
|
|
29
43
|
|
|
30
44
|
scope :passwordless do
|
|
45
|
+
# Deprecated: use web.passwordless_login to control WebEngine passwordless login.
|
|
46
|
+
# Retained for backwards compatibility with consuming apps that set this field.
|
|
31
47
|
field :enabled, type: :boolean, default: false
|
|
32
48
|
field :connection, type: :string, default: "email"
|
|
33
49
|
field :code_ttl, type: :integer, default: 600 # 10 minutes in seconds
|
|
@@ -81,4 +97,15 @@ StandardConfig.schema.draw do
|
|
|
81
97
|
field :allowed_redirect_url_prefixes, type: :array, default: []
|
|
82
98
|
field :available_scopes, type: :array, default: -> { [] }
|
|
83
99
|
end
|
|
100
|
+
|
|
101
|
+
scope :web do
|
|
102
|
+
field :password_login, type: :boolean, default: true
|
|
103
|
+
field :signup, type: :boolean, default: true
|
|
104
|
+
field :passwordless_login, type: :boolean, default: false
|
|
105
|
+
field :social_login, type: :boolean, default: true
|
|
106
|
+
field :password_reset, type: :boolean, default: true
|
|
107
|
+
field :email_verification, type: :boolean, default: true
|
|
108
|
+
field :phone_verification, type: :boolean, default: true
|
|
109
|
+
field :sessions_management, type: :boolean, default: true
|
|
110
|
+
end
|
|
84
111
|
end
|
data/lib/standard_id/errors.rb
CHANGED
|
@@ -70,6 +70,9 @@ module StandardId
|
|
|
70
70
|
def oauth_error_code = :unsupported_response_type
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
+
# Lifecycle hook errors
|
|
74
|
+
class AuthenticationDenied < StandardError; end
|
|
75
|
+
|
|
73
76
|
# Audience verification errors
|
|
74
77
|
class InvalidAudienceError < StandardError
|
|
75
78
|
attr_reader :required, :actual
|
data/lib/standard_id/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jaryl Sim
|
|
@@ -112,12 +112,14 @@ files:
|
|
|
112
112
|
- app/controllers/concerns/standard_id/controller_policy.rb
|
|
113
113
|
- app/controllers/concerns/standard_id/inertia_rendering.rb
|
|
114
114
|
- app/controllers/concerns/standard_id/inertia_support.rb
|
|
115
|
+
- app/controllers/concerns/standard_id/lifecycle_hooks.rb
|
|
115
116
|
- app/controllers/concerns/standard_id/passwordless_strategy.rb
|
|
116
117
|
- app/controllers/concerns/standard_id/sentry_context.rb
|
|
117
118
|
- app/controllers/concerns/standard_id/set_current_request_details.rb
|
|
118
119
|
- app/controllers/concerns/standard_id/social_authentication.rb
|
|
119
120
|
- app/controllers/concerns/standard_id/web/social_login_params.rb
|
|
120
121
|
- app/controllers/concerns/standard_id/web_authentication.rb
|
|
122
|
+
- app/controllers/concerns/standard_id/web_mechanism_gate.rb
|
|
121
123
|
- app/controllers/standard_id/api/authorization_controller.rb
|
|
122
124
|
- app/controllers/standard_id/api/base_controller.rb
|
|
123
125
|
- app/controllers/standard_id/api/oauth/base_controller.rb
|
|
@@ -265,6 +267,7 @@ metadata:
|
|
|
265
267
|
homepage_uri: https://github.com/rarebit-one/standard_id
|
|
266
268
|
source_code_uri: https://github.com/rarebit-one/standard_id
|
|
267
269
|
changelog_uri: https://github.com/rarebit-one/standard_id/blob/main/CHANGELOG.md
|
|
270
|
+
bug_tracker_uri: https://github.com/rarebit-one/standard_id/issues
|
|
268
271
|
rdoc_options: []
|
|
269
272
|
require_paths:
|
|
270
273
|
- lib
|