Skip to content
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

Fix bug in credential email route with missing credential email #20145

Merged
merged 1 commit into from
Jan 9, 2025

Conversation

bosawt
Copy link
Contributor

@bosawt bosawt commented Jan 7, 2025

Summary

  • This PR fixes a bug in the credential email route that occurs when a user's UserVerification does not have a UserCredentialEmail

What areas of the site does it impact?

Interstitial Authentication

@bosawt bosawt requested a review from a team as a code owner January 7, 2025 23:48
@va-vfs-bot va-vfs-bot temporarily deployed to credential_email_bug_fix/main/main January 7, 2025 23:56 Inactive
@joeniquette
Copy link
Contributor

@bosawt to test this would I login with a dslogon account that doesnt have either an idme or login.gov account attached to it? I would expect there to be no email present? Or is this it just that the dslogon or mhv account should have no contact email but also have an idme or login.gov verified account?

@bosawt
Copy link
Contributor Author

bosawt commented Jan 8, 2025

@bosawt to test this would I login with a dslogon account that doesnt have either an idme or login.gov account attached to it? I would expect there to be no email present? Or is this it just that the dslogon or mhv account should have no contact email but also have an idme or login.gov verified account?

I left out the testing instructions because you have to set things up locally in a kind of contrived way. Basically you should always have an email on your account regardless of what you sign in as, it will be like this for all test accounts. If you really want to test, you have to:

  • log in with id.me, discover your idme uuid
  • on a rails console, run UserVerification.find_by(idme_uuid: your_idme_uuid).user_credential_email.destroy to get rid of the user credential email on the user verification
  • Since you can't naturally get the interstitial to pop up (you'd have to log in with MHV which you can't do locally), put the backend route in the browser: localhost:3000/v0/user/credential_emails, if you don't get an error and get an empty response, then it's a success

emilykim13
emilykim13 previously approved these changes Jan 8, 2025
Copy link
Contributor

@emilykim13 emilykim13 left a comment

Choose a reason for hiding this comment

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

I tested via rails console, lgtm

Testing a user without user_verifications: (line 24 was successfully skipped)

user_account = (some user with no user_verification)
...
vets-api(dev)*   emails = user_account.user_verifications.each_with_object({}) do |verification, credentials|
vets-api(dev)*     next unless verification.user_credential_email
vets-api(dev)* 
vets-api(dev)*     credentials[verification.credential_type.to_sym] = verification.user_credential_email.credential_email
vets-api(dev)>   end
=> {}

Then I tested to make sure the opposite condition provides the credential emails:

vets-api(dev)> UserAccount.left_joins(:user_verifications).group('user_accounts.id').having('COUNT(user_verifications.id) = 2')

vets-api(dev)> ua2 = UserAccount.find("29bf2f0d-61d3-46e4-a0db-331b45c1d069")

vets-api(dev)* emails = ua2.user_verifications.each_with_object({}) do |verification, credentials|
vets-api(dev)*     next unless verification.user_credential_email
vets-api(dev)*     credentials[verification.credential_type.to_sym] = verification.user_credential_email.credential_email
vets-api(dev)>   end

2025-01-08 10:59:19.339716 D [22468:11700 log_subscriber.rb:164] Rails --   Decrypt Data Key (0.0ms)  Context: {:model_name=>"UserCredentialEmail", :model_id=>6}
=> {:idme=>"vets.gov.user+1@gmail.com", :logingov=>"vets.gov.user+1@gmail.com"}

@@ -19,8 +19,9 @@ def icn

def credential_emails
emails = current_user.user_account.user_verifications.each_with_object({}) do |verification, credentials|
credentials[verification.credential_type.to_sym] =
verification.user_credential_email.credential_email
next unless verification.user_credential_email
Copy link
Contributor

Choose a reason for hiding this comment

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

Kind of a nitpick but I think it would be a bit cleaner if we select the user_verifications we want first instead of looping through them

verifications = current_user.user_account.user_verifications.select { |v| v.user_credential_email }

emails = verifications.to_h { |v|  [v.credential_type, v.user_credential_email.credential_email] }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

or for that matter I suppose we could do user_verifications.where.not(user_credential_email: nil), and just do it with the query

@bosawt bosawt merged commit 1f1be47 into master Jan 9, 2025
30 checks passed
@bosawt bosawt deleted the credential_email_bug_fix branch January 9, 2025 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants