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(react): Send fxaLogin webchannel message conditionally after password reset #15412

Merged
merged 1 commit into from
Jun 21, 2023

Conversation

LZoog
Copy link
Contributor

@LZoog LZoog commented Jun 6, 2023

Because:

  • The browser should be be notified when a PW reset occurs on a verified account through the Sync flow, as this logs the user in

This commit:

  • Conditionally runs the fxaLogin command with required account data after a password reset with or without recovery key, when the flow is sync
  • Receives other values off the account reset call needed for webchannel account data
  • Temporarily checks for SyncBasic and SyncDesktop flows to run the check because we don't need to port over context in local storage logic (which would account for SyncDesktop only), since we are switching to codes soon
  • Sends up service with the email request so we can append the param and check when link is received (causing the SyncBasic integration)
  • Removes resendResetPassword and calls resetPassword where needed since the code was duplicated

Fixes FXA-7172

// Object.entries(loginData).filter(([key, value]) => value !== undefined)
// );
// }
const REQUIRED_LOGIN_FIELDS: Array<keyof FxALoginRequest> = [
Copy link
Contributor Author

@LZoog LZoog Jun 6, 2023

Choose a reason for hiding this comment

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

There's a link to what params are used on the FF side above FxALoginRequest. This is different than the previous "allowed" and "required" fields which were commented out, please see what we're doing in this file and double check me. I figure if there's more we need later for the "confirm" pages we can add them then.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks right. One comment, is that although authAt is listed in the FF source as a field, but I don't see it being used, and it looks like the content-server auth broker model doesn't have it listed as a required field. It seems like what you have is technically more correct though, so it is probably fine.

async resetPassword(email: string): Promise<PasswordForgotSendCodePayload> {
async resetPassword(
email: string,
service?: string
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if this would have been preferred anyway but I tried using CreateRelier here, and ran into issues. There was nothing in the console, so I worked my way up and saw this was struggling to pull off of Context here, maybe because this isn't a React component? Didn't dive too deep, since we're replacing links with codes soon anyway, and just called CreateRelier in the component using it instead.

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 that's good. I don't think we should be accessing context here. Better to pass it in.

// for (const key of ALLOWED_LOGIN_FIELDS) {
// loginData[key] = account[key];
// }
// // TODO: account for multiservice when we combine reliers
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm going to add this comment back since we do need this. I think this has to do with the signup or confirm view since in content-server, _formatForMultiServiceBrowser will send offeredSyncEngines and declinedSyncEngines. It can be looked at in https://mozilla-hub.atlassian.net/browse/FXA-7308.

},
},
});
currentAccount(getOldSettingsData(accountReset));
sessionToken(accountReset.sessionToken);
return accountReset;
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably a follow up item, but it'd be great to return something other than 'any' here.

@LZoog
Copy link
Contributor Author

LZoog commented Jun 7, 2023

Going to go ahead and open this as ready - there are 2 failing tests I'm still looking into but should be g2g otherwise.

(edit: not sure why GH is showing no changes since I just pushed, will push again in a sec...)

@LZoog LZoog marked this pull request as ready for review June 7, 2023 16:43
@LZoog LZoog requested a review from a team as a code owner June 7, 2023 16:43
@LZoog
Copy link
Contributor Author

LZoog commented Jun 7, 2023

I just pushed again with everything passing locally for me but looks like I'm afflicted by the Github outage so it hasn't shown up yet. The push from 1512f88 to 6ca824c contains everything except the last two failures.

One thing to note, everything passes but I'm seeing a few warnings around An update to [component] inside a test was not wrapped in act(...).: At least one of them was here before this branch, so I'm just going to file a follow up. edit: follow up is here

@@ -614,51 +629,6 @@ export class Account implements AccountData {
}
}

