better_auth-sso 0.2.0 → 0.6.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.
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module Routes
6
+ module Schemas
7
+ OIDC_MAPPING_KEYS = %i[id email email_verified name image extra_fields].freeze
8
+ SAML_MAPPING_KEYS = %i[id email email_verified name first_name last_name extra_fields].freeze
9
+ OIDC_CONFIG_KEYS = %i[
10
+ client_id
11
+ client_secret
12
+ authorization_endpoint
13
+ token_endpoint
14
+ user_info_endpoint
15
+ token_endpoint_authentication
16
+ jwks_endpoint
17
+ discovery_endpoint
18
+ scopes
19
+ pkce
20
+ override_user_info
21
+ mapping
22
+ ].freeze
23
+ SAML_CONFIG_KEYS = %i[
24
+ entry_point
25
+ cert
26
+ callback_url
27
+ audience
28
+ idp_metadata
29
+ sp_metadata
30
+ want_assertions_signed
31
+ authn_requests_signed
32
+ want_logout_request_signed
33
+ want_logout_response_signed
34
+ signature_algorithm
35
+ digest_algorithm
36
+ identifier_format
37
+ private_key
38
+ decryption_pvk
39
+ additional_params
40
+ mapping
41
+ ].freeze
42
+
43
+ module_function
44
+
45
+ def plugin_schema(config = {})
46
+ normalized = BetterAuth::Plugins.normalize_hash(config || {})
47
+ fields = {
48
+ issuer: {type: "string", required: true},
49
+ oidcConfig: {type: "string", required: false},
50
+ samlConfig: {type: "string", required: false},
51
+ userId: {type: "string", required: true},
52
+ providerId: {type: "string", required: true, unique: true},
53
+ domain: {type: "string", required: true},
54
+ organizationId: {type: "string", required: false}
55
+ }
56
+ if normalized.dig(:domain_verification, :enabled)
57
+ fields[:domainVerified] = {type: "boolean", required: false, default_value: false}
58
+ end
59
+ {
60
+ ssoProvider: {
61
+ model_name: normalized[:model_name] || "ssoProviders",
62
+ fields: fields
63
+ }
64
+ }
65
+ end
66
+
67
+ def oidc_config_key?(key)
68
+ OIDC_CONFIG_KEYS.include?(BetterAuth::Plugins.normalize_key(key))
69
+ end
70
+
71
+ def saml_config_key?(key)
72
+ SAML_CONFIG_KEYS.include?(BetterAuth::Plugins.normalize_key(key))
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module Routes
6
+ module SSO
7
+ module_function
8
+
9
+ def endpoints(config = {})
10
+ normalized = BetterAuth::Plugins.normalize_hash(config || {})
11
+ endpoints = {
12
+ sp_metadata: BetterAuth::Plugins.sso_sp_metadata_endpoint(normalized),
13
+ register_sso_provider: BetterAuth::Plugins.sso_register_provider_endpoint(normalized),
14
+ sign_in_sso: BetterAuth::Plugins.sso_sign_in_endpoint(normalized),
15
+ callback_sso: BetterAuth::Plugins.sso_oidc_callback_endpoint(normalized),
16
+ callback_sso_shared: BetterAuth::Plugins.sso_oidc_shared_callback_endpoint(normalized),
17
+ callback_sso_saml: BetterAuth::Plugins.sso_saml_callback_endpoint(normalized),
18
+ acs_endpoint: BetterAuth::Plugins.sso_saml_acs_endpoint(normalized),
19
+ slo_endpoint: BetterAuth::Plugins.sso_saml_slo_endpoint(normalized),
20
+ initiate_slo: BetterAuth::Plugins.sso_initiate_slo_endpoint(normalized),
21
+ list_sso_providers: BetterAuth::Plugins.sso_list_providers_endpoint,
22
+ get_sso_provider: BetterAuth::Plugins.sso_get_provider_endpoint,
23
+ update_sso_provider: BetterAuth::Plugins.sso_update_provider_endpoint,
24
+ delete_sso_provider: BetterAuth::Plugins.sso_delete_provider_endpoint
25
+ }
26
+ if normalized.dig(:domain_verification, :enabled)
27
+ endpoints[:request_domain_verification] = BetterAuth::Plugins.sso_request_domain_verification_endpoint(normalized)
28
+ endpoints[:verify_domain] = BetterAuth::Plugins.sso_verify_domain_endpoint(normalized)
29
+ end
30
+ endpoints
31
+ end
32
+
33
+ def oidc_redirect_uri(context, provider_id)
34
+ BetterAuth::Plugins.sso_oidc_redirect_uri(context, provider_id)
35
+ end
36
+
37
+ def saml_authorization_url(provider, relay_state, ctx = nil, config = {})
38
+ BetterAuth::Plugins.sso_saml_authorization_url(provider, relay_state, ctx, config)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module SAML
6
+ module Algorithms
7
+ module_function
8
+
9
+ SignatureAlgorithm = BetterAuth::Plugins::SSO_SAML_SIGNATURE_ALGORITHMS.merge(
10
+ RSA_SHA1: "http://www.w3.org/2000/09/xmldsig#rsa-sha1",
11
+ RSA_SHA256: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
12
+ RSA_SHA384: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384",
13
+ RSA_SHA512: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512",
14
+ ECDSA_SHA256: "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256",
15
+ ECDSA_SHA384: "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384",
16
+ ECDSA_SHA512: "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"
17
+ ).freeze
18
+ DigestAlgorithm = BetterAuth::Plugins::SSO_SAML_DIGEST_ALGORITHMS.merge(
19
+ SHA1: "http://www.w3.org/2000/09/xmldsig#sha1",
20
+ SHA256: "http://www.w3.org/2001/04/xmlenc#sha256",
21
+ SHA384: "http://www.w3.org/2001/04/xmldsig-more#sha384",
22
+ SHA512: "http://www.w3.org/2001/04/xmlenc#sha512"
23
+ ).freeze
24
+ KEY_ENCRYPTION_ALGORITHM = {
25
+ RSA_1_5: "http://www.w3.org/2001/04/xmlenc#rsa-1_5",
26
+ RSA_OAEP: "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p",
27
+ RSA_OAEP_SHA256: "http://www.w3.org/2009/xmlenc11#rsa-oaep"
28
+ }.freeze
29
+ DATA_ENCRYPTION_ALGORITHM = {
30
+ TRIPLEDES_CBC: "http://www.w3.org/2001/04/xmlenc#tripledes-cbc",
31
+ AES_128_CBC: "http://www.w3.org/2001/04/xmlenc#aes128-cbc",
32
+ AES_192_CBC: "http://www.w3.org/2001/04/xmlenc#aes192-cbc",
33
+ AES_256_CBC: "http://www.w3.org/2001/04/xmlenc#aes256-cbc",
34
+ AES_128_GCM: "http://www.w3.org/2009/xmlenc11#aes128-gcm",
35
+ AES_192_GCM: "http://www.w3.org/2009/xmlenc11#aes192-gcm",
36
+ AES_256_GCM: "http://www.w3.org/2009/xmlenc11#aes256-gcm"
37
+ }.freeze
38
+ SecureSignatureAlgorithms = BetterAuth::Plugins::SSO_SAML_SECURE_SIGNATURE_ALGORITHMS
39
+ SecureDigestAlgorithms = BetterAuth::Plugins::SSO_SAML_SECURE_DIGEST_ALGORITHMS
40
+
41
+ def validate(xml, **options)
42
+ if xml.is_a?(Hash)
43
+ return validate_response(
44
+ sig_alg: xml[:sig_alg] || xml[:sigAlg] || xml["sig_alg"] || xml["sigAlg"],
45
+ saml_content: xml[:saml_content] || xml[:samlContent] || xml["saml_content"] || xml["samlContent"],
46
+ **options
47
+ )
48
+ end
49
+
50
+ BetterAuth::Plugins.sso_validate_saml_algorithms!(xml, normalize_options(options))
51
+ end
52
+
53
+ def validate_response(sig_alg: nil, saml_content: "", **options)
54
+ xml = +""
55
+ xml << "<ds:SignatureMethod Algorithm=\"#{sig_alg}\"/>" unless sig_alg.to_s.empty?
56
+ xml << saml_content.to_s
57
+ BetterAuth::Plugins.sso_validate_saml_algorithms!(xml, normalize_options(options))
58
+ end
59
+
60
+ def validate_config(config = {}, **options)
61
+ config_keys = %i[signature_algorithm signatureAlgorithm digest_algorithm digestAlgorithm]
62
+ inline_config = options.slice(*config_keys)
63
+ normalized = BetterAuth::Plugins.normalize_hash((config || {}).merge(inline_config))
64
+ options = options.except(*config_keys)
65
+ xml = +""
66
+ unless normalized[:signature_algorithm].to_s.empty?
67
+ xml << "<ds:SignatureMethod Algorithm=\"#{normalized[:signature_algorithm]}\"/>"
68
+ end
69
+ unless normalized[:digest_algorithm].to_s.empty?
70
+ xml << "<ds:DigestMethod Algorithm=\"#{normalized[:digest_algorithm]}\"/>"
71
+ end
72
+ BetterAuth::Plugins.sso_validate_saml_algorithms!(xml, normalize_options(options))
73
+ end
74
+
75
+ def normalize_signature(algorithm)
76
+ BetterAuth::Plugins.sso_normalize_saml_signature_algorithm(algorithm)
77
+ end
78
+
79
+ def normalize_digest(algorithm)
80
+ BetterAuth::Plugins.sso_normalize_saml_digest_algorithm(algorithm)
81
+ end
82
+
83
+ def normalize_options(options)
84
+ normalized = BetterAuth::Plugins.normalize_hash(options || {})
85
+ {
86
+ on_deprecated: normalized[:on_deprecated],
87
+ allowed_signature_algorithms: normalized[:allowed_signature_algorithms],
88
+ allowed_digest_algorithms: normalized[:allowed_digest_algorithms],
89
+ allowed_key_encryption_algorithms: normalized[:allowed_key_encryption_algorithms],
90
+ allowed_data_encryption_algorithms: normalized[:allowed_data_encryption_algorithms]
91
+ }.compact
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module SAML
6
+ module Assertions
7
+ module_function
8
+
9
+ def validate_single_assertion!(saml_response)
10
+ BetterAuth::Plugins.sso_validate_single_saml_assertion!(saml_response)
11
+ end
12
+
13
+ def count(xml)
14
+ assertions = xml.to_s.scan(/<(?:\w+:)?Assertion(?:\s|>|\/)/).length
15
+ encrypted_assertions = xml.to_s.scan(/<(?:\w+:)?EncryptedAssertion(?:\s|>|\/)/).length
16
+ {assertions: assertions, encrypted_assertions: encrypted_assertions, total: assertions + encrypted_assertions}
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module SAML
6
+ module ErrorCodes
7
+ SAML_ERROR_CODES = {
8
+ single_logout_not_enabled: "Single Logout is not enabled",
9
+ invalid_logout_response: "Invalid LogoutResponse",
10
+ invalid_logout_request: "Invalid LogoutRequest",
11
+ logout_failed_at_idp: "Logout failed at IdP",
12
+ idp_slo_not_supported: "IdP does not support Single Logout Service",
13
+ saml_provider_not_found: "SAML provider not found"
14
+ }.freeze
15
+
16
+ module_function
17
+
18
+ def message(code)
19
+ SAML_ERROR_CODES[BetterAuth::Plugins.normalize_key(code)]
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module SAML
6
+ module Parser
7
+ module_function
8
+
9
+ def parse_response(value, config = {}, provider = nil, ctx = nil)
10
+ BetterAuth::Plugins.sso_parse_saml_response(value, config, provider, ctx)
11
+ end
12
+
13
+ def base64_xml?(value)
14
+ BetterAuth::Plugins.sso_base64_xml?(value)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module SAML
6
+ module Timestamp
7
+ module_function
8
+
9
+ def validate!(conditions, config = {}, now: Time.now.utc)
10
+ BetterAuth::Plugins.sso_validate_saml_timestamp!(conditions, config, now: now)
11
+ end
12
+
13
+ def conditions(assertion)
14
+ BetterAuth::Plugins.sso_saml_timestamp_conditions(assertion)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "base64"
4
+ require "logger"
4
5
  require "onelogin/ruby-saml"
