booth 0.0.1 → 0.0.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.
Files changed (383) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/LICENSE.md +1 -2
  4. data/README.md +37 -6
  5. data/app/assets/images/booth/browsers/README.md +1 -2
  6. data/app/assets/images/booth/browsers/chrome.svg +1 -1
  7. data/app/assets/images/booth/browsers/edge.svg +1 -1
  8. data/app/assets/images/booth/browsers/firefox.svg +1 -1
  9. data/app/assets/images/booth/browsers/opera.svg +1 -1
  10. data/app/assets/images/booth/browsers/safari.svg +1 -1
  11. data/app/assets/images/booth/fido/passkey_mark_a.svg +10 -0
  12. data/app/assets/images/booth/fido/passkey_mark_a_black.svg +32 -0
  13. data/app/assets/images/booth/fido/passkey_mark_a_reverse.svg +33 -0
  14. data/app/assets/images/booth/fido/passkey_mark_a_white.svg +32 -0
  15. data/app/assets/images/booth/fido/passkey_mark_b_black.svg +1 -0
  16. data/app/assets/images/booth/platforms/android.svg +1 -6
  17. data/app/assets/images/booth/platforms/apple.svg +1 -6
  18. data/app/assets/images/booth/platforms/linux.svg +1 -6
  19. data/app/assets/images/booth/platforms/windows.svg +1 -6
  20. data/app/assets/javascripts/booth/authentication.js +29 -0
  21. data/app/assets/javascripts/booth/authentication.js.map +1 -0
  22. data/app/assets/javascripts/booth/error.js +38 -0
  23. data/app/assets/javascripts/booth/error.js.map +1 -0
  24. data/app/assets/javascripts/booth/form.js +78 -0
  25. data/app/assets/javascripts/booth/form.js.map +1 -0
  26. data/app/assets/javascripts/booth/gui.js +53 -0
  27. data/app/assets/javascripts/booth/gui.js.map +1 -0
  28. data/app/assets/javascripts/booth/registration.js +29 -0
  29. data/app/assets/javascripts/booth/registration.js.map +1 -0
  30. data/app/assets/javascripts/booth/setup.js +14 -0
  31. data/app/assets/javascripts/booth/verification.js +49 -0
  32. data/app/assets/javascripts/booth/verification.js.map +1 -0
  33. data/app/assets/javascripts/declarations/authentication.d.ts +6 -0
  34. data/app/assets/javascripts/declarations/error.d.ts +36 -0
  35. data/app/assets/javascripts/declarations/form.d.ts +8 -0
  36. data/app/assets/javascripts/declarations/gui.d.ts +4 -0
  37. data/app/assets/javascripts/declarations/registration.d.ts +6 -0
  38. data/app/assets/javascripts/declarations/setup.d.ts +3 -0
  39. data/app/assets/javascripts/declarations/verification.d.ts +6 -0
  40. data/app/assets/javascripts/src/authentication.ts +41 -0
  41. data/app/assets/javascripts/src/error.ts +35 -0
  42. data/app/assets/javascripts/src/form.ts +90 -0
  43. data/app/assets/javascripts/src/gui.ts +59 -0
  44. data/app/assets/javascripts/src/registration.ts +44 -0
  45. data/app/assets/javascripts/src/verification.ts +61 -0
  46. data/app/assets/stylesheets/booth/booth.css +3 -0
  47. data/config/importmap.rb +11 -0
  48. data/config/locales/de.yml +14 -38
  49. data/config/locales/en.yml +17 -36
  50. data/data/combined_aaguid.json +1 -0
  51. data/lib/booth/adminland/credentials/create.rb +10 -12
  52. data/lib/booth/adminland/credentials/index.rb +31 -0
  53. data/lib/booth/adminland/onboardings/create.rb +24 -15
  54. data/lib/booth/adminland/onboardings/destroy.rb +8 -4
  55. data/lib/booth/adminland/onboardings/find.rb +52 -45
  56. data/lib/booth/adminland/onboardings/find_unconsumed.rb +61 -0
  57. data/lib/booth/adminland/onboardings/index.rb +6 -3
  58. data/lib/booth/adminland/periodic_cleanup.rb +7 -2
  59. data/lib/booth/adminland.rb +17 -18
  60. data/lib/booth/coercers/domain.rb +11 -0
  61. data/lib/booth/coercers/request.rb +51 -0
  62. data/lib/booth/coercers/scope.rb +11 -0
  63. data/lib/booth/comparisons/domain.rb +38 -0
  64. data/lib/booth/comparisons/scope.rb +38 -0
  65. data/lib/booth/concerns/action.rb +25 -13
  66. data/lib/booth/concerns/transition.rb +5 -2
  67. data/lib/booth/configuration.rb +14 -73
  68. data/lib/booth/configure.rb +3 -10
  69. data/lib/booth/{audits/register → core/audit}/completed_onboarding.rb +8 -6
  70. data/lib/booth/core/audit/credential_created.rb +24 -0
  71. data/lib/booth/core/audit/logout.rb +24 -0
  72. data/lib/booth/core/authenticators/confirm.rb +30 -0
  73. data/lib/booth/core/authenticators/step.rb +24 -0
  74. data/lib/booth/core/cooldowns/distance_of_time.rb +50 -0
  75. data/lib/booth/core/cooldowns/strategies/exponential.rb +88 -0
  76. data/lib/booth/core/cooldowns/strategies/global.rb +66 -0
  77. data/lib/booth/core/cooldowns/strategies/result.rb +27 -0
  78. data/lib/booth/core/credentials/create.rb +32 -0
  79. data/lib/booth/core/credentials/find_by_username.rb +63 -0
  80. data/lib/booth/core/credentials/index.rb +15 -0
  81. data/lib/booth/core/credentials/webauth_challenge.rb +37 -0
  82. data/lib/booth/core/geolocation.rb +25 -0
  83. data/lib/booth/core/onboardings/find.rb +92 -0
  84. data/lib/booth/core/onboardings/step.rb +19 -0
  85. data/lib/booth/core/remotes/get.rb +45 -0
  86. data/lib/booth/core/remotes/respond.rb +82 -0
  87. data/lib/booth/core/remotes/set_for_login.rb +31 -0
  88. data/lib/booth/core/sessions/create_and_login.rb +63 -0
  89. data/lib/booth/core/sessions/historical_locations.rb +22 -0
  90. data/lib/booth/core/sessions/index.rb +66 -0
  91. data/lib/booth/core/sessions/revoke.rb +59 -0
  92. data/lib/booth/core/sessions/revoke_all_others.rb +49 -0
  93. data/lib/booth/core/sessions/to_passport.rb +35 -0
  94. data/lib/booth/core/webauth/authentication_verification.rb +76 -0
  95. data/lib/booth/core/webauth/options_for_create.rb +56 -0
  96. data/lib/booth/core/webauth/options_for_get.rb +30 -0
  97. data/lib/booth/core/webauth/provider.rb +36 -0
  98. data/lib/booth/core/webauth/registration_verification.rb +100 -0
  99. data/lib/booth/credential.rb +35 -0
  100. data/lib/booth/engine.rb +15 -4
  101. data/lib/booth/errors.rb +2 -0
  102. data/lib/booth/hooks/after_fetch.rb +14 -6
  103. data/lib/booth/hooks/before_logout.rb +5 -3
  104. data/lib/booth/hooks/serialize_from_session.rb +13 -5
  105. data/lib/booth/hooks/serialize_into_session.rb +6 -3
  106. data/lib/booth/logging.rb +13 -42
  107. data/lib/booth/models/application_record.rb +3 -0
  108. data/lib/booth/models/audit.rb +10 -11
  109. data/lib/booth/models/authenticator.rb +6 -9
  110. data/lib/booth/models/credential.rb +17 -20
  111. data/lib/booth/models/onboarding.rb +16 -39
  112. data/lib/booth/models/{contest.rb → remote.rb} +13 -14
  113. data/lib/booth/models/remotes/scopes/recently_created.rb +26 -0
  114. data/lib/booth/models/remotes/scopes/recently_responded.rb +35 -0
  115. data/lib/booth/models/session.rb +15 -10
  116. data/lib/booth/models/user_agent.rb +2 -0
  117. data/lib/booth/request.rb +43 -22
  118. data/lib/booth/requests/agent.rb +3 -1
  119. data/lib/booth/requests/authentication.rb +15 -5
  120. data/lib/booth/requests/ip.rb +4 -2
  121. data/lib/booth/requests/return_path.rb +4 -2
  122. data/lib/booth/requests/session.rb +6 -4
  123. data/lib/booth/requests/storage.rb +5 -31
  124. data/lib/booth/requests/storages/login.rb +35 -29
  125. data/lib/booth/requests/storages/registration.rb +2 -0
  126. data/lib/booth/requests/storages/webauth.rb +3 -0
  127. data/lib/booth/requests/sudo.rb +6 -50
  128. data/lib/booth/routes/userland.rb +13 -59
  129. data/lib/booth/syntaxes/domain.rb +46 -0
  130. data/lib/booth/syntaxes/email.rb +11 -8
  131. data/lib/booth/syntaxes/ip.rb +6 -4
  132. data/lib/booth/syntaxes/remote_code.rb +60 -0
  133. data/lib/booth/syntaxes/scope.rb +7 -3
  134. data/lib/booth/syntaxes/secret_key.rb +8 -6
  135. data/lib/booth/syntaxes/username.rb +23 -10
  136. data/lib/booth/syntaxes/uuid.rb +3 -1
  137. data/lib/booth/test.rb +27 -22
  138. data/lib/booth/testing/incorporation_test_case.rb +29 -0
  139. data/lib/booth/testing/shortcuts.rb +77 -0
  140. data/lib/booth/testing/support/assert_all_partials_were_covered.rb +69 -0
  141. data/lib/booth/testing/support/assert_logged_in.rb +68 -0
  142. data/lib/booth/{test → testing}/support/assert_logged_out.rb +7 -4
  143. data/lib/booth/testing/support/assert_partial.rb +56 -0
  144. data/lib/booth/{test → testing}/support/force_login.rb +10 -4
  145. data/lib/booth/{test → testing}/support/get_session_value.rb +8 -6
  146. data/lib/booth/testing/support/scenario.rb +23 -0
  147. data/lib/booth/testing/support/shortcuts/create_and_onboard.rb +56 -0
  148. data/lib/booth/testing/support/shortcuts/login_with_passkey.rb +55 -0
  149. data/lib/booth/testing/support/shortcuts/register_new_passkey.rb +51 -0
  150. data/lib/booth/testing/support/soft_reset_session.rb +24 -0
  151. data/lib/booth/testing/support/virtual_authenticators/create.rb +34 -0
  152. data/lib/booth/testing/support/virtual_authenticators/destroy.rb +20 -0
  153. data/lib/booth/testing/support/virtual_authenticators/enable.rb +24 -0
  154. data/lib/booth/testing/support/virtual_authenticators/load.rb +38 -0
  155. data/lib/booth/testing/support/virtual_authenticators/manager.rb +124 -0
  156. data/lib/booth/testing/support/visit.rb +62 -0
  157. data/lib/booth/testing/userland/login_remotely.rb +100 -0
  158. data/lib/booth/testing/userland/onboarding_first_time.rb +81 -0
  159. data/lib/booth/testing/userland/onboarding_to_reset_passkeys.rb +129 -0
  160. data/lib/booth/testing/userland/registration_with_passkey.rb +93 -0
  161. data/lib/booth/testing/userland/registration_without_passkey.rb +101 -0
  162. data/lib/booth/testing/userland/sessions_manage_behavior.rb +68 -0
  163. data/lib/booth/testing/userland/sessions_revoke_all_others.rb +17 -0
  164. data/lib/booth/testing/userland/sessions_revoke_one.rb +17 -0
  165. data/lib/booth/testing/userland.rb +36 -0
  166. data/lib/booth/to_struct.rb +9 -2
  167. data/lib/booth/userland/extract_flash_messages.rb +10 -3
  168. data/lib/booth/userland/logins/create.rb +8 -6
  169. data/lib/booth/userland/logins/destroy.rb +23 -6
  170. data/lib/booth/userland/logins/new.rb +23 -25
  171. data/lib/booth/userland/logins/transitions/create/choose_username.rb +62 -27
  172. data/lib/booth/userland/logins/transitions/create/skip_remotes.rb +18 -14
  173. data/lib/booth/userland/logins/transitions/create/webauth_authentication_initiation.rb +54 -48
  174. data/lib/booth/userland/logins/transitions/create/webauth_authentication_verification.rb +62 -58
  175. data/lib/booth/userland/logins/transitions/new/already_logged_in.rb +4 -3
  176. data/lib/booth/userland/logins/transitions/new/fallible.rb +4 -0
  177. data/lib/booth/userland/logins/transitions/new/{mode_username_and_password.rb → missing_authenticators.rb} +5 -4
  178. data/lib/booth/userland/logins/transitions/new/mode_username_and_webauth.rb +6 -4
  179. data/lib/booth/userland/logins/transitions/new/no_username_chosen.rb +3 -1
  180. data/lib/booth/userland/logins/transitions/new/remote_session_available.rb +20 -13
  181. data/lib/booth/userland/logins/transitions/new/timed_out.rb +3 -1
  182. data/lib/booth/userland/onboardings/show.rb +65 -39
  183. data/lib/booth/userland/onboardings/update.rb +46 -38
  184. data/lib/booth/userland/registrations/create.rb +51 -20
  185. data/lib/booth/userland/registrations/new.rb +6 -7
  186. data/lib/booth/userland/remotes/show.rb +56 -0
  187. data/lib/booth/userland/{personal_contests → remotes}/update.rb +5 -3
  188. data/lib/booth/userland/sessions/destroy_one_or_other.rb +3 -16
  189. data/lib/booth/userland/sessions/index.rb +4 -2
  190. data/lib/booth/userland/sessions/show.rb +5 -6
  191. data/lib/booth/userland/sessions/transitions/destroy/enter_webauth.rb +8 -6
  192. data/lib/booth/userland/sessions/transitions/destroy/webauth_authentication_initiation.rb +8 -6
  193. data/lib/booth/userland/sessions/transitions/destroy/webauth_authentication_verification.rb +7 -5
  194. data/lib/booth/userland/sessions/transitions/show/enter_webauth.rb +8 -6
  195. data/lib/booth/userland/webauths/create.rb +20 -17
  196. data/lib/booth/userland/webauths/destroy.rb +6 -16
  197. data/lib/booth/userland/webauths/guards/sudo.rb +10 -5
  198. data/lib/booth/userland/webauths/index.rb +4 -2
  199. data/lib/booth/userland/webauths/new.rb +7 -22
  200. data/lib/booth/userland/webauths/sudo.rb +3 -1
  201. data/lib/booth/userland/webauths/transitions/create/authentication_initiation.rb +8 -11
  202. data/lib/booth/userland/webauths/transitions/create/authentication_verification.rb +11 -13
  203. data/lib/booth/userland/webauths/transitions/create/choose_nickname.rb +8 -5
  204. data/lib/booth/userland/webauths/transitions/create/registration_initiation.rb +15 -14
  205. data/lib/booth/userland/webauths/transitions/create/registration_verification.rb +34 -28
  206. data/lib/booth/userland/webauths/transitions/create/reset.rb +2 -0
  207. data/lib/booth/userland/webauths/transitions/new/step.rb +3 -1
  208. data/lib/booth/userland/webauths/transitions/sudo/authentication_initiation.rb +5 -10
  209. data/lib/booth/userland/webauths/transitions/sudo/authentication_verification.rb +4 -2
  210. data/lib/booth/userland.rb +53 -109
  211. data/lib/booth/version.rb +3 -1
  212. data/lib/booth.rb +6 -236
  213. data/lib/generators/booth/migration/migration_generator.rb +2 -1
  214. data/lib/generators/booth/migration/templates/add_credential_to_users.erb +6 -4
  215. data/lib/generators/booth/migration/templates/create_booth_tables.erb +61 -72
  216. metadata +124 -571
  217. data/app/assets/config/booth_manifest.js +0 -15
  218. data/app/assets/images/booth/browsers/internet_explorer.svg +0 -1
  219. data/app/assets/javascripts/booth/all.js +0 -162
  220. data/app/assets/javascripts/booth/all.js.map +0 -1
  221. data/app/assets/javascripts/booth/booth.ts +0 -194
  222. data/app/assets/javascripts/booth/webauthn-json.ts +0 -99
  223. data/lib/booth/adminland/recoveries/consume.rb +0 -70
  224. data/lib/booth/audits/register/added_otp.rb +0 -22
  225. data/lib/booth/audits/register/changed_otp.rb +0 -22
  226. data/lib/booth/audits/register/correct_otp.rb +0 -42
  227. data/lib/booth/audits/register/correct_password.rb +0 -43
  228. data/lib/booth/audits/register/logout.rb +0 -22
  229. data/lib/booth/audits/register/requested_password_reset.rb +0 -22
  230. data/lib/booth/audits/register/wrong_otp.rb +0 -22
  231. data/lib/booth/audits/register/wrong_password.rb +0 -25
  232. data/lib/booth/authenticators/confirm.rb +0 -34
  233. data/lib/booth/authenticators/credential_mode_after_confirmation.rb +0 -25
  234. data/lib/booth/authenticators/step.rb +0 -19
  235. data/lib/booth/contests/get.rb +0 -36
  236. data/lib/booth/contests/respond.rb +0 -78
  237. data/lib/booth/contests/set_for_login.rb +0 -28
  238. data/lib/booth/cooldowns/distance_of_time.rb +0 -46
  239. data/lib/booth/cooldowns/otp.rb +0 -22
  240. data/lib/booth/cooldowns/password.rb +0 -44
  241. data/lib/booth/cooldowns/password_reset.rb +0 -24
  242. data/lib/booth/cooldowns/strategies/exponential.rb +0 -82
  243. data/lib/booth/cooldowns/strategies/global.rb +0 -62
  244. data/lib/booth/cooldowns/strategies/result.rb +0 -22
  245. data/lib/booth/credentials/create.rb +0 -28
  246. data/lib/booth/credentials/create_with_onboarding.rb +0 -26
  247. data/lib/booth/credentials/find_by_username.rb +0 -45
  248. data/lib/booth/credentials/mode.rb +0 -69
  249. data/lib/booth/credentials/modes/otp_addable.rb +0 -23
  250. data/lib/booth/credentials/modes/otp_changeable.rb +0 -23
  251. data/lib/booth/credentials/modes/otp_manageable.rb +0 -17
  252. data/lib/booth/credentials/modes/otp_removable.rb +0 -23
  253. data/lib/booth/credentials/modes/password_addable.rb +0 -29
  254. data/lib/booth/credentials/modes/password_changeable.rb +0 -31
  255. data/lib/booth/credentials/modes/password_manageable.rb +0 -17
  256. data/lib/booth/credentials/modes/password_removable.rb +0 -24
  257. data/lib/booth/credentials/modes/password_removal_requires_user_verifiable_webauth.rb +0 -16
  258. data/lib/booth/credentials/modes/webauth_addable.rb +0 -26
  259. data/lib/booth/credentials/modes/webauth_manageable.rb +0 -16
  260. data/lib/booth/credentials/modes/webauth_removable.rb +0 -25
  261. data/lib/booth/credentials/otp_authentication.rb +0 -59
  262. data/lib/booth/credentials/password_authentication.rb +0 -72
  263. data/lib/booth/credentials/webauth_challenge.rb +0 -28
  264. data/lib/booth/geolocation.rb +0 -20
  265. data/lib/booth/logger.rb +0 -41
  266. data/lib/booth/method_object.rb +0 -73
  267. data/lib/booth/mode.rb +0 -22
  268. data/lib/booth/models/concerns/modeable.rb +0 -50
  269. data/lib/booth/models/concerns/otpable.rb +0 -37
  270. data/lib/booth/models/concerns/passwordable.rb +0 -58
  271. data/lib/booth/models/contests/scopes/recently_created.rb +0 -23
  272. data/lib/booth/models/contests/scopes/recently_responded.rb +0 -32
  273. data/lib/booth/models/password_reset.rb +0 -41
  274. data/lib/booth/models/recovery.rb +0 -32
  275. data/lib/booth/models/registration.rb +0 -10
  276. data/lib/booth/modes/base.rb +0 -25
  277. data/lib/booth/modes/username_and_password.rb +0 -7
  278. data/lib/booth/modes/username_and_webauth.rb +0 -7
  279. data/lib/booth/modes/username_password_and_otp.rb +0 -7
  280. data/lib/booth/modes/username_password_and_webauth.rb +0 -7
  281. data/lib/booth/onboardings/find.rb +0 -35
  282. data/lib/booth/onboardings/propagate_to_credential.rb +0 -63
  283. data/lib/booth/onboardings/step.rb +0 -68
  284. data/lib/booth/password_resets/create.rb +0 -57
  285. data/lib/booth/password_resets/find.rb +0 -36
  286. data/lib/booth/password_resets/propagate_to_credential.rb +0 -36
  287. data/lib/booth/password_resets/step.rb +0 -18
  288. data/lib/booth/recoveries/create.rb +0 -45
  289. data/lib/booth/requests/storages/otp.rb +0 -54
  290. data/lib/booth/requests/storages/password.rb +0 -49
  291. data/lib/booth/requests/storages/password_reset.rb +0 -35
  292. data/lib/booth/requests/storages/recovery.rb +0 -35
  293. data/lib/booth/sessions/create_and_login.rb +0 -46
  294. data/lib/booth/sessions/historical_locations.rb +0 -18
  295. data/lib/booth/sessions/index.rb +0 -59
  296. data/lib/booth/sessions/revoke.rb +0 -51
  297. data/lib/booth/sessions/revoke_all_others.rb +0 -43
  298. data/lib/booth/sessions/to_passport.rb +0 -51
  299. data/lib/booth/syntaxes/contest_code.rb +0 -58
  300. data/lib/booth/syntaxes/otp.rb +0 -57
  301. data/lib/booth/syntaxes/scope_comparison.rb +0 -28
  302. data/lib/booth/test/helpers.rb +0 -63
  303. data/lib/booth/test/support/assert_all_partials_were_covered.rb +0 -63
  304. data/lib/booth/test/support/assert_logged_in.rb +0 -49
  305. data/lib/booth/test/support/assert_partial.rb +0 -29
  306. data/lib/booth/test/support/otp_code_from_session.rb +0 -30
  307. data/lib/booth/test/support/soft_reset_session.rb +0 -22
  308. data/lib/booth/test/userland/logins/missing_authenticators.rb +0 -72
  309. data/lib/booth/test/userland/logins/missing_onboarding.rb +0 -35
  310. data/lib/booth/test/userland/logins/username_and_password.rb +0 -40
  311. data/lib/booth/test/userland/logins/username_and_webauth.rb +0 -75
  312. data/lib/booth/test/userland/logins/username_password_and_otp.rb +0 -45
  313. data/lib/booth/test/userland/logins/username_password_and_webauth.rb +0 -86
  314. data/lib/booth/test/userland/onboardings/already_logged_in.rb +0 -64
  315. data/lib/booth/test/userland/onboardings/otp.rb +0 -63
  316. data/lib/booth/test/userland/onboardings/password.rb +0 -49
  317. data/lib/booth/test/userland/onboardings/timeout.rb +0 -47
  318. data/lib/booth/test/userland/otps/manage.rb +0 -86
  319. data/lib/booth/test/userland/password_resets/reset.rb +0 -102
  320. data/lib/booth/test/userland.rb +0 -38
  321. data/lib/booth/test/webauthn/disable.rb +0 -17
  322. data/lib/booth/test/webauthn/enable.rb +0 -19
  323. data/lib/booth/test/webauthn/virtual_authenticators/create.rb +0 -38
  324. data/lib/booth/test/webauthn/virtual_authenticators/destroy.rb +0 -20
  325. data/lib/booth/userland/logins/transitions/create/enter_otp.rb +0 -70
  326. data/lib/booth/userland/logins/transitions/create/verify_password.rb +0 -70
  327. data/lib/booth/userland/logins/transitions/new/mode_first_time.rb +0 -20
  328. data/lib/booth/userland/logins/transitions/new/mode_username_password_and_otp.rb +0 -24
  329. data/lib/booth/userland/logins/transitions/new/mode_username_password_and_webauth.rb +0 -24
  330. data/lib/booth/userland/onboardings/transitions/update/choose_mode.rb +0 -58
  331. data/lib/booth/userland/onboardings/transitions/update/choose_password.rb +0 -41
  332. data/lib/booth/userland/onboardings/transitions/update/choose_webauth_nickname.rb +0 -50
  333. data/lib/booth/userland/onboardings/transitions/update/confirm_otp.rb +0 -58
  334. data/lib/booth/userland/onboardings/transitions/update/confirm_password.rb +0 -49
  335. data/lib/booth/userland/onboardings/transitions/update/register_otp.rb +0 -31
  336. data/lib/booth/userland/onboardings/transitions/update/reset_otp.rb +0 -40
  337. data/lib/booth/userland/onboardings/transitions/update/reset_password.rb +0 -35
  338. data/lib/booth/userland/onboardings/transitions/update/reset_webauth.rb +0 -46
  339. data/lib/booth/userland/onboardings/transitions/update/webauth_authentication_initiation.rb +0 -40
  340. data/lib/booth/userland/onboardings/transitions/update/webauth_authentication_verification.rb +0 -59
  341. data/lib/booth/userland/onboardings/transitions/update/webauth_registration_initiation.rb +0 -46
  342. data/lib/booth/userland/onboardings/transitions/update/webauth_registration_verification.rb +0 -56
  343. data/lib/booth/userland/otps/destroy.rb +0 -42
  344. data/lib/booth/userland/otps/edit.rb +0 -72
  345. data/lib/booth/userland/otps/guards/manageable.rb +0 -21
  346. data/lib/booth/userland/otps/guards/sudo.rb +0 -23
  347. data/lib/booth/userland/otps/show.rb +0 -36
  348. data/lib/booth/userland/otps/sudo.rb +0 -51
  349. data/lib/booth/userland/otps/transitions/update/confirm.rb +0 -84
  350. data/lib/booth/userland/otps/transitions/update/register.rb +0 -40
  351. data/lib/booth/userland/otps/transitions/update/reset.rb +0 -31
  352. data/lib/booth/userland/otps/update.rb +0 -34
  353. data/lib/booth/userland/password_resets/create.rb +0 -73
  354. data/lib/booth/userland/password_resets/guards/logged_out.rb +0 -21
  355. data/lib/booth/userland/password_resets/new.rb +0 -57
  356. data/lib/booth/userland/password_resets/show.rb +0 -77
  357. data/lib/booth/userland/password_resets/transitions/update/choose_password.rb +0 -48
  358. data/lib/booth/userland/password_resets/transitions/update/confirm_password.rb +0 -54
  359. data/lib/booth/userland/password_resets/transitions/update/reset_password.rb +0 -29
  360. data/lib/booth/userland/password_resets/update.rb +0 -65
  361. data/lib/booth/userland/passwords/destroy.rb +0 -41
  362. data/lib/booth/userland/passwords/edit.rb +0 -54
  363. data/lib/booth/userland/passwords/guards/manageable.rb +0 -21
  364. data/lib/booth/userland/passwords/guards/removable.rb +0 -21
  365. data/lib/booth/userland/passwords/guards/sudo.rb +0 -21
  366. data/lib/booth/userland/passwords/remove.rb +0 -34
  367. data/lib/booth/userland/passwords/show.rb +0 -32
  368. data/lib/booth/userland/passwords/sudo.rb +0 -55
  369. data/lib/booth/userland/passwords/transitions/remove/step.rb +0 -27
  370. data/lib/booth/userland/passwords/transitions/update/choose_password.rb +0 -62
  371. data/lib/booth/userland/passwords/transitions/update/confirm_password.rb +0 -82
  372. data/lib/booth/userland/passwords/update.rb +0 -33
  373. data/lib/booth/userland/personal_contests/show.rb +0 -60
  374. data/lib/booth/userland/recoveries/create.rb +0 -48
  375. data/lib/booth/userland/recoveries/new.rb +0 -35
  376. data/lib/booth/userland/sessions/transitions/destroy/enter_password.rb +0 -50
  377. data/lib/booth/userland/sessions/transitions/destroy/verify_password.rb +0 -83
  378. data/lib/booth/userland/webauths/guards/manageable.rb +0 -21
  379. data/lib/booth/webauth/authentication_verification.rb +0 -68
  380. data/lib/booth/webauth/demand_user_verification.rb +0 -29
  381. data/lib/booth/webauth/options_for_create.rb +0 -46
  382. data/lib/booth/webauth/options_for_get.rb +0 -29
  383. data/lib/generators/booth/migration/templates/create_booth_mode_types.erb +0 -20
