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,15 +0,0 @@
1
- // This file was generated using a rake task
2
-
3
- //= link booth/browsers/chrome.svg
4
- //= link booth/browsers/edge.svg
5
- //= link booth/browsers/firefox.svg
6
- //= link booth/browsers/opera.svg
7
- //= link booth/browsers/safari.svg
8
- //= link booth/browsers/internet_explorer.svg
9
- //= link booth/browsers/unknown.svg
10
-
11
- //= link booth/platforms/android.svg
12
- //= link booth/platforms/apple.svg
13
- //= link booth/platforms/linux.svg
14
- //= link booth/platforms/windows.svg
15
- //= link booth/platforms/unknown.svg
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 -2 313 305"><defs><radialGradient xlink:href="#a" id="e" cx="173.96" cy="149.58" r="161.64" gradientTransform="matrix(0 1 -.8 0 293.62 -24.38)"><stop offset=".55" stop-color="#99fbff"/><stop offset=".61" stop-color="#92f6fe"/><stop offset=".7" stop-color="#80e7fa"/><stop offset=".8" stop-color="#62cff3"/><stop offset=".91" stop-color="#38adea"/><stop offset="1" stop-color="#0f8ce1"/></radialGradient><radialGradient xlink:href="#a" id="o" cx="62.968" cy="220.74" r="48.326" gradientTransform="matrix(3.4175 -2.0751 1.0888 1.7931 -389.83 -12.808)"><stop offset="0" stop-color="#fcf69f" stop-opacity="0"/><stop offset=".5" stop-color="#fcf69f" stop-opacity="0"/><stop offset="1" stop-color="#fcf69f" stop-opacity=".77"/></radialGradient><radialGradient xlink:href="#a" id="k" cx="100.32" cy="148.8" r="138.81" gradientTransform="matrix(.9302 -.83744 .32785 .36414 17.035 155.03)"><stop offset="0" stop-color="#f8b633" stop-opacity="0"/><stop offset=".83" stop-color="#fabc3f" stop-opacity="0"/><stop offset=".92" stop-color="#fdf8c3" stop-opacity=".98"/><stop offset=".96" stop-color="#fdf8c3" stop-opacity=".98"/><stop offset="1" stop-color="#fdf6b0" stop-opacity=".98"/></radialGradient><radialGradient xlink:href="#a" id="p" cx="138.27" cy="245.02" r="84.078" gradientTransform="matrix(1.3738 -1.4223 .47637 .46011 -146.79 229.99)"><stop offset="0" stop-color="#3d3a04" stop-opacity="0"/><stop offset=".924" stop-color="#454205" stop-opacity="0"/><stop offset="1" stop-color="#4e4a06" stop-opacity=".27"/></radialGradient><radialGradient xlink:href="#a" id="n" cx="92.079" cy="70.362" r="64.365" gradientTransform="matrix(1.82 .03223 -.03882 2.1923 -73.94 -85.114)"><stop offset="0" stop-color="#a0f5fc"/><stop offset="1" stop-color="#a0f3fc" stop-opacity="0"/></radialGradient><radialGradient xlink:href="#a" id="b" cx="136.1" cy="93.932" r="157.94" gradientTransform="matrix(.67825 -.45732 .55906 .82913 -15.248 63.774)"><stop offset="0" stop-color="#fcfcfc"/><stop offset=".681" stop-color="#fff"/><stop offset="1"/></radialGradient><radialGradient xlink:href="#a" id="h" cx="160.08" cy="156.25" r="138.81" gradientTransform="matrix(1.0704 -1.0538 .44083 .44775 -75.068 245.37)"><stop offset="0" stop-opacity="0"/><stop offset=".82" stop-color="#fdbb36" stop-opacity=".94"/><stop offset=".89" stop-color="#fbd44d" stop-opacity=".92"/><stop offset="1" stop-color="#fbcf39" stop-opacity=".88"/></radialGradient><radialGradient xlink:href="#a" id="i" cx="180.99" cy="167.23" r="138.81" gradientTransform="matrix(1.1348 -1.1322 .52964 .53081 -114.38 274.24)"><stop offset="0" stop-color="#f7ab32" stop-opacity="0"/><stop offset=".76" stop-color="#f7b535" stop-opacity=".92"/><stop offset=".84" stop-color="#f7b33f" stop-opacity=".96"/><stop offset=".93" stop-color="#f7e232"/><stop offset="1" stop-color="#f5ec80"/></radialGradient><radialGradient xlink:href="#a" id="m" cx="-2.5" cy="136.62" r="138.81" gradientTransform="matrix(.85784 -.85837 .28831 .28814 123.22 99.466)"><stop offset="0"/><stop offset=".94" stop-color="#fee259" stop-opacity=".5"/><stop offset="1" stop-color="#fff045" stop-opacity="0"/></radialGradient><radialGradient xlink:href="#a" id="c" cx="222.81" cy="221.24" r="156.35" gradientTransform="matrix(1.1049 -.66263 .37599 .62704 -95.652 198.56)"><stop offset="0"/><stop offset=".672"/><stop offset="1" stop-color="#fff"/></radialGradient><radialGradient xlink:href="#a" id="d" cx="101.97" cy="109.66" r="158" gradientTransform="matrix(.84189 -.58292 .28064 .4054 -11.053 122.85)"><stop offset="0" stop-color="#fff"/><stop offset=".69" stop-color="#fff"/><stop offset="1"/></radialGradient><mask id="l" maskUnits="userSpaceOnUse"><path fill="url(#b)" fill-rule="evenodd" stroke="#000" d="M.5-12.389h314.89v314.89H.5z"/></mask><mask id="f" maskUnits="userSpaceOnUse"><path fill="url(#c)" fill-rule="evenodd" d="M0-.374h312.71v302.26H0z"/></mask><mask id="j" maskUnits="userSpaceOnUse"><path fill="url(#d)" fill-rule="evenodd" stroke="#000" d="M.5-12.5h315v315H.5z"/></mask><linearGradient id="a" gradientUnits="userSpaceOnUse"/><path id="g" d="M108.75 260.53c-27.7 14.08-50 17.08-61.5 5.6-25-25 7.8-94.8 74.3-161.32S257.86 5.5 282.9 30.52c10.13 10.13 9 28.72-1.14 52q2.1 3.34 4 6.82c13.47-31.15 14.25-57.5-1.46-73.2-28.75-29.12-126.4 4.2-186.67 67.3S-.16 242.8 27.74 271.4c18.14 18.14 51.2 13.87 89.56-6.43q-4.38-2.05-8.55-4.43z"/></defs><path fill="url(#e)" stroke="#1b62a2" stroke-opacity=".878" stroke-width="4.913" d="M226.06 194.2c-10.23 17.2-29.93 28.53-51.3 28.53a56.08 56.08 0 0 1-56.28-56v-2.2H298a125.85 125.85 0 0 0 .77-13.88A124.27 124.27 0 0 0 174.44 25.82c-69.08 0-125.9 55.76-125.9 124.84 0 22.48 6.47 43.56 16.7 61.75 9.15 16.27 21.16 30.23 36.5 40.8 20.22 13.92 45.5 21.58 72 21.58 27.95 0 54.67-8.54 75.7-23.84A122 122 0 0 0 292 194.19zM176.56 79c30.52 0 53.3 24.3 54.13 54.6H118.2c.97-30.3 27.8-54.6 58.37-54.6z" paint-order="stroke markers fill"/><g mask="url(#f)"><use xlink:href="#g" fill="url(#h)"/><path fill="url(#i)" d="M108.75 260.53c-27.7 14.08-50 17.08-61.5 5.6-25-25 7.8-94.8 74.3-161.32S257.86 5.5 282.9 30.52c10.13 10.13 9 28.72-1.14 52q2.1 3.34 4 6.82c13.47-31.15 14.25-57.5-1.46-73.2-28.75-29.12-126.4 4.2-186.67 67.3S-.16 242.8 27.74 271.4c18.14 18.14 51.2 13.87 89.56-6.43q-4.38-2.05-8.55-4.43z" mask="url(#j)" opacity=".93"/><path fill="url(#k)" d="M108.75 260.53c-27.7 14.08-50 17.08-61.5 5.6-25-25 7.8-94.8 74.3-161.32S257.86 5.5 282.9 30.52c10.13 10.13 9 28.72-1.14 52q2.1 3.34 4 6.82c13.47-31.15 14.25-57.5-1.46-73.2-28.75-29.12-126.4 4.2-186.67 67.3S-.16 242.8 27.74 271.4c18.14 18.14 51.2 13.87 89.56-6.43q-4.38-2.05-8.55-4.43z" mask="url(#l)" opacity=".835"/><use xlink:href="#g" fill="url(#m)"/></g><path fill="url(#n)" d="M174.44 27.82c-68.937 0-125.66 55.53-125.89 124.41 13.174-23.455 29.981-46.791 49.086-66.793 23.061-24.144 51.592-43.919 79.645-57.514l-2.836-.105z" transform="translate(0 -2)"/><path fill="url(#o)" d="M46.15 154.56c12.851-24.577 33.552-52.853 50.53-70.16-19.184 16.918-38.242 38.928-50 53.93C4.16 193.01-8.37 240.79 5.33 264.03c11.08 18.8 32.27 23.17 53 18.83-12.4-.08-22.86-3.75-30.6-11.48-18.48-18.97-8.2-67.73 18.4-116.82z" opacity=".877"/><path fill="url(#p)" d="M217.33 35.551c-28.801 13.432-62.699 38.165-95.781 71.258-29.291 29.3-52.032 59.233-66.188 85.697a131.825 131.825 0 0 0 4.354 10.953c6.442-25.294 32.58-54.181 64.28-92.234 1.748-2.1 3.675-5.125 5.817-7.215a59.603 59.603 0 0 1 14.154-13.086c29.88-18.073 54.304-40.563 79.551-52.885a124.255 124.255 0 0 0-6.187-2.488z" transform="translate(0 -2)"/></svg>
@@ -1,162 +0,0 @@
1
- /// <reference path='webauthn-json.ts' />
2
- //= require rails-ujs
3
- //= require @github/webauthn-json/dist/browser-global/webauthn-json.browser-global
4
- var Booth;
5
- (function (Booth) {
6
- function reloadSoon() {
7
- const seconds = Math.floor(Math.random() * 3) + 5; // 4,5,6 or 7 to avoid request bursts
8
- setTimeout(() => {
9
- console.debug('Reloading page...');
10
- window.location.reload();
11
- }, 1000 * seconds);
12
- }
13
- Booth.reloadSoon = reloadSoon;
14
- let Webauth;
15
- (function (Webauth) {
16
- class Registration {
17
- constructor(form, challengeData) {
18
- this.form = form;
19
- this.challengeData = challengeData;
20
- this.call();
21
- }
22
- call() {
23
- console.debug('WebAuthn Registration Ceremony - Initiation Phase Part 2 - START');
24
- webauthnJSON.create({ publicKey: this.challengeData }).then((responseData) => {
25
- console.debug(`WebAuthn Registration Ceremony - Initiation Phase Part 2 - SUCCESS - ${JSON.stringify(responseData)}`);
26
- new Verification(this.form, responseData);
27
- }).catch((error) => {
28
- console.error(`WebAuthn Registration Ceremony - Verification Phase - ERROR - ${error.name} - ${error.message}`);
29
- if (error.name == 'NotAllowedError') {
30
- // Every webauth registration form needs this localized error message.
31
- alert(this.form.dataset.boothIncompatibleDeviceMessage);
32
- }
33
- else {
34
- alert(error.message);
35
- }
36
- });
37
- }
38
- }
39
- Webauth.Registration = Registration;
40
- class Authentication {
41
- constructor(form, challengeData) {
42
- this.form = form;
43
- this.challengeData = challengeData;
44
- this.call();
45
- }
46
- call() {
47
- console.debug('WebAuthn Authentication Ceremony - Initiation Phase Part 2 - START');
48
- webauthnJSON.get({ publicKey: this.challengeData }).then((responseData) => {
49
- console.debug(`WebAuthn Authentication Ceremony - Initiation Phase Part 2 - SUCCESS - ${JSON.stringify(responseData)}`);
50
- new Verification(this.form, responseData);
51
- }).catch((error) => {
52
- console.error(`WebAuthn Authentication Ceremony - Verification Phase - ERROR - ${error.name} - ${error.message}`);
53
- if (error.name == 'NotAllowedError') {
54
- // Every webauth authentication form needs this localized error message.
55
- alert(this.form.dataset.boothUnknownDeviceMessage);
56
- }
57
- else {
58
- alert(error.message);
59
- }
60
- });
61
- }
62
- }
63
- Webauth.Authentication = Authentication;
64
- class Verification {
65
- constructor(form, webauth) {
66
- this.form = form;
67
- this.webauth = webauth;
68
- this.call();
69
- }
70
- call() {
71
- console.debug(`WebAuthn Ceremony - Verification Phase - START - ${this.formMethod} ${this.formUrl}`);
72
- const options = {
73
- body: JSON.stringify(this.webauth),
74
- method: this.formMethod,
75
- credentials: 'same-origin',
76
- // Rails should not redirect us anywhere when making API calls.
77
- // But in order to avoid mistakes let's be sure and never follow anywhere.
78
- redirect: 'manual',
79
- headers: {
80
- 'Content-type': 'application/json',
81
- 'Accept': 'application/json',
82
- 'X-CSRF-Token': this.csrfToken
83
- }
84
- };
85
- fetch(this.formUrl, options)
86
- .then((response) => {
87
- // Conventionally the server returns 201 on successful WebAuth verification.
88
- // That makes it easier to detect a mistake (most other server responses will usually return 200).
89
- if (response.status == 201) {
90
- console.debug(`WebAuthn Ceremony - Verification Phase - SUCCESS - ${response.statusText}`);
91
- console.info(`Reloading page with a GET request: ${window.location.href}`);
92
- window.location.href = window.location.href;
93
- }
94
- else {
95
- // TODO: Extract error message from JSON that the server sent.
96
- const message = `WebAuthn Ceremony - Verification Phase - ERROR - ${response.statusText} ${response.body}`;
97
- console.debug(message);
98
- alert(message);
99
- }
100
- }).catch((error) => {
101
- const message = 'Please check your Internet connection and try again later.';
102
- console.error(message);
103
- alert(message);
104
- });
105
- }
106
- get formUrl() {
107
- return this.form.action;
108
- }
109
- get formMethod() {
110
- return this.form.querySelector('input[name="_method"]')?.value?.toUpperCase() || 'POST';
111
- }
112
- get csrfToken() {
113
- return document.querySelector('meta[name="csrf-token"]')?.content;
114
- }
115
- }
116
- Webauth.Verification = Verification;
117
- })(Webauth = Booth.Webauth || (Booth.Webauth = {}));
118
- })(Booth || (Booth = {}));
119
- // --------------
120
- // Initialization
121
- // --------------
122
- document.addEventListener('DOMContentLoaded', function () {
123
- document.querySelectorAll('.js-booth-webauth-registration').forEach((form) => {
124
- form.addEventListener('ajax:before', () => {
125
- console.debug('WebAuthn Registration Ceremony - Initiation Phase Part 1 - START');
126
- });
127
- form.addEventListener('ajax:success', (event) => {
128
- const [data, status, xhr] = event.detail;
129
- console.debug(`WebAuthn Registration Ceremony - Initiation Phase Part 1 - SUCCESS - ${JSON.stringify(data)}`);
130
- new Booth.Webauth.Registration(form, data);
131
- });
132
- form.addEventListener('ajax:error', (event) => {
133
- const [data, status, xhr] = event.detail;
134
- // TODO: Extract error message from JSON that the server sent.
135
- // I don't think we need to reload the page on the registration page.
136
- const message = `WebAuthn Registration Ceremony - Initiation Phase Part 1 - ERROR - ${xhr.responseText}`;
137
- console.error(message);
138
- alert(message);
139
- });
140
- });
141
- document.querySelectorAll('.js-booth-webauth-authentication').forEach((form) => {
142
- form.addEventListener('ajax:before', () => {
143
- console.debug('WebAuthn Authentication Ceremony - Initiation Phase Part 1 - START');
144
- });
145
- form.addEventListener('ajax:success', (event) => {
146
- const [data, status, xhr] = event.detail;
147
- console.debug(`WebAuthn Authentication Ceremony - Initiation Phase Part 1 - SUCCESS - ${JSON.stringify(data)}`);
148
- new Booth.Webauth.Authentication(form, data);
149
- });
150
- form.addEventListener('ajax:error', (event) => {
151
- const [data, status, xhr] = event.detail;
152
- // TODO: Extract error message from JSON that the server sent.
153
- // On the authentication page there are timeout restrictions, it would be a good idea to reload page.
154
- const message = `WebAuthn Authentication Ceremony - Initiation Phase Part 1 - ERROR - ${xhr.responseText}`;
155
- console.error(message);
156
- alert(message);
157
- });
158
- });
159
- if (document.querySelector('.js-booth-polling'))
160
- Booth.reloadSoon();
161
- });
162
- //# sourceMappingURL=all.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"all.js","sourceRoot":"","sources":["webauthn-json.ts","booth.ts"],"names":[],"mappings":"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"}
@@ -1,194 +0,0 @@
1
- /// <reference path='webauthn-json.ts' />
2
-
3
- //= require rails-ujs
4
- //= require @github/webauthn-json/dist/browser-global/webauthn-json.browser-global
5
-
6
- namespace Booth {
7
- export function reloadSoon() {
8
- const seconds = Math.floor(Math.random() * 3) + 5 // 4,5,6 or 7 to avoid request bursts
9
-
10
- setTimeout(() => {
11
- console.debug('Reloading page...')
12
- window.location.reload()
13
- }, 1000 * seconds)
14
- }
15
-
16
- export namespace Webauth {
17
- export class Registration {
18
- private form: HTMLFormElement
19
- private challengeData: any
20
-
21
- constructor(form: HTMLFormElement, challengeData: any) {
22
- this.form = form
23
- this.challengeData = challengeData
24
- this.call()
25
- }
26
-
27
- private call() {
28
- console.debug('WebAuthn Registration Ceremony - Initiation Phase Part 2 - START')
29
- webauthnJSON.create({ publicKey: this.challengeData }).then((responseData) => {
30
- console.debug(`WebAuthn Registration Ceremony - Initiation Phase Part 2 - SUCCESS - ${JSON.stringify(responseData)}`)
31
- new Verification(this.form, responseData)
32
-
33
- }).catch((error: DOMException) => {
34
- console.error(`WebAuthn Registration Ceremony - Verification Phase - ERROR - ${error.name} - ${error.message}`)
35
-
36
- if (error.name == 'NotAllowedError') {
37
- // Every webauth registration form needs this localized error message.
38
- alert(this.form.dataset.boothIncompatibleDeviceMessage)
39
- } else {
40
- alert(error.message)
41
- }
42
- })
43
- }
44
- }
45
-
46
- export class Authentication {
47
- private form: HTMLFormElement
48
- private challengeData: any
49
-
50
- constructor(form: HTMLFormElement, challengeData: any) {
51
- this.form = form
52
- this.challengeData = challengeData
53
- this.call()
54
- }
55
-
56
- private call() {
57
- console.debug('WebAuthn Authentication Ceremony - Initiation Phase Part 2 - START')
58
- webauthnJSON.get({ publicKey: this.challengeData }).then((responseData) => {
59
- console.debug(`WebAuthn Authentication Ceremony - Initiation Phase Part 2 - SUCCESS - ${JSON.stringify(responseData)}`)
60
- new Verification(this.form, responseData)
61
-
62
- }).catch((error) => {
63
- console.error(`WebAuthn Authentication Ceremony - Verification Phase - ERROR - ${error.name} - ${error.message}`)
64
-
65
- if (error.name == 'NotAllowedError') {
66
- // Every webauth authentication form needs this localized error message.
67
- alert(this.form.dataset.boothUnknownDeviceMessage)
68
- } else {
69
- alert(error.message)
70
- }
71
- })
72
- }
73
- }
74
-
75
- export class Verification {
76
- private form: HTMLFormElement
77
- private webauth: any
78
-
79
- public constructor(form: HTMLFormElement, webauth: any) {
80
- this.form = form
81
- this.webauth = webauth
82
- this.call()
83
- }
84
-
85
- private call() {
86
- console.debug(`WebAuthn Ceremony - Verification Phase - START - ${this.formMethod} ${this.formUrl}`)
87
-
88
- const options: RequestInit = {
89
- body: JSON.stringify(this.webauth),
90
- method: this.formMethod,
91
- credentials: 'same-origin',
92
- // Rails should not redirect us anywhere when making API calls.
93
- // But in order to avoid mistakes let's be sure and never follow anywhere.
94
- redirect: 'manual',
95
- headers: {
96
- 'Content-type': 'application/json',
97
- 'Accept': 'application/json',
98
- 'X-CSRF-Token': this.csrfToken
99
- }
100
- }
101
-
102
- fetch(this.formUrl, options)
103
- .then((response) => {
104
-
105
- // Conventionally the server returns 201 on successful WebAuth verification.
106
- // That makes it easier to detect a mistake (most other server responses will usually return 200).
107
- if (response.status == 201) {
108
- console.debug(`WebAuthn Ceremony - Verification Phase - SUCCESS - ${response.statusText}`)
109
- console.info(`Reloading page with a GET request: ${window.location.href}`)
110
- window.location.href = window.location.href
111
-
112
- } else {
113
- // TODO: Extract error message from JSON that the server sent.
114
- const message = `WebAuthn Ceremony - Verification Phase - ERROR - ${response.statusText} ${response.body}`
115
- console.debug(message)
116
- alert(message)
117
- }
118
-
119
- }).catch((error) => {
120
- const message = 'Please check your Internet connection and try again later.'
121
- console.error(message)
122
- alert(message)
123
- })
124
- }
125
-
126
- private get formUrl() {
127
- return this.form.action
128
- }
129
-
130
- private get formMethod() {
131
- return this.form.querySelector<HTMLInputElement>('input[name="_method"]')?.value?.toUpperCase() || 'POST'
132
- }
133
-
134
- private get csrfToken() {
135
- return document.querySelector<HTMLMetaElement>('meta[name="csrf-token"]')?.content
136
- }
137
- }
138
- }
139
- }
140
-
141
-
142
-
143
-
144
- // --------------
145
- // Initialization
146
- // --------------
147
-
148
- document.addEventListener('DOMContentLoaded', function() {
149
-
150
- document.querySelectorAll('.js-booth-webauth-registration').forEach((form: HTMLFormElement) => {
151
- form.addEventListener('ajax:before', () => {
152
- console.debug('WebAuthn Registration Ceremony - Initiation Phase Part 1 - START')
153
- })
154
-
155
- form.addEventListener('ajax:success', (event: CustomEvent) => {
156
- const [data, status, xhr] = event.detail
157
- console.debug(`WebAuthn Registration Ceremony - Initiation Phase Part 1 - SUCCESS - ${JSON.stringify(data)}`)
158
- new Booth.Webauth.Registration(form, data)
159
- })
160
-
161
- form.addEventListener('ajax:error', (event: CustomEvent) => {
162
- const [data, status, xhr] = event.detail
163
- // TODO: Extract error message from JSON that the server sent.
164
- // I don't think we need to reload the page on the registration page.
165
- const message = `WebAuthn Registration Ceremony - Initiation Phase Part 1 - ERROR - ${xhr.responseText}`
166
- console.error(message)
167
- alert(message)
168
- })
169
- })
170
-
171
- document.querySelectorAll('.js-booth-webauth-authentication').forEach((form: HTMLFormElement) => {
172
- form.addEventListener('ajax:before', () => {
173
- console.debug('WebAuthn Authentication Ceremony - Initiation Phase Part 1 - START')
174
- })
175
-
176
- form.addEventListener('ajax:success', (event: CustomEvent) => {
177
- const [data, status, xhr] = event.detail
178
- console.debug(`WebAuthn Authentication Ceremony - Initiation Phase Part 1 - SUCCESS - ${JSON.stringify(data)}`)
179
- new Booth.Webauth.Authentication(form, data)
180
- })
181
-
182
- form.addEventListener('ajax:error', (event: CustomEvent) => {
183
- const [data, status, xhr] = event.detail
184
- // TODO: Extract error message from JSON that the server sent.
185
- // On the authentication page there are timeout restrictions, it would be a good idea to reload page.
186
- const message = `WebAuthn Authentication Ceremony - Initiation Phase Part 1 - ERROR - ${xhr.responseText}`
187
- console.error(message)
188
- alert(message)
189
- })
190
- })
191
-
192
- if (document.querySelector('.js-booth-polling')) Booth.reloadSoon()
193
-
194
- })
@@ -1,99 +0,0 @@
1
- type Base64urlString = string;
2
- type SchemaLeaf = "copy" | "convert";
3
- interface SchemaObject {
4
- [property: string]: {
5
- required: boolean;
6
- schema: Schema;
7
- };
8
- }
9
- type SchemaArray = [SchemaObject] | [SchemaLeaf];
10
- type Schema = SchemaLeaf | SchemaArray | SchemaObject;
11
- interface CredPropsAuthenticationExtensionsClientOutputsJSON {
12
- rk: boolean;
13
- }
14
- interface PublicKeyCredentialDescriptorJSON {
15
- type: PublicKeyCredentialType;
16
- id: Base64urlString;
17
- transports?: AuthenticatorTransport[];
18
- }
19
- interface SimpleWebAuthnExtensionsJSON {
20
- appid?: string;
21
- appidExclude?: string;
22
- credProps?: boolean;
23
- }
24
- interface SimpleClientExtensionResultsJSON {
25
- appid?: boolean;
26
- appidExclude?: boolean;
27
- credProps?: CredPropsAuthenticationExtensionsClientOutputsJSON;
28
- }
29
- interface PublicKeyCredentialUserEntityJSON extends PublicKeyCredentialEntity {
30
- displayName: string;
31
- id: Base64urlString;
32
- }
33
- declare interface AuthenticatorSelectionCriteriaJSON extends AuthenticatorSelectionCriteria {
34
- residentKey?: ResidentKeyRequirement;
35
- }
36
- interface PublicKeyCredentialCreationOptionsJSON {
37
- rp: PublicKeyCredentialRpEntity;
38
- user: PublicKeyCredentialUserEntityJSON;
39
- challenge: Base64urlString;
40
- pubKeyCredParams: PublicKeyCredentialParameters[];
41
- timeout?: number;
42
- excludeCredentials?: PublicKeyCredentialDescriptorJSON[];
43
- authenticatorSelection?: AuthenticatorSelectionCriteriaJSON;
44
- attestation?: AttestationConveyancePreference;
45
- extensions?: SimpleWebAuthnExtensionsJSON;
46
- }
47
- declare interface CredentialCreationOptionsJSON {
48
- publicKey: PublicKeyCredentialCreationOptionsJSON;
49
- signal?: AbortSignal;
50
- }
51
- interface AuthenticatorAttestationResponseJSON {
52
- clientDataJSON: Base64urlString;
53
- attestationObject: Base64urlString;
54
- }
55
- declare interface PublicKeyCredentialWithAttestationJSON {
56
- id: string;
57
- type: PublicKeyCredentialType;
58
- rawId: Base64urlString;
59
- response: AuthenticatorAttestationResponseJSON;
60
- clientExtensionResults: SimpleClientExtensionResultsJSON;
61
- }
62
- interface PublicKeyCredentialRequestOptionsJSON {
63
- challenge: Base64urlString;
64
- timeout?: number;
65
- rpId?: string;
66
- allowCredentials?: PublicKeyCredentialDescriptorJSON[];
67
- userVerification?: UserVerificationRequirement;
68
- extensions?: SimpleWebAuthnExtensionsJSON;
69
- }
70
- declare interface CredentialRequestOptionsJSON {
71
- mediation?: CredentialMediationRequirement;
72
- publicKey?: PublicKeyCredentialRequestOptionsJSON;
73
- signal?: AbortSignal;
74
- }
75
- interface AuthenticatorAssertionResponseJSON {
76
- clientDataJSON: Base64urlString;
77
- authenticatorData: Base64urlString;
78
- signature: Base64urlString;
79
- userHandle: Base64urlString | null;
80
- }
81
- declare interface PublicKeyCredentialWithAssertionJSON {
82
- type: PublicKeyCredentialType;
83
- id: string;
84
- rawId: Base64urlString;
85
- response: AuthenticatorAssertionResponseJSON;
86
- clientExtensionResults: SimpleClientExtensionResultsJSON;
87
- }
88
- declare const schema: {
89
- [s: string]: Schema;
90
- };
91
- // export function create(requestJSON: CredentialCreationOptionsJSON): Promise<PublicKeyCredentialWithAttestationJSON>;
92
- // export function get(requestJSON: CredentialRequestOptionsJSON): Promise<PublicKeyCredentialWithAssertionJSON>;
93
- // export function supported(): boolean;
94
-
95
- declare class webauthnJSON {
96
- static create(requestJSON: CredentialCreationOptionsJSON): Promise<PublicKeyCredentialWithAttestationJSON>;
97
- static get(requestJSON: CredentialRequestOptionsJSON): Promise<PublicKeyCredentialWithAssertionJSON>;
98
- static supported(): boolean;
99
- }
@@ -1,70 +0,0 @@
1
- module Booth
2
- module Adminland
3
- module Recoveries
4
- # When sending out username recovery emails,
5
- # this class helps to keep the sending mechanism idempodent.
6
- class Consume
7
- include ::Booth::MethodObject
8
- include ::Booth::Logging
9
-
10
- option :recovery_id
11
- option :credential_id
12
-
13
- def call
14
- do_find_recovery
15
- .on_success { do_find_credential }
16
- .on_success { do_check_eligibility }
17
- .on_success { do_consume }
18
- end
19
-
20
- private
21
-
22
- def do_find_recovery
23
- debug { "Looking for Recovery with ID #{recovery_id.inspect}" }
24
- @recovery = ::Booth::Models::Recovery.find_by(id: recovery_id)
25
-
26
- if @recovery
27
- debug { 'Recovery was found' }
28
- return Tron.success :recovery_exists
29
- end
30
-
31
- debug { 'Did not find Recovery' }
32
- Tron.failure :recovery_not_found, provided_id: recovery_id.inspect
33
- end
34
-
35
- def do_find_credential
36
- debug { "Looking for Credential with ID #{credential_id.inspect}" }
37
- @credential = ::Booth::Models::Credential.find_by(id: credential_id)
38
-
39
- if @credential
40
- debug { 'Credential was found' }
41
- return Tron.success :credential_exists
42
- end
43
-
44
- debug { 'Did not find Credential' }
45
- Tron.failure :credential_not_found, provided_id: credential_id.inspect
46
- end
47
-
48
- def do_check_eligibility
49
- return Tron.failure :already_consumed if @recovery.consumed?
50
-
51
- return Tron.failure :already_revoked if @recovery.revoked?
52
-
53
- Tron.success :can_be_consumed
54
- end
55
-
56
- def do_consume
57
- @recovery.transaction do
58
- @recovery.update! consumed_at: Time.current
59
-
60
- @recovery.other_recoveries_with_this_scope_and_email
61
- .update_all revoked_at: Time.current # rubocop:disable Rails/SkipsModelValidations
62
- end
63
-
64
- Tron.success :recovery_consumed, email: @recovery.email,
65
- username: @credential.username
66
- end
67
- end
68
- end
69
- end
70
- end
@@ -1,22 +0,0 @@
1
- module Booth
2
- module Audits
3
- module Register
4
- class AddedOtp
5
- include ::Booth::MethodObject
6
-
7
- option :credential
8
- option :ip
9
- option :agent
10
-
11
- def call
12
- ::Booth::Models::Audit.create! credential: credential,
13
- ip: ip,
14
- agent: agent,
15
- event: :added_otp
16
-
17
- nil
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- module Booth
2
- module Audits
3
- module Register
4
- class ChangedOtp
5
- include ::Booth::MethodObject
6
-
7
- option :credential
8
- option :ip
9
- option :agent
10
-
11
- def call
12
- ::Booth::Models::Audit.create! credential: credential,
13
- ip: ip,
14
- agent: agent,
15
- event: :changed_otp
16
-
17
- nil
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,42 +0,0 @@
1
- module Booth
2
- module Audits
3
- module Register
4
- class CorrectOtp
5
- include ::Booth::MethodObject
6
- include ::Booth::Logging
7
-
8
- option :credential
9
- option :ip
10
- option :agent
11
-
12
- def call
13
- ::Booth::Models::Audit.transaction do
14
- register_attempt!
15
- clear_failed_attempts!
16
- end
17
-
18
- nil
19
- end
20
-
21
- private
22
-
23
- def register_attempt!
24
- debug { "Auditing correct OTP for credential `#{credential.id}` and IP `#{ip}`" }
25
-
26
- ::Booth::Models::Audit.create! credential:,
27
- ip:,
28
- agent:,
29
- event: :entered_correct_password
30
- end
31
-
32
- def clear_failed_attempts!
33
- debug { "Redeeming all failed OTP attempts for credential `#{credential.id}`" }
34
-
35
- ::Booth::Models::Audit.where(credential:)
36
- .where(event: :entered_wrong_otp)
37
- .update_all(deleted_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
38
- end
39
- end
40
- end
41
- end
42
- end