5
6
  require "uri"
6
7
 
@@ -25,6 +26,18 @@ module BetterAuth
25
26
  }
26
27
  end
27
28
 
29
+ def validate_config_algorithms(config = {}, **options)
30
+ Algorithms.validate_config(config, **options)
31
+ end
32
+
33
+ def validate_saml_algorithms(xml, **options)
34
+ Algorithms.validate(xml, **options)
35
+ end
36
+
37
+ def validate_single_assertion(saml_response)
38
+ Assertions.validate_single_assertion!(saml_response)
39
+ end
40
+
28
41
  def auth_request_url(settings: nil, request_options: {}, **_options)
29
42
  lambda do |provider:, relay_state:, context:|
30
43
  config = BetterAuth::Plugins.normalize_hash(provider["samlConfig"] || provider[:samlConfig] || {})
@@ -69,11 +82,18 @@ module BetterAuth
69
82
  settings = overrides || OneLogin::RubySaml::Settings.new
70
83
  provider_id = provider.fetch("providerId")
71
84
  base_url = context.context.base_url
72
- settings.assertion_consumer_service_url = config[:callback_url] || "#{base_url}/sso/saml2/sp/acs/#{provider_id}"
85
+ idp_metadata = BetterAuth::Plugins.respond_to?(:sso_saml_idp_metadata) ? BetterAuth::Plugins.sso_saml_idp_metadata(config) : {}
86
+ sso_service = BetterAuth::Plugins.respond_to?(:sso_saml_preferred_service) ? BetterAuth::Plugins.sso_saml_preferred_service(idp_metadata[:single_sign_on_service]) : nil
87
+ sso_service = BetterAuth::Plugins.normalize_hash(sso_service || {})
88
+ settings.assertion_consumer_service_url = if BetterAuth::Plugins.respond_to?(:sso_saml_acs_url?) && BetterAuth::Plugins.sso_saml_acs_url?(config[:callback_url])
89
+ config[:callback_url]
90
+ else
91
+ "#{base_url}/sso/saml2/sp/acs/#{URI.encode_www_form_component(provider_id)}"
92
+ end
73
93
  settings.sp_entity_id = config.dig(:sp_metadata, :entity_id) || config[:audience] || "#{base_url}/sso/saml2/sp/metadata?providerId=#{URI.encode_www_form_component(provider_id)}"
