rodauth-tools 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49ed411752d1850001a89d8be7260feef6e8b4dae04547100d75bde5c80d1afd
4
- data.tar.gz: ce7e4e431d01a64f4e6a8f1847795a1df7caa529895b0aa12568543668aaca71
3
+ metadata.gz: 3229a291fcbbef1fa0f00904dfbb171243f21a9478cf673d33d6f747ed30cbb4
4
+ data.tar.gz: 25dff26d7c164d0d8a8409c626c467b5cd3c9b3b64d18771d1ccdfcb8b84c5c4
5
5
  SHA512:
6
- metadata.gz: 76cec388e98fb42c5413d25ac99ee8db3351db79f6c68c57abee7049286738b7242b0afa0527bc3c1df2066d002c667687d6089fc54a20a1a3df5553d52ffee8
7
- data.tar.gz: 3eface17b5e1d077bb93498c793af35d9554d9e42bf72511eb7c9569ad84fd5a2cfaf7eee84c9c91b9af5d9672ef111bee01e1bd5dbe65c4434b76df3e10c845
6
+ metadata.gz: 35506a929bcb7cbd354f08f592331bb6718894f9d0f0331cf337545ce06c4858c1a83ad2ad4aa4af97a9039cd0d1e85004ba8c626d34bb55215032999886e5a8
7
+ data.tar.gz: 13f488f19cb2794315dcf1fefb408306e15b994b40c5b03c47e21194a16a11a92e4809733ece96a0cd639af0b7ae71b1256efe9b72bc5ad6b913ea7c5852e868
data/.rubocop.yml CHANGED
@@ -11,6 +11,10 @@ AllCops:
11
11
  NewCops: enable
12
12
  SuggestExtensions: false
13
13
 
14
+ Style/OneClassPerFile:
15
+ Exclude:
16
+ - 'examples/**/*'
17
+
14
18
  Style/StringLiterals:
15
19
  EnforcedStyle: single_quotes
16
20
 
data/.rubocop_todo.yml CHANGED
@@ -49,7 +49,7 @@ Metrics/AbcSize:
49
49
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
50
50
  # AllowedMethods: refine
51
51
  Metrics/BlockLength:
52
- Max: 509
52
+ Max: 532
53
53
 
54
54
  # Offense count: 1
55
55
  # Configuration parameters: CountComments, CountAsOne.
@@ -64,12 +64,12 @@ Metrics/CyclomaticComplexity:
64
64
  # Offense count: 41
65
65
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
66
66
  Metrics/MethodLength:
67
- Max: 64
67
+ Max: 69
68
68
 
69
69
  # Offense count: 3
70
70
  # Configuration parameters: CountComments, CountAsOne.
71
71
  Metrics/ModuleLength:
72
- Max: 511
72
+ Max: 534
73
73
 
74
74
  # Offense count: 10
75
75
  # Configuration parameters: AllowedMethods, AllowedPatterns.
@@ -108,6 +108,8 @@ RSpec/DescribeClass:
108
108
  - '**/spec/views/**/*'
109
109
  - 'spec/rodauth/features/external_identity/external_identity_spec.rb'
110
110
  - 'spec/rodauth/features/external_identity_autocreate_integration_spec.rb'
111
+ - 'spec/rodauth/features/secret_guard_combined_spec.rb'
112
+ - 'spec/rodauth/features/table_guard/table_guard_destructive_modes_spec.rb'
111
113
  - 'spec/rodauth/features/table_guard/table_guard_integration_spec.rb'
112
114
  - 'spec/rodauth/features/table_guard/table_guard_simple_spec.rb'
113
115
  - 'spec/rodauth/features/table_guard/table_guard_spec.rb'
@@ -154,6 +156,7 @@ Style/Documentation:
154
156
  Exclude:
155
157
  - 'spec/**/*'
156
158
  - 'test/**/*'
159
+ - 'lib/rodauth/features/account_id_obfuscation.rb'
157
160
  - 'lib/rodauth/features/external_identity.rb'
158
161
  - 'lib/rodauth/features/hmac_secret_guard.rb'
159
162
  - 'lib/rodauth/features/jwt_secret_guard.rb'
@@ -204,6 +207,8 @@ Style/SafeNavigation:
204
207
  - 'spec/rodauth/features/external_identity_autocreate_integration_spec.rb'
