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(authenticator): fetch current user on routed apps after refresh #1580

Merged
merged 18 commits into from
Mar 25, 2022

Conversation

wlee221
Copy link
Contributor

@wlee221 wlee221 commented Mar 24, 2022

Problem

Previously, useAuthenticator hook/composable/service required an instance of Authenticator in the DOM tree to initiate the machine and look for any current authenticated user in the local storage.

This caused problems when a user refreshed in an authenticated route. For example, imagine the following structure:

  • / is the entry to the home page and has the <Authenticator /> instance to enable sign in.
  • /my-account is an authenticated route that users can go after they signed in. This doesn't have <Authenticator /> in DOM because they already signed in.

Whenever a user refreshed on /my-account, the page wouldn't have an Authenticator in the DOM to initiate the authMachine, and so auth contexts from the hooks returned undefined.

Fix

This PR adjusts useAuthenticator hooks so that it first looks for Auth.currentAuthenticatedUser. If there are, it'll just transition directly to authenticated route and does not require an instance of <Authenticator /> whatsoever. Otherwise, it would proceed to the setup state, in which it will wait for Authenticator to send the INIT event.

From the framework side, <Authenticator /> will subscribe to authMachine changes. Once the machine gets to setup state and is ready for the INIT event, authenticator will send an INIT event with all the machine options.

Remaining Problems

Note that there are still bugs we have to address for routed app use cases, namely #1581. This PR will at least correct the refresh behavior and remove the need for Authenticator in the DOM tree for machines to start.

Issue #, if available

Related to #1332, #1497

Description of how you validated changes

#1578 adds new examples and tests for refreshing. #1578 is to be merged into this PR once approved.

Checklist

  • PR description included
  • yarn test passes
  • Tests are updated
  • Relevant documentation is changed or added (and PR referenced)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@changeset-bot
Copy link

changeset-bot bot commented Mar 24, 2022

🦋 Changeset detected

Latest commit: 111bf94

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@aws-amplify/ui-react Patch
@aws-amplify/ui Patch
@aws-amplify/ui-vue Patch
@aws-amplify/ui-angular Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wlee221 wlee221 changed the title Get user on refresh/state machine fix(authenticator): get current user on refresh on routed apps Mar 24, 2022
@lgtm-com
Copy link

lgtm-com bot commented Mar 24, 2022

This pull request introduces 2 alerts when merging fc71b28 into eedae23 - view on LGTM.com

new alerts:

  • 2 for Unused variable, import, function or class

@@ -25,47 +25,58 @@ export function createAuthenticatorMachine() {
context: {
user: undefined,
config: {},
services: {},
services: { ...defaultServices },
actorRef: undefined,
},
states: {
// See: https://xstate.js.org/docs/guides/communication.html#invoking-promises
idle: {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

idle state now starts with Auth.currentAuthenticatedUser call.

Knowing that, idle is a bad name (it's on me!) and should be named more explicitly. I scoped this out of this PR, because that would change our route names and I would rather deal with it in 3.0 changes.

target: 'authenticated',
initial: 'waitConfig',
states: {
waitConfig: {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

At this stage, we confirmed that no user has signed in yet. Now we wait for Authenticator to send INIT event to pass machine props like initialState.

},
onError: [
},
applyConfig: {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Once we have all the machine props ready, we apply those configs to get loginMechanisms, etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Comment on lines 60 to 63
// send INIT event once machine is at 'setup' state
this.authenticator.subscribe(() => {
const { route } = this.authenticator;
if (!this.hasInitialized && route === 'setup') {
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 authMachine got stuck in idle state until an Authenticator in DOM sends an INIT event on mount. Now authMachine starts independently (see state machine changes below), and will explicitly ask for config from Authenticator once it's in setup state.

Once Authenticator sees that state is in setup, it'll send the usual INIT event.

@wlee221 wlee221 changed the title fix(authenticator): get current user on refresh on routed apps fix(authenticator): fetch current user on routed apps after refresh Mar 24, 2022
@wlee221 wlee221 temporarily deployed to ci March 24, 2022 13:49 Inactive
Copy link
Member

@calebpollman calebpollman left a comment

Choose a reason for hiding this comment

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

Granted I am still learning how xstate and the Authenticator state machine work but LGTM 👍🏽. Left some questions

packages/ui/src/machines/authenticator/index.ts Outdated Show resolved Hide resolved
packages/vue/src/components/authenticator.vue Outdated Show resolved Hide resolved
packages/vue/src/components/authenticator.vue Outdated Show resolved Hide resolved
Co-authored-by: Caleb Pollman <cpollman@amazon.com>
@wlee221 wlee221 temporarily deployed to ci March 24, 2022 18:05 Inactive
@wlee221 wlee221 requested a review from calebpollman March 24, 2022 22:43
Copy link
Member

@calebpollman calebpollman left a comment

Choose a reason for hiding this comment

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

LGTM 🚢 Thanks for addressing the feedback!

* Angular Example

* React example

* Vue examples

* Add missing !

* Update useAuthenticator test

* Use slots on parent route

* Configure Amplify on `/home`

* Add react sign out button

* Update wording on react example

* Add sign out test

* Add angular sign out buttons

* Sign Out button in Vue

* destructure signOut ref

* Add hidden Authenticator on Vue

* Fix copy paste typo
@lgtm-com
Copy link

lgtm-com bot commented Mar 24, 2022

This pull request introduces 3 alerts when merging 43119e4 into 8278c72 - view on LGTM.com

new alerts:

  • 3 for Unused variable, import, function or class

@wlee221
Copy link
Contributor Author

wlee221 commented Mar 25, 2022

fyi, I added 9 liner commit b8c36bb to fix a autoSignIn test failure. autoSignIn flow needed to be adjusted so that it goes to the correct state based on signUp result. This uses the same flow as before, just made more explicit.

I'll merge this tomorrow morning unless there are objections!

@lgtm-com
Copy link

lgtm-com bot commented Mar 25, 2022

This pull request introduces 3 alerts when merging 111bf94 into 683eac9 - view on LGTM.com

new alerts:

  • 3 for Unused variable, import, function or class

@wlee221 wlee221 temporarily deployed to ci March 25, 2022 17:27 Inactive
@wlee221 wlee221 temporarily deployed to ci March 25, 2022 17:27 Inactive
@wlee221 wlee221 temporarily deployed to ci March 25, 2022 17:27 Inactive
@wlee221 wlee221 temporarily deployed to ci March 25, 2022 17:27 Inactive
Copy link
Contributor

@slaymance slaymance left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@wlee221 wlee221 merged commit 1ac9cda into main Mar 25, 2022
@wlee221 wlee221 deleted the get-user-on-refresh/state-machine branch March 25, 2022 18:58
This was referenced Mar 25, 2022
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.

4 participants