-
Notifications
You must be signed in to change notification settings - Fork 50
[Login] Backup Codes #10434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
rluodev
wants to merge
99
commits into
main
Choose a base branch
from
rluodev/6707-login-create-back-up-codes
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+459
−4
Open
[Login] Backup Codes #10434
Changes from all commits
Commits
Show all changes
99 commits
Select commit
Hold shift + click to select a range
268ef86
cryptographically secure backup code generation
rluodev cad6cc8
create used scope and make sure that variable scope is limited to nee…
rluodev 08e9cb9
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 89637c9
add backup code deleted_at column
rluodev 06f55a7
annotate
rluodev ae8207b
allow choosing backup code as a login option
rluodev c49175d
fix class name
rluodev 527ddc3
add backup_code authentication factor
rluodev f3b93c6
allow 1fa even if 2fa if backup code used
rluodev cabcf72
use greater than or equal to ensure that backup code can be used at a…
rluodev 6410b07
allow redeeming backup code
rluodev c836d47
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 960938b
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 1a30972
Update app/mailers/user/backup_code_mailer.rb
rluodev 59b3150
Update app/models/login.rb
rluodev 69e3613
Apply suggestions from code review
rluodev d38f4fa
remove acts_as_paranoid
rluodev 067e3b2
create class hash gen method and use it
rluodev e7fd663
add code_used mailer
rluodev eacf338
change hash name and add unique index
rluodev 25a0c72
schema changes
rluodev 4ba9044
use new field name
rluodev 2b1eb79
add migrations
rluodev ff77265
bang methods
rluodev 41af4b5
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 89b6fc2
resolve merge conflict
rluodev fe14484
remove extra end statement
rluodev f3a22fd
add user controller methods, routes, and policy
rluodev c7526f3
rename few codes left mailer
rluodev d5c47f5
change invalidate_backup_code logic
rluodev ca44052
change mailer name used
rluodev 5ed994b
add bottom margin
rluodev d9b3ce5
make sure we check if backup codes are available on normal login code…
rluodev 3d3ecd1
add the actual mailers
rluodev 43d59c2
add ability to generate and disable backup codes in security settings
rluodev 2b8d792
add turbo frame partial
rluodev ffd1131
lint
rluodev 7038864
undo irrelevant schema changes
rluodev 8ce3fe2
one last schema fix
rluodev 04e3aa4
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
garyhtou 669a58e
Update edit_security.html.erb
rluodev 1df7c5d
Update app/views/users/generate_backup_codes.html.erb
rluodev b8899c3
apply sam's copy and css edits
rluodev 8867574
use mail_to helper
rluodev 0595796
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev d00c70c
the great rename
rluodev 21b539f
mailer rename
rluodev 506db33
Update app/views/users/generate_backup_codes.html.erb
rluodev c3e261c
slight copy edit
rluodev d4ed35e
add mailer preview
rluodev cb978df
add newline
rluodev 37708d7
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 63e4c5b
sentence case
rluodev 193fcad
rename new code generated mailer and remove redundant mailer and edit…
rluodev 89fd638
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev f00eee3
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 04aa1cc
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev c4fda79
Disallow admins to generate and active backup codes
garyhtou ba9652a
use `active_backup_codes` selector
rluodev e8496a8
change mailer order and use `active_backup_codes` selector
rluodev 161f59d
Remove unused mailer view
garyhtou 587170f
use `active_backup_codes` selector in `users_controller.rb`
rluodev 1713510
Apply suggestions from code review
rluodev c613776
Update app/views/user/backup_code_mailer/no_codes_remaining.html.erb
rluodev c194275
Update app/models/user.rb
rluodev 432854f
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 54a6ed7
fix rubocop
rluodev c982ec1
Update user.rb
rluodev 0f7e83a
Update app/controllers/users_controller.rb
rluodev 8069fd5
still require 2 methods of auth if backup code used
rluodev 2f97e3f
use transaction
rluodev 2e0b309
fix association
rluodev f7f1d6e
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 33a7f1f
code pairing changes
rluodev 864e4f9
add updated index
rluodev 56b0bc4
next instead of return
rluodev c5cd3c9
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 1096575
update logins_controller_spec.rb
rluodev 9d830b5
update (wrong path)
rluodev b39c061
Update user.rb
rluodev b7a9bf9
Update backup_code.rb
rluodev 12ff2cf
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev 4c7b316
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev caf4e87
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev b512f6b
get rid of redundant unique index
rluodev 516bef1
annotation
rluodev be272e8
remove duplicate mailers, change to using backup_codes.active scope, …
rluodev 35591a6
fail loudly instead of ignore error
rluodev 697d1ab
remove lines in mailer preview
rluodev 6fd8668
redirect with flash when user uses their last backup code
rluodev 0a66503
add newline for lint
rluodev ffff627
update spec to test for proper redirection if user uses last backup_code
rluodev b56f252
fix spec
rluodev 10608f4
annotation format change
rluodev a827333
fix flash color
rluodev 598aa63
move backup code activation to be in `user.rb` instead of `users_cont…
rluodev 6116411
Merge branch 'main' into rluodev/6707-login-create-back-up-codes
rluodev c434605
Update app/models/user.rb
rluodev 5b4e7fc
remove extra space in base mailer case
rluodev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -229,4 +229,6 @@ gem "irb" | |
|
||
gem "pstore" | ||
|
||
gem "bcrypt", "~> 3.1.7" | ||
|
||
gem "prosemirror_to_html" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,6 +138,12 @@ def complete | |
else | ||
return redirect_to totp_login_path(@login), flash: { error: "Invalid TOTP code, please try again." } | ||
end | ||
when "backup_code" | ||
if @user.redeem_backup_code!(params[:backup_code]) | ||
@login.update(authenticated_with_backup_code: true) | ||
else | ||
return redirect_to backup_code_login_path(@login), flash: { error: "Invalid backup code, please try again." } | ||
end | ||
end | ||
|
||
# Clear the flash - this prevents the error message showing up after an unsuccessful -> successful login | ||
|
@@ -149,6 +155,8 @@ def complete | |
@login.update(user_session: sign_in(user: @login.user, fingerprint_info:)) | ||
if @user.full_name.blank? || @user.phone_number.blank? | ||
redirect_to edit_user_path(@user.slug, return_to: params[:return_to]) | ||
elsif @login.authenticated_with_backup_code && @user.backup_codes.active.size == 0 | ||
redirect_to security_user_path(@user), flash: { warning: "You've just used your last backup code, and we recommend generating more." } | ||
else | ||
redirect_to(params[:return_to] || root_path) | ||
end | ||
|
@@ -207,6 +215,7 @@ def set_available_methods | |
@sms_available = @user&.phone_number_verified && [email protected]_with_sms | ||
@webauthn_available = @user&.webauthn_credentials&.any? && [email protected]_with_webauthn | ||
@totp_available = @user&.totp.present? && [email protected]_with_totp | ||
@backup_code_available = @user&.backup_codes_enabled? && [email protected]_with_backup_code | ||
end | ||
|
||
def set_return_to | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# frozen_string_literal: true | ||
|
||
class User | ||
class BackupCodeMailer < ApplicationMailer | ||
before_action :set_user | ||
|
||
default to: -> { @user.email_address_with_name } | ||
|
||
def new_codes_activated | ||
mail subject: "You've generated new backup codes for HCB" | ||
end | ||
|
||
def code_used | ||
subject = "You've used a backup code to login to HCB" | ||
case @user.backup_codes.active.size | ||
when 0 | ||
subject = "[Action Required] You've used all your backup codes for HCB" | ||
when 1..3 | ||
subject = "[Action Requested] You've almost used all your backup codes for HCB" | ||
end | ||
mail subject: subject | ||
end | ||
|
||
def backup_codes_disabled | ||
mail subject: "You've disabled your HCB backup codes" | ||
end | ||
|
||
private | ||
|
||
def set_user | ||
@user = User.find(params[:user_id]) | ||
end | ||
|
||
end | ||
|
||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# frozen_string_literal: true | ||
|
||
# == Schema Information | ||
# | ||
# Table name: user_backup_codes | ||
# | ||
# id :bigint not null, primary key | ||
# aasm_state :string default("previewed"), not null | ||
# code_digest :text not null | ||
# created_at :datetime not null | ||
# updated_at :datetime not null | ||
# user_id :bigint not null | ||
# | ||
# Indexes | ||
# | ||
# index_user_backup_codes_on_user_id (user_id) | ||
# | ||
# Foreign Keys | ||
# | ||
# fk_rails_... (user_id => users.id) | ||
# | ||
class User | ||
class BackupCode < ApplicationRecord | ||
has_paper_trail | ||
|
||
has_secure_password :code | ||
|
||
include AASM | ||
|
||
belongs_to :user | ||
|
||
validates :code_digest, presence: true | ||
|
||
aasm do | ||
state :previewed, initial: true | ||
state :active | ||
state :used | ||
state :discarded | ||
|
||
event :mark_active do | ||
transitions from: :previewed, to: :active | ||
end | ||
event :mark_used do | ||
transitions from: :active, to: :used | ||
|
||
after do | ||
User::BackupCodeMailer.with(user_id: user.id).code_used.deliver_now | ||
end | ||
end | ||
event :mark_discarded do | ||
transitions from: :active, to: :discarded | ||
end | ||
end | ||
|
||
end | ||
|
||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<% title "Enter backup code" %> | ||
<% content_for(:page_class) { "bg-snow" } %> | ||
|
||
<div class="flex flex-col flex-1 justify-center max-w-md w-full"> | ||
<%= render "header", label: "Sign in to HCB" do %> | ||
Backup code | ||
<% end %> | ||
<%= render "badge", user: @login.user %> | ||
<p> | ||
Please enter one of the backup codes you generated previously. | ||
</p> | ||
<%= form_tag complete_login_path(@login) do %> | ||
<%= text_field :backup_code, "", placeholder: "Enter your backup code", name: "backup_code", class: "!max-w-full w-max", required: true, autofocus: true %> | ||
<%= hidden_field_tag :method, :backup_code %> | ||
<%= hidden_field_tag :fingerprint %> | ||
<%= hidden_field_tag :device_info %> | ||
<%= hidden_field_tag :os_info %> | ||
<%= hidden_field_tag :timezone %> | ||
<%= hidden_field_tag :return_to, @return_to if @return_to %> | ||
<div class="flex flex-row justify-between items-center mt-4 gap-2"> | ||
<% if @webauthn_available || @totp_available || @email_available || @sms_available %> | ||
<%= link_to "Sign in another way", choose_login_preference_login_path(@login, return_to: @return_to), class: "block mt-0 no-underline" %> | ||
<% end %> | ||
<button data-webauthn-auth-target="continueButton" type="submit" class="gap-2 btn"> | ||
Continue | ||
</button> | ||
</div> | ||
<% end %> | ||
<%= javascript_include_tag "https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js" %> | ||
<%= javascript_include_tag "fingerprint.js" %> | ||
</div> | ||
<%= render partial: "environment_banner" %> | ||
<%= render partial: "footer" %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
app/views/user/backup_code_mailer/backup_codes_disabled.html.erb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<p> | ||
Hey <%= @user.first_name %>, | ||
</p> | ||
|
||
<p> | ||
You've just disabled backup codes for HCB. If you had any unused backup codes, they were invalidated. | ||
</p> | ||
|
||
<p> | ||
If this was you, great! If you didn't do this, please <%= mail_to "[email protected]", "contact us", subject: "My backup codes were disabled and it was not me" %> immediately. | ||
</p> | ||
|
||
<p> | ||
Thanks,<br> | ||
The HCB Team | ||
</p> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<p> | ||
Hey <%= @user.first_name %>, | ||
</p> | ||
|
||
<p> | ||
You've just used one of your backup codes to login to | ||
<% if @user.backup_codes.active.size == 0 %> | ||
HCB and have none left. We strongly urge you to regenerate more codes at your earliest convenience in your <%= link_to "user settings", security_user_url(@user) %> to ensure you can always access your account. | ||
<% elsif @user.backup_codes.active.size <= 3 %> | ||
HCB and only have <%= @user.backup_codes.active.size %> left. We strongly urge you to regenerate more codes at your earliest convenience in your <%= link_to "user settings", security_user_url(@user) %> to ensure you can always access your account. | ||
<% else %> | ||
HCB. | ||
<% end %> | ||
</p> | ||
|
||
<p> | ||
If this was you, great! If you didn't do this, please <%= mail_to "[email protected]", "contact us", subject: "Unauthorized access with backup code" %> immediately. | ||
</p> | ||
|
||
<p> | ||
Thanks,<br> | ||
The HCB Team | ||
</p> | ||
rluodev marked this conversation as resolved.
Show resolved
Hide resolved
|
16 changes: 16 additions & 0 deletions
16
app/views/user/backup_code_mailer/new_codes_activated.html.erb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<p> | ||
Hey <%= @user.first_name %>, | ||
</p> | ||
|
||
<p> | ||
You've just generated backup codes for HCB and have 10 codes available. Please make sure to save the codes in a safe place in case you lose access to your account. HCB staff will never ask for your backup codes. | ||
</p> | ||
|
||
<p> | ||
If this was you, great! If you didn't do this, please <%= mail_to "[email protected]", "contact us", subject: "Unauthorized backup codes generated" %> immediately. | ||
</p> | ||
|
||
<p> | ||
Thanks,<br> | ||
The HCB Team | ||
</p> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.