205
208
  - 'spec/rodauth/features/hmac_secret_guard/hmac_secret_guard_spec.rb'
206
209
  - 'spec/rodauth/features/jwt_secret_guard/jwt_secret_guard_spec.rb'
210
+ - 'spec/rodauth/features/secret_guard_combined_spec.rb'
211
+ - 'spec/rodauth/features/table_guard/table_guard_destructive_modes_spec.rb'
207
212
  - 'spec/rodauth/features/table_guard/table_guard_simple_spec.rb'
208
213
 
209
214
  # Offense count: 1
@@ -231,6 +236,8 @@ Style/SymbolProc:
231
236
  - 'spec/rodauth/features/external_identity_autocreate_integration_spec.rb'
232
237
  - 'spec/rodauth/features/hmac_secret_guard/hmac_secret_guard_spec.rb'
233
238
  - 'spec/rodauth/features/jwt_secret_guard/jwt_secret_guard_spec.rb'
239
+ - 'spec/rodauth/features/secret_guard_combined_spec.rb'
240
+ - 'spec/rodauth/features/table_guard/table_guard_destructive_modes_spec.rb'
234
241
  - 'spec/rodauth/features/table_guard/table_guard_integration_spec.rb'
235
242
  - 'spec/rodauth/features/table_guard/table_guard_simple_spec.rb'
236
243
  - 'try/features/external_identity_try.rb'
data/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.0] - 2026-07-05
9
+
10
+ ### Added
11
+
12
+ - **Account ID Obfuscation feature** (`account_id_obfuscation`) - Keyed, reversible
13
+ obfuscation of the numeric `account_id` that leaks into email-link tokens (e.g.
14
+ `/verify-account?key=2_...`) and the remember-me cookie, with no database schema
15
+ change. Wraps the two `email_base` chokepoints (`token_param_value` /
16
+ `account_from_key`), so a single `enable` covers verify_account, reset_password,
17
+ email_auth, verify_login_change and lockout/unlock; also obfuscates the remember
18
+ cookie when `remember` is enabled. Loads a dedicated `ACCOUNT_ID_SECRET` following
19
+ the `hmac_secret_guard` pattern. Backward compatible with in-flight numeric links
20
+ and legacy cookies, with config-driven secret rotation via a version tag.
21
+ - **`Rodauth::Tools::AccountIdCipher`** - Framework-agnostic 4-round Feistel
22
+ format-preserving encryption utility (stdlib `openssl` only, no new dependencies).
23
+
24
+ ## [0.3.1] - 2026-01-13
25
+
26
+ ### Changed
27
+
28
+ - Dependency and development-tooling maintenance (bundled `rodauth`, `sequel`,
29
+ `rubocop`, and related updates).
30
+
8
31
  ## [0.3.0] - 2025-11-25
9
32
 
10
33
  ### Added
@@ -76,6 +99,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
76
99
  - Namespace changed from `Rodauth::Rack::Generators::Migration` to `Rodauth::Tools::Migration`
77
100
  - Evolution from Rack adapter to framework-agnostic utilities
78
101
 
102
+ [0.4.0]: https://github.com/delano/rodauth-tools/compare/v0.3.1...v0.4.0
103
+ [0.3.1]: https://github.com/delano/rodauth-tools/compare/v0.3.0...v0.3.1
79
104
  [0.3.0]: https://github.com/delano/rodauth-tools/compare/v0.2.0...v0.3.0
80
105
  [0.2.0]: https://github.com/delano/rodauth-tools/compare/v0.1.0...v0.2.0
81
106
  [0.1.0]: https://github.com/delano/rodauth-tools/releases/tag/v0.1.0
data/CLAUDE.md CHANGED
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
6
6
 
7
7
  Framework-agnostic utilities for Rodauth authentication:
8
8
 
9
- 1. **External Rodauth Features** - `table_guard` for database validation, `external_identity` for external service IDs, `hmac_secret_guard` for HMAC secret validation, `jwt_secret_guard` for JWT secret validation
9
+ 1. **External Rodauth Features** - `table_guard` for database validation, `external_identity` for external service IDs, `hmac_secret_guard` for HMAC secret validation, `jwt_secret_guard` for JWT secret validation, `account_id_obfuscation` for hiding numeric account ids in email links and cookies
10
10
  2. **Sequel Migration Generator** - Generate migrations for 19 Rodauth features
