diff --git a/.circleci/config.yml b/.circleci/config.yml index e84a7ae15..6a74a8ad7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -259,7 +259,9 @@ workflows: branches: only: - dev - - PROD-4406_new-dice + - justin_fixes + - talent_search_fixes + - PROD-4398_integrate-userflow-remove-sprig - deployQa: context: org-global diff --git a/package.json b/package.json index 584a7f6a9..2ef92fbc4 100644 --- a/package.json +++ b/package.json @@ -246,9 +246,5 @@ } } ] - }, - "volta": { - "node": "16.15.0", - "yarn": "1.22.19" } } diff --git a/src/apps/accounts/src/lib/assets/security/credential.png b/src/apps/accounts/src/lib/assets/security/credential.png deleted file mode 100644 index 914e8d04f..000000000 Binary files a/src/apps/accounts/src/lib/assets/security/credential.png and /dev/null differ diff --git a/src/apps/accounts/src/lib/assets/security/index.ts b/src/apps/accounts/src/lib/assets/security/index.ts index 4559e27b4..8b87173a7 100644 --- a/src/apps/accounts/src/lib/assets/security/index.ts +++ b/src/apps/accounts/src/lib/assets/security/index.ts @@ -1,6 +1,6 @@ import { ReactComponent as MFAImage } from './mfa.svg' import { ReactComponent as AppleStore } from './apple-store.svg' -import credentialImage from './credential.png' +import { ReactComponent as UnSuccessfullDiceVerificationIcon } from './unsuccessful.svg' import diceIdLogo from './dicelogo.png' import diceIdLogoBig from './dicelogobig.png' import diceIdLogoSmall from './dicelogosmall.png' @@ -8,10 +8,10 @@ import googlePlay from './google-play.png' export { AppleStore, - credentialImage, diceIdLogo, diceIdLogoBig, diceIdLogoSmall, googlePlay, MFAImage, + UnSuccessfullDiceVerificationIcon, } diff --git a/src/apps/accounts/src/settings/tabs/account/security/Security.tsx b/src/apps/accounts/src/settings/tabs/account/security/Security.tsx index f521783bf..f8a608d40 100644 --- a/src/apps/accounts/src/settings/tabs/account/security/Security.tsx +++ b/src/apps/accounts/src/settings/tabs/account/security/Security.tsx @@ -1,8 +1,9 @@ import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react' import { toast } from 'react-toastify' import { KeyedMutator } from 'swr' +import { noop } from 'lodash' -import { Button, Collapsible, FormToggleSwitch } from '~/libs/ui' +import { Button, Collapsible, FormToggleSwitch, IconSolid, Tooltip } from '~/libs/ui' import { diceIdLogo, MFAImage, SettingSection, triggerSurvey } from '~/apps/accounts/src/lib' import { MemberMFAStatus, updateMemberMFAStatusAsync, useMemberMFAStatus, UserProfile } from '~/libs/core' @@ -22,12 +23,10 @@ const Security: FC = (props: SecurityProps) => { } = useMemberMFAStatus(props.profile.userId) const [mfaEnabled, setMFAEnabled]: [boolean, Dispatch>] = useState(false) - const [diceEnabled, setDiceEnabled]: [boolean, Dispatch>] = useState(false) useEffect(() => { if (mfaStatusData) { setMFAEnabled(mfaStatusData.mfaEnabled) - setDiceEnabled(mfaStatusData.diceEnabled) } }, [mfaStatusData]) @@ -37,9 +36,8 @@ const Security: FC = (props: SecurityProps) => { mfaEnabled: !mfaEnabled, }, }) - .then(response => { - setMFAEnabled(response.result.content.mfaEnabled) - setDiceEnabled(response.result.content.diceEnabled) + .then(() => { + setMFAEnabled(!mfaEnabled) toast.success('Your Multi Factor Authentication (MFA) status was updated.') triggerSurvey() }) @@ -48,27 +46,6 @@ const Security: FC = (props: SecurityProps) => { }) } - function handleUserDiceChange(): void { - if (!diceEnabled) { - return - } - - updateMemberMFAStatusAsync(props.profile.userId, { - param: { - diceEnabled: !diceEnabled, - }, - }) - .then(response => { - setMFAEnabled(response.result.content.mfaEnabled) - setDiceEnabled(response.result.content.diceEnabled) - toast.success('Your DICE credential was disabled.') - triggerSurvey() - }) - .catch(() => { - toast.error('Something went wrong. Please try again later.') - }) - } - function handleDiceModalStatus(): void { setSetupDiceModalOpen(!setupDiceModalOpen) } @@ -93,6 +70,7 @@ const Security: FC = (props: SecurityProps) => { name='mfaStatus' onChange={handleUserMFAChange} value={mfaEnabled} + disabled={mfaStatusData?.diceEnabled} /> )} /> @@ -108,11 +86,12 @@ const Security: FC = (props: SecurityProps) => { actionElement={(
{ - diceEnabled ? ( + mfaStatusData?.diceEnabled ? ( ) : (
)} /> diff --git a/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/ConnectionHandler/index.tsx b/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/ConnectionHandler/index.tsx deleted file mode 100644 index 07e3f7075..000000000 --- a/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/ConnectionHandler/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { FC, useEffect } from 'react' - -import { DiceConnectionStatus, useDiceIdConnection } from '~/libs/core' - -interface ConnectionHandlerProps { - onChange: (newStatus: DiceConnectionStatus) => void; - userId: number; -} - -export const ConnectionHandler: FC = ( - props: ConnectionHandlerProps, -) => { - const diceConnection: DiceConnectionStatus | undefined = useDiceIdConnection(props.userId) - - useEffect(() => { - if (diceConnection) { - props.onChange(diceConnection) - } - }, [diceConnection, props]) - - return ( - <> - ) -} diff --git a/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/DiceSetupModal.module.scss b/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/DiceSetupModal.module.scss index 0fe6f3dec..dd1329b65 100644 --- a/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/DiceSetupModal.module.scss +++ b/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/DiceSetupModal.module.scss @@ -34,12 +34,6 @@ margin: auto; } - .credentialImage { - height: 280px; - width: 400px; - align-self: center; - } - .diceBigLogo { margin: $sp-4 0; } diff --git a/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/DiceSetupModal.tsx b/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/DiceSetupModal.tsx index 1b03bce41..6e9cb87e5 100644 --- a/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/DiceSetupModal.tsx +++ b/src/apps/accounts/src/settings/tabs/account/security/dice-setup-modal/DiceSetupModal.tsx @@ -1,20 +1,21 @@ -/* eslint-disable complexity */ -import { Dispatch, FC, SetStateAction, useState } from 'react' +import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react' import { QRCodeSVG } from 'qrcode.react' +import { get, isUndefined, lowerCase } from 'lodash' import { toast } from 'react-toastify' import { KeyedMutator } from 'swr' import { BaseModal, Button } from '~/libs/ui' import { AppleStore, - credentialImage, diceIdLogoBig, diceIdLogoSmall, googlePlay, + UnSuccessfullDiceVerificationIcon, } from '~/apps/accounts/src/lib' -import { DiceConnectionStatus, UserProfile } from '~/libs/core' +import { DiceConnectionStatus, updateMemberMFAStatusAsync, useDiceIdConnection, UserProfile } from '~/libs/core' +import { EnvironmentConfig } from '~/config' -import { ConnectionHandler } from './ConnectionHandler' +import { VerificationListener } from './VerificationListener' import styles from './DiceSetupModal.module.scss' const GooglePlayLink: string = 'https://play.google.com/store/apps/details?id=com.diwallet1' @@ -28,7 +29,24 @@ interface DiceSetupModalProps { const DiceSetupModal: FC = (props: DiceSetupModalProps) => { const [step, setStep]: [number, Dispatch>] = useState(1) - const [diceConnectionUrl, setDiceConnectionUrl] = useState() + const [diceConnectionId, setDiceConnectionId]: [ + number | undefined, + Dispatch> + ] = useState() + + const diceConnection: DiceConnectionStatus | undefined = useDiceIdConnection(props.profile.userId, diceConnectionId) + + const [isVerificationProcessing, setIsVerificationProcessing]: [boolean, Dispatch>] + = useState(false) + + useEffect(() => { + if (diceConnection && !diceConnectionId) { + setDiceConnectionId(diceConnection.id) + } + }, [ + diceConnection, + diceConnectionId, + ]) function handleSecondaryButtonClick(): void { switch (step) { @@ -40,25 +58,42 @@ const DiceSetupModal: FC = (props: DiceSetupModalProps) => function handlePrimaryButtonClick(): void { switch (step) { case 1: + case 2: return setStep(step + 1) default: return props.onClose() } } - function handleDiceConnectionStatusChange(newStatus: DiceConnectionStatus): void { - if (newStatus.diceEnabled) { - setStep(4) - toast.success('Your credentials have been verified and you are all set for' - + ' MFA using your decentralized identity (DICE ID).') - props.mutateMFAData() - } else if (newStatus.accepted) { - setStep(3) - } else if (newStatus.connection) { - setDiceConnectionUrl(newStatus.connection) - setStep(2) + function verificationCallback(data: any): void { + if (data.success) { + const userEmail: string = get(data, 'user.profile.Email') + if (!isUndefined(userEmail) && lowerCase(userEmail) === lowerCase(props.profile.email)) { + updateMemberMFAStatusAsync(props.profile.userId, { + param: { + diceEnabled: true, + }, + }) + .then(() => { + props.mutateMFAData() + setStep(4) + // eslint-disable-next-line max-len + toast.success('Your credentials have been verified and you are all set for MFA using your decentralized identity (DICE ID).') + }) + .catch(() => { + toast.error('Something went wrong. Please try again later.') + }) + } else { + setStep(5) + } + } else { + setStep(5) } } + function onStartProcessing(): void { + setIsVerificationProcessing(true) + } + return ( = (props: DiceSetupModalProps) => onClick={handleSecondaryButtonClick} /> { - (step === 1 || step === 4) && ( + step !== 3 && (