74
- settings.idp_entity_id = provider["issuer"] || provider[:issuer]
75
- settings.idp_sso_service_url = config[:entry_point]
76
- settings.idp_cert = config[:cert] unless config[:cert].to_s.empty?
94
+ settings.idp_entity_id = idp_metadata[:entity_id] || provider["issuer"] || provider[:issuer]
95
+ settings.idp_sso_service_url = config[:entry_point] || sso_service[:location]
96
+ settings.idp_cert = config[:cert] || idp_metadata[:cert] unless (config[:cert] || idp_metadata[:cert]).to_s.empty?
77
97
  settings.name_identifier_format = config[:identifier_format] unless config[:identifier_format].to_s.empty?
78
98
  private_key = config.dig(:sp_metadata, :private_key) || config[:private_key] || config[:sp_private_key]
79
99
  authn_requests_signed = config.fetch(:authn_requests_signed, config[:want_authn_requests_signed])
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module SAMLState
6
+ module_function
7
+
8
+ def generate_relay_state(ctx, link = nil, additional_data = {})
9
+ callback_url = BetterAuth::Plugins.sso_fetch(ctx.body, :callback_url)
10
+ raise APIError.new("BAD_REQUEST", message: "callbackURL is required") if callback_url.to_s.empty?
11
+
12
+ extra = (additional_data == false) ? {} : (additional_data || {})
13
+ BetterAuth::Plugins.sso_generate_saml_relay_state(
14
+ ctx,
15
+ extra.merge(
16
+ callbackURL: callback_url,
17
+ errorURL: BetterAuth::Plugins.sso_fetch(ctx.body, :error_callback_url),
18
+ newUserURL: BetterAuth::Plugins.sso_fetch(ctx.body, :new_user_callback_url),
19
+ requestSignUp: BetterAuth::Plugins.sso_fetch(ctx.body, :request_sign_up),
20
+ link: link
21
+ )
22
+ )
23
+ end
24
+
25
+ def parse_relay_state(ctx)
26
+ BetterAuth::Plugins.sso_parse_saml_relay_state(ctx, BetterAuth::Plugins.sso_fetch(ctx.body, :relay_state))
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterAuth
4
+ module SSO
5
+ module Types
6
+ PROVIDER_TYPES = %w[oidc saml].freeze
7
+ OIDC_TOKEN_ENDPOINT_AUTH_METHODS = %w[client_secret_post client_secret_basic].freeze
8
+
9
+ module_function
10
+
11
+ def provider_type?(value)
12
+ PROVIDER_TYPES.include?(value.to_s)
13
+ end
14
+
15
+ def oidc_token_endpoint_auth_method?(value)
16
+ OIDC_TOKEN_ENDPOINT_AUTH_METHODS.include?(value.to_s)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "openssl"
5
+
6
+ module BetterAuth
7
+ module SSO
8
+ module Utils
9
+ module_function
10
+
11
+ def safe_json_parse(value)
12
+ return nil if value.nil? || value == ""
13
+ return value if value.is_a?(Hash) || value.is_a?(Array)
14
+
15
+ JSON.parse(value.to_s)
16
+ rescue JSON::ParserError => error
17
+ raise Error, "Failed to parse JSON: #{error.message}"
18
+ end
19
+
20
+ def domain_matches?(search_domain, domain_list)
21
+ BetterAuth::Plugins.sso_email_domain_matches?(search_domain, domain_list)
22
+ end
23
+
24
+ def validate_email_domain(email, domain)
25
+ BetterAuth::Plugins.sso_email_domain_matches?(email, domain)
26
+ end
27
+
28
+ def parse_certificate(cert)
29
+ value = cert.to_s
30
+ normalized = if value.include?("-----BEGIN")
31
+ value
32
+ else
33
+ body = value.delete("\n\r\t ")
34
+ "-----BEGIN CERTIFICATE-----\n#{body.scan(/.{1,64}/).join("\n")}\n-----END CERTIFICATE-----"
35
+ end
36
+ certificate = OpenSSL::X509::Certificate.new(normalized)
37
+ fingerprint = OpenSSL::Digest::SHA256.hexdigest(certificate.to_der).upcase.scan(/../).join(":")
38
+ {
39
+ fingerprint_sha256: fingerprint,
40
+ not_before: certificate.not_before,
41
+ not_after: certificate.not_after,
42
+ public_key_algorithm: certificate.public_key.class.name.split("::").last.upcase
43
+ }
44
+ end
45
+
46
+ def hostname_from_domain(domain)
47
+ BetterAuth::Plugins.sso_hostname_from_domain(domain)
48
+ end
49
+
50
+ def mask_client_id(client_id)
51
+ BetterAuth::Plugins.sso_mask_client_id(client_id)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module BetterAuth
4
4
  module SSO