11
11
 
12
12
  **Not a framework adapter.** For Rails integration, use rodauth-rails. This project demonstrates Rodauth's extensibility and provides reference implementations.
@@ -42,22 +42,45 @@ bin/console
42
42
  - Uses `Rodauth::Feature.define(:hmac_secret_guard, :HmacSecretGuard)` pattern
43
43
  - Automatically loads HMAC secret from environment variable (defaults to `HMAC_SECRET`)
44
44
  - Validates secret is configured at application startup via `post_configure` hook
45
- - Production mode: Raises `ConfigurationError` if secret missing
46
- - Development mode: Logs warning and uses configurable fallback secret
47
- - Deletes secret from ENV after loading for security
48
- - Provides `production?` and `validate_secrets!` public methods
45
+ - Production mode: Raises `ConfigurationError` if secret missing, blank, or (when `minimum_secret_length` is set) too short
46
+ - Development mode: Logs warning and uses a fallback secret (random per-process by default)
47
+ - Deletes secret from ENV after loading for security (strips whitespace; blank values treated as absent)
48
+ - Provides `production?`, `validate_hmac_secret!`, and (aliased) `validate_secrets!` public methods
49
49
 
50
50
  **lib/rodauth/features/jwt_secret_guard.rb** - External Rodauth feature
51
51
 
52
52
  - Uses `Rodauth::Feature.define(:jwt_secret_guard, :JwtSecretGuard)` pattern
53
53
  - Automatically loads JWT secret from environment variable (defaults to `JWT_SECRET`)
54
54
  - Validates secret is configured at application startup via `post_configure` hook
55
- - Production mode: Raises `ConfigurationError` if secret missing
56
- - Development mode: Logs warning and uses configurable fallback secret
57
- - Deletes secret from ENV after loading for security
58
- - Provides `production?` and `validate_secrets!` public methods
55
+ - Production mode: Raises `ConfigurationError` if secret missing, blank, or (when `minimum_secret_length` is set) too short
56
+ - Development mode: Logs warning and uses a fallback secret (random per-process by default)
57
+ - Deletes secret from ENV after loading for security (strips whitespace; blank values treated as absent)
58
+ - Provides `production?`, `validate_jwt_secret!`, and (aliased) `validate_secrets!` public methods
59
59
  - Defines `jwt_secret` configuration method for standalone use
60
60
 
61
+ **lib/rodauth/features/account_id_obfuscation.rb** - External Rodauth feature
62
+
63
+ - Uses `Rodauth::Feature.define(:account_id_obfuscation, :AccountIdObfuscation)` pattern
64
+ - Obfuscates `account_id` in email-link tokens and the remember cookie via scoped `token_param_value`/`account_from_key` (and conditional `_set_/_get_remember_cookie`) overrides
65
+ - Never touches the global `split_token`/`convert_token_id`, so `jwt_refresh` and other token consumers are unaffected
66
+ - Loads a dedicated `ACCOUNT_ID_SECRET` like the secret guards; `production?`/`validate_secrets!` lifecycle
67
+ - Non-digit version tag makes legacy-vs-obfuscated deterministic and drives config-driven secret rotation
68
+ - Delegates the crypto to the standalone `Rodauth::Tools::AccountIdCipher`
69
+
70
+ **lib/rodauth/tools/account_id_cipher.rb** - Framework-agnostic utility
71
+
72
+ - Keyed format-preserving obfuscation of a 64-bit integer id (4-round Feistel network, HMAC-SHA256 round function)
73
+ - Pure `Integer <-> 13-char Crockford Base32` bijection; stdlib `openssl` only, independently testable
74
+ - `decode` returns `nil` on malformed input so callers can pass legacy/foreign values through
75
+ **lib/rodauth/secret_guard.rb** - Shared support module (`Rodauth::SecretGuard`)
76
+
77
+ - Kind-parameterized (`:hmac`/`:jwt`) logic behind both secret-guard features
78
+ - Plain module functions taking the Rodauth instance explicitly — no mixed-in
79
+ method names, so both guards can be enabled together without one shadowing the
80
+ other (each feature's `post_configure` validates its own secret via `kind`)
81
+ - Handles ENV loading (`load_from_env!`), validation (`validate!`), blank/whitespace
82
+ detection, production detection, and minimum-length enforcement
83
+
61
84
  **lib/rodauth/tools/migration.rb** - Sequel migration generator
62
85
 
63
86
  - Generates database migrations for 19 Rodauth features
@@ -106,7 +129,7 @@ end
106
129
 
107
130
  ### Table Guard Implementation Details
108
131
 
109
- **Logger Suppression:** The `table_exists?` method temporarily suppresses Sequel's logger during table existence checks. This prevents confusing ERROR logs from Sequel when checking non-existent tables (Sequel's `table_exists?` attempts a SELECT and logs the exception before catching it).
132
+ **Existence Checks (no logger suppression):** The `table_exists?` method matches names against the database's table/view list (`db.tables` + `db.views`) rather than probing each table with a SELECT. An earlier implementation used Sequel's `table_exists?` probe and suppressed the logger around it (clearing/restoring the shared `db.loggers` array) to hide the "no such table" ERROR that Sequel logs before catching internally — but that mutation of shared connection state was not thread-safe. Listing names avoids the failed probe entirely, so no logger suppression (and no shared-state mutation) is needed. Schema-qualified identifiers (a `Sequel::SQL::QualifiedIdentifier` or a `:schema__table` Symbol) are not present in the unqualified list, so they take a separate schema-aware `db.table_exists?` probe path.
110
133
 