async resendResetPassword(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suprised this was duplicated like this 😅

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.

Running this locally and looks like storybook is failing

Users/vijaybudhram/Desktop/working/fxa/packages/fxa-settings/src/pages/ResetPassword/CompleteResetPassword/index.stories.tsx
TypeScript error in /Users/vijaybudhram/Desktop/working/fxa/packages/fxa-settings/src/pages/ResetPassword/CompleteResetPassword/index.stories.tsx(10,34):
Module '"./mocks"' has no exported member 'Subject'.  TS2305

     8 | import { Account } from '../../../models';
     9 | import { withLocalization } from '../../../../.storybook/decorators';
  > 10 | import { paramsWithMissingEmail, Subject } from './mocks';
       |                                  ^
    11 | 
    12 | export default {
    13 |   title: 'Pages/ResetPassword/CompleteResetPassword',

Looks like Subject is now renderSubject?

@LZoog LZoog force-pushed the FXA-7172 branch 3 times, most recently from 45eb136 to de6c7ca Compare June 9, 2023 23:45
@LZoog
Copy link
Contributor Author

LZoog commented Jun 9, 2023

@dschom @vbudhram I had to refactor some mocks/tests/storybook things due to this. I'd changed it so Subject would be renderSubject, but that does not work with our Storybook setup and since it's nice to share state/test set up like we have there I changed it to getSubject. Most changes were needed because when we need to call CreateRelier, we need to mock a lot more than without.

One problem I'm having now is something @dschom I think you and I have both ran into, where rendering a "damaged" link causes all other stories to show the damaged link (CompleteResetPassword, AccountRecoveryConfirmKey) because Storybook builds all stories at runtime and I think there's some global window state that's persisting across stories. It's almost like we need a resetState method on our ReachRouterWindow to run between each story with a decorator... but we haven't needed to do this yet. Do you see what's causing this? 🥹 I've spent more time on stories/test refactors here than I thought I would, (EDIT: fixed! 🎉) it's really starting to bother me how inconsistent we are doing various things heh, definitely something to call out and file issues for in that architecture epic...

Feel free to test locally now though (and comment out the DamagedLink stories to see the others), if you create an account and then run fxa-dev-launcher (see you're not signed in via the menu), make sure the feature flag is on, then reset through the Sync flow in that window by clicking "Looking for Sync?" > "Forgot password?" > append &showReactApp=true and follow the link with the param as well. On successful reset you'll see you're logged in.

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.

@LZoog Works as described! LGTM 👍🏽

Copy link
Contributor

@dschom dschom left a comment

Choose a reason for hiding this comment

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

LGMT

@@ -76,7 +76,8 @@ const renderSubject = ({
account = accountWithValidResetToken,
params = mockCompleteResetPasswordParams,
} = {}) => {
render(<Subject {...{ account, params }} />);
const { Subject, history, appCtx } = getSubject(account, params);
return renderWithRouter(<Subject />, { history }, appCtx);
Copy link
Contributor

Choose a reason for hiding this comment

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

Note that the 'render' import above is no longer used!

@@ -6,14 +6,21 @@ import React from 'react';
import { MozServices } from '../../../lib/types';
import { LocationProvider } from '@reach/router';
import { Account, AppContext } from '../../../models';
import { mockAppContext, MOCK_ACCOUNT } from '../../../models/mocks';
import {
Copy link
Contributor

Choose a reason for hiding this comment

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

LocationProvider and AppContext on the lines above are both unnused now.

mockCompleteResetPasswordParams,
paramsWithMissingCode,
paramsWithMissingEmail,
paramsWithMissingEmailToHashWith,
paramsWithMissingToken,
paramsWithSyncDesktop,
Subject,
} from './mocks';
Copy link
Contributor

Choose a reason for hiding this comment

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

Subject isn't used

@@ -3,26 +3,22 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

Copy link
Contributor

Choose a reason for hiding this comment

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

render isn't used

</LocationProvider>
</AppContext.Provider>
);
storageData: new StorageDataMock(windowWrapper),
Copy link
Contributor

Choose a reason for hiding this comment

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

Accoding to the type account must always be defined. Is there a reason for the account &&

@@ -9,7 +9,13 @@ import CompleteResetPassword from '.';
import LinkValidator from '../../../components/LinkValidator';
import { StorageData, UrlQueryData } from '../../../lib/model-data';
import { Account, AppContext } from '../../../models';
Copy link
Contributor

Choose a reason for hiding this comment

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

AppContext unused and LocationProvider above is also unused.

@@ -4,71 +4,53 @@

import React from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

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

AppContext & LocationProvider are not used.

mockAppContext,
MOCK_ACCOUNT,
createHistoryWithQuery,
renderWithRouter,
Copy link
Contributor

Choose a reason for hiding this comment

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

renderWithRouter not used. Same with AppContext & LocationProvider.

Copy link
Contributor

Choose a reason for hiding this comment

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

renderWithRouter not used. Same with AppContex & LocationProvider.

route: string,
account = MOCK_ACCOUNT as unknown as Account,
queryParams?: string,
appCtx?: AppContextValue
Copy link
Contributor

Choose a reason for hiding this comment

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

appCtx not used?

mockAppContext,
MOCK_ACCOUNT,
createHistoryWithQuery,
renderWithRouter,
Copy link
Contributor

Choose a reason for hiding this comment

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

renderWithRouter not used. Same with ApPContext & LocationProvider above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dschom Thanks for all the callouts. I said this in some other issue but I thought unused imports would show up in CI or something now.

…sword reset

Because:
* The browser should be be notified when a PW reset occurs on a verified account through the Sync flow, as this logs the user in

This commit:
* Conditionally runs the fxaLogin command with required account data after a password reset with or without recovery key, when the flow is sync
* Receives other values off the account reset call needed for webchannel account data
* Temporarily checks for SyncBasic and SyncDesktop flows to run the check because we don't need to port over context in local storage logic (which would account for SyncDesktop only), since we are switching to codes soon
* Sends up `service` with the email request so we can append the param and check when link is received (causing the  SyncBasic integration)
* Removes resendResetPassword and calls resetPassword where needed since the code was duplicated

Fixes FXA-7172
@LZoog
Copy link
Contributor Author

LZoog commented Jun 21, 2023

Just pushed an update removing unused imports. Going to go ahead and merge since CI was already happy and we are about to tag.

@LZoog LZoog merged commit 49816e8 into main Jun 21, 2023
@LZoog LZoog deleted the FXA-7172 branch June 21, 2023 16:42
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