From b0b8feaa3f1bf60f3b68350cff18c18b0afc628f Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Wed, 9 Aug 2023 15:01:52 -0500 Subject: [PATCH 01/19] feat: de-modal mfa unpair TODO: - Fix unpair success navigation, which fails. --- apps/tup-ui/src/App.tsx | 7 +- apps/tup-ui/src/pages/Mfa/Mfa.tsx | 7 +- .../src/accounts/ManageAccount.module.css | 26 ---- .../src/accounts/ManageAccountMfa.tsx | 142 ++---------------- .../tup-components/src/mfa/MfaPairingView.tsx | 6 + libs/tup-components/src/mfa/MfaSelection.tsx | 4 +- .../tup-components/src/mfa/MfaSuccessView.tsx | 9 +- .../src/mfa/MfaUnpairingView.tsx | 112 ++++++++++++++ libs/tup-components/src/mfa/MfaWrapper.tsx | 15 -- libs/tup-components/src/mfa/index.ts | 2 +- libs/tup-components/styles/c-step-panels.css | 3 + 11 files changed, 151 insertions(+), 182 deletions(-) create mode 100644 libs/tup-components/src/mfa/MfaUnpairingView.tsx delete mode 100644 libs/tup-components/src/mfa/MfaWrapper.tsx diff --git a/apps/tup-ui/src/App.tsx b/apps/tup-ui/src/App.tsx index 052eb0a7f..32469804f 100644 --- a/apps/tup-ui/src/App.tsx +++ b/apps/tup-ui/src/App.tsx @@ -5,6 +5,7 @@ import { Sidebar, Tickets, MfaPairingview, + MfaUnpairingview, MfaSelection, ManageAccount, RequireAuth, @@ -52,8 +53,10 @@ function App() { } /> }> } /> - } /> - } /> + } /> + } /> + } /> + } /> {
- {/* Default to a "success" view if user has a verified token */} - - - +
); diff --git a/libs/tup-components/src/accounts/ManageAccount.module.css b/libs/tup-components/src/accounts/ManageAccount.module.css index 72475f961..a7edcdd8d 100644 --- a/libs/tup-components/src/accounts/ManageAccount.module.css +++ b/libs/tup-components/src/accounts/ManageAccount.module.css @@ -1,29 +1,3 @@ -@import url('@tacc/core-styles/src/lib/_imports/tools/media-queries.css'); - -/* Layout styles */ -.unpairing-container { - composes: c-step-panels c-step-panels--has-scroll-parent from '../../styles/c-step-panels.css'; -} -.unpairing-separator { - composes: c-step-panels__separator from '../../styles/c-step-panels.css'; -} -.has-sms { - width: 100%; - max-width: 375px; - grid-template-columns: 1fr auto 1fr; -} -@media screen and (--medium-and-above) { - .unpairing-container { - composes: c-step-panels--horizontal from '../../styles/c-step-panels.css'; - } - .mfa-message { - composes: c-step-panels__message from '../../styles/c-step-panels.css'; - } -} -.mfa-fieldwrap { - composes: c-step-panels__content from '../../styles/c-step-panels.css'; -} - .account-layout{ padding: var(--global-space--section); padding-right: 30px; diff --git a/libs/tup-components/src/accounts/ManageAccountMfa.tsx b/libs/tup-components/src/accounts/ManageAccountMfa.tsx index 0e49caee4..434e48ce3 100644 --- a/libs/tup-components/src/accounts/ManageAccountMfa.tsx +++ b/libs/tup-components/src/accounts/ManageAccountMfa.tsx @@ -1,141 +1,16 @@ +import React from 'react'; import { Button, - InlineMessage, LoadingSpinner, SectionMessage, } from '@tacc/core-components'; import { - MfaTokenResponse, - useMfa, - useMfaDelete, - useMfaChallenge, - useMfaEmailUnpair, + useMfa } from '@tacc/tup-hooks'; -import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; import { TicketCreateModal } from '../tickets'; -import React, { useState } from 'react'; import { Link } from 'react-router-dom'; import styles from './ManageAccount.module.css'; -const MfaUnpair: React.FC<{ pairing: MfaTokenResponse }> = ({ pairing }) => { - const [isOpen, setIsOpen] = useState(false); - const toggle = () => { - setIsOpen(!isOpen); - }; - - const closeBtn = ( - - ); - const [currentToken, setCurrentToken] = useState(''); - const { mutate: unpairWithCode, isError } = useMfaDelete(); - const { mutate: unpairWithEmail, isSuccess: emailSentSuccess } = - useMfaEmailUnpair(); - const { mutate: sendChallenge } = useMfaChallenge(); - - const submit = (e: React.FormEvent) => { - e.preventDefault(); - e.stopPropagation(); - setCurrentToken(''); - - unpairWithCode({ - otpcode: currentToken, - }); - }; - - const useSms = pairing.token?.tokentype === 'sms'; - - return ( - <> - - - - Unpair Multifactor Authentication - -
submit(e)}> - - - You are about to remove multifactor authentication from your - account. - -
-
    - {useSms && ( - <> -
  1. - -
  2. -
  3. - - )} -
  4. -
    - - setCurrentToken(e.target.value)} - id="current-mfa-token" - /> -
    - -

    - Alternatively,{' '} - - . -

    - - {isError && ( - - There was an error verifying your MFA token. - - )} -
  5. -
- {emailSentSuccess && ( - - An email has been sent to the address listed on your account. - Follow its instructions to continue the unpairing. - - )} -
- - - - -
-
- - ); -}; - const MfaSectionHeader: React.FC = () => (
MFA Pairing @@ -161,7 +36,14 @@ export const AccountMfa: React.FC = () => { ); } - if (isLoading || !data) return ; + if (isLoading || !data) { + return ( + <> + + + + ) + }; const hasPairing = data?.token?.rollout_state === 'enrolled'; return ( <> @@ -179,7 +61,9 @@ export const AccountMfa: React.FC = () => {

{TOKEN_TYPE[data.token.tokentype]} ({data.token.serial})

- + + +
)} diff --git a/libs/tup-components/src/mfa/MfaPairingView.tsx b/libs/tup-components/src/mfa/MfaPairingView.tsx index ddbc52212..ded666cd8 100644 --- a/libs/tup-components/src/mfa/MfaPairingView.tsx +++ b/libs/tup-components/src/mfa/MfaPairingView.tsx @@ -1,10 +1,16 @@ import React from 'react'; +import { useMfa } from '@tacc/tup-hooks'; import MfaQRPanel from './MfaQRPanel'; import MfaSmsPanel from './MfaSmsPanel'; import MfaValidationPanel from './MfaValidationPanel'; +import MfaSuccessView from './MfaSuccessView'; import styles from './Mfa.module.css'; const MfaPairingLayout: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { + const { data } = useMfa(); + + if (data?.token?.rollout_state === 'enrolled') return ; + return (
  1. diff --git a/libs/tup-components/src/mfa/MfaSelection.tsx b/libs/tup-components/src/mfa/MfaSelection.tsx index 92ff4cf19..415c26b2e 100644 --- a/libs/tup-components/src/mfa/MfaSelection.tsx +++ b/libs/tup-components/src/mfa/MfaSelection.tsx @@ -9,10 +9,10 @@ const MfaSelector: React.FC = () => { Select whether you want to use an MFA token app or SMS texting for authenticating to your TACC account.
    - + - +
    diff --git a/libs/tup-components/src/mfa/MfaSuccessView.tsx b/libs/tup-components/src/mfa/MfaSuccessView.tsx index b72bedb91..8143387c2 100644 --- a/libs/tup-components/src/mfa/MfaSuccessView.tsx +++ b/libs/tup-components/src/mfa/MfaSuccessView.tsx @@ -3,12 +3,17 @@ import { Button, SectionMessage } from '@tacc/core-components'; import { useNavigate } from 'react-router-dom'; import styles from './Mfa.module.css'; -const MfaSuccessView: React.FC = () => { +const MfaSuccessView: React.FC<{ task: 'pair' | 'unpair' }> = ({ task }) => { const navigate = useNavigate(); return (
    - Pairing Successful + {task === 'pair' && ( + 'Pairing successful' + )} + {task === 'unpair' && ( + 'Unpairing successful' + )} + + )} + {method === 'totp' && ( + + )} +
  2. +
  3. +
  4. +
    submit(e)} + className={`${styles['mfa-form']} s-form`} + > +
    + + setCurrentToken(e.target.value)} + id="current-mfa-token" + /> +
    + +
    + + {!sendChallengeSuccess && ( +

    + Alternatively,{' '} + + . + {emailSentSuccess && ( + + An email has been sent to the address listed on your account. + Follow its instructions to continue the unpairing. + + )} +

    + )} + + {method === 'sms' && sendChallengeSuccess && ( +

    + Didn't receive a message within 5 minutes?{' '} + Get Help +

    + )} + + {isError && ( + + There was an error verifying your MFA token. + + )} +
  5. +
+ + ); +}; + +export default MfaUnpairingView; diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx deleted file mode 100644 index 7f62ddf47..000000000 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import MfaSuccessView from './MfaSuccessView'; -import { useMfa } from '@tacc/tup-hooks'; -import { LoadingSpinner } from '@tacc/core-components'; - -const MfaWrapper: React.FC = ({ children }) => { - const { isLoading, data } = useMfa(); - - if (isLoading) return ; - if (data?.token?.rollout_state === 'enrolled') return ; - /*eslint-disable-next-line react/jsx-no-useless-fragment */ - return <>{children}; -}; - -export default MfaWrapper; diff --git a/libs/tup-components/src/mfa/index.ts b/libs/tup-components/src/mfa/index.ts index f112d43e1..9f3c20ec5 100644 --- a/libs/tup-components/src/mfa/index.ts +++ b/libs/tup-components/src/mfa/index.ts @@ -1,4 +1,4 @@ export { default as MfaSelection } from './MfaSelection'; export { default as MfaHeader } from './MfaHeader'; export { default as MfaPairingview } from './MfaPairingView'; -export { default as MfaWrapper } from './MfaWrapper'; +export { default as MfaUnpairingview } from './MfaUnpairingView'; diff --git a/libs/tup-components/styles/c-step-panels.css b/libs/tup-components/styles/c-step-panels.css index 6eeb24b61..0e1ed4861 100644 --- a/libs/tup-components/styles/c-step-panels.css +++ b/libs/tup-components/styles/c-step-panels.css @@ -97,4 +97,7 @@ li.c-step-panels__separator { right: 0; margin-left: auto; margin-right: auto; + + /* To horizontally center text (not content) */ + text-align: center; } From 60afcbb4db3b29d9049b7c0fe328b9a105b840a8 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Wed, 9 Aug 2023 18:07:35 -0500 Subject: [PATCH 02/19] test: restore MfaWrapper (incomplete) --- apps/tup-ui/src/pages/Mfa/Mfa.tsx | 7 +++++-- libs/tup-components/src/mfa/index.ts | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/tup-ui/src/pages/Mfa/Mfa.tsx b/apps/tup-ui/src/pages/Mfa/Mfa.tsx index 2fae08ebf..b126ab1d5 100644 --- a/apps/tup-ui/src/pages/Mfa/Mfa.tsx +++ b/apps/tup-ui/src/pages/Mfa/Mfa.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { MfaHeader, RequireAuth } from '@tacc/tup-components'; +import { MfaHeader, MfaWrapper, RequireAuth } from '@tacc/tup-components'; import styles from './Mfa.module.css'; import { Outlet } from 'react-router-dom'; @@ -8,7 +8,10 @@ const Mfa: React.FC = () => {
- + {/* Default to a "success" view if user has a verified token */} + + +
); diff --git a/libs/tup-components/src/mfa/index.ts b/libs/tup-components/src/mfa/index.ts index 9f3c20ec5..6ce7f09c6 100644 --- a/libs/tup-components/src/mfa/index.ts +++ b/libs/tup-components/src/mfa/index.ts @@ -2,3 +2,4 @@ export { default as MfaSelection } from './MfaSelection'; export { default as MfaHeader } from './MfaHeader'; export { default as MfaPairingview } from './MfaPairingView'; export { default as MfaUnpairingview } from './MfaUnpairingView'; +export { default as MfaWrapper } from './MfaWrapper'; From 22517cb876a42fb451823936a479cec91d5ea1ec Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Wed, 9 Aug 2023 18:07:41 -0500 Subject: [PATCH 03/19] Revert "test: restore MfaWrapper (incomplete)" This reverts commit 60afcbb4db3b29d9049b7c0fe328b9a105b840a8. --- apps/tup-ui/src/pages/Mfa/Mfa.tsx | 7 ++----- libs/tup-components/src/mfa/index.ts | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/tup-ui/src/pages/Mfa/Mfa.tsx b/apps/tup-ui/src/pages/Mfa/Mfa.tsx index b126ab1d5..2fae08ebf 100644 --- a/apps/tup-ui/src/pages/Mfa/Mfa.tsx +++ b/apps/tup-ui/src/pages/Mfa/Mfa.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { MfaHeader, MfaWrapper, RequireAuth } from '@tacc/tup-components'; +import { MfaHeader, RequireAuth } from '@tacc/tup-components'; import styles from './Mfa.module.css'; import { Outlet } from 'react-router-dom'; @@ -8,10 +8,7 @@ const Mfa: React.FC = () => {
- {/* Default to a "success" view if user has a verified token */} - - - +
); diff --git a/libs/tup-components/src/mfa/index.ts b/libs/tup-components/src/mfa/index.ts index 6ce7f09c6..9f3c20ec5 100644 --- a/libs/tup-components/src/mfa/index.ts +++ b/libs/tup-components/src/mfa/index.ts @@ -2,4 +2,3 @@ export { default as MfaSelection } from './MfaSelection'; export { default as MfaHeader } from './MfaHeader'; export { default as MfaPairingview } from './MfaPairingView'; export { default as MfaUnpairingview } from './MfaUnpairingView'; -export { default as MfaWrapper } from './MfaWrapper'; From ec0b32d248cb3c080b642247971cfd05a032915d Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Wed, 9 Aug 2023 18:11:31 -0500 Subject: [PATCH 04/19] fix: `` param typo --- libs/tup-components/src/mfa/MfaUnpairingView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/tup-components/src/mfa/MfaUnpairingView.tsx b/libs/tup-components/src/mfa/MfaUnpairingView.tsx index 81a733745..86fe26748 100644 --- a/libs/tup-components/src/mfa/MfaUnpairingView.tsx +++ b/libs/tup-components/src/mfa/MfaUnpairingView.tsx @@ -32,7 +32,7 @@ const MfaUnpairingView: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { }); }; - if (data?.token?.rollout_state === 'verify') return ; + if (data?.token?.rollout_state === 'verify') return ; return ( <> From c090092b0a05bfd74b79f65d2b6498486ec6f465 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Thu, 10 Aug 2023 10:28:47 -0500 Subject: [PATCH 05/19] test: restore & tweak MfaWrapper TODO: - Fix unpair success navigation, which fails. --- apps/tup-ui/src/pages/Mfa/Mfa.tsx | 7 +++-- .../tup-components/src/mfa/MfaPairingView.tsx | 3 --- .../src/mfa/MfaUnpairingView.tsx | 3 --- libs/tup-components/src/mfa/MfaWrapper.tsx | 26 +++++++++++++++++++ libs/tup-components/src/mfa/index.ts | 1 + 5 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 libs/tup-components/src/mfa/MfaWrapper.tsx diff --git a/apps/tup-ui/src/pages/Mfa/Mfa.tsx b/apps/tup-ui/src/pages/Mfa/Mfa.tsx index 2fae08ebf..b126ab1d5 100644 --- a/apps/tup-ui/src/pages/Mfa/Mfa.tsx +++ b/apps/tup-ui/src/pages/Mfa/Mfa.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { MfaHeader, RequireAuth } from '@tacc/tup-components'; +import { MfaHeader, MfaWrapper, RequireAuth } from '@tacc/tup-components'; import styles from './Mfa.module.css'; import { Outlet } from 'react-router-dom'; @@ -8,7 +8,10 @@ const Mfa: React.FC = () => {
- + {/* Default to a "success" view if user has a verified token */} + + +
); diff --git a/libs/tup-components/src/mfa/MfaPairingView.tsx b/libs/tup-components/src/mfa/MfaPairingView.tsx index ded666cd8..49f08b0c2 100644 --- a/libs/tup-components/src/mfa/MfaPairingView.tsx +++ b/libs/tup-components/src/mfa/MfaPairingView.tsx @@ -3,14 +3,11 @@ import { useMfa } from '@tacc/tup-hooks'; import MfaQRPanel from './MfaQRPanel'; import MfaSmsPanel from './MfaSmsPanel'; import MfaValidationPanel from './MfaValidationPanel'; -import MfaSuccessView from './MfaSuccessView'; import styles from './Mfa.module.css'; const MfaPairingLayout: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { const { data } = useMfa(); - if (data?.token?.rollout_state === 'enrolled') return ; - return (
  1. diff --git a/libs/tup-components/src/mfa/MfaUnpairingView.tsx b/libs/tup-components/src/mfa/MfaUnpairingView.tsx index 86fe26748..5841a40ed 100644 --- a/libs/tup-components/src/mfa/MfaUnpairingView.tsx +++ b/libs/tup-components/src/mfa/MfaUnpairingView.tsx @@ -11,7 +11,6 @@ import { useMfaEmailUnpair, } from '@tacc/tup-hooks'; import TicketCreateModal from '../tickets/TicketCreateModal'; -import MfaSuccessView from './MfaSuccessView'; import styles from './Mfa.module.css'; const MfaUnpairingView: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { @@ -32,8 +31,6 @@ const MfaUnpairingView: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { }); }; - if (data?.token?.rollout_state === 'verify') return ; - return ( <> diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx new file mode 100644 index 000000000..55e225da0 --- /dev/null +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { useLocation } from 'react-router-dom'; +import MfaSelection from './MfaSelection'; +import MfaSuccessView from './MfaSuccessView'; +import { useMfa } from '@tacc/tup-hooks'; +import { LoadingSpinner } from '@tacc/core-components'; + +const MfaWrapper: React.FC = ({ children }) => { + const location = useLocation(); + const isUnpairing = location.pathname.includes('unpair'); + const isPairing = location.pathname.includes('pair') && !isUnpairing; + const { isLoading, data } = useMfa(); + + return ( + <> + {isLoading ? + : (data?.token?.rollout_state === 'enrolled' && isPairing) ? + : (data?.token?.rollout_state === 'verify' && isUnpairing) ? + : (!data) ? + : <>{children} + } + + ) +}; + +export default MfaWrapper; diff --git a/libs/tup-components/src/mfa/index.ts b/libs/tup-components/src/mfa/index.ts index 9f3c20ec5..6ce7f09c6 100644 --- a/libs/tup-components/src/mfa/index.ts +++ b/libs/tup-components/src/mfa/index.ts @@ -2,3 +2,4 @@ export { default as MfaSelection } from './MfaSelection'; export { default as MfaHeader } from './MfaHeader'; export { default as MfaPairingview } from './MfaPairingView'; export { default as MfaUnpairingview } from './MfaUnpairingView'; +export { default as MfaWrapper } from './MfaWrapper'; From 0098d01693a9ffc74a8bc19795255db842c3a3d0 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Thu, 10 Aug 2023 12:41:04 -0500 Subject: [PATCH 06/19] chore: remove unused imports and vars --- libs/tup-components/src/mfa/MfaPairingView.tsx | 3 --- libs/tup-components/src/mfa/MfaUnpairingView.tsx | 2 -- 2 files changed, 5 deletions(-) diff --git a/libs/tup-components/src/mfa/MfaPairingView.tsx b/libs/tup-components/src/mfa/MfaPairingView.tsx index 49f08b0c2..ddbc52212 100644 --- a/libs/tup-components/src/mfa/MfaPairingView.tsx +++ b/libs/tup-components/src/mfa/MfaPairingView.tsx @@ -1,13 +1,10 @@ import React from 'react'; -import { useMfa } from '@tacc/tup-hooks'; import MfaQRPanel from './MfaQRPanel'; import MfaSmsPanel from './MfaSmsPanel'; import MfaValidationPanel from './MfaValidationPanel'; import styles from './Mfa.module.css'; const MfaPairingLayout: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { - const { data } = useMfa(); - return (
    1. diff --git a/libs/tup-components/src/mfa/MfaUnpairingView.tsx b/libs/tup-components/src/mfa/MfaUnpairingView.tsx index 5841a40ed..a2026096c 100644 --- a/libs/tup-components/src/mfa/MfaUnpairingView.tsx +++ b/libs/tup-components/src/mfa/MfaUnpairingView.tsx @@ -5,7 +5,6 @@ import { SectionMessage, } from '@tacc/core-components'; import { - useMfa, useMfaDelete, useMfaChallenge, useMfaEmailUnpair, @@ -14,7 +13,6 @@ import TicketCreateModal from '../tickets/TicketCreateModal'; import styles from './Mfa.module.css'; const MfaUnpairingView: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { - const { data } = useMfa(); const [currentToken, setCurrentToken] = useState(''); const { mutate: unpairWithCode, isError } = useMfaDelete(); const { mutate: unpairWithEmail, isSuccess: emailSentSuccess } = From 81d196320691389cd4aeae389eac63525bf76471 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Thu, 10 Aug 2023 12:41:20 -0500 Subject: [PATCH 07/19] chore: nx format:write --- apps/tup-ui/src/App.tsx | 10 ++++-- .../src/accounts/ManageAccountMfa.tsx | 19 +++++------ .../tup-components/src/mfa/MfaSuccessView.tsx | 8 ++--- .../src/mfa/MfaUnpairingView.tsx | 32 ++++++++----------- libs/tup-components/src/mfa/MfaWrapper.tsx | 19 +++++++---- 5 files changed, 43 insertions(+), 45 deletions(-) diff --git a/apps/tup-ui/src/App.tsx b/apps/tup-ui/src/App.tsx index 32469804f..910b3a672 100644 --- a/apps/tup-ui/src/App.tsx +++ b/apps/tup-ui/src/App.tsx @@ -55,8 +55,14 @@ function App() { } /> } /> } /> - } /> - } /> + } + /> + } + /> { - ) - }; + ); + } const hasPairing = data?.token?.rollout_state === 'enrolled'; return ( <> @@ -61,7 +55,10 @@ export const AccountMfa: React.FC = () => {

      {TOKEN_TYPE[data.token.tokentype]} ({data.token.serial})

      - + diff --git a/libs/tup-components/src/mfa/MfaSuccessView.tsx b/libs/tup-components/src/mfa/MfaSuccessView.tsx index 8143387c2..f29484e13 100644 --- a/libs/tup-components/src/mfa/MfaSuccessView.tsx +++ b/libs/tup-components/src/mfa/MfaSuccessView.tsx @@ -8,12 +8,8 @@ const MfaSuccessView: React.FC<{ task: 'pair' | 'unpair' }> = ({ task }) => { return (
      - {task === 'pair' && ( - 'Pairing successful' - )} - {task === 'unpair' && ( - 'Unpairing successful' - )} + {task === 'pair' && 'Pairing successful'} + {task === 'unpair' && 'Unpairing successful'} - - )} - {method === 'totp' && ( - - )} + {method === 'sms' && ( + <> + + + + )} + {method === 'totp' && }
    2. diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx index 55e225da0..767d820dd 100644 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -13,14 +13,19 @@ const MfaWrapper: React.FC = ({ children }) => { return ( <> - {isLoading ? - : (data?.token?.rollout_state === 'enrolled' && isPairing) ? - : (data?.token?.rollout_state === 'verify' && isUnpairing) ? - : (!data) ? - : <>{children} - } + {isLoading ? ( + + ) : data?.token?.rollout_state === 'enrolled' && isPairing ? ( + + ) : data?.token?.rollout_state === 'verify' && isUnpairing ? ( + + ) : !data ? ( + + ) : ( + <>{children} + )} - ) + ); }; export default MfaWrapper; From f5283c28d2ebbf55818ec671bd3ec26dd167b041 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 11:13:25 -0500 Subject: [PATCH 08/19] style: simplify MfaWrapper conditional return --- libs/tup-components/src/mfa/MfaWrapper.tsx | 26 +++++++++------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx index 767d820dd..35da9c57f 100644 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -11,21 +11,17 @@ const MfaWrapper: React.FC = ({ children }) => { const isPairing = location.pathname.includes('pair') && !isUnpairing; const { isLoading, data } = useMfa(); - return ( - <> - {isLoading ? ( - - ) : data?.token?.rollout_state === 'enrolled' && isPairing ? ( - - ) : data?.token?.rollout_state === 'verify' && isUnpairing ? ( - - ) : !data ? ( - - ) : ( - <>{children} - )} - - ); + if (isLoading) { + return ; + } else if (data?.token?.rollout_state === 'enrolled' && isPairing) { + return ; + } else if (data?.token?.rollout_state === 'verify' && isUnpairing) { + return ; + } else if (!data) { + return ; + } else { + return {children}; + } }; export default MfaWrapper; From 617c20556b12a431c38d7fce28203d0e08a15367 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 11:21:25 -0500 Subject: [PATCH 09/19] refactor: MfaWrapper return statement had warnings --- libs/tup-components/src/mfa/MfaWrapper.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx index 35da9c57f..3246a9581 100644 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -19,9 +19,10 @@ const MfaWrapper: React.FC = ({ children }) => { return ; } else if (!data) { return ; - } else { - return {children}; } + + /*eslint-disable-next-line react/jsx-no-useless-fragment */ + return <>{children}; }; export default MfaWrapper; From cb5c568d1d3213b2831ef4f4ff61d0207f72ea5f Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 11:23:28 -0500 Subject: [PATCH 10/19] refactor: MfaWrapper return statement simplified --- libs/tup-components/src/mfa/MfaWrapper.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx index 3246a9581..edbd92495 100644 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -13,11 +13,14 @@ const MfaWrapper: React.FC = ({ children }) => { if (isLoading) { return ; - } else if (data?.token?.rollout_state === 'enrolled' && isPairing) { + } + if (data?.token?.rollout_state === 'enrolled' && isPairing) { return ; - } else if (data?.token?.rollout_state === 'verify' && isUnpairing) { + } + if (data?.token?.rollout_state === 'verify' && isUnpairing) { return ; - } else if (!data) { + } + if (!data) { return ; } From e2c486dced32117bdf1e2f79823b929ed3644b70 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 12:12:10 -0500 Subject: [PATCH 11/19] refactor: use tokentype not path during unpairing --- apps/tup-ui/src/App.tsx | 9 +-------- .../src/mfa/MfaUnpairingView.tsx | 19 ++++++++++++++++--- libs/tup-components/src/mfa/MfaWrapper.tsx | 9 +++------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/tup-ui/src/App.tsx b/apps/tup-ui/src/App.tsx index 910b3a672..3ed7dbc4b 100644 --- a/apps/tup-ui/src/App.tsx +++ b/apps/tup-ui/src/App.tsx @@ -55,14 +55,7 @@ function App() { } /> } /> } /> - } - /> - } - /> + } /> = ({ method }) => { +const MfaUnpairingView: React.FC = () => { const [currentToken, setCurrentToken] = useState(''); - const { mutate: unpairWithCode, isError } = useMfaDelete(); + const { data, isLoading } = useMfa(); + const { mutate: unpairWithCode, isError: isError } = useMfaDelete(); const { mutate: unpairWithEmail, isSuccess: emailSentSuccess } = useMfaEmailUnpair(); const { mutate: sendChallenge, isSuccess: sendChallengeSuccess } = useMfaChallenge(); + const method = data?.token?.tokentype; + const submit = (e: React.FormEvent) => { e.preventDefault(); e.stopPropagation(); @@ -26,6 +35,10 @@ const MfaUnpairingView: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { }); }; + if (isLoading || !data) { + return ; + } + return ( <> diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx index edbd92495..92563c70b 100644 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -1,23 +1,20 @@ import React from 'react'; -import { useLocation } from 'react-router-dom'; import MfaSelection from './MfaSelection'; import MfaSuccessView from './MfaSuccessView'; import { useMfa } from '@tacc/tup-hooks'; import { LoadingSpinner } from '@tacc/core-components'; const MfaWrapper: React.FC = ({ children }) => { - const location = useLocation(); - const isUnpairing = location.pathname.includes('unpair'); - const isPairing = location.pathname.includes('pair') && !isUnpairing; const { isLoading, data } = useMfa(); + const hasToken = Boolean( data?.token?.tokentype ); if (isLoading) { return ; } - if (data?.token?.rollout_state === 'enrolled' && isPairing) { + if (data?.token?.rollout_state === 'enrolled' && !hasToken) { return ; } - if (data?.token?.rollout_state === 'verify' && isUnpairing) { + if (data?.token?.rollout_state === 'verify' && hasToken) { return ; } if (!data) { From ea6dfc275fd34ddbcf85fd748dde4b6c8445e40a Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 12:15:23 -0500 Subject: [PATCH 12/19] fix: use the now simpler route paths --- apps/tup-ui/src/App.tsx | 4 ++-- libs/tup-components/src/accounts/ManageAccountMfa.tsx | 5 +---- libs/tup-components/src/mfa/MfaSelection.tsx | 4 ++-- libs/tup-hooks/src/mfa/useMfa.tsx | 4 ++-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/apps/tup-ui/src/App.tsx b/apps/tup-ui/src/App.tsx index 3ed7dbc4b..500e57104 100644 --- a/apps/tup-ui/src/App.tsx +++ b/apps/tup-ui/src/App.tsx @@ -53,8 +53,8 @@ function App() { } /> }> } /> - } /> - } /> + } /> + } /> } /> {

      {TOKEN_TYPE[data.token.tokentype]} ({data.token.serial})

      - + diff --git a/libs/tup-components/src/mfa/MfaSelection.tsx b/libs/tup-components/src/mfa/MfaSelection.tsx index 415c26b2e..92ff4cf19 100644 --- a/libs/tup-components/src/mfa/MfaSelection.tsx +++ b/libs/tup-components/src/mfa/MfaSelection.tsx @@ -9,10 +9,10 @@ const MfaSelector: React.FC = () => { Select whether you want to use an MFA token app or SMS texting for authenticating to your TACC account.
      - + - +
      diff --git a/libs/tup-hooks/src/mfa/useMfa.tsx b/libs/tup-hooks/src/mfa/useMfa.tsx index aa2099c0b..57883c58d 100644 --- a/libs/tup-hooks/src/mfa/useMfa.tsx +++ b/libs/tup-hooks/src/mfa/useMfa.tsx @@ -13,7 +13,7 @@ export const useMfa = (): UseQueryResult => { export const useMfaPairTotp = () => { const mutation = usePost({ - endpoint: '/mfa/pair/totp', + endpoint: '/mfa/totp', options: { mutationKey: ['mfapair'] }, }); return mutation; @@ -21,7 +21,7 @@ export const useMfaPairTotp = () => { export const useMfaPairSms = () => { const mutation = usePost<{ phoneNumber: string }, MfaPairingResponse>({ - endpoint: '/mfa/pair/sms', + endpoint: '/mfa/sms', options: { mutationKey: ['mfapair'] }, }); return mutation; From 626b39b2f61fc8f3460b73c181e4f2fe2f204238 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 12:15:37 -0500 Subject: [PATCH 13/19] chore: nx format:write --- libs/tup-components/src/mfa/MfaWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx index 92563c70b..87131d994 100644 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -6,7 +6,7 @@ import { LoadingSpinner } from '@tacc/core-components'; const MfaWrapper: React.FC = ({ children }) => { const { isLoading, data } = useMfa(); - const hasToken = Boolean( data?.token?.tokentype ); + const hasToken = Boolean(data?.token?.tokentype); if (isLoading) { return ; From 779be5356c3f48ad3cbdb34c5adcb0bf575bb47a Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 12:59:57 -0500 Subject: [PATCH 14/19] refactor: remove redundant code form MfaWrapper --- libs/tup-components/src/mfa/MfaWrapper.tsx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx index 87131d994..4c274708b 100644 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -1,25 +1,17 @@ import React from 'react'; -import MfaSelection from './MfaSelection'; import MfaSuccessView from './MfaSuccessView'; import { useMfa } from '@tacc/tup-hooks'; import { LoadingSpinner } from '@tacc/core-components'; const MfaWrapper: React.FC = ({ children }) => { const { isLoading, data } = useMfa(); - const hasToken = Boolean(data?.token?.tokentype); if (isLoading) { return ; } - if (data?.token?.rollout_state === 'enrolled' && !hasToken) { + if (data?.token?.rollout_state === 'enrolled') { return ; } - if (data?.token?.rollout_state === 'verify' && hasToken) { - return ; - } - if (!data) { - return ; - } /*eslint-disable-next-line react/jsx-no-useless-fragment */ return <>{children}; From 4a58bda96c18298f497b9ac46bafbb3dc1a37250 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 13:30:49 -0500 Subject: [PATCH 15/19] fix: resotre accidental API endpoint rename --- libs/tup-hooks/src/mfa/useMfa.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/tup-hooks/src/mfa/useMfa.tsx b/libs/tup-hooks/src/mfa/useMfa.tsx index 57883c58d..aa2099c0b 100644 --- a/libs/tup-hooks/src/mfa/useMfa.tsx +++ b/libs/tup-hooks/src/mfa/useMfa.tsx @@ -13,7 +13,7 @@ export const useMfa = (): UseQueryResult => { export const useMfaPairTotp = () => { const mutation = usePost({ - endpoint: '/mfa/totp', + endpoint: '/mfa/pair/totp', options: { mutationKey: ['mfapair'] }, }); return mutation; @@ -21,7 +21,7 @@ export const useMfaPairTotp = () => { export const useMfaPairSms = () => { const mutation = usePost<{ phoneNumber: string }, MfaPairingResponse>({ - endpoint: '/mfa/sms', + endpoint: '/mfa/pair/sms', options: { mutationKey: ['mfapair'] }, }); return mutation; From b662a7a09dfe1d218c6b08c34db8755a7e6e3ad1 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 13:50:57 -0500 Subject: [PATCH 16/19] chore: restore MfaWrapper logic to as it was --- libs/tup-components/src/mfa/MfaWrapper.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libs/tup-components/src/mfa/MfaWrapper.tsx b/libs/tup-components/src/mfa/MfaWrapper.tsx index 4c274708b..aee2b2bbe 100644 --- a/libs/tup-components/src/mfa/MfaWrapper.tsx +++ b/libs/tup-components/src/mfa/MfaWrapper.tsx @@ -6,12 +6,9 @@ import { LoadingSpinner } from '@tacc/core-components'; const MfaWrapper: React.FC = ({ children }) => { const { isLoading, data } = useMfa(); - if (isLoading) { - return ; - } - if (data?.token?.rollout_state === 'enrolled') { + if (isLoading) return ; + if (data?.token?.rollout_state === 'enrolled') return ; - } /*eslint-disable-next-line react/jsx-no-useless-fragment */ return <>{children}; From b5c09236a812be72f025bb386310ddf642b87a2f Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 13:52:19 -0500 Subject: [PATCH 17/19] fix: unpairing & pairing navigation --- apps/tup-ui/src/App.tsx | 8 ++++++-- apps/tup-ui/src/pages/Mfa/Mfa.tsx | 6 +++++- libs/tup-components/src/mfa/MfaUnpairingView.tsx | 7 +++++-- libs/tup-components/src/mfa/index.ts | 1 + 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/apps/tup-ui/src/App.tsx b/apps/tup-ui/src/App.tsx index 500e57104..e044d79d6 100644 --- a/apps/tup-ui/src/App.tsx +++ b/apps/tup-ui/src/App.tsx @@ -6,6 +6,7 @@ import { Tickets, MfaPairingview, MfaUnpairingview, + MfaSuccessview, MfaSelection, ManageAccount, RequireAuth, @@ -51,11 +52,14 @@ function App() {
      }> } /> - }> + }> } /> } /> } /> - } /> + + }> + } /> + } /> { +const Mfa: React.FC<{ task: 'pair' | 'unpair' }> = ({ task }) => { return (
      {/* Default to a "success" view if user has a verified token */} + {task === 'pair' ? ( + ) : ( + + )}
      ); diff --git a/libs/tup-components/src/mfa/MfaUnpairingView.tsx b/libs/tup-components/src/mfa/MfaUnpairingView.tsx index abba780ce..8fbbf501d 100644 --- a/libs/tup-components/src/mfa/MfaUnpairingView.tsx +++ b/libs/tup-components/src/mfa/MfaUnpairingView.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; +import { Navigate } from 'react-router-dom'; import { useMfa } from '@tacc/tup-hooks'; import { Button, @@ -17,7 +18,7 @@ import styles from './Mfa.module.css'; const MfaUnpairingView: React.FC = () => { const [currentToken, setCurrentToken] = useState(''); const { data, isLoading } = useMfa(); - const { mutate: unpairWithCode, isError: isError } = useMfaDelete(); + const { mutate: unpairWithCode, isError, isSuccess } = useMfaDelete(); const { mutate: unpairWithEmail, isSuccess: emailSentSuccess } = useMfaEmailUnpair(); const { mutate: sendChallenge, isSuccess: sendChallengeSuccess } = @@ -72,7 +73,7 @@ const MfaUnpairingView: React.FC = () => { id="current-mfa-token" /> - @@ -105,6 +106,8 @@ const MfaUnpairingView: React.FC = () => { There was an error verifying your MFA token. )} + + {isSuccess && }
    diff --git a/libs/tup-components/src/mfa/index.ts b/libs/tup-components/src/mfa/index.ts index 6ce7f09c6..666fa19f2 100644 --- a/libs/tup-components/src/mfa/index.ts +++ b/libs/tup-components/src/mfa/index.ts @@ -2,4 +2,5 @@ export { default as MfaSelection } from './MfaSelection'; export { default as MfaHeader } from './MfaHeader'; export { default as MfaPairingview } from './MfaPairingView'; export { default as MfaUnpairingview } from './MfaUnpairingView'; +export { default as MfaSuccessview } from './MfaSuccessView'; export { default as MfaWrapper } from './MfaWrapper'; From d647346afb703be3745d559eb7be1967c0fe5fc8 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 14:08:01 -0500 Subject: [PATCH 18/19] feat: loading state for sms pair challenge send --- libs/tup-components/src/mfa/MfaUnpairingView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/tup-components/src/mfa/MfaUnpairingView.tsx b/libs/tup-components/src/mfa/MfaUnpairingView.tsx index 8fbbf501d..da571f614 100644 --- a/libs/tup-components/src/mfa/MfaUnpairingView.tsx +++ b/libs/tup-components/src/mfa/MfaUnpairingView.tsx @@ -21,7 +21,7 @@ const MfaUnpairingView: React.FC = () => { const { mutate: unpairWithCode, isError, isSuccess } = useMfaDelete(); const { mutate: unpairWithEmail, isSuccess: emailSentSuccess } = useMfaEmailUnpair(); - const { mutate: sendChallenge, isSuccess: sendChallengeSuccess } = + const { mutate: sendChallenge, isSuccess: sendChallengeSuccess, isLoading: isChallengeLoading } = useMfaChallenge(); const method = data?.token?.tokentype; @@ -51,7 +51,7 @@ const MfaUnpairingView: React.FC = () => { {method === 'sms' && ( <> - From 8ec7f05f6e0677d429acb416b0b5ce6a151bc941 Mon Sep 17 00:00:00 2001 From: Wesley Bomar Date: Fri, 25 Aug 2023 14:14:34 -0500 Subject: [PATCH 19/19] chore: nx format:write --- apps/tup-ui/src/pages/Mfa/Mfa.tsx | 6 +++--- libs/tup-components/src/mfa/MfaUnpairingView.tsx | 13 ++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/apps/tup-ui/src/pages/Mfa/Mfa.tsx b/apps/tup-ui/src/pages/Mfa/Mfa.tsx index 115d2b7d3..ef7b1eaba 100644 --- a/apps/tup-ui/src/pages/Mfa/Mfa.tsx +++ b/apps/tup-ui/src/pages/Mfa/Mfa.tsx @@ -10,9 +10,9 @@ const Mfa: React.FC<{ task: 'pair' | 'unpair' }> = ({ task }) => { {/* Default to a "success" view if user has a verified token */} {task === 'pair' ? ( - - - + + + ) : ( )} diff --git a/libs/tup-components/src/mfa/MfaUnpairingView.tsx b/libs/tup-components/src/mfa/MfaUnpairingView.tsx index da571f614..d49b8b67f 100644 --- a/libs/tup-components/src/mfa/MfaUnpairingView.tsx +++ b/libs/tup-components/src/mfa/MfaUnpairingView.tsx @@ -21,8 +21,11 @@ const MfaUnpairingView: React.FC = () => { const { mutate: unpairWithCode, isError, isSuccess } = useMfaDelete(); const { mutate: unpairWithEmail, isSuccess: emailSentSuccess } = useMfaEmailUnpair(); - const { mutate: sendChallenge, isSuccess: sendChallengeSuccess, isLoading: isChallengeLoading } = - useMfaChallenge(); + const { + mutate: sendChallenge, + isSuccess: sendChallengeSuccess, + isLoading: isChallengeLoading, + } = useMfaChallenge(); const method = data?.token?.tokentype; @@ -51,7 +54,11 @@ const MfaUnpairingView: React.FC = () => { {method === 'sms' && ( <> -