111
134
  **Configuration Storage:** Uses instance variables set by `auth_value_method`:
112
135
 
@@ -129,7 +152,7 @@ end
129
152
  **Introspection Methods:**
130
153
 
131
154
  - `all_table_methods` - Finds all methods ending in `_table` using Ruby reflection
132
- - `missing_tables` - Checks each table method against `db.table_exists?`
155
+ - `missing_tables` - Checks each required table against the existing table/view name set (fetched once per pass to avoid an N+1 of catalog queries)
133
156
  - `table_status` - Returns array of hashes with method, table name, and existence status
134
157
 
135
158
  ### Migration Generator Architecture
data/Gemfile CHANGED
@@ -8,12 +8,12 @@ gemspec
8
8
 
9
9
  gem 'dry-inflector'
10
10
  gem 'irb'
11
- gem 'rake', '~> 13.3'
11
+ gem 'rake', '~> 13.4'
12
12
 
13
13
  group :development do
14
14
  gem 'bundler-audit'
15
15
  gem 'rspec', '~> 3.0'
16
- gem 'rubocop', '~> 1.81'
16
+ gem 'rubocop', '~> 1.88'
17
17
  gem 'rubocop-rake'
18
18
  gem 'rubocop-rspec'
19
19
  end
@@ -21,14 +21,14 @@ end
21
21
  group :test do
22
22
  gem 'bcrypt', '~> 3.1'
23
23
  gem 'capybara'
24
- gem 'jwt', '~> 3.1'
24
+ gem 'jwt', '~> 3.2'
25
25
  gem 'rack-test', '~> 2.1'
26
26
  gem 'rails', '>= 6.0'
27
27
  gem 'rotp'
28
28
  gem 'rqrcode'
29
29
  gem 'sequel-activerecord_connection', '~> 2.0'
30
- gem 'sqlite3', '~> 2.8'
31
- gem 'tilt', '~> 2.4'
30
+ gem 'sqlite3', '~> 2.9'
31
+ gem 'tilt', '~> 2.7'
32
32
  gem 'tryouts', '~> 3.0'
33
33
  gem 'warning'
34
34
  gem 'webauthn' unless RUBY_ENGINE == 'jruby'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rodauth-tools (0.3.0)
4
+ rodauth-tools (0.4.0)
5
5
  dry-inflector (~> 1.1)
6
6
  rodauth (~> 2.41)
7
7
  sequel (~> 5.0)
@@ -9,31 +9,31 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- action_text-trix (2.1.15)
12
+ action_text-trix (2.1.18)
13
13
  railties
14
- actioncable (8.1.1)
15
- actionpack (= 8.1.1)
16
- activesupport (= 8.1.1)
14
+ actioncable (8.1.3)
15
+ actionpack (= 8.1.3)
16
+ activesupport (= 8.1.3)
17
17
  nio4r (~> 2.0)
18
18
  websocket-driver (>= 0.6.1)
19
19
  zeitwerk (~> 2.6)