5
- VERSION = "0.2.0"
5
+ VERSION = "0.6.2"
6
+ PACKAGE_VERSION = VERSION
6
7
  end
7
8
  end
@@ -2,9 +2,33 @@
2
2
 
3
3
  require "better_auth"
4
4
  require_relative "sso/version"
5
+ require_relative "sso/client"
5
6
  require_relative "sso/saml_hooks"
6
7
  require_relative "sso/saml"
7
8
  require_relative "plugins/sso"
9
+ require_relative "sso/constants"
10
+ require_relative "sso/types"
11
+ require_relative "sso/utils"
12
+ require_relative "sso/domain_verification"
13
+ require_relative "sso/oidc"
14
+ require_relative "sso/oidc/discovery"
15
+ require_relative "sso/oidc/errors"
16
+ require_relative "sso/oidc/types"
17
+ require_relative "sso/linking"
18
+ require_relative "sso/linking/types"
19
+ require_relative "sso/linking/org_assignment"
20
+ require_relative "sso/saml/algorithms"
21
+ require_relative "sso/saml/assertions"
22
+ require_relative "sso/saml/error_codes"
23
+ require_relative "sso/saml/timestamp"
24
+ require_relative "sso/saml/parser"
25
+ require_relative "sso/routes/helpers"
26
+ require_relative "sso/routes/providers"
27
+ require_relative "sso/routes/schemas"
28
+ require_relative "sso/routes/domain_verification"
29
+ require_relative "sso/routes/saml_pipeline"
30
+ require_relative "sso/routes/sso"
31
+ require_relative "sso/saml_state"
8
32
 