@@ -1,70 +0,0 @@
1
- module Booth
2
- module Logins
3
- module Transitions
4
- module Create
5
- class EnterOtp
6
- include ::Booth::Concerns::Transition
7
-
8
- def self.applicable?(params:)
9
- params.dig :login, :otp
10
- end
11
-
12
- def call
13
- do_check_stale_session
14
- .on_success { do_find_credential }
15
- .on_success { do_check_otp }
16
- end
17
-
18
- private
19
-
20
- # Helpers
21
-
22
- delegate :sudo, to: :request
23
-
24
- def do_check_stale_session
25
- return Tron.success :session_not_stale unless storage.timed_out?
26
-
27
- public_message = I18n.t('booth.login_timeout', lifespan_minutes: (storage.lifespan / 60))
28
- Tron.failure :stale_session, step: :enter_username,
29
- public_message:
30
- end
31
-
32
- def do_find_credential
33
- @credential = storage.password_authenticated_credential
34
- return Tron.success :found_credential if @credential
35
-
36
- Tron.failure :missing_credential
37
- end
38
-
39
- def do_check_credential_mode
40
- return Tron.success :credential_is_otp if @credential.mode_username_password_and_otp?
41
-
42
- Tron.failure :credential_is_not_otp
43
- end
44
-
45
- def do_check_otp
46
- checking = ::Booth::Credentials::OtpAuthentication.call(
47
- credential: @credential,
48
- code: code_param,
49
- ip: request.ip,
50
- agent: request.agent
51
- )
52
- return checking if checking.failure
53
-
54
- storage.reset
55
- ::Booth::Sessions::CreateAndLogin.call(credential: @credential, request:)
56
- Tron.success :login_completed
57
- end
58
-
59
- def code_param
60
- params.require(:login).permit(:otp)[:otp]
61
- end
62
-
63
- def storage
64
- request.storage.login
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
@@ -1,70 +0,0 @@
1
- module Booth
2
- module Logins
3
- module Transitions
4
- module Create
5
- class VerifyPassword
6
- include ::Booth::Concerns::Transition
7
-
8
- def self.applicable?(params:)
9
- params.dig :login, :password
10
- end
11
-
12
- def call
13
- do_check_stale_session
14
- .on_success { do_find_credential }
15
- .on_success { do_check_password }
16
- end
17
-
18
- # Helpers
19
-
20
- def do_check_stale_session
21
- return Tron.success :session_not_stale unless storage.timed_out?
22
-
23
- public_message = I18n.t('booth.login_timeout', lifespan_minutes: (storage.lifespan / 60))
24
- Tron.failure :stale_session, step: :enter_username,
25
- public_message:
26
- end
27
-
28
- def do_find_credential
29
- @credential = storage.credential_for_username
30
- return Tron.success :found_credential if @credential
31
-
32
- Tron.failure :missing_credential
33
- end
34
-
35
- def do_check_password
36
- checking = ::Booth::Credentials::PasswordAuthentication.call(
37
- credential: @credential,
38
- password: password_param,
39
- ip: request.ip,
40
- agent: request.agent
41
- )
42
- return checking if checking.failure
43
-
44
- sudo.password!
45
-
46
- # TODO: Re-check with haveibeenpwned and flag `flagged_pwned_at` password as insecure.
47
-
48
- if @credential.mode_username_and_password?
49
- ::Booth::Sessions::CreateAndLogin.call(credential: @credential, request:)
50
- return Tron.success :login_completed, return_path: request.return_path
51
- end
52
-
53
- storage.password_authenticated_credential = @credential
54
- Tron.success :correct_password
55
- end
56
-
57
- def password_param
58
- params.require(:login).permit(:password)[:password]
59
- end
60
-
61
- def storage
62
- request.storage.login
63
- end
64
-
65
- delegate :sudo, to: :request
66
- end
67
- end
68
- end
69
- end
70
- end
@@ -1,20 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Logins
4
- module Transitions
5
- module New
6
- class ModeFirstTime
7
- include ::Booth::Concerns::Transition
8
- include ::Booth::Userland::Logins::Transitions::New::Fallible
9
-
10
- def call
11
- debug { 'This credential has not gone through onboarding yet.' }
12
- # storage.login.reset_credential_for_username
13
- fail_with :need_webauth, step: :needs_onboarding
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,24 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Logins
4
- module Transitions
5
- module New
6
- class ModeUsernamePasswordAndOtp
7
- include ::Booth::Concerns::Transition
8
- include ::Booth::Userland::Logins::Transitions::New::Fallible
9
-
10
- def call
11
- if storage.password_authenticated_credential
12
- debug { 'I have your username and your password, now I need your OTP' }
13
- fail_with :need_otp, step: :enter_otp
14
- else
15
- debug { 'I have your username but not your password, let alone your OTP' }
16
- fail_with :need_password_and_otp, step: :enter_password
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,24 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Logins
4
- module Transitions
5
- module New
6
- class ModeUsernamePasswordAndWebauth
7
- include ::Booth::Concerns::Transition
8
- include ::Booth::Userland::Logins::Transitions::New::Fallible
9
-
10
- def call
11
- if storage.password_authenticated_credential
12
- debug { 'I have your username and your password, now I need your Webauth' }
13
- fail_with :need_webauth, step: :enter_webauth
14
- else
15
- debug { 'I have your username but not your password, let alone your Webauth' }
16
- fail_with :need_password_and_webauth, step: :enter_password
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,58 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class ChooseMode
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- # `mode` sets to a specific mode and `reset` clears any mode.
13
- params.key?(:mode) || params.key?(:reset)
14
- end
15
-
16
- def call
17
- do_reset_password
18
- .on_success { do_reset_otp }
19
- .on_success { do_reset_webauth }
20
- .on_success { do_update_mode }
21
- end
22
-
23
- private
24
-
25
- def do_reset_password
26
- ::Booth::Userland::Onboardings::Transitions::Update::ResetPassword.call(onboarding:,
27
- request:)
28
- end
29
-
30
- def do_reset_otp
31
- ::Booth::Userland::Onboardings::Transitions::Update::ResetOtp.call(onboarding:,
32
- request:)
33
- end
34
-
35
- def do_reset_webauth
36
- ::Booth::Userland::Onboardings::Transitions::Update::ResetWebauth.call(onboarding:,
37
- request:)
38
- end
39
-
40
- def do_update_mode
41
- if onboarding.update mode: mode_param
42
- debug { "You chose the mode #{@onboarding.mode.inspect}" }
43
- return Tron.success :mode_chosen
44
- end
45
-
46
- debug { "Could not choose mode #{mode_param.inspect}: #{onboarding.errors.to_a.to_sentence}" }
47
- Tron.failure :mode_update_failed
48
- end
49
-
50
- def mode_param
51
- params[:mode] || 'first_time'
52
- end
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,41 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class ChoosePassword
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params.key?(:onboarding) && params[:onboarding].key?(:password)
13
- end
14
-
15
- def call
16
- do_update_password
17
- end
18
-
19
- private
20
-
21
- def do_update_password
22
- if onboarding.update password: password_param,
23
- password_chosen_at: Time.current
24
- debug { 'You chose a password' }
25
- return Tron.success :password_chosen
26
- end
27
-
28
- public_message = onboarding.errors.to_a.to_sentence
29
- debug { "Could not choose password: #{public_message}" }
30
- Tron.failure :password_update_failed, public_message:
31
- end
32
-
33
- def password_param
34
- params.require(:onboarding).permit(:password)[:password]
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,50 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class ChooseWebauthNickname
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params&.key?(:onboarding) && params[:onboarding]&.key?(:authenticator_nickname)
13
- end
14
-
15
- def call
16
- do_check_blank_nickname
17
- .on_success { do_update_webauth }
18
- end
19
-
20
- private
21
-
22
- def do_check_blank_nickname
23
- return Tron.success :nickname_is_present if nickname_param.present?
24
-
25
- onboarding.errors.add(:authenticator_nickname, :blank)
26
- public_message = onboarding.errors.to_a.to_sentence
27
- debug { 'The nickname was blank' }
28
- Tron.failure :nickname_is_blank, public_message:
29
- end
30
-
31
- def do_update_webauth
32
- if onboarding.update authenticator_nickname: nickname_param
33
- debug { 'The nickname successfully changed' }
34
- Tron.success :webauth_nickname_saved
35
- else
36
- public_message = onboarding.errors.to_a.to_sentence
37
- debug { "The nickname could not be updated: #{public_message}" }
38
- Tron.failure :webauth_nickname_failed, public_message:
39
- end
40
- end
41
-
42
- def nickname_param
43
- params.require(:onboarding).permit(:authenticator_nickname)[:authenticator_nickname]
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,58 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class ConfirmOtp
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params.key?(:onboarding) && params[:onboarding].key?(:otp_confirmation)
13
- end
14
-
15
- def call
16
- do_check_otp_code_syntax
17
- .on_success { do_authenticate_otp }
18
- .on_success { do_update_confirmation }
19
- end
20
-
21
- private
22
-
23
- def do_check_otp_code_syntax
24
- check = ::Booth::Syntaxes::Otp.call(code_param)
25
- return check if check.failure?
26
-
27
- @normalized_otp_code = check.normalized_otp
28
- check
29
- end
30
-
31
- def do_authenticate_otp
32
- return Tron.success :correct_code if @onboarding.authenticate_otp(@normalized_otp_code)
33
-
34
- @onboarding.errors.add :base, I18n.t('booth.wrong_otp')
35
- public_message = onboarding.errors.to_a.to_sentence
36
- debug { "Could not confirm otp: #{public_message}" }
37
- Tron.failure :otp_did_not_match, public_message:
38
- end
39
-
40
- def do_update_confirmation
41
- if @onboarding.update(otp_confirmed_at: Time.current)
42
- debug { 'You confirmed your otp' }
43
- return Tron.success :otp_confirmed
44
- end
45
-
46
- debug { "The confirmation was correct but the update failed: #{onboarding.errors.to_a.to_sentence}" }
47
- Tron.failure :correct_otp_confirmation_failed
48
- end
49
-
50
- def code_param
51
- params.require(:onboarding).permit(:otp_confirmation)[:otp_confirmation]
52
- end
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,49 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class ConfirmPassword
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params.key?(:onboarding) && params[:onboarding].key?(:password_confirmation)
13
- end
14
-
15
- def call
16
- do_authenticate_password
17
- .on_success { do_update_confirmation }
18
- end
19
-
20
- private
21
-
22
- def do_authenticate_password
23
- return Tron.success :password_matches if @onboarding.authenticate_password(password)
24
-
25
- @onboarding.errors.add :password_confirmation, :confirmation
26
- public_message = onboarding.errors.to_a.to_sentence
27
- debug { "Could not confirm password: #{public_message}" }
28
- Tron.failure :password_did_not_match, public_message:
29
- end
30
-
31
- def do_update_confirmation
32
- if @onboarding.update(password_confirmed_at: Time.current)
33
- debug { 'You confirmed your password' }
34
- return Tron.success :password_confirmed
35
- end
36
-
37
- debug { "The confirmation was correct but the update failed: #{onboarding.errors.to_a.to_sentence}" }
38
- Tron.failure :correct_password_confirmation_failed
39
- end
40
-
41
- def password
42
- params.require(:onboarding).permit(:password_confirmation)[:password_confirmation]
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,31 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class RegisterOtp
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params&.key?(:register_otp) && !params&.key?(:onboarding)
13
- end
14
-
15
- def call
16
- do_register
17
- end
18
-
19
- private
20
-
21
- def do_register
22
- return Tron.success :otp_secret_regenerated if onboarding.update(otp_registered_at: Time.current)
23
-
24
- Tron.failure :generating_otp_secret_failed
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,40 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class ResetOtp
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params.key?(:reset_otp)
13
- end
14
-
15
- def call
16
- do_regenerate_secret
17
- .on_success { do_reset_confirmation }
18
- end
19
-
20
- def do_regenerate_secret
21
- return Tron.success :secret_regenerated if onboarding.otp_regenerate_secret
22
-
23
- Tron.failure :secret_regeneration_failed
24
- end
25
-
26
- def do_reset_confirmation
27
- if onboarding.update(otp_registered_at: nil, otp_confirmed_at: nil)
28
- debug { 'The Onboarding otp was reset.' }
29
- return Tron.success :otp_reset
30
- end
31
-
32
- debug { "Could not reset otp: #{onboarding.errors.to_a.to_sentence}" }
33
- Tron.failure :otp_reset_failed
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,35 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class ResetPassword
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params.key?(:reset_password)
13
- end
14
-
15
- def call
16
- do_reset_password_confirmation
17
- end
18
-
19
- private
20
-
21
- def do_reset_password_confirmation
22
- if onboarding.update(password_chosen_at: nil, password_confirmed_at: nil)
23
- debug { 'The Onboarding password was reset.' }
24
- return Tron.success :password_reset
25
- end
26
-
27
- debug { "Could not reset password: #{onboarding.errors.to_a.to_sentence}" }
28
- Tron.failure :password_reset_failed
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,46 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class ResetWebauth
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params.key?(:reset_webauth)
13
- end
14
-
15
- def call
16
- do_clear_webauth
17
- end
18
-
19
- private
20
-
21
- def do_clear_webauth
22
- if onboarding.update(niled_attributes)
23
- debug { 'The Onboarding webauth was reset.' }
24
- return Tron.success :webauth_reset
25
- end
26
-
27
- debug { "Could not reset webauth: #{onboarding.errors.to_a.to_sentence}" }
28
- Tron.failure :webauth_reset_failed
29
- end
30
-
31
- def niled_attributes
32
- {
33
- webauthn_id: nil,
34
- authenticator_id: nil,
35
- authenticator_nickname: nil,
36
- authenticator_challenge: nil,
37
- authenticator_public_key: nil,
38
- authenticator_sign_count: nil
39
- }
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,40 +0,0 @@
1
- module Booth
2
- module Userland
3
- module Onboardings
4
- module Transitions
5
- module Update
6
- class WebauthAuthenticationInitiation
7
- include ::Booth::Concerns::Transition
8
-
9
- option :onboarding
10
-
11
- def self.applicable?(params:)
12
- params&.key?(:test_webauth) && !params&.key?(:onboarding)
13
- end
14
-
15
- def call
16
- do_challenge
17
- end
18
-
19
- private
20
-
21
- def do_challenge
22
- webauth = ::Booth::Webauth::OptionsForGet.call(
23
- allowed_device_ids: onboarding.authenticator_id,
24
- requires_user_verification: onboarding.requires_user_verification?
25
- )
26
-
27
- debug { "Remembering test challenge #{webauth.challenge.inspect}" }
28
-
29
- if onboarding.update authenticator_challenge: webauth.challenge
30
- Tron.success :test_challenge_created, public_json: webauth.as_json, http_status: :created
31
- else
32
- Tron.failure :storing_test_challenge_failed
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end