20
- actionmailbox (8.1.1)
21
- actionpack (= 8.1.1)
22
- activejob (= 8.1.1)
23
- activerecord (= 8.1.1)
24
- activestorage (= 8.1.1)
25
- activesupport (= 8.1.1)
20
+ actionmailbox (8.1.3)
21
+ actionpack (= 8.1.3)
22
+ activejob (= 8.1.3)
23
+ activerecord (= 8.1.3)
24
+ activestorage (= 8.1.3)
25
+ activesupport (= 8.1.3)
26
26
  mail (>= 2.8.0)
27
- actionmailer (8.1.1)
28
- actionpack (= 8.1.1)
29
- actionview (= 8.1.1)
30
- activejob (= 8.1.1)
31
- activesupport (= 8.1.1)
27
+ actionmailer (8.1.3)
28
+ actionpack (= 8.1.3)
29
+ actionview (= 8.1.3)
30
+ activejob (= 8.1.3)
31
+ activesupport (= 8.1.3)
32
32
  mail (>= 2.8.0)
33
33
  rails-dom-testing (~> 2.2)
34
- actionpack (8.1.1)
35
- actionview (= 8.1.1)
36
- activesupport (= 8.1.1)
34
+ actionpack (8.1.3)
35
+ actionview (= 8.1.3)
36
+ activesupport (= 8.1.3)
37
37
  nokogiri (>= 1.8.5)
38
38
  rack (>= 2.2.4)
39
39
  rack-session (>= 1.0.1)
@@ -41,36 +41,36 @@ GEM
41
41
  rails-dom-testing (~> 2.2)
42
42
  rails-html-sanitizer (~> 1.6)
43
43
  useragent (~> 0.16)
44
- actiontext (8.1.1)
44
+ actiontext (8.1.3)
45
45
  action_text-trix (~> 2.1.15)
46
- actionpack (= 8.1.1)
47
- activerecord (= 8.1.1)
48
- activestorage (= 8.1.1)
49
- activesupport (= 8.1.1)
46
+ actionpack (= 8.1.3)
47
+ activerecord (= 8.1.3)
48
+ activestorage (= 8.1.3)
49
+ activesupport (= 8.1.3)
50
50
  globalid (>= 0.6.0)
51
51
  nokogiri (>= 1.8.5)
52
- actionview (8.1.1)
53
- activesupport (= 8.1.1)
52
+ actionview (8.1.3)
53
+ activesupport (= 8.1.3)
54
54
  builder (~> 3.1)
55
55
  erubi (~> 1.11)
56
56
  rails-dom-testing (~> 2.2)
57
57
  rails-html-sanitizer (~> 1.6)
58
- activejob (8.1.1)
59
- activesupport (= 8.1.1)
58
+ activejob (8.1.3)
59
+ activesupport (= 8.1.3)
60
60
  globalid (>= 0.3.6)
61
- activemodel (8.1.1)
62
- activesupport (= 8.1.1)
63
- activerecord (8.1.1)
64
- activemodel (= 8.1.1)
65
- activesupport (= 8.1.1)
61
+ activemodel (8.1.3)
62
+ activesupport (= 8.1.3)
63
+ activerecord (8.1.3)
64
+ activemodel (= 8.1.3)
65
+ activesupport (= 8.1.3)
66
66
  timeout (>= 0.4.0)
67
- activestorage (8.1.1)
68
- actionpack (= 8.1.1)
69
- activejob (= 8.1.1)
70
- activerecord (= 8.1.1)
71
- activesupport (= 8.1.1)
67
+ activestorage (8.1.3)
68
+ actionpack (= 8.1.3)
69
+ activejob (= 8.1.3)
70
+ activerecord (= 8.1.3)
71
+ activesupport (= 8.1.3)
72
72
  marcel (~> 1.0)
73
- activesupport (8.1.1)
73
+ activesupport (8.1.3)
74
74
  base64
75
75
  bigdecimal
76
76
  concurrent-ruby (~> 1.0, >= 1.3.1)
@@ -83,17 +83,17 @@ GEM
83
83
  securerandom (>= 0.3)
84
84
  tzinfo (~> 2.0, >= 2.0.5)
85
85
  uri (>= 0.13.1)
