Skip to content

feat: [M3-7921] - Added Dialog to Refresh Proxy Tokens as Time Expires#10361

Merged
jaalah-akamai merged 14 commits intolinode:developfrom
jaalah-akamai:M3-7921
May 6, 2024
Merged

feat: [M3-7921] - Added Dialog to Refresh Proxy Tokens as Time Expires#10361
jaalah-akamai merged 14 commits intolinode:developfrom
jaalah-akamai:M3-7921

Conversation

@jaalah-akamai
Copy link
Contributor

@jaalah-akamai jaalah-akamai commented Apr 8, 2024

Description 📝

When time is about to expire, we want to prompt the user with a modal window that indicates they will be logged out soon (show when 5min is remaining) and ask them if they want to continue working (refresh their token).

Note

I also did refactoring in SwitchAccountDrawer to implement the useParentChildAuthentication, hopefully making the file more readable.

Additional Issues

  • Parent Account: The drawer lacks a loading indicator when choosing a child account. This can lead to multiple selections and redundant requests for slow networks.
  • Proxy Account: Slow networks can cause the "Switch back to your account" action to initiate multiple requests.
  • Token Revocation: Currently, a toast notification appears when revoking a token. However, it often fails to display before the page is refreshed during the switch. Given the refresh, the toast notification is unnecessary.

Changes 🔄

New Files:

  • SessionExpirationDialog: Displayed for users logged into a proxy account. It performs three main functions:
    • Initiates a countdown timer based on the token's expiration time, displaying the dialog when only 5 minutes remain.
    • Provides options to either refresh the token or dismiss the dialog, allowing the token to expire naturally.
    • Provides option to logout (returns to parent account if parent token is valid or logs out if not)
  • useInterval: Introduced a familiar hook for reliable timer management.
  • useParentChildAuthentication: In order to make the creation/revoking/updating/validating of tokens, I created this hook to make things more DRY. This allows us to do a lot of cleanup and in several files (SessionExpirationDialog, SwitchAccountDrawer, AccountLanding).

Deleted:

  • usePendingRevocationToken: We are now using usePersonalAccessTokensQuery directly in places it's needed.

Changes:

  • Renamed useParentTokenManagement to useIsParentTokenExpired for clarity

Target release date 🗓️

4/29

Preview 📷

feature.mp4

How to test 🧪

Prerequisites

  • Log into Parent account using developer credentials

Reproduction steps

Loading Indicators:

  • Open user menu and "Switch Account"
  • Select a child company and observe there's no loading indicator
  • In addition, if you slowed network you can repeatedly send requests
  • In proxy account (after switching to child company), open user menu and "Switch Account"
  • Observe same issue with "Switch back to your account"

Verification steps

Loading Indicators:

  • Checkout branch and log into Parent account
  • Open user menu and "Switch Account"
  • Observe that selecting child company shows loading indicator
  • Observe the same process for Proxy account when trying to "Switch back to your account"

