Module: BetterAuth::Doctor
- Defined in:
- lib/better_auth/doctor.rb
Defined Under Namespace
Classes: Result
Class Method Summary collapse
- .check(config_or_options) ⇒ Object
- .check_base_url(config, result) ⇒ Object
- .check_database(config, result) ⇒ Object
- .check_rate_limit(config, result) ⇒ Object
- .check_secret(config, result) ⇒ Object
- .entropy(value) ⇒ Object
- .print(result, stdout:, stderr:) ⇒ Object
Class Method Details
.check(config_or_options) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/better_auth/doctor.rb', line 15 def check() config = BetterAuth::SQLMigration.configuration_for() result = Result.new(ok: ["config loaded"], warnings: [], errors: []) check_secret(config, result) check_base_url(config, result) check_rate_limit(config, result) check_database(config, result) result end |
.check_base_url(config, result) ⇒ Object
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/better_auth/doctor.rb', line 49 def check_base_url(config, result) base_url = config.base_url.to_s if base_url.empty? result.warnings << "base_url is not configured; set it explicitly in production" elsif !base_url.start_with?("https://") result.warnings << "base_url is not HTTPS" else result.ok << "base_url uses HTTPS" end end |
.check_database(config, result) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/better_auth/doctor.rb', line 70 def check_database(config, result) auth = BetterAuth.auth(config.to_h) adapter = auth.context.adapter unless adapter.respond_to?(:dialect) && adapter.respond_to?(:connection) result.warnings << "database adapter does not expose SQL migration introspection; schema drift check skipped" return end result.ok << "database adapter supports SQL migrations" plan = BetterAuth::SQLMigration.plan(config, connection: adapter.connection, dialect: adapter.dialect) if plan.empty? result.ok << "database schema is up to date" else result.warnings << "database has pending Better Auth migrations" plan.warnings.each { |warning| result.warnings << warning } end rescue BetterAuth::SQLMigration::UnsupportedAdapterError => error result.warnings << error. end |
.check_rate_limit(config, result) ⇒ Object
60 61 62 63 64 65 66 67 68 |
# File 'lib/better_auth/doctor.rb', line 60 def check_rate_limit(config, result) rate_limit = config.rate_limit || {} result.warnings << "rate_limit is disabled" unless rate_limit[:enabled] if rate_limit[:storage].to_s == "memory" result.warnings << "rate_limit uses memory storage; use database or secondary-storage for multi-process production deployments" else result.ok << "rate_limit storage is #{rate_limit[:storage]}" end end |
.check_secret(config, result) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/better_auth/doctor.rb', line 34 def check_secret(config, result) secret = config.secret.to_s if secret.empty? result.errors << "secret is missing" elsif secret == BetterAuth::Configuration::DEFAULT_SECRET result.errors << "secret uses the default development value" elsif secret.length < 32 result.errors << "secret should be at least 32 characters" elsif entropy(secret) < 120 result.errors << "secret appears low-entropy; use a random production secret" else result.ok << "secret length and entropy look acceptable" end end |
.entropy(value) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/better_auth/doctor.rb', line 90 def entropy(value) unique = value.chars.uniq.length return 0 if unique.zero? Math.log2(unique**value.length) end |
.print(result, stdout:, stderr:) ⇒ Object
27 28 29 30 31 32 |
# File 'lib/better_auth/doctor.rb', line 27 def print(result, stdout:, stderr:) result.ok.each { || stdout.puts "OK #{}" } result.warnings.each { || stdout.puts "WARN #{}" } result.errors.each { || stderr.puts "ERROR #{}" } result.success? ? 0 : 1 end |