86
- addressable (2.8.7)
87
- public_suffix (>= 2.0.2, < 7.0)
86
+ addressable (2.9.0)
87
+ public_suffix (>= 2.0.2, < 8.0)
88
88
  android_key_attestation (0.3.0)
89
89
  ast (2.4.3)
90
90
  base64 (0.3.0)
91
- bcrypt (3.1.20)
92
- bigdecimal (3.3.1)
91
+ bcrypt (3.1.22)
92
+ bigdecimal (4.1.2)
93
93
  bindata (2.5.1)
94
94
  builder (3.3.0)
95
- bundler-audit (0.9.2)
96
- bundler (>= 1.2.0, < 3)
95
+ bundler-audit (0.9.3)
96
+ bundler (>= 1.2.0)
97
97
  thor (~> 1.0)
98
98
  capybara (3.40.0)
99
99
  addressable
@@ -106,34 +106,35 @@ GEM
106
106
  xpath (~> 3.2)
107
107
  cbor (0.5.10.1)
108
108
  chunky_png (1.4.0)
109
- concurrent-ruby (1.3.5)
110
- connection_pool (2.5.4)
109
+ concurrent-ruby (1.3.7)
110
+ connection_pool (3.0.2)
111
111
  cose (1.3.1)
112
112
  cbor (~> 0.5.9)
113
113
  openssl-signature_algorithm (~> 1.0)
114
114
  crass (1.0.6)
115
- date (3.5.0)
115
+ date (3.5.1)
116
116
  diff-lcs (1.6.2)
117
117
  drb (2.2.3)
118
- dry-inflector (1.2.0)
119
- erb (5.1.3)
118
+ dry-inflector (1.3.1)
119
+ erb (6.0.4)
120
120
  erubi (1.13.1)
121
121
  globalid (1.3.0)
122
122
  activesupport (>= 6.1)
123
- i18n (1.14.7)
123
+ i18n (1.14.8)
124
124
  concurrent-ruby (~> 1.0)
125
- io-console (0.8.1)
126
- irb (1.15.3)
125
+ io-console (0.8.2)
126
+ irb (1.18.0)
127
127
  pp (>= 0.6.0)
128
+ prism (>= 1.3.0)
128
129
  rdoc (>= 4.0.0)
129
130
  reline (>= 0.4.2)
130
- json (2.16.0)
131
- jwt (3.1.2)
131
+ json (2.19.9)
132
+ jwt (3.2.0)
132
133
  base64
133
134
  language_server-protocol (3.17.0.5)
134
135
  lint_roller (1.1.0)
135
136
  logger (1.7.0)
136
- loofah (2.24.1)
137
+ loofah (2.25.1)
137
138
  crass (~> 1.0.2)
138
139
  nokogiri (>= 1.12.0)
139
140
  mail (2.9.0)
@@ -145,8 +146,8 @@ GEM
145
146
  marcel (1.1.0)
146
147
  matrix (0.4.3)
147
148
  mini_mime (1.1.5)
148
- minitest (5.26.0)
149
- net-imap (0.5.12)
149
+ minitest (5.27.0)
150
+ net-imap (0.6.4.1)
150
151
  date
151
152
  net-protocol
152
153
  net-pop (0.1.2)
@@ -156,15 +157,15 @@ GEM
156
157
  net-smtp (0.5.1)
157
158
  net-protocol
158
159
  nio4r (2.7.5)
159
- nokogiri (1.18.10-arm64-darwin)
160
+ nokogiri (1.19.4-arm64-darwin)
160
161
  racc (~> 1.4)
161
- nokogiri (1.18.10-x86_64-linux-gnu)
162
+ nokogiri (1.19.4-x86_64-linux-gnu)
162
163
  racc (~> 1.4)
163
164
  openssl (3.3.1)
164
165
  openssl-signature_algorithm (1.3.0)
165
166
  openssl (> 2.0)
166
- parallel (1.27.0)
167
- parser (3.3.10.0)
167
+ parallel (1.28.0)
168
+ parser (3.3.11.1)
168
169
  ast (~> 2.4.1)
169
170
  racc
170
171
  pastel (0.8.0)
@@ -172,44 +173,44 @@ GEM
172
173
  pp (0.6.3)
173
174
  prettyprint
174
175
  prettyprint (0.2.0)
175
- prism (1.6.0)
176
- psych (5.2.6)
176
+ prism (1.9.0)
177
+ psych (5.3.1)
177
178
  date