Session Expiry:

  • Checkout branch and log into Parent account
  • Change L70 to if (timeRemaining.minutes < 15) { to observe modal
  • Test that closing modal should do nothing allowing user to return to work without refreshing token
  • Test that logging out sends user back to parent account
  • Change L100 to true to test that logging out sends you to log in
  • Test that "Continue Working" refreshes token and closes modal.

As an Author I have considered 🤔

Check all that apply

  • 👀 Doing a self review
  • ❔ Our contribution guidelines
  • 🤏 Splitting feature into small PRs
  • ➕ Adding a changeset
  • 🧪 Providing/Improving test coverage
  • 🔐 Removing all sensitive information from the code and PR description
  • 🚩 Using a feature flag to protect the release
  • 👣 Providing comprehensive reproduction steps
  • 📑 Providing or updating our documentation
  • 🕛 Scheduling a pair reviewing session
  • 📱 Providing mobile support
  • ♿ Providing accessibility support

isSideMenuOpen={!desktopMenuIsOpen}
openSideMenu={() => toggleMenu(true)}
username={username}
<SessionExpirationProvider value={sessionExpirationContextValue}>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only change in JSX was to add a new context provider

interface Props {
onClose: () => void;
open: boolean;
proxyToken?: Token;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No need to pass token in anymore, we're handling this within component now.

const currentParentTokenWithBearer =
getStorage('authentication/parent_token/token') ?? '';

const handleProxyTokenRevocation = React.useCallback(async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Handled by useParentChildAuthentication.revokeToken and removed toasts since they're not necessary when switching accounts.

validateParentToken,
} = useParentChildAuthentication({
tokenIdToRevoke: pendingRevocationToken?.id ?? -1,
});
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is how the new hook will be used

* For 'proxy' userType, use the stored parent token in the request.
* Determine whether the tokens used for switchable accounts are still valid.
*/
export const isParentTokenValid = (): boolean => {
Copy link
Contributor Author

@jaalah-akamai jaalah-akamai Apr 9, 2024

Choose a reason for hiding this comment

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

These functions were moved from parent utils file since they pertain to Account Switching.

  • isParentTokenValid
  • setTokenInLocalStorage
  • updateCurrentTokenBasedOnUserType
  • getPersonalAccessTokenForRevocation

token.token &&
currentTokenWithBearer.replace('Bearer ', '').startsWith(token.token)
);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved all these to /SwitchAccounts/utils

@mjac0bs mjac0bs self-requested a review April 11, 2024 15:09
@jaalah-akamai jaalah-akamai marked this pull request as ready for review April 11, 2024 15:45
@jaalah-akamai jaalah-akamai requested a review from a team as a code owner April 11, 2024 15:45
@jaalah-akamai jaalah-akamai requested review from bnussman-akamai and cpathipa and removed request for a team April 11, 2024 15:45
Copy link
Contributor

@mjac0bs mjac0bs left a comment

Choose a reason for hiding this comment

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

Thanks again for the pair review on this; it was definitely helpful to digest these changes. Confirmed that the token will refresh if a user clicks "Continue Working", won't refresh if they cancel out, and will either log out the user and return them to the parent account or to login if the parent token has expired.

I wonder if the proxy log out and return to parent account will be surprising to the parent, since they may be expecting to be logged out of CM entirely. I would imagine it would be a welcome feature from their end, though I'm not sure if it would be immediately clear to them what happened. We could consider adding something like "If your own session is still valid, you will be returned to your parent account on logout." to the session dialog, but maybe we get some input from UX or wait to see if parent users report and feedback or confusion before making any adjustments.

I left comments on a few other things I've noticed while testing. It also looks like the unit test for SessionExpirationDialog is currently failing. I replicated that locally:

Screenshot 2024-04-17 at 10 14 09 AM

@jaalah-akamai
Copy link
Contributor Author

  • @bnussman-akamai Good suggestion on using the endpoint directly, was able to clean things up in several files
  • @mjac0bs Hitting the endpoints on slow network requests should be fixed with the way I switched things around, essentially the loading state from RQ was taking too long, so handling this with state

@jaalah-akamai jaalah-akamai requested a review from mjac0bs May 1, 2024 19:28
@github-actions
Copy link

github-actions bot commented May 1, 2024

Coverage Report:
Base Coverage: 82%
Current Coverage: 82.01%

Copy link
Contributor

@mjac0bs mjac0bs left a comment

Choose a reason for hiding this comment

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

Switching accounts from parent to proxy and back, as well as to other child accounts via proxy is still looking good with the latest. Confirmed the slow network edge case behavior I was seeing before is fixed. The dialog still works as expected; I set it to 14 minutes and confirmed it popped up on time. New dialog copy looks good to me.

This should be unrelated to this PR; I just happened to notice it while testing: token revoke events, which are plentiful if you switch between accounts or continue working many times, try to make a network request to /account/users/[proxy-username] and get 403 forbidden as a response. It looks gravatar related to me. 😓 (just furthering our hopes 🪓 )

Screenshot 2024-05-02 at 2 43 56 PM

Comment on lines +13 to +17
'&:disabled': {
color: theme.palette.text.disabled,
cursor: 'not-allowed',
},
'&:hover:not(:disabled)': {
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks nice!

Screen.Recording.2024-05-02.at.2.25.02.PM.mov

@bnussman-akamai bnussman-akamai added the Approved Multiple approvals and ready to merge! label May 3, 2024
@jaalah-akamai jaalah-akamai merged commit 423d84f into linode:develop May 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Approved Multiple approvals and ready to merge! Parent / Child Account Ready for Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants