standard_id 0.1.5 → 0.1.7
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/README.md +529 -20
- data/app/controllers/concerns/standard_id/inertia_rendering.rb +49 -0
- data/app/controllers/concerns/standard_id/inertia_support.rb +31 -0
- data/app/controllers/concerns/standard_id/set_current_request_details.rb +19 -0
- data/app/controllers/concerns/standard_id/social_authentication.rb +86 -37
- data/app/controllers/concerns/standard_id/web_authentication.rb +50 -1
- data/app/controllers/standard_id/api/base_controller.rb +1 -0
- data/app/controllers/standard_id/api/oauth/callback/providers_controller.rb +7 -18
- data/app/controllers/standard_id/web/auth/callback/providers_controller.rb +33 -37
- data/app/controllers/standard_id/web/base_controller.rb +1 -0
- data/app/controllers/standard_id/web/login_controller.rb +12 -21
- data/app/controllers/standard_id/web/signup_controller.rb +11 -8
- data/app/forms/standard_id/web/signup_form.rb +32 -1
- data/app/models/standard_id/browser_session.rb +8 -0
- data/app/models/standard_id/client_secret_credential.rb +11 -0
- data/app/models/standard_id/device_session.rb +4 -0
- data/app/models/standard_id/identifier.rb +28 -0
- data/app/models/standard_id/service_session.rb +1 -1
- data/app/models/standard_id/session.rb +16 -2
- data/app/views/standard_id/web/auth/callback/providers/{apple_mobile.html.erb → mobile_callback.html.erb} +1 -1
- data/config/routes/api.rb +1 -2
- data/config/routes/web.rb +4 -3
- data/lib/generators/standard_id/install/templates/standard_id.rb +19 -8
- data/lib/standard_config/config.rb +13 -12
- data/lib/standard_config/config_provider.rb +6 -6
- data/lib/standard_config/schema.rb +2 -2
- data/lib/standard_id/account_locking.rb +86 -0
- data/lib/standard_id/account_status.rb +45 -0
- data/lib/standard_id/api/authentication_guard.rb +40 -1
- data/lib/standard_id/api/token_manager.rb +1 -1
- data/lib/standard_id/config/schema.rb +13 -9
- data/lib/standard_id/current_attributes.rb +9 -0
- data/lib/standard_id/engine.rb +9 -0
- data/lib/standard_id/errors.rb +12 -0
- data/lib/standard_id/events/definitions.rb +157 -0
- data/lib/standard_id/events/event.rb +123 -0
- data/lib/standard_id/events/subscribers/account_locking_subscriber.rb +17 -0
- data/lib/standard_id/events/subscribers/account_status_subscriber.rb +17 -0
- data/lib/standard_id/events/subscribers/base.rb +165 -0
- data/lib/standard_id/events/subscribers/logging_subscriber.rb +122 -0
- data/lib/standard_id/events.rb +137 -0
- data/lib/standard_id/oauth/authorization_code_flow.rb +10 -0
- data/lib/standard_id/oauth/client_credentials_flow.rb +31 -0
- data/lib/standard_id/oauth/password_flow.rb +36 -4
- data/lib/standard_id/oauth/passwordless_otp_flow.rb +38 -2
- data/lib/standard_id/oauth/subflows/social_login_grant.rb +11 -22
- data/lib/standard_id/oauth/token_grant_flow.rb +22 -1
- data/lib/standard_id/passwordless/base_strategy.rb +32 -0
- data/lib/standard_id/provider_registry.rb +73 -0
- data/lib/standard_id/{social_providers → providers}/apple.rb +46 -7
- data/lib/standard_id/providers/base.rb +242 -0
- data/lib/standard_id/{social_providers → providers}/google.rb +26 -7
- data/lib/standard_id/version.rb +1 -1
- data/lib/standard_id/web/authentication_guard.rb +29 -0
- data/lib/standard_id/web/session_manager.rb +39 -1
- data/lib/standard_id/web/token_manager.rb +2 -2
- data/lib/standard_id.rb +13 -2
- metadata +20 -6
- data/lib/standard_id/social_providers/response_builder.rb +0 -18
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
module StandardId
|
|
2
|
+
module Providers
|
|
3
|
+
# Base class for social login providers.
|
|
4
|
+
#
|
|
5
|
+
# All provider implementations (Google, Apple, GitHub, etc.) must inherit from this class
|
|
6
|
+
# and implement the required interface methods. This enables a plugin architecture where
|
|
7
|
+
# provider gems can be developed independently and registered with StandardId.
|
|
8
|
+
#
|
|
9
|
+
# @example Creating a custom provider
|
|
10
|
+
# module StandardId
|
|
11
|
+
# module Providers
|
|
12
|
+
# class GitHub < Base
|
|
13
|
+
# def self.provider_name
|
|
14
|
+
# "github"
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# def self.authorization_url(state:, redirect_uri:, **options)
|
|
18
|
+
# # Build and return GitHub OAuth authorization URL
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# def self.get_user_info(code: nil, id_token: nil, access_token: nil, redirect_uri: nil, **options)
|
|
22
|
+
# # Exchange credentials for user info and return standardized response
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# def self.config_schema
|
|
26
|
+
# {
|
|
27
|
+
# github_client_id: { type: :string, default: nil },
|
|
28
|
+
# github_client_secret: { type: :string, default: nil }
|
|
29
|
+
# }
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# # Register the provider
|
|
36
|
+
# StandardId::ProviderRegistry.register(:github, StandardId::Providers::GitHub)
|
|
37
|
+
#
|
|
38
|
+
class Base
|
|
39
|
+
class << self
|
|
40
|
+
# Provider identifier used for routing and configuration.
|
|
41
|
+
#
|
|
42
|
+
# @return [String] Unique provider name (e.g., "google", "apple", "github")
|
|
43
|
+
# @raise [NotImplementedError] if not overridden by subclass
|
|
44
|
+
#
|
|
45
|
+
# @example
|
|
46
|
+
# StandardId::Providers::Google.provider_name #=> "google"
|
|
47
|
+
#
|
|
48
|
+
def provider_name
|
|
49
|
+
raise NotImplementedError, "#{name} must implement .provider_name"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Generate OAuth authorization URL for redirecting users to the provider.
|
|
53
|
+
#
|
|
54
|
+
# @param state [String] OAuth state parameter (typically encoded with redirect + session info)
|
|
55
|
+
# @param redirect_uri [String] Callback URL where provider will redirect after authentication
|
|
56
|
+
# @param options [Hash] Provider-specific options (scope, prompt, response_mode, etc.)
|
|
57
|
+
# @return [String] Full authorization URL to redirect user to
|
|
58
|
+
# @raise [NotImplementedError] if not overridden by subclass
|
|
59
|
+
#
|
|
60
|
+
# @example
|
|
61
|
+
# url = StandardId::Providers::Google.authorization_url(
|
|
62
|
+
# state: "encoded_state_data",
|
|
63
|
+
# redirect_uri: "https://app.example.com/auth/callback/google",
|
|
64
|
+
# scope: "openid email profile"
|
|
65
|
+
# )
|
|
66
|
+
#
|
|
67
|
+
def authorization_url(state:, redirect_uri:, **options)
|
|
68
|
+
raise NotImplementedError, "#{name} must implement .authorization_url"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Exchange OAuth credentials for user information.
|
|
72
|
+
#
|
|
73
|
+
# Providers must support at least one of: authorization code, ID token, or access token.
|
|
74
|
+
# The method should validate the credentials with the provider and return standardized
|
|
75
|
+
# user information.
|
|
76
|
+
#
|
|
77
|
+
# @param code [String, nil] OAuth authorization code (web flow)
|
|
78
|
+
# @param id_token [String, nil] JWT ID token (mobile/implicit flow)
|
|
79
|
+
# @param access_token [String, nil] Access token (implicit flow)
|
|
80
|
+
# @param redirect_uri [String, nil] Original redirect_uri for code exchange validation
|
|
81
|
+
# @param options [Hash] Provider-specific options (client_id for Apple mobile, etc.)
|
|
82
|
+
# @return [HashWithIndifferentAccess] Standardized response with user_info and tokens
|
|
83
|
+
# @raise [NotImplementedError] if not overridden by subclass
|
|
84
|
+
# @raise [StandardId::InvalidRequestError] if credentials are missing or invalid
|
|
85
|
+
# @raise [StandardId::OAuthError] if provider returns an error
|
|
86
|
+
#
|
|
87
|
+
# @example Response format
|
|
88
|
+
# {
|
|
89
|
+
# user_info: {
|
|
90
|
+
# "sub" => "unique_provider_user_id",
|
|
91
|
+
# "email" => "user@example.com",
|
|
92
|
+
# "email_verified" => true,
|
|
93
|
+
# "name" => "Full Name",
|
|
94
|
+
# # ... other provider-specific fields
|
|
95
|
+
# },
|
|
96
|
+
# tokens: {
|
|
97
|
+
# id_token: "...",
|
|
98
|
+
# access_token: "...",
|
|
99
|
+
# refresh_token: "..."
|
|
100
|
+
# }
|
|
101
|
+
# }
|
|
102
|
+
#
|
|
103
|
+
def get_user_info(code: nil, id_token: nil, access_token: nil, redirect_uri: nil, **options)
|
|
104
|
+
raise NotImplementedError, "#{name} must implement .get_user_info"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Define configuration schema fields for this provider.
|
|
108
|
+
#
|
|
109
|
+
# Returns a hash of field definitions compatible with StandardConfig schema DSL.
|
|
110
|
+
# These fields will be registered under the :social configuration scope.
|
|
111
|
+
#
|
|
112
|
+
# @return [Hash] Field definitions with types and defaults
|
|
113
|
+
#
|
|
114
|
+
# @example
|
|
115
|
+
# def self.config_schema
|
|
116
|
+
# {
|
|
117
|
+
# github_client_id: { type: :string, default: nil },
|
|
118
|
+
# github_client_secret: { type: :string, default: nil }
|
|
119
|
+
# }
|
|
120
|
+
# end
|
|
121
|
+
#
|
|
122
|
+
def config_schema
|
|
123
|
+
{}
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Resolve provider-specific parameters based on context.
|
|
127
|
+
#
|
|
128
|
+
# Override this method to customize parameters based on flow type,
|
|
129
|
+
# platform, or other contextual information. This allows providers
|
|
130
|
+
# to handle platform-specific requirements (e.g., Apple's different
|
|
131
|
+
# client IDs for web vs mobile).
|
|
132
|
+
#
|
|
133
|
+
# @param params [Hash] Base parameters from the controller
|
|
134
|
+
# @param context [Hash] Contextual information
|
|
135
|
+
# @option context [Symbol] :flow The authentication flow (:web or :mobile)
|
|
136
|
+
# @return [Hash] Modified parameters with provider-specific adjustments
|
|
137
|
+
#
|
|
138
|
+
# @example Apple provider overriding for mobile flow
|
|
139
|
+
# def self.resolve_params(params, context: {})
|
|
140
|
+
# if context[:flow] == :mobile
|
|
141
|
+
# params.merge(client_id: StandardId.config.apple_mobile_client_id)
|
|
142
|
+
# else
|
|
143
|
+
# params
|
|
144
|
+
# end
|
|
145
|
+
# end
|
|
146
|
+
#
|
|
147
|
+
def resolve_params(params, context: {})
|
|
148
|
+
params
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Returns the callback path for this provider.
|
|
152
|
+
#
|
|
153
|
+
# Used to build the OAuth redirect URI. Uses the engine's route helpers
|
|
154
|
+
# to respect the mount path.
|
|
155
|
+
#
|
|
156
|
+
# @return [String] The callback path (respects engine mount path)
|
|
157
|
+
#
|
|
158
|
+
# @example Engine mounted at "/"
|
|
159
|
+
# StandardId::Providers::Google.callback_path #=> "/auth/callback/google"
|
|
160
|
+
#
|
|
161
|
+
# @example Engine mounted at "/identity"
|
|
162
|
+
# StandardId::Providers::Google.callback_path #=> "/identity/auth/callback/google"
|
|
163
|
+
#
|
|
164
|
+
def callback_path
|
|
165
|
+
StandardId::WebEngine.routes.url_helpers.auth_callback_provider_path(provider: provider_name)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Returns the default OAuth scope for this provider.
|
|
169
|
+
#
|
|
170
|
+
# Can be overridden by passing :scope in authorization_url options.
|
|
171
|
+
# Returns nil by default, letting the provider use its own default.
|
|
172
|
+
#
|
|
173
|
+
# @return [String, nil] Default scope string
|
|
174
|
+
#
|
|
175
|
+
# @example
|
|
176
|
+
# StandardId::Providers::Google.default_scope #=> "openid email profile"
|
|
177
|
+
#
|
|
178
|
+
def default_scope
|
|
179
|
+
nil
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Whether to skip CSRF verification for web callbacks.
|
|
183
|
+
#
|
|
184
|
+
# Some providers (like Apple) use POST callbacks which require
|
|
185
|
+
# CSRF verification to be skipped. Override this method to return
|
|
186
|
+
# true if your provider uses POST callbacks.
|
|
187
|
+
#
|
|
188
|
+
# @return [Boolean] true to skip CSRF verification
|
|
189
|
+
#
|
|
190
|
+
# @example Apple provider (POST callback)
|
|
191
|
+
# def self.skip_csrf?
|
|
192
|
+
# true
|
|
193
|
+
# end
|
|
194
|
+
#
|
|
195
|
+
def skip_csrf?
|
|
196
|
+
false
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Whether this provider supports mobile callback flow.
|
|
200
|
+
#
|
|
201
|
+
# Mobile callbacks are used when native apps (especially Android)
|
|
202
|
+
# need a server-side redirect back to the app after OAuth.
|
|
203
|
+
# For example, Apple Sign In on Android uses a web-based flow
|
|
204
|
+
# that requires the server to redirect back to the app.
|
|
205
|
+
#
|
|
206
|
+
# @return [Boolean] true if provider supports mobile callback
|
|
207
|
+
#
|
|
208
|
+
def supports_mobile_callback?
|
|
209
|
+
false
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Optional setup hook called when provider is registered.
|
|
213
|
+
#
|
|
214
|
+
# Override this method to perform initialization tasks like:
|
|
215
|
+
# - Registering additional routes
|
|
216
|
+
# - Adding custom validations
|
|
217
|
+
# - Setting up caching for JWKS
|
|
218
|
+
#
|
|
219
|
+
# @return [void]
|
|
220
|
+
#
|
|
221
|
+
def setup
|
|
222
|
+
# Override in subclasses if needed
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
protected
|
|
226
|
+
|
|
227
|
+
# Helper to build standardized response format.
|
|
228
|
+
#
|
|
229
|
+
# @param user_info [Hash] User information from provider
|
|
230
|
+
# @param tokens [Hash] OAuth tokens (id_token, access_token, refresh_token)
|
|
231
|
+
# @return [HashWithIndifferentAccess] Standardized response
|
|
232
|
+
#
|
|
233
|
+
def build_response(user_info, tokens: {})
|
|
234
|
+
{
|
|
235
|
+
user_info: user_info,
|
|
236
|
+
tokens: tokens.compact
|
|
237
|
+
}.with_indifferent_access
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
require_relative "
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module StandardId
|
|
4
|
-
module
|
|
5
|
-
class Google
|
|
6
|
-
include ResponseBuilder
|
|
7
|
-
|
|
4
|
+
module Providers
|
|
5
|
+
class Google < Base
|
|
8
6
|
AUTH_ENDPOINT = "https://accounts.google.com/o/oauth2/v2/auth".freeze
|
|
9
7
|
TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token".freeze
|
|
10
8
|
USERINFO_ENDPOINT = "https://www.googleapis.com/oauth2/v2/userinfo".freeze
|
|
@@ -12,7 +10,14 @@ module StandardId
|
|
|
12
10
|
DEFAULT_SCOPE = "openid email profile".freeze
|
|
13
11
|
|
|
14
12
|
class << self
|
|
15
|
-
def
|
|
13
|
+
def provider_name
|
|
14
|
+
"google"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def authorization_url(state:, redirect_uri:, **options)
|
|
18
|
+
scope = options[:scope] || DEFAULT_SCOPE
|
|
19
|
+
prompt = options[:prompt]
|
|
20
|
+
|
|
16
21
|
query = {
|
|
17
22
|
client_id: credentials[:client_id],
|
|
18
23
|
redirect_uri: redirect_uri,
|
|
@@ -26,7 +31,7 @@ module StandardId
|
|
|
26
31
|
"#{AUTH_ENDPOINT}?#{URI.encode_www_form(query)}"
|
|
27
32
|
end
|
|
28
33
|
|
|
29
|
-
def get_user_info(code: nil, id_token: nil, access_token: nil, redirect_uri: nil)
|
|
34
|
+
def get_user_info(code: nil, id_token: nil, access_token: nil, redirect_uri: nil, **options)
|
|
30
35
|
if id_token.present?
|
|
31
36
|
build_response(
|
|
32
37
|
verify_id_token(id_token: id_token),
|
|
@@ -44,6 +49,17 @@ module StandardId
|
|
|
44
49
|
end
|
|
45
50
|
end
|
|
46
51
|
|
|
52
|
+
def config_schema
|
|
53
|
+
{
|
|
54
|
+
google_client_id: { type: :string, default: nil },
|
|
55
|
+
google_client_secret: { type: :string, default: nil }
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def default_scope
|
|
60
|
+
DEFAULT_SCOPE
|
|
61
|
+
end
|
|
62
|
+
|
|
47
63
|
def exchange_code_for_user_info(code:, redirect_uri:)
|
|
48
64
|
raise StandardId::InvalidRequestError, "Missing authorization code" if code.blank?
|
|
49
65
|
|
|
@@ -166,3 +182,6 @@ module StandardId
|
|
|
166
182
|
end
|
|
167
183
|
end
|
|
168
184
|
end
|
|
185
|
+
|
|
186
|
+
# Auto-register with the provider registry
|
|
187
|
+
StandardId::ProviderRegistry.register(:google, StandardId::Providers::Google)
|
data/lib/standard_id/version.rb
CHANGED
|
@@ -5,10 +5,12 @@ module StandardId
|
|
|
5
5
|
session[:return_to_after_authenticating] = request.url
|
|
6
6
|
|
|
7
7
|
browser_session = session_manager.current_session
|
|
8
|
+
emit_session_validating(browser_session, request)
|
|
8
9
|
|
|
9
10
|
if browser_session.blank?
|
|
10
11
|
raise StandardId::NotAuthenticatedError
|
|
11
12
|
elsif browser_session.expired?
|
|
13
|
+
emit_session_expired(browser_session)
|
|
12
14
|
session_manager.clear_session!
|
|
13
15
|
raise StandardId::ExpiredSessionError
|
|
14
16
|
elsif browser_session.revoked?
|
|
@@ -16,8 +18,35 @@ module StandardId
|
|
|
16
18
|
raise StandardId::RevokedSessionError
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
emit_session_validated(browser_session)
|
|
19
22
|
browser_session
|
|
20
23
|
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def emit_session_validating(browser_session, request)
|
|
28
|
+
StandardId::Events.publish(
|
|
29
|
+
StandardId::Events::SESSION_VALIDATING,
|
|
30
|
+
session: browser_session
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def emit_session_validated(browser_session)
|
|
35
|
+
StandardId::Events.publish(
|
|
36
|
+
StandardId::Events::SESSION_VALIDATED,
|
|
37
|
+
session: browser_session,
|
|
38
|
+
account: browser_session.account
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def emit_session_expired(browser_session)
|
|
43
|
+
StandardId::Events.publish(
|
|
44
|
+
StandardId::Events::SESSION_EXPIRED,
|
|
45
|
+
session: browser_session,
|
|
46
|
+
account: browser_session.account,
|
|
47
|
+
expired_at: browser_session.expires_at
|
|
48
|
+
)
|
|
49
|
+
end
|
|
21
50
|
end
|
|
22
51
|
end
|
|
23
52
|
end
|
|
@@ -19,9 +19,11 @@ module StandardId
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def sign_in_account(account)
|
|
22
|
+
emit_session_creating(account, "browser")
|
|
22
23
|
token_manager.create_browser_session(account).tap do |browser_session|
|
|
23
24
|
session[:session_token] = browser_session.token
|
|
24
25
|
Current.session = browser_session
|
|
26
|
+
emit_session_created(browser_session, account, "browser")
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
|
|
@@ -48,7 +50,16 @@ module StandardId
|
|
|
48
50
|
Current.session ||= load_session_from_session_token
|
|
49
51
|
Current.session ||= load_session_from_remember_token
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
if Current.session.present?
|
|
54
|
+
if Current.session.expired?
|
|
55
|
+
emit_session_expired(Current.session)
|
|
56
|
+
clear_session!
|
|
57
|
+
elsif Current.session.revoked?
|
|
58
|
+
clear_session!
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
clear_session!
|
|
62
|
+
end
|
|
52
63
|
|
|
53
64
|
Current.session
|
|
54
65
|
end
|
|
@@ -66,6 +77,33 @@ module StandardId
|
|
|
66
77
|
cookies[:remember_token] = token_manager.create_remember_token(password_credential)
|
|
67
78
|
end
|
|
68
79
|
end
|
|
80
|
+
|
|
81
|
+
def emit_session_creating(account, session_type)
|
|
82
|
+
StandardId::Events.publish(
|
|
83
|
+
StandardId::Events::SESSION_CREATING,
|
|
84
|
+
account: account,
|
|
85
|
+
session_type: session_type
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def emit_session_created(browser_session, account, session_type)
|
|
90
|
+
StandardId::Events.publish(
|
|
91
|
+
StandardId::Events::SESSION_CREATED,
|
|
92
|
+
session: browser_session,
|
|
93
|
+
account: account,
|
|
94
|
+
session_type: session_type,
|
|
95
|
+
token_issued: true
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def emit_session_expired(browser_session)
|
|
100
|
+
StandardId::Events.publish(
|
|
101
|
+
StandardId::Events::SESSION_EXPIRED,
|
|
102
|
+
session: browser_session,
|
|
103
|
+
account: browser_session.account,
|
|
104
|
+
expired_at: browser_session.expires_at
|
|
105
|
+
)
|
|
106
|
+
end
|
|
69
107
|
end
|
|
70
108
|
end
|
|
71
109
|
end
|
|
@@ -12,14 +12,14 @@ module StandardId
|
|
|
12
12
|
account: account,
|
|
13
13
|
ip_address: request.remote_ip,
|
|
14
14
|
user_agent: request.user_agent,
|
|
15
|
-
expires_at:
|
|
15
|
+
expires_at: StandardId::BrowserSession.expiry
|
|
16
16
|
)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def create_remember_token(password_credential)
|
|
20
20
|
{
|
|
21
21
|
value: password_credential.generate_token_for(:remember_me),
|
|
22
|
-
expires:
|
|
22
|
+
expires: StandardId::BrowserSession.remember_me_expiry,
|
|
23
23
|
httponly: true,
|
|
24
24
|
secure: request.ssl?,
|
|
25
25
|
same_site: :lax
|
data/lib/standard_id.rb
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
require "standard_id/version"
|
|
2
|
+
require "standard_id/current_attributes"
|
|
2
3
|
require "standard_id/engine"
|
|
3
4
|
require "standard_id/web_engine"
|
|
4
5
|
require "standard_id/api_engine"
|
|
5
6
|
require "standard_id/config/schema"
|
|
6
7
|
require "standard_id/errors"
|
|
8
|
+
require "standard_id/events"
|
|
9
|
+
require "standard_id/events/subscribers/base"
|
|
10
|
+
require "standard_id/events/subscribers/logging_subscriber"
|
|
11
|
+
require "standard_id/events/subscribers/account_status_subscriber"
|
|
12
|
+
require "standard_id/events/subscribers/account_locking_subscriber"
|
|
13
|
+
require "standard_id/account_status"
|
|
14
|
+
require "standard_id/account_locking"
|
|
7
15
|
require "standard_id/http_client"
|
|
8
16
|
require "standard_id/jwt_service"
|
|
9
17
|
require "standard_id/web/session_manager"
|
|
@@ -31,8 +39,11 @@ require "standard_id/passwordless/base_strategy"
|
|
|
31
39
|
require "standard_id/passwordless/email_strategy"
|
|
32
40
|
require "standard_id/passwordless/sms_strategy"
|
|
33
41
|
require "standard_id/utils/callable_parameter_filter"
|
|
34
|
-
|
|
35
|
-
require "standard_id/
|
|
42
|
+
|
|
43
|
+
require "standard_id/providers/base"
|
|
44
|
+
require "standard_id/provider_registry"
|
|
45
|
+
require "standard_id/providers/google"
|
|
46
|
+
require "standard_id/providers/apple"
|
|
36
47
|
|
|
37
48
|
module StandardId
|
|
38
49
|
class << self
|
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.
|
|
4
|
+
version: 0.1.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jaryl Sim
|
|
@@ -65,6 +65,9 @@ files:
|
|
|
65
65
|
- Rakefile
|
|
66
66
|
- app/assets/stylesheets/standard_id/application.css
|
|
67
67
|
- app/controllers/concerns/standard_id/api_authentication.rb
|
|
68
|
+
- app/controllers/concerns/standard_id/inertia_rendering.rb
|
|
69
|
+
- app/controllers/concerns/standard_id/inertia_support.rb
|
|
70
|
+
- app/controllers/concerns/standard_id/set_current_request_details.rb
|
|
68
71
|
- app/controllers/concerns/standard_id/social_authentication.rb
|
|
69
72
|
- app/controllers/concerns/standard_id/web_authentication.rb
|
|
70
73
|
- app/controllers/standard_id/api/authorization_controller.rb
|
|
@@ -115,7 +118,7 @@ files:
|
|
|
115
118
|
- app/models/standard_id/username_identifier.rb
|
|
116
119
|
- app/views/standard_id/web/account/edit.html.erb
|
|
117
120
|
- app/views/standard_id/web/account/show.html.erb
|
|
118
|
-
- app/views/standard_id/web/auth/callback/providers/
|
|
121
|
+
- app/views/standard_id/web/auth/callback/providers/mobile_callback.html.erb
|
|
119
122
|
- app/views/standard_id/web/login/show.html.erb
|
|
120
123
|
- app/views/standard_id/web/reset_password/confirm/show.html.erb
|
|
121
124
|
- app/views/standard_id/web/reset_password/start/show.html.erb
|
|
@@ -141,13 +144,23 @@ files:
|
|
|
141
144
|
- lib/standard_config/manager.rb
|
|
142
145
|
- lib/standard_config/schema.rb
|
|
143
146
|
- lib/standard_id.rb
|
|
147
|
+
- lib/standard_id/account_locking.rb
|
|
148
|
+
- lib/standard_id/account_status.rb
|
|
144
149
|
- lib/standard_id/api/authentication_guard.rb
|
|
145
150
|
- lib/standard_id/api/session_manager.rb
|
|
146
151
|
- lib/standard_id/api/token_manager.rb
|
|
147
152
|
- lib/standard_id/api_engine.rb
|
|
148
153
|
- lib/standard_id/config/schema.rb
|
|
154
|
+
- lib/standard_id/current_attributes.rb
|
|
149
155
|
- lib/standard_id/engine.rb
|
|
150
156
|
- lib/standard_id/errors.rb
|
|
157
|
+
- lib/standard_id/events.rb
|
|
158
|
+
- lib/standard_id/events/definitions.rb
|
|
159
|
+
- lib/standard_id/events/event.rb
|
|
160
|
+
- lib/standard_id/events/subscribers/account_locking_subscriber.rb
|
|
161
|
+
- lib/standard_id/events/subscribers/account_status_subscriber.rb
|
|
162
|
+
- lib/standard_id/events/subscribers/base.rb
|
|
163
|
+
- lib/standard_id/events/subscribers/logging_subscriber.rb
|
|
151
164
|
- lib/standard_id/http_client.rb
|
|
152
165
|
- lib/standard_id/jwt_service.rb
|
|
153
166
|
- lib/standard_id/oauth/authorization_code_authorization_flow.rb
|
|
@@ -168,9 +181,10 @@ files:
|
|
|
168
181
|
- lib/standard_id/passwordless/base_strategy.rb
|
|
169
182
|
- lib/standard_id/passwordless/email_strategy.rb
|
|
170
183
|
- lib/standard_id/passwordless/sms_strategy.rb
|
|
171
|
-
- lib/standard_id/
|
|
172
|
-
- lib/standard_id/
|
|
173
|
-
- lib/standard_id/
|
|
184
|
+
- lib/standard_id/provider_registry.rb
|
|
185
|
+
- lib/standard_id/providers/apple.rb
|
|
186
|
+
- lib/standard_id/providers/base.rb
|
|
187
|
+
- lib/standard_id/providers/google.rb
|
|
174
188
|
- lib/standard_id/utils/callable_parameter_filter.rb
|
|
175
189
|
- lib/standard_id/version.rb
|
|
176
190
|
- lib/standard_id/web/authentication_guard.rb
|
|
@@ -192,7 +206,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
192
206
|
requirements:
|
|
193
207
|
- - ">="
|
|
194
208
|
- !ruby/object:Gem::Version
|
|
195
|
-
version: '3.
|
|
209
|
+
version: '3.2'
|
|
196
210
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
211
|
requirements:
|
|
198
212
|
- - ">="
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
require "active_support/concern"
|
|
2
|
-
|
|
3
|
-
module StandardId
|
|
4
|
-
module SocialProviders
|
|
5
|
-
module ResponseBuilder
|
|
6
|
-
extend ActiveSupport::Concern
|
|
7
|
-
|
|
8
|
-
class_methods do
|
|
9
|
-
def build_response(user_info, tokens: {})
|
|
10
|
-
{
|
|
11
|
-
user_info: user_info,
|
|
12
|
-
tokens: tokens.compact
|
|
13
|
-
}.with_indifferent_access
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|