9
33
  module BetterAuth
10
34
  module SSO
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_auth-sso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Sala
@@ -43,6 +43,26 @@ dependencies:
43
43
  - - "<"
44
44
  - !ruby/object:Gem::Version
45
45
  version: '1.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: logger
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '1.6'
53
+ - - "<"
54
+ - !ruby/object:Gem::Version
55
+ version: '2.0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '1.6'
63
+ - - "<"
64
+ - !ruby/object:Gem::Version
65
+ version: '2.0'
46
66
  - !ruby/object:Gem::Dependency
47
67
  name: ruby-saml
48
68
  requirement: !ruby/object:Gem::Requirement
@@ -131,8 +151,32 @@ files:
131
151
  - README.md
132
152
  - lib/better_auth/plugins/sso.rb
133
153
  - lib/better_auth/sso.rb
154
+ - lib/better_auth/sso/client.rb
155
+ - lib/better_auth/sso/constants.rb
156
+ - lib/better_auth/sso/domain_verification.rb
157
+ - lib/better_auth/sso/linking.rb
158
+ - lib/better_auth/sso/linking/org_assignment.rb
159
+ - lib/better_auth/sso/linking/types.rb
160
+ - lib/better_auth/sso/oidc.rb
161
+ - lib/better_auth/sso/oidc/discovery.rb
162
+ - lib/better_auth/sso/oidc/errors.rb
163
+ - lib/better_auth/sso/oidc/types.rb
164
+ - lib/better_auth/sso/routes/domain_verification.rb
165
+ - lib/better_auth/sso/routes/helpers.rb
166
+ - lib/better_auth/sso/routes/providers.rb
167
+ - lib/better_auth/sso/routes/saml_pipeline.rb
168
+ - lib/better_auth/sso/routes/schemas.rb
169
+ - lib/better_auth/sso/routes/sso.rb
134
170
  - lib/better_auth/sso/saml.rb
171
+ - lib/better_auth/sso/saml/algorithms.rb
172
+ - lib/better_auth/sso/saml/assertions.rb
173
+ - lib/better_auth/sso/saml/error_codes.rb
174
+ - lib/better_auth/sso/saml/parser.rb
175
+ - lib/better_auth/sso/saml/timestamp.rb
135
176
  - lib/better_auth/sso/saml_hooks.rb
177
+ - lib/better_auth/sso/saml_state.rb
178
+ - lib/better_auth/sso/types.rb
179
+ - lib/better_auth/sso/utils.rb
136
180
  - lib/better_auth/sso/version.rb
137
181
  homepage: https://github.com/sebasxsala/better-auth
138
182
  licenses: