Class: BetterAuth::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/better_auth/configuration.rb

Constant Summary collapse

DEFAULT_BASE_PATH =
"/api/auth"
DEFAULT_SECRET =
"better-auth-secret-12345678901234567890"
DEFAULT_SESSION =
{
  update_age: 24 * 60 * 60,
  expires_in: 60 * 60 * 24 * 7,
  fresh_age: 60 * 60 * 24
}.freeze
DEFAULT_EMAIL_AND_PASSWORD =
{
  min_password_length: 8,
  max_password_length: 128
}.freeze
DEFAULT_PASSWORD_HASHER =
:scrypt
SUPPORTED_PASSWORD_HASHERS =
[:scrypt, :bcrypt].freeze
DEFAULT_STATELESS_SESSION =
{
  cookie_cache: {
    enabled: true,
    strategy: "jwe",
    refresh_cache: true
  }
}.freeze
DEFAULT_STATELESS_ACCOUNT =
{
  store_state_strategy: "cookie",
  store_account_cookie: true
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Configuration

Returns a new instance of Configuration.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/better_auth/configuration.rb', line 61

def initialize(options = {})
  options = symbolize_keys(options)
  @explicit_options = deep_dup(options)

  @logger = options[:logger]
  @app_name = options[:app_name] || "Better Auth"
  @base_path = normalize_base_path(options.fetch(:base_path, DEFAULT_BASE_PATH))
  @database = options[:database]
  @secondary_storage = options[:secondary_storage]
  @plugins = normalize_plugins(options[:plugins])
  @advanced = deep_merge({}, symbolize_keys(options[:advanced] || {}))
  @disabled_paths = Array(options[:disabled_paths]).compact.map(&:to_s)
  @database_hooks = options[:database_hooks]
  @hooks = options[:hooks]
  @on_api_error = symbolize_keys(options[:on_api_error] || options[:on_apierror] || {})
  @social_providers = symbolize_keys(options[:social_providers] || {})
  @trusted_origins_callbacks = []
  @trusted_origins_callbacks << options[:trusted_origins] if options[:trusted_origins].respond_to?(:call)
  @trusted_origins_callback = combined_trusted_origins_callback
  legacy_secret = resolve_secret(options, allow_test_default: false)
  secrets = options.key?(:secrets) ? options[:secrets] : SecretConfig.parse_env(ENV["BETTER_AUTH_SECRETS"])
  if secrets
    @secret_config = SecretConfig.build(secrets, legacy_secret, logger: logger)
    @secret = @secret_config.current_secret
  else
    @secret = legacy_secret || (test_environment? ? DEFAULT_SECRET : nil)
    @secret_config = @secret
  end
  @base_url_config = options[:base_url]
  @base_url, @context_base_url = normalize_base_url(options[:base_url])
  @session = normalize_session(options[:session])
  @account = (options[:account])
  @user = symbolize_keys(options[:user] || {})
  @verification = symbolize_keys(options[:verification] || {})
  @email_and_password = normalize_email_and_password(options[:email_and_password])
  @password_hasher = normalize_password_hasher(options[:password_hasher])
  @email_verification = symbolize_keys(options[:email_verification] || {})
  @experimental = normalize_experimental(options[:experimental])
  @rate_limit = normalize_rate_limit(options[:rate_limit])
  @trusted_origins = normalize_trusted_origins(options[:trusted_origins])

  validate_secret
end

Instance Attribute Details

#accountObject (readonly)

Returns the value of attribute account.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def 
  @account
end

#advancedObject (readonly)

Returns the value of attribute advanced.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def advanced
  @advanced
end

#app_nameObject (readonly)

Returns the value of attribute app_name.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def app_name
  @app_name
end

#base_pathObject (readonly)

Returns the value of attribute base_path.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def base_path
  @base_path
end

#base_url_configObject (readonly)

Returns the value of attribute base_url_config.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def base_url_config
  @base_url_config
end

#context_base_urlObject (readonly)

Returns the value of attribute context_base_url.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def context_base_url
  @context_base_url
end

#databaseObject (readonly)

Returns the value of attribute database.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def database
  @database
end

#database_hooksObject (readonly)

Returns the value of attribute database_hooks.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def database_hooks
  @database_hooks
end

#disabled_pathsObject (readonly)

Returns the value of attribute disabled_paths.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def disabled_paths
  @disabled_paths
end

#email_and_passwordObject (readonly)

Returns the value of attribute email_and_password.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def email_and_password
  @email_and_password
end

#email_verificationObject (readonly)

Returns the value of attribute email_verification.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def email_verification
  @email_verification
end

#experimentalObject (readonly)

Returns the value of attribute experimental.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def experimental
  @experimental
end

#hooksObject (readonly)

Returns the value of attribute hooks.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def hooks
  @hooks
end

#loggerObject (readonly)

Returns the value of attribute logger.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def logger
  @logger
end

#on_api_errorObject (readonly)

Returns the value of attribute on_api_error.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def on_api_error
  @on_api_error
end

#password_hasherObject (readonly)

Returns the value of attribute password_hasher.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def password_hasher
  @password_hasher
end

#pluginsObject (readonly)

Returns the value of attribute plugins.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def plugins
  @plugins
end

#rate_limitObject (readonly)

Returns the value of attribute rate_limit.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def rate_limit
  @rate_limit
end

#secondary_storageObject (readonly)

Returns the value of attribute secondary_storage.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def secondary_storage
  @secondary_storage
end

#secretObject (readonly)

Returns the value of attribute secret.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def secret
  @secret
end

#secret_configObject (readonly)

Returns the value of attribute secret_config.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def secret_config
  @secret_config
end

#sessionObject (readonly)

Returns the value of attribute session.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def session
  @session
end

#social_providersObject (readonly)

Returns the value of attribute social_providers.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def social_providers
  @social_providers
end

#trusted_originsObject (readonly)

Returns the value of attribute trusted_origins.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def trusted_origins
  @trusted_origins
end

#trusted_origins_callbackObject (readonly)

Returns the value of attribute trusted_origins_callback.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def trusted_origins_callback
  @trusted_origins_callback
end

#userObject (readonly)

Returns the value of attribute user.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def user
  @user
end

#verificationObject (readonly)

Returns the value of attribute verification.



33
34
35
# File 'lib/better_auth/configuration.rb', line 33

def verification
  @verification
end

Class Method Details

.matches_origin_pattern?(url, pattern, allow_relative_paths: false) ⇒ Boolean

Returns:

  • (Boolean)


175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/better_auth/configuration.rb', line 175

def self.matches_origin_pattern?(url, pattern, allow_relative_paths: false)
  return relative_path_allowed?(url) if url.start_with?("/") && allow_relative_paths
  return false if url.start_with?("/")

  uri = parse_uri(url)
  return false unless uri

  if pattern.include?("*") || pattern.include?("?")
    if pattern.include?("://")
      origin = origin_for(uri)
      return true if origin && wildcard_match?(pattern, origin)

      return wildcard_match?(pattern, url)
    end

    return wildcard_match?(pattern, uri.host.to_s)
  end

  protocol = uri.scheme&.then { |scheme| "#{scheme}:" }
  if protocol == "http:" || protocol == "https:" || protocol.nil?
    pattern == origin_for(uri)
  else
    url.start_with?(pattern)
  end
end

.origin_for(uri) ⇒ Object



211
212
213
214
215
216
217
218
219
220
# File 'lib/better_auth/configuration.rb', line 211

def self.origin_for(uri)
  return nil unless uri.scheme && uri.host

  port = uri.port
  default_port = (uri.scheme == "http" && port == 80) || (uri.scheme == "https" && port == 443)
  host = uri.host
  host = "[#{host}]" if host.include?(":") && !host.start_with?("[")
  origin = "#{uri.scheme}://#{host}"
  default_port ? origin : "#{origin}:#{port}"
end

.parse_uri(url) ⇒ Object



205
206
207
208
209
# File 'lib/better_auth/configuration.rb', line 205

def self.parse_uri(url)
  URI.parse(url)
rescue URI::InvalidURIError
  nil
end

.relative_path_allowed?(url) ⇒ Boolean

Returns:

  • (Boolean)


201
202
203
# File 'lib/better_auth/configuration.rb', line 201

def self.relative_path_allowed?(url)
  %r{\A/(?!/|\\|%2f|%5c)[\w\-.+/@]*(?:\?[\w\-.+/=&%@]*)?\z}i.match?(url)
end

.wildcard_match?(pattern, value) ⇒ Boolean

Returns:

  • (Boolean)


222
223
224
225
# File 'lib/better_auth/configuration.rb', line 222

def self.wildcard_match?(pattern, value)
  regex = Regexp.escape(pattern).gsub("\\*", ".*").gsub("\\?", ".")
  /\A#{regex}\z/.match?(value)
end

Instance Method Details

#base_urlObject



111
112
113
# File 'lib/better_auth/configuration.rb', line 111

def base_url
  Thread.current[base_url_runtime_key] || @base_url
end

#clear_runtime_base_url!Object



119
120
121
# File 'lib/better_auth/configuration.rb', line 119

def clear_runtime_base_url!
  Thread.current[base_url_runtime_key] = nil
end

#dynamic_base_url?Boolean

Returns:

  • (Boolean)


127
128
129
# File 'lib/better_auth/configuration.rb', line 127

def dynamic_base_url?
  URLHelpers.dynamic_config?(base_url_config)
end

#merge_defaults!(defaults) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/better_auth/configuration.rb', line 160

def merge_defaults!(defaults)
  normalized = symbolize_keys(defaults || {})
  normalized.each do |key, value|
    next unless respond_to?(key)
    next if key == :database_hooks

    if key == :trusted_origins
      merge_trusted_origins_default(value)
      next
    end

    instance_variable_set("@#{key}", merge_default_value([key], public_send(key), value))
  end
end

#production?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/better_auth/configuration.rb', line 123

def production?
  production_environment?
end

#set_runtime_base_url(value) ⇒ Object



115
116
117
# File 'lib/better_auth/configuration.rb', line 115

def set_runtime_base_url(value)
  Thread.current[base_url_runtime_key] = value
end

#to_hObject



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/better_auth/configuration.rb', line 131

def to_h
  {
    app_name: app_name,
    base_url: base_url,
    base_path: base_path,
    secret: secret,
    secret_config: secret_config,
    database: database,
    plugins: plugins,
    trusted_origins: trusted_origins,
    rate_limit: rate_limit,
    session: session,
    account: ,
    user: user,
    verification: verification,
    advanced: advanced,
    email_and_password: email_and_password,
    password_hasher: password_hasher,
    email_verification: email_verification,
    social_providers: social_providers,
    experimental: experimental,
    secondary_storage: secondary_storage,
    database_hooks: database_hooks,
    hooks: hooks,
    on_api_error: on_api_error,
    disabled_paths: disabled_paths
  }
end

#trusted_origin?(url, allow_relative_paths: false) ⇒ Boolean

Returns:

  • (Boolean)


105
106
107
108
109
# File 'lib/better_auth/configuration.rb', line 105

def trusted_origin?(url, allow_relative_paths: false)
  trusted_origins.any? do |origin|
    self.class.matches_origin_pattern?(url, origin, allow_relative_paths: allow_relative_paths)
  end
end