rodauth-tools 0.3.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 +7 -0
- data/.gitignore +93 -0
- data/.gitlint +9 -0
- data/.markdownlint-cli2.jsonc +26 -0
- data/.pre-commit-config.yaml +46 -0
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +243 -0
- data/CHANGELOG.md +81 -0
- data/CLAUDE.md +262 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/CONTRIBUTING.md +111 -0
- data/Gemfile +35 -0
- data/Gemfile.lock +356 -0
- data/LICENSE.txt +21 -0
- data/README.md +339 -0
- data/Rakefile +8 -0
- data/lib/rodauth/features/external_identity.rb +946 -0
- data/lib/rodauth/features/hmac_secret_guard.rb +119 -0
- data/lib/rodauth/features/jwt_secret_guard.rb +120 -0
- data/lib/rodauth/features/table_guard.rb +937 -0
- data/lib/rodauth/sequel_generator.rb +531 -0
- data/lib/rodauth/table_inspector.rb +124 -0
- data/lib/rodauth/template_inspector.rb +134 -0
- data/lib/rodauth/tools/console_helpers.rb +158 -0
- data/lib/rodauth/tools/migration/sequel/account_expiration.erb +9 -0
- data/lib/rodauth/tools/migration/sequel/active_sessions.erb +10 -0
- data/lib/rodauth/tools/migration/sequel/audit_logging.erb +12 -0
- data/lib/rodauth/tools/migration/sequel/base.erb +41 -0
- data/lib/rodauth/tools/migration/sequel/disallow_password_reuse.erb +8 -0
- data/lib/rodauth/tools/migration/sequel/email_auth.erb +17 -0
- data/lib/rodauth/tools/migration/sequel/jwt_refresh.erb +18 -0
- data/lib/rodauth/tools/migration/sequel/lockout.erb +21 -0
- data/lib/rodauth/tools/migration/sequel/otp.erb +9 -0
- data/lib/rodauth/tools/migration/sequel/otp_unlock.erb +8 -0
- data/lib/rodauth/tools/migration/sequel/password_expiration.erb +7 -0
- data/lib/rodauth/tools/migration/sequel/recovery_codes.erb +8 -0
- data/lib/rodauth/tools/migration/sequel/remember.erb +16 -0
- data/lib/rodauth/tools/migration/sequel/reset_password.erb +17 -0
- data/lib/rodauth/tools/migration/sequel/single_session.erb +7 -0
- data/lib/rodauth/tools/migration/sequel/sms_codes.erb +10 -0
- data/lib/rodauth/tools/migration/sequel/verify_account.erb +9 -0
- data/lib/rodauth/tools/migration/sequel/verify_login_change.erb +17 -0
- data/lib/rodauth/tools/migration/sequel/webauthn.erb +15 -0
- data/lib/rodauth/tools/migration.rb +188 -0
- data/lib/rodauth/tools/version.rb +9 -0
- data/lib/rodauth/tools.rb +29 -0
- data/package-lock.json +500 -0
- data/package.json +11 -0
- data/rodauth-tools.gemspec +40 -0
- metadata +136 -0
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
rodauth-tools (0.3.0)
|
|
5
|
+
dry-inflector (~> 1.1)
|
|
6
|
+
rodauth (~> 2.41)
|
|
7
|
+
sequel (~> 5.0)
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
action_text-trix (2.1.15)
|
|
13
|
+
railties
|
|
14
|
+
actioncable (8.1.1)
|
|
15
|
+
actionpack (= 8.1.1)
|
|
16
|
+
activesupport (= 8.1.1)
|
|
17
|
+
nio4r (~> 2.0)
|
|
18
|
+
websocket-driver (>= 0.6.1)
|
|
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)
|
|
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)
|
|
32
|
+
mail (>= 2.8.0)
|
|
33
|
+
rails-dom-testing (~> 2.2)
|
|
34
|
+
actionpack (8.1.1)
|
|
35
|
+
actionview (= 8.1.1)
|
|
36
|
+
activesupport (= 8.1.1)
|
|
37
|
+
nokogiri (>= 1.8.5)
|
|
38
|
+
rack (>= 2.2.4)
|
|
39
|
+
rack-session (>= 1.0.1)
|
|
40
|
+
rack-test (>= 0.6.3)
|
|
41
|
+
rails-dom-testing (~> 2.2)
|
|
42
|
+
rails-html-sanitizer (~> 1.6)
|
|
43
|
+
useragent (~> 0.16)
|
|
44
|
+
actiontext (8.1.1)
|
|
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)
|
|
50
|
+
globalid (>= 0.6.0)
|
|
51
|
+
nokogiri (>= 1.8.5)
|
|
52
|
+
actionview (8.1.1)
|
|
53
|
+
activesupport (= 8.1.1)
|
|
54
|
+
builder (~> 3.1)
|
|
55
|
+
erubi (~> 1.11)
|
|
56
|
+
rails-dom-testing (~> 2.2)
|
|
57
|
+
rails-html-sanitizer (~> 1.6)
|
|
58
|
+
activejob (8.1.1)
|
|
59
|
+
activesupport (= 8.1.1)
|
|
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)
|
|
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)
|
|
72
|
+
marcel (~> 1.0)
|
|
73
|
+
activesupport (8.1.1)
|
|
74
|
+
base64
|
|
75
|
+
bigdecimal
|
|
76
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
77
|
+
connection_pool (>= 2.2.5)
|
|
78
|
+
drb
|
|
79
|
+
i18n (>= 1.6, < 2)
|
|
80
|
+
json
|
|
81
|
+
logger (>= 1.4.2)
|
|
82
|
+
minitest (>= 5.1)
|
|
83
|
+
securerandom (>= 0.3)
|
|
84
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
85
|
+
uri (>= 0.13.1)
|
|
86
|
+
addressable (2.8.7)
|
|
87
|
+
public_suffix (>= 2.0.2, < 7.0)
|
|
88
|
+
android_key_attestation (0.3.0)
|
|
89
|
+
ast (2.4.3)
|
|
90
|
+
base64 (0.3.0)
|
|
91
|
+
bcrypt (3.1.20)
|
|
92
|
+
bigdecimal (3.3.1)
|
|
93
|
+
bindata (2.5.1)
|
|
94
|
+
builder (3.3.0)
|
|
95
|
+
bundler-audit (0.9.2)
|
|
96
|
+
bundler (>= 1.2.0, < 3)
|
|
97
|
+
thor (~> 1.0)
|
|
98
|
+
capybara (3.40.0)
|
|
99
|
+
addressable
|
|
100
|
+
matrix
|
|
101
|
+
mini_mime (>= 0.1.3)
|
|
102
|
+
nokogiri (~> 1.11)
|
|
103
|
+
rack (>= 1.6.0)
|
|
104
|
+
rack-test (>= 0.6.3)
|
|
105
|
+
regexp_parser (>= 1.5, < 3.0)
|
|
106
|
+
xpath (~> 3.2)
|
|
107
|
+
cbor (0.5.10.1)
|
|
108
|
+
chunky_png (1.4.0)
|
|
109
|
+
concurrent-ruby (1.3.5)
|
|
110
|
+
connection_pool (2.5.4)
|
|
111
|
+
cose (1.3.1)
|
|
112
|
+
cbor (~> 0.5.9)
|
|
113
|
+
openssl-signature_algorithm (~> 1.0)
|
|
114
|
+
crass (1.0.6)
|
|
115
|
+
date (3.5.0)
|
|
116
|
+
diff-lcs (1.6.2)
|
|
117
|
+
drb (2.2.3)
|
|
118
|
+
dry-inflector (1.2.0)
|
|
119
|
+
erb (5.1.3)
|
|
120
|
+
erubi (1.13.1)
|
|
121
|
+
globalid (1.3.0)
|
|
122
|
+
activesupport (>= 6.1)
|
|
123
|
+
i18n (1.14.7)
|
|
124
|
+
concurrent-ruby (~> 1.0)
|
|
125
|
+
io-console (0.8.1)
|
|
126
|
+
irb (1.15.3)
|
|
127
|
+
pp (>= 0.6.0)
|
|
128
|
+
rdoc (>= 4.0.0)
|
|
129
|
+
reline (>= 0.4.2)
|
|
130
|
+
json (2.16.0)
|
|
131
|
+
jwt (3.1.2)
|
|
132
|
+
base64
|
|
133
|
+
language_server-protocol (3.17.0.5)
|
|
134
|
+
lint_roller (1.1.0)
|
|
135
|
+
logger (1.7.0)
|
|
136
|
+
loofah (2.24.1)
|
|
137
|
+
crass (~> 1.0.2)
|
|
138
|
+
nokogiri (>= 1.12.0)
|
|
139
|
+
mail (2.9.0)
|
|
140
|
+
logger
|
|
141
|
+
mini_mime (>= 0.1.1)
|
|
142
|
+
net-imap
|
|
143
|
+
net-pop
|
|
144
|
+
net-smtp
|
|
145
|
+
marcel (1.1.0)
|
|
146
|
+
matrix (0.4.3)
|
|
147
|
+
mini_mime (1.1.5)
|
|
148
|
+
minitest (5.26.0)
|
|
149
|
+
net-imap (0.5.12)
|
|
150
|
+
date
|
|
151
|
+
net-protocol
|
|
152
|
+
net-pop (0.1.2)
|
|
153
|
+
net-protocol
|
|
154
|
+
net-protocol (0.2.2)
|
|
155
|
+
timeout
|
|
156
|
+
net-smtp (0.5.1)
|
|
157
|
+
net-protocol
|
|
158
|
+
nio4r (2.7.5)
|
|
159
|
+
nokogiri (1.18.10-arm64-darwin)
|
|
160
|
+
racc (~> 1.4)
|
|
161
|
+
nokogiri (1.18.10-x86_64-linux-gnu)
|
|
162
|
+
racc (~> 1.4)
|
|
163
|
+
openssl (3.3.1)
|
|
164
|
+
openssl-signature_algorithm (1.3.0)
|
|
165
|
+
openssl (> 2.0)
|
|
166
|
+
parallel (1.27.0)
|
|
167
|
+
parser (3.3.10.0)
|
|
168
|
+
ast (~> 2.4.1)
|
|
169
|
+
racc
|
|
170
|
+
pastel (0.8.0)
|
|
171
|
+
tty-color (~> 0.5)
|
|
172
|
+
pp (0.6.3)
|
|
173
|
+
prettyprint
|
|
174
|
+
prettyprint (0.2.0)
|
|
175
|
+
prism (1.6.0)
|
|
176
|
+
psych (5.2.6)
|
|
177
|
+
date
|
|
178
|
+
stringio
|
|
179
|
+
public_suffix (6.0.2)
|
|
180
|
+
racc (1.8.1)
|
|
181
|
+
rack (3.2.4)
|
|
182
|
+
rack-session (2.1.1)
|
|
183
|
+
base64 (>= 0.1.0)
|
|
184
|
+
rack (>= 3.0.0)
|
|
185
|
+
rack-test (2.2.0)
|
|
186
|
+
rack (>= 1.3)
|
|
187
|
+
rackup (2.2.1)
|
|
188
|
+
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)
|
|
201
|
+
bundler (>= 1.15.0)
|
|
202
|
+
railties (= 8.1.1)
|
|
203
|
+
rails-dom-testing (2.3.0)
|
|
204
|
+
activesupport (>= 5.0.0)
|
|
205
|
+
minitest
|
|
206
|
+
nokogiri (>= 1.6)
|
|
207
|
+
rails-html-sanitizer (1.6.2)
|
|
208
|
+
loofah (~> 2.21)
|
|
209
|
+
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)
|
|
213
|
+
irb (~> 1.13)
|
|
214
|
+
rackup (>= 1.0.0)
|
|
215
|
+
rake (>= 12.2)
|
|
216
|
+
thor (~> 1.0, >= 1.2.2)
|
|
217
|
+
tsort (>= 0.2)
|
|
218
|
+
zeitwerk (~> 2.6)
|
|
219
|
+
rainbow (3.1.1)
|
|
220
|
+
rake (13.3.1)
|
|
221
|
+
rdoc (6.15.1)
|
|
222
|
+
erb
|
|
223
|
+
psych (>= 4.0.0)
|
|
224
|
+
tsort
|
|
225
|
+
regexp_parser (2.11.3)
|
|
226
|
+
reline (0.6.2)
|
|
227
|
+
io-console (~> 0.5)
|
|
228
|
+
roda (3.98.0)
|
|
229
|
+
rack
|
|
230
|
+
rodauth (2.41.0)
|
|
231
|
+
roda (>= 2.6.0)
|
|
232
|
+
sequel (>= 4)
|
|
233
|
+
rotp (6.3.0)
|
|
234
|
+
rqrcode (3.1.0)
|
|
235
|
+
chunky_png (~> 1.0)
|
|
236
|
+
rqrcode_core (~> 2.0)
|
|
237
|
+
rqrcode_core (2.0.0)
|
|
238
|
+
rspec (3.13.2)
|
|
239
|
+
rspec-core (~> 3.13.0)
|
|
240
|
+
rspec-expectations (~> 3.13.0)
|
|
241
|
+
rspec-mocks (~> 3.13.0)
|
|
242
|
+
rspec-core (3.13.6)
|
|
243
|
+
rspec-support (~> 3.13.0)
|
|
244
|
+
rspec-expectations (3.13.5)
|
|
245
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
246
|
+
rspec-support (~> 3.13.0)
|
|
247
|
+
rspec-mocks (3.13.6)
|
|
248
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
249
|
+
rspec-support (~> 3.13.0)
|
|
250
|
+
rspec-support (3.13.6)
|
|
251
|
+
rubocop (1.81.7)
|
|
252
|
+
json (~> 2.3)
|
|
253
|
+
language_server-protocol (~> 3.17.0.2)
|
|
254
|
+
lint_roller (~> 1.1.0)
|
|
255
|
+
parallel (~> 1.10)
|
|
256
|
+
parser (>= 3.3.0.2)
|
|
257
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
258
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
259
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
|
260
|
+
ruby-progressbar (~> 1.7)
|
|
261
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
262
|
+
rubocop-ast (1.48.0)
|
|
263
|
+
parser (>= 3.3.7.2)
|
|
264
|
+
prism (~> 1.4)
|
|
265
|
+
rubocop-rake (0.7.1)
|
|
266
|
+
lint_roller (~> 1.1)
|
|
267
|
+
rubocop (>= 1.72.1)
|
|
268
|
+
rubocop-rspec (3.8.0)
|
|
269
|
+
lint_roller (~> 1.1)
|
|
270
|
+
rubocop (~> 1.81)
|
|
271
|
+
ruby-progressbar (1.13.0)
|
|
272
|
+
safety_net_attestation (0.5.0)
|
|
273
|
+
jwt (>= 2.0, < 4.0)
|
|
274
|
+
securerandom (0.4.1)
|
|
275
|
+
sequel (5.98.0)
|
|
276
|
+
bigdecimal
|
|
277
|
+
sequel-activerecord_connection (2.0.1)
|
|
278
|
+
activerecord (>= 5.1)
|
|
279
|
+
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)
|
|
286
|
+
tpm-key_attestation (0.14.1)
|
|
287
|
+
bindata (~> 2.4)
|
|
288
|
+
openssl (> 2.0)
|
|
289
|
+
openssl-signature_algorithm (~> 1.0)
|
|
290
|
+
tryouts (3.7.1)
|
|
291
|
+
concurrent-ruby (~> 1.0, < 2)
|
|
292
|
+
irb
|
|
293
|
+
minitest (~> 5.0)
|
|
294
|
+
pastel (~> 0.8)
|
|
295
|
+
prism (~> 1.0)
|
|
296
|
+
rspec (>= 3.0, < 5.0)
|
|
297
|
+
tty-cursor (~> 0.7)
|
|
298
|
+
tty-screen (~> 0.8)
|
|
299
|
+
tsort (0.2.0)
|
|
300
|
+
tty-color (0.6.0)
|
|
301
|
+
tty-cursor (0.7.1)
|
|
302
|
+
tty-screen (0.8.2)
|
|
303
|
+
tzinfo (2.0.6)
|
|
304
|
+
concurrent-ruby (~> 1.0)
|
|
305
|
+
unicode-display_width (3.2.0)
|
|
306
|
+
unicode-emoji (~> 4.1)
|
|
307
|
+
unicode-emoji (4.1.0)
|
|
308
|
+
uri (1.1.0)
|
|
309
|
+
useragent (0.16.11)
|
|
310
|
+
warning (1.5.0)
|
|
311
|
+
webauthn (3.4.3)
|
|
312
|
+
android_key_attestation (~> 0.3.0)
|
|
313
|
+
bindata (~> 2.4)
|
|
314
|
+
cbor (~> 0.5.9)
|
|
315
|
+
cose (~> 1.1)
|
|
316
|
+
openssl (>= 2.2)
|
|
317
|
+
safety_net_attestation (~> 0.5.0)
|
|
318
|
+
tpm-key_attestation (~> 0.14.0)
|
|
319
|
+
websocket-driver (0.8.0)
|
|
320
|
+
base64
|
|
321
|
+
websocket-extensions (>= 0.1.0)
|
|
322
|
+
websocket-extensions (0.1.5)
|
|
323
|
+
xpath (3.2.0)
|
|
324
|
+
nokogiri (~> 1.8)
|
|
325
|
+
zeitwerk (2.7.3)
|
|
326
|
+
|
|
327
|
+
PLATFORMS
|
|
328
|
+
arm64-darwin-25
|
|
329
|
+
x86_64-linux
|
|
330
|
+
|
|
331
|
+
DEPENDENCIES
|
|
332
|
+
bcrypt (~> 3.1)
|
|
333
|
+
bundler-audit
|
|
334
|
+
capybara
|
|
335
|
+
dry-inflector
|
|
336
|
+
irb
|
|
337
|
+
jwt (~> 3.1)
|
|
338
|
+
rack-test (~> 2.1)
|
|
339
|
+
rails (>= 6.0)
|
|
340
|
+
rake (~> 13.3)
|
|
341
|
+
rodauth-tools!
|
|
342
|
+
rotp
|
|
343
|
+
rqrcode
|
|
344
|
+
rspec (~> 3.0)
|
|
345
|
+
rubocop (~> 1.81)
|
|
346
|
+
rubocop-rake
|
|
347
|
+
rubocop-rspec
|
|
348
|
+
sequel-activerecord_connection (~> 2.0)
|
|
349
|
+
sqlite3 (~> 2.8)
|
|
350
|
+
tilt (~> 2.4)
|
|
351
|
+
tryouts (~> 3.0)
|
|
352
|
+
warning
|
|
353
|
+
webauthn
|
|
354
|
+
|
|
355
|
+
BUNDLED WITH
|
|
356
|
+
2.7.2
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 delano
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# Rodauth::Tools
|
|
2
|
+
|
|
3
|
+
Framework-agnostic utilities for [Rodauth](http://rodauth.jeremyevans.net) authentication. Provides external Rodauth features and Sequel migration generators.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# 1. Add table_guard to catch missing tables at startup
|
|
9
|
+
class RodauthApp < Roda
|
|
10
|
+
plugin :rodauth do
|
|
11
|
+
enable :login, :logout
|
|
12
|
+
enable :table_guard # ← Validates tables exist
|
|
13
|
+
|
|
14
|
+
# Production: fail fast if tables missing
|
|
15
|
+
table_guard_mode :raise
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# 2. Run your app - catches problems immediately!
|
|
20
|
+
# => Rodauth::ConfigurationError: Missing required database tables!
|
|
21
|
+
# - accounts (feature: base)
|
|
22
|
+
# - account_password_hashes (feature: base)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Overview
|
|
26
|
+
|
|
27
|
+
Rodauth::Tools provides utilities that work with any Rodauth setup, regardless of framework:
|
|
28
|
+
|
|
29
|
+
1. **External Rodauth Features** - Like `table_guard` for validating database table setup, `external_identity` for tracking external IDs, and secret guards.
|
|
30
|
+
2. **Sequel Migration Generator** - Generate Rodauth database migrations for 19 features.
|
|
31
|
+
|
|
32
|
+
This is NOT a framework adapter. It is a collection of tools extracted from framework integrations to be used in any Rodauth environment. For specific framework integration, use:
|
|
33
|
+
|
|
34
|
+
- Rails: [rodauth-rails](https://github.com/janko/rodauth-rails)
|
|
35
|
+
- Others: Integrate Rodauth directly - [see integration guide](docs/rodauth-integration.md)
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
Add this line to your application's Gemfile:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
gem 'rodauth-tools'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
And then execute:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
bundle install
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or install it yourself as:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
gem install rodauth-tools
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
### 1. Table Guard Feature
|
|
60
|
+
|
|
61
|
+
Validates that required database tables exist for enabled Rodauth features.
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
class RodauthApp < Roda
|
|
65
|
+
plugin :rodauth do
|
|
66
|
+
enable :login, :logout, :otp
|
|
67
|
+
enable :table_guard # ← Add this
|
|
68
|
+
|
|
69
|
+
table_guard_mode :raise # or :warn, :error, :halt, :silent
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Modes:**
|
|
75
|
+
|
|
76
|
+
- `:silent` / `:skip` / `nil` - Disable validation (debug log only)
|
|
77
|
+
- `:warn` - Log warning message and continue execution
|
|
78
|
+
- `:error` - Print distinctive message to error log but continue execution
|
|
79
|
+
- `:raise` - Log error and raise `Rodauth::ConfigurationError` (recommended for production)
|
|
80
|
+
- `:halt` / `:exit` - Log error and exit the process immediately
|
|
81
|
+
- Block - Custom handler (see docs)
|
|
82
|
+
|
|
83
|
+
**Introspection:**
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
rodauth = MyApp.rodauth
|
|
87
|
+
|
|
88
|
+
# List all required tables
|
|
89
|
+
rodauth.list_all_required_tables
|
|
90
|
+
# => [:accounts, :account_password_hashes, :account_otp_keys, ...]
|
|
91
|
+
|
|
92
|
+
# Check status of each table
|
|
93
|
+
rodauth.table_status
|
|
94
|
+
# => [{method: :accounts_table, table: :accounts, exists: true}, ...]
|
|
95
|
+
|
|
96
|
+
# Get missing tables
|
|
97
|
+
rodauth.missing_tables
|
|
98
|
+
# => [{method: :otp_keys_table, table: :account_otp_keys}, ...]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Documentation:** [docs/features/table-guard.md](docs/features/table-guard.md)
|
|
102
|
+
|
|
103
|
+
### 2. External Identity Feature
|
|
104
|
+
|
|
105
|
+
Store external service identifiers in your accounts table with automatic helper methods.
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
class RodauthApp < Roda
|
|
109
|
+
plugin :rodauth do
|
|
110
|
+
enable :external_identity
|
|
111
|
+
|
|
112
|
+
# Declare columns (names used as-is)
|
|
113
|
+
external_identity_column :stripe_customer_id
|
|
114
|
+
external_identity_column :redis_uuid
|
|
115
|
+
external_identity_column :elasticsearch_doc_id
|
|
116
|
+
|
|
117
|
+
# Configuration
|
|
118
|
+
external_identity_check_columns :autocreate # Generate migration code
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Usage - helper methods match column names
|
|
123
|
+
rodauth.stripe_customer_id # => "cus_abc123"
|
|
124
|
+
rodauth.redis_uuid # => "550e8400-e29b-41d4-..."
|
|
125
|
+
rodauth.elasticsearch_doc_id # => "doc_789xyz"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Key Features:**
|
|
129
|
+
|
|
130
|
+
- Declarative column configuration
|
|
131
|
+
- Automatic helper method generation
|
|
132
|
+
- Auto-inclusion in `account_select`
|
|
133
|
+
- Column existence validation with migration code generation
|
|
134
|
+
- Introspection API for debugging
|
|
135
|
+
|
|
136
|
+
**Common Use Cases:**
|
|
137
|
+
|
|
138
|
+
- Payment integration (Stripe customer IDs)
|
|
139
|
+
- Session management (Redis keys)
|
|
140
|
+
- Search indexing (Elasticsearch document IDs)
|
|
141
|
+
- Federated authentication (Auth0 user IDs)
|
|
142
|
+
|
|
143
|
+
**Documentation:** [docs/features/external-identity.md](docs/features/external-identity.md)
|
|
144
|
+
|
|
145
|
+
### 3. HMAC Secret Guard Feature
|
|
146
|
+
|
|
147
|
+
Automatically configure and validate HMAC secrets at application startup to prevent deployment errors.
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
class RodauthApp < Roda
|
|
151
|
+
plugin :rodauth do
|
|
152
|
+
enable :hmac_secret_guard
|
|
153
|
+
|
|
154
|
+
# Production: Raises error if HMAC_SECRET missing
|
|
155
|
+
# Development: Uses fallback secret with warning
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Key Features:**
|
|
161
|
+
|
|
162
|
+
- Automatic loading from `HMAC_SECRET` environment variable
|
|
163
|
+
- Production mode: Raises `ConfigurationError` if secret missing
|
|
164
|
+
- Development mode: Logs warning and uses fallback
|
|
165
|
+
- Deletes secret from ENV after loading (security)
|
|
166
|
+
- Configurable production detection and error messages
|
|
167
|
+
|
|
168
|
+
**Documentation:** [docs/features/hmac-secret-guard.md](docs/features/hmac-secret-guard.md)
|
|
169
|
+
|
|
170
|
+
### 4. JWT Secret Guard Feature
|
|
171
|
+
|
|
172
|
+
Automatically configure and validate JWT secrets at application startup to prevent deployment errors.
|
|
173
|
+
|
|
174
|
+
```ruby
|
|
175
|
+
class RodauthApp < Roda
|
|
176
|
+
plugin :rodauth do
|
|
177
|
+
enable :jwt_secret_guard
|
|
178
|
+
|
|
179
|
+
# Production: Raises error if JWT_SECRET missing
|
|
180
|
+
# Development: Uses fallback secret with warning
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Key Features:**
|
|
186
|
+
|
|
187
|
+
- Automatic loading from `JWT_SECRET` environment variable
|
|
188
|
+
- Production mode: Raises `ConfigurationError` if secret missing
|
|
189
|
+
- Development mode: Logs warning and uses fallback
|
|
190
|
+
- Deletes secret from ENV after loading (security)
|
|
191
|
+
- Defines `jwt_secret` method for standalone use (no JWT feature required)
|
|
192
|
+
|
|
193
|
+
**Documentation:** [docs/features/jwt-secret-guard.md](docs/features/jwt-secret-guard.md)
|
|
194
|
+
|
|
195
|
+
### 5. Sequel Migration Generator
|
|
196
|
+
|
|
197
|
+
Generate database migrations for Rodauth features.
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
require "rodauth/tools"
|
|
201
|
+
|
|
202
|
+
generator = Rodauth::Tools::Migration.new(
|
|
203
|
+
features: [:base, :verify_account, :otp],
|
|
204
|
+
prefix: "account" # table prefix (default: "account")
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# Get migration content
|
|
208
|
+
puts generator.generate
|
|
209
|
+
|
|
210
|
+
# Get Rodauth configuration
|
|
211
|
+
puts generator.configuration
|
|
212
|
+
# => {
|
|
213
|
+
# accounts_table: :accounts,
|
|
214
|
+
# verify_account_table: :account_verification_keys,
|
|
215
|
+
# otp_keys_table: :account_otp_keys
|
|
216
|
+
# }
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Supported Features** (19 total):
|
|
220
|
+
|
|
221
|
+
- `base` - Core accounts table
|
|
222
|
+
- `remember` - Remember me functionality
|
|
223
|
+
- `verify_account` - Account verification
|
|
224
|
+
- `verify_login_change` - Login change verification
|
|
225
|
+
- `reset_password` - Password reset
|
|
226
|
+
- `email_auth` - Passwordless email authentication
|
|
227
|
+
- `otp` - TOTP multifactor authentication
|
|
228
|
+
- `otp_unlock` - OTP unlock
|
|
229
|
+
- `sms_codes` - SMS codes
|
|
230
|
+
- `recovery_codes` - Backup recovery codes
|
|
231
|
+
- `webauthn` - WebAuthn keys
|
|
232
|
+
- `lockout` - Account lockouts
|
|
233
|
+
- `active_sessions` - Session management
|
|
234
|
+
- `account_expiration` - Account expiration
|
|
235
|
+
- `password_expiration` - Password expiration
|
|
236
|
+
- `single_session` - Single session per account
|
|
237
|
+
- `audit_logging` - Authentication audit logs
|
|
238
|
+
- `disallow_password_reuse` - Password history
|
|
239
|
+
- `jwt_refresh` - JWT refresh tokens
|
|
240
|
+
|
|
241
|
+
## Console
|
|
242
|
+
|
|
243
|
+
Interactive console for testing:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
bin/console
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Example session:
|
|
250
|
+
|
|
251
|
+
```ruby
|
|
252
|
+
db = setup_test_db
|
|
253
|
+
app = create_app(db, features: [:login, :otp])
|
|
254
|
+
rodauth = app.rodauth
|
|
255
|
+
|
|
256
|
+
rodauth.list_all_required_tables
|
|
257
|
+
rodauth.table_status
|
|
258
|
+
rodauth.missing_tables
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Development
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Run tests
|
|
265
|
+
bundle exec rspec
|
|
266
|
+
|
|
267
|
+
# Run console
|
|
268
|
+
bin/console
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Architecture
|
|
272
|
+
|
|
273
|
+
```plain
|
|
274
|
+
┌─────────────────────────┐
|
|
275
|
+
│ Rodauth │ ← the real work
|
|
276
|
+
│ (jeremyevans/rodauth) │
|
|
277
|
+
└───────────┬─────────────┘
|
|
278
|
+
│
|
|
279
|
+
┌───────────────────────┼───────────────────────┐
|
|
280
|
+
│ │ │
|
|
281
|
+
▼ ▼ ▼
|
|
282
|
+
rodauth-rails rodauth-tools your own
|
|
283
|
+
(janko) (this gem) features
|
|
284
|
+
│ │
|
|
285
|
+
│ ┌───────┴───────┐
|
|
286
|
+
│ │ │
|
|
287
|
+
│ features migrations
|
|
288
|
+
│ │ │
|
|
289
|
+
│ table_guard sequel templates (based on rodauth-rails)
|
|
290
|
+
│ external_identity
|
|
291
|
+
│ *_secret_guard
|
|
292
|
+
│
|
|
293
|
+
└───────────────┬───────────────┘
|
|
294
|
+
│
|
|
295
|
+
▼
|
|
296
|
+
Your Rack app
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Rodauth Feature Architecture:**
|
|
300
|
+
|
|
301
|
+
Rodauth Features are modules that mix into `Rodauth::Auth` instances at runtime. They use lifecycle hooks like `post_configure` for initialization and `auth_value_method` for user-overridable settings. See [docs/rodauth-features-api.md](docs/rodauth-features-api.md) for a DSL reference.
|
|
302
|
+
|
|
303
|
+
## Documentation
|
|
304
|
+
|
|
305
|
+
- **[Table Guard Feature](docs/features/table-guard.md)** - Validate required database tables
|
|
306
|
+
- **[External Identity Feature](docs/features/external-identity.md)** - Track external service identifiers
|
|
307
|
+
- **[HMAC Secret Guard Feature](docs/features/hmac-secret-guard.md)** - Validate HMAC secrets at startup
|
|
308
|
+
- **[JWT Secret Guard Feature](docs/features/jwt-secret-guard.md)** - Validate JWT secrets at startup
|
|
309
|
+
- **[Sequel Migrations](docs/sequel-migrations.md)** - Integrating table_guard with Sequel migrations
|
|
310
|
+
- **[Rodauth Feature API](docs/rodauth-features-api.md)** - Complete DSL reference for feature development
|
|
311
|
+
- **[Rodauth Integration](docs/rodauth-integration.md)** - Framework integration patterns
|
|
312
|
+
- **[Mail Configuration](docs/rodauth-mail.md)** - Email and SMTP setup
|
|
313
|
+
|
|
314
|
+
## Related Projects
|
|
315
|
+
|
|
316
|
+
- [rodauth](https://github.com/jeremyevans/rodauth) - The authentication framework
|
|
317
|
+
- [rodauth-rails](https://github.com/janko/rodauth-rails) - Rails integration
|
|
318
|
+
- [roda](https://github.com/jeremyevans/roda) - Routing tree web toolkit
|
|
319
|
+
|
|
320
|
+
## AI Development Assistance
|
|
321
|
+
|
|
322
|
+
Version 0.3.0's features were developed with AI assistance:
|
|
323
|
+
|
|
324
|
+
- **Zed Agent (Claude Sonnet 4)** - Core feature implementation: Secret Guards, Table Guard, and Migrations
|
|
325
|
+
- **Gemini 3 Pro** - Release readiness assessment
|
|
326
|
+
- **GitHub Copilot** - Code completion
|
|
327
|
+
|
|
328
|
+
The maintainer remains responsible for all security decisions and implementation. We believe in transparency about development tools, especially for security-focused software.
|
|
329
|
+
|
|
330
|
+
## Acknowledgments
|
|
331
|
+
|
|
332
|
+
This project originated as an effort to bring some of the excellent developer experience of [rodauth-rails](https://github.com/janko/rodauth-rails) to non-Rails environments. It started as a rack adapter (`rodauth-rack`) but was eventually distilled into this collection of framework-agnostic tools.
|
|
333
|
+
|
|
334
|
+
- **Migration Templates**: Heavily borrowed from [rodauth-rails](https://github.com/janko/rodauth-rails) by Janko Marohnić.
|
|
335
|
+
- **Inspiration**: The `rodauth-rails` project demonstrated how much easier Rodauth configuration could be with the right tooling.
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
MIT License
|