Deprecated: Function get_magic_quotes_gpc() is deprecated in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 99

Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 619

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1169

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176
8000 Recovery code support for webauthn by ericherscovich · Pull Request #3859 · rubygems/rubygems.org · GitHub
Nothing Special   »   [go: up one dir, main page]

Skip to content

Conversation

ericherscovich
Copy link
Contributor

What problem are you solving?

This PR allows recovery codes to be used with webauthn. If a user generates webauthn credentials after #3821 was merged, or has OTP enabled, they will have recovery codes which can be used. On both prompts, this functionality is now supported.

If a user has webauthn only enabled, and has recovery codes, this is what they will see:
Screenshot 2023-06-08 at 1 49 20 PM

Contributes to #3800

What approach did you choose and why?

There is a case where a webauthn user wouldn't have recovery codes. That is, if they had webauthn only enabled before #3821 was merged. So, there is protection in rendering, in order to not render the recovery code prompt if a user does not have these recovery codes. The recovery code field simply uses the existing OTP field.

@codecov
Copy link
codecov bot commented Jun 13, 2023

Codecov Report

Merging #3859 (42fe8ef) into master (bbb1af8) will decrease coverage by 0.01%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master    #3859      +/-   ##
==========================================
- Coverage   98.79%   98.79%   -0.01%     
==========================================
  Files         216      216              
  Lines        5404     5394      -10     
==========================================
- Hits         5339     5329      -10     
  Misses         65       65              
Impacted Files Coverage Δ
app/controllers/email_confirmations_controller.rb 100.00% <100.00%> (ø)
app/controllers/multifactor_auths_controller.rb 100.00% <100.00%> (ø)
app/controllers/passwords_controller.rb 100.00% <100.00%> (ø)
app/controllers/sessions_controller.rb 100.00% <100.00%> (ø)
app/models/concerns/user_webauthn_methods.rb 100.00% <100.00%> (ø)

Copy link
Member
@jenshenny jenshenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did some initial testing with the sign in flow and it works well! I have some initial questions and suggestions

@user = find_user

if @user && (@user.mfa_enabled? || @user.webauthn_credentials.any?)
setup_webauthn_authentication(form_url: webauthn_create_session_path, session_options: { "user" => @user.id })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

session_options: { "user" => @user.id }

could we use session[:mfa_user] instead now in webauthn_create?

(Can punt this to later)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think we can rely on session[:mfa_user] instead. But will save that for a separate issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a difference between mfa_prompt and this view? We could possibly consolidate the two views into one if there aren't any differences.

(Can punt this to later)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No there isn't. The only difference is prompt has a hard-coded callback, whereas mfa_prompt requires you to pass one through. I chatted about this with Betty, and we think we should switch to using just mfa_prompt so we don't have two of essentially the same file. But, that change is outside the scope of this PR.

<% if @user.totp_enabled? %>
<%= label_tag :otp, t('multifactor_auths.otp_or_recovery'), class: 'form__label' %>
<%= text_field_tag :otp, '', class: 'form__input', autofocus: true, autocomplete: :off %>
<% elsif @user.webauthn_only_with_recovery? %>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hot take: could we render this even if there aren't any recovery codes? A user could have generated codes and used them all... I don't think we should be expose any details of if the user has any codes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chatted about this with Jenny, and we decided to keep it the way it is - specifically to not show the recovery code prompt if the user doesn't have any. The justification for this, is that it takes up half of the page, and would do so while serving the user no functionality. So if a user doesn't have recovery codes, it would just be confusing to have half the page prompting them for it. The simplest design philosophy for users is not showing them stuff that is irrelevant to them, which is what we are doing.

<%= label_tag :otp, t('multifactor_auths.otp_or_recovery'), class: 'form__label' %>
<%= text_field_tag :otp, '', class: 'form__input', autofocus: true, autocomplete: :off %>
<% elsif @user.webauthn_only_with_recovery? %>
<%= label_tag :otp, t('multifactor_auths.recovery_code'), class: 'form__label' %>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: do we need the label tag here? It looks a bit redundant that the heading is also Recovery code
Screenshot 2023-06-14 at 10 45 22 AM

Copy link
Contributor Author
7440

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe for accessibility it's better to keep the label tag there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the label will still be associated with the text field even if hidden?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Herm ... I agree with Jenny. It does feel redundant 😅 . I think Eric & I had noted this while prototyping too. Staring at this longer, I'm inclined to advise dropping the label as well.

From an a11y standpoint, we can remove the label and add the aria-label attribute on the input (e.g. aria-label="Recovery code").

Copy link
Member
@jenshenny jenshenny Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added aria label! 93a7934

@ericherscovich ericherscovich force-pushed the eric/authn-recovery-codes branch from 8df7e38 to e439db9 Compare June 15, 2023 19:38
Copy link
Member
@jenshenny jenshenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested these flows with 1. no MFA, 2. webauthn no recovery, 3. only totp, 4. totp and webauthn, 5. webauthn with recovery.

  • signin
  • password reset
  • email confirmations
  • update mfa level

Can you squash the commits since it's close to merge?

@ericherscovich ericherscovich force-pushed the eric/authn-recovery-codes branch 3 times, most recently from 441d039 to 426a15b Compare June 22, 2023 18:17
Copy link
Member
@jenshenny jenshenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Tested all the flows and they work as expected. As Eric is out for most of this week, I'll address the remaining comments.

Copy link
Contributor
@simi simi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems there are few last bits needed to be tweaked on UI and wording side. Feel free to merge once you're happy @jenshenny @bettymakes.

@jenshenny jenshenny force-pushed the eric/authn-recovery-codes branch from 426a15b to 9537bd5 Compare June 26, 2023 23:29
@jenshenny jenshenny force-pushed the eric/authn-recovery-codes branch from 9537bd5 to 42fe8ef Compare June 26, 2023 23:40
@jenshenny jenshenny merged commit 74e7294 into rubygems:master Jun 26, 2023
@rubygems-org-shipit rubygems-org-shipit bot temporarily deployed to staging June 27, 2023 10:48 Inactive
@rubygems-org-shipit rubygems-org-shipit bot temporarily deployed to production June 27, 2023 17:11 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

0