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

feat(recovery): fetch recovery key status with passwordForgotToken #17636

Merged
merged 1 commit into from
Sep 19, 2024

Conversation

chenba
Copy link
Contributor

@chenba chenba commented Sep 18, 2024

Because:

  • we want to allow the user to get their recovery key status with the 'passwordForgotToken' they received during the reset password flow

This commit:

  • adds passwordForgotToken to the allowed auth strategies for the /recoveryKey/exists auth-server endpoint
    • updates the auth client to use the passwordForgotToken to access that endpoint
  • returns the recovery key hint along with the exists status
  • passes the hint in Setting when navigating post-reset

Fixes FXA-9398, FXA-7400

@chenba chenba requested a review from a team as a code owner September 18, 2024 13:41
@chenba
Copy link
Contributor Author

chenba commented Sep 18, 2024

@vpomerleau I believe this is relevant to your interests.

@@ -297,7 +297,7 @@ module.exports = (
...RECOVERY_KEY_DOCS.RECOVERYKEY_EXISTS_POST,
auth: {
mode: 'optional',
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this now returns the recovery key hint which could contain sensitive data, we'd want to make sure this request always uses either a session token or a passwordForgotToken (= not optional)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. I think I'll keep it optional for backwards compat but only return a hint if the request's authenticated.

@chenba chenba marked this pull request as draft September 18, 2024 16:34
@@ -296,8 +296,10 @@ module.exports = (
options: {
...RECOVERY_KEY_DOCS.RECOVERYKEY_EXISTS_POST,
auth: {
mode: 'optional',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

auth is no longer optional for this endpoint.

Copy link
Contributor

Choose a reason for hiding this comment

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

Should also update the swagger docs to reflect the change?

@chenba chenba force-pushed the FXA-9398-forgot-token-auth branch 2 times, most recently from b2bfdf0 to b4916b7 Compare September 19, 2024 15:35
@chenba chenba marked this pull request as ready for review September 19, 2024 16:10
token = await getCredentialsFunc(parsedHeader.id);
} catch (_) {
// we'll handle the empty token case below
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously if getCredentialsFunc throws an error, that's the resulting error of the auth. This makes the error a bit more consistent, but it is a change in the API.

strategies: [
'multiStrategySessionToken',
'multiStrategyPasswordForgotToken',
],
},
validate: {
payload: isA.object({
Copy link
Contributor

Choose a reason for hiding this comment

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

We could remove this email here since we're no longer allowing unauthenticated use of this endpoint?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could, yes. I don't know how much clean up it would require. So, I could either file a follow-up jira or I can clean it up as part of this patch. Since this PR is blocking you, what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it is scope creep since it doesn't technically cause problems to keep email as an optional payload... Could perhaps be noted in the backbone reset password cleanup ticket (FXA-8267) since that's the only remaining place (that I can see) that attempts to check for recovery key with an email.

Copy link
Contributor

Choose a reason for hiding this comment

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

Follow up is probably fine. I don't see any risks with removing the email value since we should be the only ones using it on our frontends. I don't believe others are using the email value in the api, or this api at all lol.

Copy link
Contributor Author

@chenba chenba Sep 19, 2024

Choose a reason for hiding this comment

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

I don't see any risks with removing the email value ...

Oh yeah, I'm not worried about breaking anything. It's just a matter of how much delay we want to tolerate to get the code as clean as we'd like.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could perhaps be noted in the backbone reset password cleanup ticket (FXA-8267) since that's the only remaining place ...

I was more concerned with the auth-client still accepting a payload for the email (and whatever might be using it). I assume the Backbone stuff will be deleted wholesale at some point anyway.

Copy link
Contributor

@vbudhram vbudhram left a comment

Choose a reason for hiding this comment

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

@chenba Thanks! I don't see anything blocking or at least could not be updated when frontend bits land.

}
const exists = await db.recoveryKeyExists(uid);
const uid = request.auth.credentials.uid;
const recoveryKeyRecordWithHint = await db.getRecoveryKeyHint(uid);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: The variable name is pretty clear, but database function name is a little confusing. Maybe they could be named similar.

@@ -401,6 +401,19 @@ async function create(log, error, config, routes, db, statsd, glean) {
hawkFxAToken.strategy(makeCredentialFn(db.passwordChangeToken.bind(db)))
);

server.auth.scheme(
Copy link
Contributor

Choose a reason for hiding this comment

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

Cool, I like this. I think a comment above might be helpful to explain how these are used.

strategies: [
'multiStrategySessionToken',
'multiStrategyPasswordForgotToken',
],
},
validate: {
payload: isA.object({
Copy link
Contributor

Choose a reason for hiding this comment

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

Follow up is probably fine. I don't see any risks with removing the email value since we should be the only ones using it on our frontends. I don't believe others are using the email value in the api, or this api at all lol.

Copy link
Contributor

@vpomerleau vpomerleau left a comment

Choose a reason for hiding this comment

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

Thanks for your work on this! Just a few comments related to the email + docs

@@ -296,8 +296,10 @@ module.exports = (
options: {
...RECOVERY_KEY_DOCS.RECOVERYKEY_EXISTS_POST,
auth: {
mode: 'optional',
Copy link
Contributor

Choose a reason for hiding this comment

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

Should also update the swagger docs to reflect the change?

strategies: [
'multiStrategySessionToken',
'multiStrategyPasswordForgotToken',
],
},
validate: {
payload: isA.object({
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it is scope creep since it doesn't technically cause problems to keep email as an optional payload... Could perhaps be noted in the backbone reset password cleanup ticket (FXA-8267) since that's the only remaining place (that I can see) that attempts to check for recovery key with an email.

const result: RecoveryKeyCheckResult =
await authClient.passwordForgotRecoveryKeyStatus(
passwordForgotToken,
email
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need to pass in the email since it's optional and won't be used by the endpoint

Because:
 - we want to allow the user to get their recovery key status with the
   'passwordForgotToken' they received during the reset password flow

This commit:
 - adds passwordForgotToken to the allowed auth strategies for the
   /recoveryKey/exists auth-server endpoint
   - removes the optional auth config on the endpoint
   - updates the auth client to use the passwordForgotToken to access
     that endpoint
 - returns the recovery key hint along with the exists status
 - passes the hint in Setting when navigating post-reset
@chenba chenba merged commit 794bf57 into main Sep 19, 2024
25 checks passed
@chenba chenba deleted the FXA-9398-forgot-token-auth branch September 19, 2024 21:42
@chenba
Copy link
Contributor Author

chenba commented Sep 20, 2024

Filed FXA-10441 as a follow-up.

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.

3 participants