178
179
  stringio
179
- public_suffix (6.0.2)
180
+ public_suffix (7.0.5)
180
181
  racc (1.8.1)
181
- rack (3.2.4)
182
- rack-session (2.1.1)
182
+ rack (3.2.6)
183
+ rack-session (2.1.2)
183
184
  base64 (>= 0.1.0)
184
185
  rack (>= 3.0.0)
185
186
  rack-test (2.2.0)
186
187
  rack (>= 1.3)
187
- rackup (2.2.1)
188
+ rackup (2.3.1)
188
189
  rack (>= 3)
189
- rails (8.1.1)
190
- actioncable (= 8.1.1)
191
- actionmailbox (= 8.1.1)
192
- actionmailer (= 8.1.1)
193
- actionpack (= 8.1.1)
194
- actiontext (= 8.1.1)
195
- actionview (= 8.1.1)
196
- activejob (= 8.1.1)
197
- activemodel (= 8.1.1)
198
- activerecord (= 8.1.1)
199
- activestorage (= 8.1.1)
200
- activesupport (= 8.1.1)
190
+ rails (8.1.3)
191
+ actioncable (= 8.1.3)
192
+ actionmailbox (= 8.1.3)
193
+ actionmailer (= 8.1.3)
194
+ actionpack (= 8.1.3)
195
+ actiontext (= 8.1.3)
196
+ actionview (= 8.1.3)
197
+ activejob (= 8.1.3)
198
+ activemodel (= 8.1.3)
199
+ activerecord (= 8.1.3)
200
+ activestorage (= 8.1.3)
201
+ activesupport (= 8.1.3)
201
202
  bundler (>= 1.15.0)
202
- railties (= 8.1.1)
203
+ railties (= 8.1.3)
203
204
  rails-dom-testing (2.3.0)
204
205
  activesupport (>= 5.0.0)
205
206
  minitest
206
207
  nokogiri (>= 1.6)
207
- rails-html-sanitizer (1.6.2)
208
- loofah (~> 2.21)
208
+ rails-html-sanitizer (1.7.0)
209
+ loofah (~> 2.25)
209
210
  nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
210
- railties (8.1.1)
211
- actionpack (= 8.1.1)
212
- activesupport (= 8.1.1)
211
+ railties (8.1.3)
212
+ actionpack (= 8.1.3)
213
+ activesupport (= 8.1.3)
213
214
  irb (~> 1.13)
214
215
  rackup (>= 1.0.0)
215
216
  rake (>= 12.2)
@@ -217,24 +218,24 @@ GEM
217
218
  tsort (>= 0.2)
218
219
  zeitwerk (~> 2.6)
219
220
  rainbow (3.1.1)
220
- rake (13.3.1)
221
- rdoc (6.15.1)
221
+ rake (13.4.2)
222
+ rdoc (7.2.0)
222
223
  erb
223
224
  psych (>= 4.0.0)
224
225
  tsort
225
- regexp_parser (2.11.3)
226
- reline (0.6.2)
226
+ regexp_parser (2.12.0)
227
+ reline (0.6.3)
227
228
  io-console (~> 0.5)
228
- roda (3.98.0)
229
+ roda (3.104.0)
229
230
  rack
230
- rodauth (2.41.0)
231
+ rodauth (2.44.0)
231
232
  roda (>= 2.6.0)
232
233
  sequel (>= 4)
233
234
  rotp (6.3.0)
234
- rqrcode (3.1.0)
235
+ rqrcode (3.2.0)
235
236
  chunky_png (~> 1.0)
236
237
  rqrcode_core (~> 2.0)
237
- rqrcode_core (2.0.0)
238
+ rqrcode_core (2.1.0)
238
239
  rspec (3.13.2)
239
240
  rspec-core (~> 3.13.0)
240
241
  rspec-expectations (~> 3.13.0)
@@ -248,41 +249,42 @@ GEM
248
249
  diff-lcs (>= 1.2.0, < 2.0)
249
250
  rspec-support (~> 3.13.0)
250
251
  rspec-support (3.13.6)
251
- rubocop (1.81.7)
252
+ rubocop (1.88.0)
252
253
  json (~> 2.3)
253
254
  language_server-protocol (~> 3.17.0.2)
254
255
  lint_roller (~> 1.1.0)
255
- parallel (~> 1.10)
256
+ parallel (>= 1.10)
256
257
  parser (>= 3.3.0.2)
257
258
  rainbow (>= 2.2.2, < 4.0)
258
259
  regexp_parser (>= 2.9.3, < 3.0)
259
- rubocop-ast (>= 1.47.1, < 2.0)
260
+ rubocop-ast (>= 1.49.0, < 2.0)
260
261
  ruby-progressbar (~> 1.7)
261
262
  unicode-display_width (>= 2.4.0, < 4.0)
262
- rubocop-ast (1.48.0)
263
+ rubocop-ast (1.49.1)
263
264
  parser (>= 3.3.7.2)
264
- prism (~> 1.4)
265
+ prism (~> 1.7)
265
266
  rubocop-rake (0.7.1)
266
267
  lint_roller (~> 1.1)
267
268
  rubocop (>= 1.72.1)
268
- rubocop-rspec (3.8.0)
269
+ rubocop-rspec (3.10.2)
269
270
  lint_roller (~> 1.1)
270
- rubocop (~> 1.81)
271
+ regexp_parser (>= 2.0)
272
+ rubocop (~> 1.86, >= 1.86.2)
271
273
  ruby-progressbar (1.13.0)
272
274
  safety_net_attestation (0.5.0)
273
275
  jwt (>= 2.0, < 4.0)
274
276
  securerandom (0.4.1)
275
- sequel (5.98.0)
277
+ sequel (5.105.0)
276
278
  bigdecimal
277
279
  sequel-activerecord_connection (2.0.1)
278
280
  activerecord (>= 5.1)
279
281
  sequel (~> 5.38)
280
- sqlite3 (2.8.0-arm64-darwin)
281
- sqlite3 (2.8.0-x86_64-linux-gnu)
282
- stringio (3.1.7)
283
- thor (1.4.0)
284
- tilt (2.6.1)
285
- timeout (0.4.4)
282
+ sqlite3 (2.9.5-arm64-darwin)
283
+ sqlite3 (2.9.5-x86_64-linux-gnu)
284
+ stringio (3.2.0)
285
+ thor (1.5.0)
286
+ tilt (2.7.0)
287
+ timeout (0.6.1)
286
288
  tpm-key_attestation (0.14.1)
287
289
  bindata (~> 2.4)
288
290
  openssl (> 2.0)
@@ -304,10 +306,10 @@ GEM
304
306
  concurrent-ruby (~> 1.0)
305
307
  unicode-display_width (3.2.0)
306
308
  unicode-emoji (~> 4.1)
307
- unicode-emoji (4.1.0)
308
- uri (1.1.0)
309
+ unicode-emoji (4.2.0)
310
+ uri (1.1.1)
309
311
  useragent (0.16.11)
310
- warning (1.5.0)
312
+ warning (1.6.0)
311
313
  webauthn (3.4.3)
312
314
  android_key_attestation (~> 0.3.0)
313
315
  bindata (~> 2.4)
@@ -322,7 +324,7 @@ GEM
322
324
  websocket-extensions (0.1.5)
323
325
  xpath (3.2.0)
324
326
  nokogiri (~> 1.8)
325
- zeitwerk (2.7.3)
327
+ zeitwerk (2.7.5)
326
328
 
327
329
  PLATFORMS
328
330
  arm64-darwin-25
@@ -334,20 +336,20 @@ DEPENDENCIES
334
336
  capybara
335
337
  dry-inflector
336
338
  irb
337
- jwt (~> 3.1)
339
+ jwt (~> 3.2)
338
340
  rack-test (~> 2.1)
339
341
  rails (>= 6.0)
340
- rake (~> 13.3)
342
+ rake (~> 13.4)
341
343
  rodauth-tools!
342
344
  rotp
343
345
  rqrcode
344
346
  rspec (~> 3.0)
345
- rubocop (~> 1.81)
347
+ rubocop (~> 1.88)
346
348
  rubocop-rake
347
349
  rubocop-rspec
348
350
  sequel-activerecord_connection (~> 2.0)
349
- sqlite3 (~> 2.8)
350
- tilt (~> 2.4)
351
+ sqlite3 (~> 2.9)
352
+ tilt (~> 2.7)
351
353
  tryouts (~> 3.0)
352
354
  warning
353
355
  webauthn