From bafae60865100b9d071be5d8c5a339ac647dc79f Mon Sep 17 00:00:00 2001 From: leora Date: Sun, 17 Dec 2023 19:30:21 -0700 Subject: [PATCH 01/20] feat(sofi): consolidate sofi status into one state --- .../src/data/auth/sagas.ts | 5 ++- .../src/data/goals/sagas.ts | 43 +++---------------- .../src/data/modules/profile/actionTypes.ts | 1 + .../src/data/modules/profile/actions.ts | 5 +++ .../src/data/modules/profile/reducers.ts | 8 ++++ .../src/data/modules/profile/sagas.ts | 17 ++++++-- .../src/data/modules/profile/selectors.ts | 3 ++ .../src/data/modules/profile/types.ts | 7 +++ .../src/modals/Sofi/Welcome/index.tsx | 24 +++-------- .../src/scenes/Home/Banners/selectors.ts | 18 ++------ 10 files changed, 58 insertions(+), 73 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/auth/sagas.ts b/packages/blockchain-wallet-v4-frontend/src/data/auth/sagas.ts index 84630bf873e..58d38cd79f2 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/auth/sagas.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/auth/sagas.ts @@ -354,6 +354,9 @@ export default ({ api, coreSagas, networks }) => { if (userEligibility?.useExternalTradingAccount?.enabled && !isSofi) { return yield put(actions.router.push('/continue-on-phone')) } + if (!isSofi) { + yield put(actions.modules.profile.fetchSofiUserStatus()) + } const guid = yield select(selectors.core.wallet.getGuid) const isAccountReset: boolean = yield select(selectors.signup.getAccountReset) @@ -434,7 +437,7 @@ export default ({ api, coreSagas, networks }) => { } else { yield put(actions.router.push('/home')) } - yield put(actions.modules.profile.fetchSofiUserStatus()) + yield call(fetchBalances) yield call(saveGoals, firstLogin) // We run goals in accountResetSaga in this case diff --git a/packages/blockchain-wallet-v4-frontend/src/data/goals/sagas.ts b/packages/blockchain-wallet-v4-frontend/src/data/goals/sagas.ts index 60b08b7cfc6..b14abd9da33 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/goals/sagas.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/goals/sagas.ts @@ -48,34 +48,6 @@ export default ({ api, coreSagas, networks }) => { .getOrElse(false) } - const sofiMigrationStatusCheck = function* () { - // If user is coming from sofi migration, awaiting user or pending, don't them this modal - const sofiMigrationInitialStatus = (yield select( - selectors.modules.profile.getSofiUserData - )).getOrElse(null) - const sofiMigrationStatus = (yield select( - selectors.modules.profile.getSofiMigrationStatus - )).getOrElse(null) - const sofiMigrationStatusFromPolling = (yield select( - selectors.modules.profile.getSofiMigrationStatusFromPolling - )).getOrElse(null) - - if ( - sofiMigrationInitialStatus || - sofiMigrationStatusFromPolling || - sofiMigrationInitialStatus === 'AWAITING_USER' - ) { - return 'AWAITING_USER' - } - if ( - sofiMigrationInitialStatus || - sofiMigrationStatusFromPolling || - sofiMigrationInitialStatus === 'PENDING' - ) { - return 'PENDING' - } - } - // TODO: use new world deeplinking once merged const defineExchangeSettingsGoal = function* (search) { const params = new URLSearchParams(search) @@ -860,13 +832,11 @@ export default ({ api, coreSagas, networks }) => { const { isSofi: isSofiSignup } = yield select(selectors.signup.getProductSignupMetadata) const isSofiAuth = yield select(selectors.auth.getIsSofi) const isSofi = isSofiSignup || isSofiAuth - const sofiMigrationStatusFromPolling = (yield select( - selectors.modules.profile.getSofiMigrationStatusFromPolling - )).getOrElse(null) + const sofiMigrationStatus = yield select(selectors.modules.profile.getSofiUserMigrationStatus) // the purpose of this modal is only to show it if // user is logging in without sofi deeplink but needs to finish // migratioon process - if (sofiMigrationStatusFromPolling === SofiUserMigrationStatus.AWAITING_USER && !isSofi) { + if (sofiMigrationStatus === SofiUserMigrationStatus.AWAITING_USER && !isSofi) { yield put( actions.goals.addInitialModal({ data: { origin }, @@ -1088,15 +1058,14 @@ export default ({ api, coreSagas, networks }) => { kycVerification: { enabled: false } } as ProductEligibilityForUser) - const sofiStatus = yield call(sofiMigrationStatusCheck) - const sofiPending = sofiStatus === 'PENDING' - const sofiAwaitingUser = sofiStatus === 'AWAITING_USER' + const { isSofi: isSofiSignup } = yield select(selectors.signup.getProductSignupMetadata) + const isSofiAuth = yield select(selectors.auth.getIsSofi) + const isSofi = isSofiSignup || isSofiAuth if ( current < 2 && !hasCowboysTag && - !sofiPending && - !sofiAwaitingUser && + !isSofi && products?.kycVerification?.enabled && kycState !== KYC_STATES.REJECTED ) { diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/actionTypes.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/actionTypes.ts index df6f68a4e26..3e7ea8439e6 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/actionTypes.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/actionTypes.ts @@ -59,6 +59,7 @@ export const INITIATE_SOFI_LANDING = '@DATA.INITIATE_SOFI_LANDING' export const SET_SOFI_LINK_DATA = '@DATA.SET_SOFI_LINK_DATA' export const FETCH_SOFI_USER_STATUS = '@DATA.FETCH_SOFI_USER_STATUS' +export const SET_SOFI_USER_STATUS = '@DATA.SET_SOFI_USER_STATUS' export const SET_SOFI_USER_STATUS_FROM_POLLING = '@DATA.SET_SOFI_USER_STATUS_FROM_POLLING' export const SET_SOFI_MIGRATED_BALANCES = '@DATA.SET_SOFI_MIGRATED_BALANCES' export const SOFI_REDIRECT_AFTER_EMAIL_VERIFICATION = '@DATA.SOFI_REDIRECT_AFTER_EMAIL_VERIFICATION' diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/actions.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/actions.ts index 469a89e4b90..015833340b1 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/actions.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/actions.ts @@ -242,3 +242,8 @@ export const setSofiMigratedBalances = (balances) => ({ export const sofiRedirectAfterEmailVerification = () => ({ type: AT.SOFI_REDIRECT_AFTER_EMAIL_VERIFICATION }) + +export const setSofiUserStatus = (sofiUserStatus) => ({ + payload: { sofiUserStatus }, + type: AT.SET_SOFI_USER_STATUS +}) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/reducers.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/reducers.ts index 61ba0b6b9c8..170f342ff7c 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/reducers.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/reducers.ts @@ -21,6 +21,7 @@ const INITIAL_STATE: ProfileState = { sofiMigrationStatus: Remote.NotAsked, sofiMigrationStatusFromPolling: Remote.NotAsked, sofiMigrationTransferedBalances: Remote.NotAsked, + sofiUserMigrationStatus: null, userCampaigns: Remote.NotAsked, userData: Remote.NotAsked, userRiskSettings: Remote.NotAsked, @@ -284,6 +285,13 @@ export function profileReducer(state = INITIAL_STATE, action: ProfileActionTypes } } + case AT.SET_SOFI_USER_STATUS: { + return { + ...state, + sofiUserMigrationStatus: action.payload.sofiUserStatus + } + } + default: return state } diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts index a25f4b23458..724eb5ac897 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts @@ -771,15 +771,20 @@ export default ({ api, coreSagas, networks }) => { const fetchSofiUserStatus = function* () { try { const response = yield call(api.sofiMigrationStatusNabuToken) - yield put(A.setSofiUserStatusFromPolling(response?.migrationStatus)) + yield put(A.setSofiUserStatus(response.migrationStatus)) - if (response.migrationStatus === 'SUCCESS' || response.migrationStatus === 'PENDING') { + if (response.migrationStatus === 'PENDING') { yield put(A.setSofiMigratedBalances(response?.balances)) - return true } - if (response.migrationStatus === 'AWAITING_USER') { + + if (response.migrationStatus === 'SUCCESS') { + yield put(A.setSofiMigratedBalances(response?.balances)) return true } + // i don't think i want to dot his + // if (response.migrationStatus === 'AWAITING_USER') { + // return true + // } if (response?.migrationStatus === 'FAILURE' || !response?.migrationStatus) { return true } @@ -805,7 +810,11 @@ export default ({ api, coreSagas, networks }) => { if (userStatusResponse.migration_status === SofiUserMigrationStatus.SUCCESS) { yield put(A.setSofiMigratedBalances(response.balances)) } + if (userStatusResponse.migration_status === SofiUserMigrationStatus.PENDING) { + yield call(fetchSofiUserStatus) + } yield put(A.migrateSofiUserSuccess(response)) + yield put(A.setSofiUserStatus(response.migration_status)) } catch (e) { yield put( A.migrateSofiUserFailure({ diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/selectors.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/selectors.ts index 8838388e78d..125d2430776 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/selectors.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/selectors.ts @@ -158,6 +158,9 @@ export const getSofiAssociateNabuUserStatus = (state: RootState) => export const getSofiMigrationStatusFromPolling = (state: RootState) => state.profile.sofiMigrationStatusFromPolling +export const getSofiUserMigrationStatus = (state: RootState) => + state.profile.sofiUserMigrationStatus + export const getSofiMigrationTransferedBalances = (state: RootState) => state.profile.sofiMigrationTransferedBalances diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/types.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/types.ts index b8be6fc0d43..234ef6685b8 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/types.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/types.ts @@ -202,6 +202,7 @@ export interface ProfileState { sofiMigrationStatus: RemoteDataType sofiMigrationStatusFromPolling: RemoteDataType sofiMigrationTransferedBalances: RemoteDataType + sofiUserMigrationStatus: SofiUserMigrationStatus | null userCampaigns: RemoteDataType userData: RemoteDataType userRiskSettings: RemoteDataType @@ -465,6 +466,11 @@ interface SetSofiMigratedBalancesAction { type: typeof AT.SET_SOFI_MIGRATED_BALANCES } +interface SetSofiUserStatusAction { + payload: { sofiUserStatus: SofiUserMigrationStatus } + type: typeof AT.SET_SOFI_USER_STATUS +} + export type ProfileActionTypes = | AssociateSofiUserSignupAction | AssociateSofiUserLoginAction @@ -510,6 +516,7 @@ export type ProfileActionTypes = | SetLinkToExchangeAccountDeeplinkAction | SetSofiLinkDataAction | SetSofiMigratedBalancesAction + | SetSofiUserStatusAction | SetSofiUserStatusFromPollingAction | ShareWalletAddressesWithExchange | ShareWalletAddressWithExchangeFailureAction diff --git a/packages/blockchain-wallet-v4-frontend/src/modals/Sofi/Welcome/index.tsx b/packages/blockchain-wallet-v4-frontend/src/modals/Sofi/Welcome/index.tsx index 5356d99b9a4..b827f77ec19 100644 --- a/packages/blockchain-wallet-v4-frontend/src/modals/Sofi/Welcome/index.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/modals/Sofi/Welcome/index.tsx @@ -21,28 +21,18 @@ const Body = styled(ModalBody)` const SofiWelcome = (props: Props) => { const dispatch = useDispatch() const sofiMigrationStatus = useSelector( - (state: RootState) => state.profile.sofiMigrationStatus - ).getOrElse(null) - const sofiMigrationStatusFromPolling = useSelector( - (state: RootState) => state.profile.sofiMigrationStatusFromPolling - ).getOrElse(null) + (state: RootState) => state.profile.sofiUserMigrationStatus + ) + // TODO: may need to optimize this to load if both statuses are null // so it doesn't start as one or finish in another. // i don't think this will happen in real cases since migration since this // modal shows only after ssn verification - const statusPending = - sofiMigrationStatus === SofiUserMigrationStatus.PENDING || - sofiMigrationStatusFromPolling === SofiUserMigrationStatus.PENDING - const statusSuccess = - sofiMigrationStatus === SofiUserMigrationStatus.SUCCESS || - sofiMigrationStatusFromPolling === SofiUserMigrationStatus.SUCCESS - const statusFailure = - sofiMigrationStatus === SofiUserMigrationStatus.FAILURE || - sofiMigrationStatusFromPolling === SofiUserMigrationStatus.FAILURE + const statusPending = sofiMigrationStatus === SofiUserMigrationStatus.PENDING - const statusAwaitingUser = - sofiMigrationStatus === SofiUserMigrationStatus.AWAITING_USER || - sofiMigrationStatusFromPolling === SofiUserMigrationStatus.AWAITING_USER + const statusSuccess = sofiMigrationStatus === SofiUserMigrationStatus.SUCCESS + const statusFailure = sofiMigrationStatus === SofiUserMigrationStatus.FAILURE + const statusAwaitingUser = sofiMigrationStatus === SofiUserMigrationStatus.AWAITING_USER const continueButtonClick = () => { dispatch(actions.modals.closeModal(ModalName.SOFI_BLOCKCHAIN_WELCOME)) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Home/Banners/selectors.ts b/packages/blockchain-wallet-v4-frontend/src/scenes/Home/Banners/selectors.ts index fb181194172..852c7faa15b 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Home/Banners/selectors.ts +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Home/Banners/selectors.ts @@ -245,20 +245,10 @@ export const getData = (state: RootState) => { const isKycEnabled = products?.kycVerification?.enabled // SOFI - const sofiMigrationPending = selectors.modules.profile - .getSofiMigrationStatus(state) - .getOrElse(null) - const sofiMigrationPendingPolling = selectors.modules.profile - .getSofiMigrationStatusFromPolling(state) - .getOrElse(null) - - const showSofiMigration = - sofiMigrationPending === SofiUserMigrationStatus.PENDING || - sofiMigrationPendingPolling === SofiUserMigrationStatus.PENDING - - const showSofiFinishMigration = - sofiMigrationPending === SofiUserMigrationStatus.AWAITING_USER || - sofiMigrationPendingPolling === SofiUserMigrationStatus.AWAITING_USER + const sofiUserMigrationStatus = selectors.modules.profile.getSofiUserMigrationStatus(state) + const showSofiMigration = sofiUserMigrationStatus === SofiUserMigrationStatus.PENDING + + const showSofiFinishMigration = sofiUserMigrationStatus === SofiUserMigrationStatus.AWAITING_USER const showSofiMigrationBanner = showBanner( showSofiMigration, From e716b61e441492e45d59359f69fdcdcd71a002d0 Mon Sep 17 00:00:00 2001 From: leora Date: Sun, 17 Dec 2023 19:50:32 -0700 Subject: [PATCH 02/20] chore(merge): add selector to fix conflict --- .../blockchain-wallet-v4/src/redux/walletOptions/selectors.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/blockchain-wallet-v4/src/redux/walletOptions/selectors.ts b/packages/blockchain-wallet-v4/src/redux/walletOptions/selectors.ts index 78c0df82d83..37e0d196422 100644 --- a/packages/blockchain-wallet-v4/src/redux/walletOptions/selectors.ts +++ b/packages/blockchain-wallet-v4/src/redux/walletOptions/selectors.ts @@ -230,3 +230,7 @@ export const getProveEnabled = (state: RootState) => // sofi export const getAssociateSofiBeforeEmailVerification = (state: RootState) => getWebOptions(state).map(path(['featureFlags', 'sofiAssociateUserBeforeEmailVerification'])) + +// Fiat Remediation +export const getFiatEntityRemediationAlert = (state: RootState) => + getWebOptions(state).map(path(['featureFlags', 'showFiatEntityRemediationAlert'])) From bcab2a9b481e93d9e5080cb16ea82342afb45316 Mon Sep 17 00:00:00 2001 From: leora Date: Mon, 18 Dec 2023 07:38:02 -0700 Subject: [PATCH 03/20] feat(sofi): pass referral code at signup too --- .../src/data/modules/profile/sagas.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts index 724eb5ac897..2b1752ddcf3 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts @@ -263,12 +263,13 @@ export default ({ api, coreSagas, networks }) => { const generateAuthCredentials = function* () { const retailToken = yield call(generateRetailToken) + const { isSofi } = yield select(selectors.signup.getProductSignupMetadata) const cookies = new Cookies() - const partnerReferralCode = cookies.get('partnerReferralCode') + const partnerReferralCodeFromCookie = cookies.get('partnerReferralCode') const { token: nabuLifetimeToken, userId: nabuUserId } = yield call( api.createOrGetUser, retailToken, - partnerReferralCode + isSofi ? 'sofi' : partnerReferralCodeFromCookie ) // write to both to support legacy mobile clients // TODO: in future, consider just writing to unifiedCredentials entry From af8e412b40f1989da838e53ef48f979fee5abc4a Mon Sep 17 00:00:00 2001 From: leora Date: Mon, 18 Dec 2023 09:04:03 -0700 Subject: [PATCH 04/20] feat(sofi): autocapitalize off on email field --- .../src/scenes/Login/Sofi/Email/index.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Sofi/Email/index.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Sofi/Email/index.tsx index 9e0beb5f2c8..7fc19be0915 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Sofi/Email/index.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Sofi/Email/index.tsx @@ -10,11 +10,6 @@ import FormGroup from 'components/Form/FormGroup' import FormItem from 'components/Form/FormItem' import TextBox from 'components/Form/TextBox' import { Wrapper } from 'components/Public' -import { selectors } from 'data' -import { LOGIN_FORM } from 'data/auth/model' -import { LoginSteps, ProductAuthOptions } from 'data/types' -import { required, validWalletIdOrEmail } from 'services/forms' -import { removeWhitespace } from 'services/forms/normalizers' import { media } from 'services/styles' import { Props } from '../..' @@ -91,6 +86,7 @@ const Email = (props: Props) => { data-e2e='sofiLoginEmail' name='sofiLoginEmail' noLastPass + autoCapitalize='none' /> From 43ccc282aeaab5cb2228034b98ab21c7440da11c Mon Sep 17 00:00:00 2001 From: leora Date: Mon, 18 Dec 2023 09:42:30 -0700 Subject: [PATCH 05/20] chore(conflict): merge conflict --- .../blockchain-wallet-v4/src/redux/walletOptions/selectors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blockchain-wallet-v4/src/redux/walletOptions/selectors.ts b/packages/blockchain-wallet-v4/src/redux/walletOptions/selectors.ts index 37e0d196422..1884fa443ce 100644 --- a/packages/blockchain-wallet-v4/src/redux/walletOptions/selectors.ts +++ b/packages/blockchain-wallet-v4/src/redux/walletOptions/selectors.ts @@ -227,7 +227,7 @@ export const getImportedAddressSweep = (state: RootState) => export const getProveEnabled = (state: RootState) => getWebOptions(state).map(path(['featureFlags', 'proveEnabled'])) -// sofi +// sofi associate before email verification export const getAssociateSofiBeforeEmailVerification = (state: RootState) => getWebOptions(state).map(path(['featureFlags', 'sofiAssociateUserBeforeEmailVerification'])) From d6a0186c774ea8b6bca16510116464e33d4f45cd Mon Sep 17 00:00:00 2001 From: leora Date: Mon, 18 Dec 2023 15:11:24 -0700 Subject: [PATCH 06/20] feat(sofi): add guid login and case sensitivity note --- .../src/data/auth/sagas.ts | 3 +++ .../src/data/modules/profile/sagas.ts | 4 ++++ .../src/scenes/Login/Sofi/Email/index.tsx | 18 ++++++++++++++++++ .../src/scenes/SofiLanding/template.error.tsx | 8 +++++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/auth/sagas.ts b/packages/blockchain-wallet-v4-frontend/src/data/auth/sagas.ts index 58d38cd79f2..f0480c398b6 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/auth/sagas.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/auth/sagas.ts @@ -963,6 +963,9 @@ export default ({ api, coreSagas, networks }) => { if (isGuid(guidOrEmail) && product === ProductAuthOptions.WALLET) { yield put(actions.form.change(LOGIN_FORM, 'guid', guidOrEmail)) yield put(actions.form.change(LOGIN_FORM, 'step', LoginSteps.ENTER_PASSWORD_WALLET)) + } else if (isGuid(sofiLoginEmail) && product === ProductAuthOptions.WALLET) { + yield put(actions.form.change(LOGIN_FORM, 'guid', sofiLoginEmail)) + yield put(actions.form.change(LOGIN_FORM, 'step', LoginSteps.ENTER_PASSWORD_WALLET)) } else if (product === ProductAuthOptions.EXCHANGE) { // trigger email for exchange form yield put(actions.form.change(LOGIN_FORM, 'exchangeEmail', exchangeEmail)) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts index 2b1752ddcf3..718c2c71270 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts @@ -743,6 +743,10 @@ export default ({ api, coreSagas, networks }) => { let sofiUserState = response.sofiJwtPayload?.state let sofiUserCountry = response.sofiJwtPayload?.country || 'US' + if (!sofiUserState) { + yield put(A.fetchSofiMigrationStatusFailure('missing US state')) + return yield put(actions.router.push('/sofi')) + } if (sofiUserState.substring(0, 2) !== 'US') { sofiUserState = 'US-' + sofiUserState } diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Sofi/Email/index.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Sofi/Email/index.tsx index 7fc19be0915..8f86393d1b3 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Sofi/Email/index.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Sofi/Email/index.tsx @@ -10,6 +10,7 @@ import FormGroup from 'components/Form/FormGroup' import FormItem from 'components/Form/FormItem' import TextBox from 'components/Form/TextBox' import { Wrapper } from 'components/Public' +import { removeWhitespace } from 'services/forms/normalizers' import { media } from 'services/styles' import { Props } from '../..' @@ -31,6 +32,14 @@ const BackArrow = styled.div` margin: 24px 8px 8px 0; ` +const HelperText = styled(Text)` + font-size: 12px; + font-weight: 400; + margin-top: 4px; + margin-left: 2px; + color: ${(props) => props.theme.grey600}; +` + const Email = (props: Props) => { const { busy, formValues, invalid, routerActions, submitting } = props @@ -87,8 +96,17 @@ const Email = (props: Props) => { name='sofiLoginEmail' noLastPass autoCapitalize='none' + normalize={removeWhitespace} /> + + + + + { + const { data, error, isLoading, isNotAsked } = useRemote( + selectors.modules.profile.getSofiUserData + ) + return ( @@ -32,7 +38,7 @@ const SofiErrorLanding = () => { > From 624059a6eb2f08c99f5d8553f2b3a9f8329b9ad9 Mon Sep 17 00:00:00 2001 From: jjBlockchain Date: Mon, 18 Dec 2023 17:08:53 -0600 Subject: [PATCH 07/20] chore(sofi-copy-changes): update check email copy --- .../src/scenes/Login/Wallet/CheckEmail/index.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Wallet/CheckEmail/index.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Wallet/CheckEmail/index.tsx index 489a42f5be5..b086014af9e 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Wallet/CheckEmail/index.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Wallet/CheckEmail/index.tsx @@ -19,6 +19,7 @@ const FormBody = styled.div` display: flex; flex-direction: column; align-items: center; + margin-bottom: 24px; ` const LoginWrapper = styled(Wrapper)` @@ -80,7 +81,7 @@ const CheckEmail = (props: Props) => { /> - + @@ -94,7 +95,13 @@ const CheckEmail = (props: Props) => { > + + + From 24fd4d91e1bbb2b485985d0730071f0850ad1f6e Mon Sep 17 00:00:00 2001 From: jjBlockchain Date: Mon, 18 Dec 2023 17:14:44 -0600 Subject: [PATCH 08/20] chore(sofi-copy-changes): update verify magic link copy --- .../src/scenes/Login/VerifyMagicLink/template.success.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/VerifyMagicLink/template.success.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/VerifyMagicLink/template.success.tsx index 3666d7cffa3..1b92657db07 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/VerifyMagicLink/template.success.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/VerifyMagicLink/template.success.tsx @@ -94,16 +94,13 @@ const Success = (props) => { - + From acf91a60c90021bd02a2b92cc8a49b0a2651602f Mon Sep 17 00:00:00 2001 From: jjBlockchain Date: Mon, 18 Dec 2023 17:25:47 -0600 Subject: [PATCH 09/20] Revert "chore(sofi-copy-changes): update check email copy" This reverts commit 624059a6eb2f08c99f5d8553f2b3a9f8329b9ad9. --- .../src/scenes/Login/Wallet/CheckEmail/index.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Wallet/CheckEmail/index.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Wallet/CheckEmail/index.tsx index b086014af9e..489a42f5be5 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Wallet/CheckEmail/index.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/Wallet/CheckEmail/index.tsx @@ -19,7 +19,6 @@ const FormBody = styled.div` display: flex; flex-direction: column; align-items: center; - margin-bottom: 24px; ` const LoginWrapper = styled(Wrapper)` @@ -81,7 +80,7 @@ const CheckEmail = (props: Props) => { /> - + @@ -95,13 +94,7 @@ const CheckEmail = (props: Props) => { > - - - From 84a3f19dbf312c1a662c3117ac3ed8f7f438f062 Mon Sep 17 00:00:00 2001 From: jjBlockchain Date: Mon, 18 Dec 2023 17:26:08 -0600 Subject: [PATCH 10/20] Revert "chore(sofi-copy-changes): update verify magic link copy" This reverts commit 24fd4d91e1bbb2b485985d0730071f0850ad1f6e. --- .../src/scenes/Login/VerifyMagicLink/template.success.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/VerifyMagicLink/template.success.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/VerifyMagicLink/template.success.tsx index 1b92657db07..3666d7cffa3 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/Login/VerifyMagicLink/template.success.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/Login/VerifyMagicLink/template.success.tsx @@ -94,13 +94,16 @@ const Success = (props) => { - + From a584993b91b607756ec2b091627529f70b29fa1c Mon Sep 17 00:00:00 2001 From: jjBlockchain Date: Mon, 18 Dec 2023 17:32:23 -0600 Subject: [PATCH 11/20] chore(sofi-copy-changes): change copies for sign up flow email verification --- .../src/scenes/VerifyEmail/template.tsx | 20 +++++++++++++------ .../VerifyEmailToken/template.success.tsx | 7 ++----- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/VerifyEmail/template.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/VerifyEmail/template.tsx index b5959422c6f..5307eb0dcd7 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/VerifyEmail/template.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/VerifyEmail/template.tsx @@ -52,14 +52,22 @@ const VerifyEmail = ({ lineHeight='1.5' > + + + - - - From f59d7a865f8800ceb01337e9c4b02088bd5d37a0 Mon Sep 17 00:00:00 2001 From: leora Date: Mon, 18 Dec 2023 18:27:43 -0700 Subject: [PATCH 15/20] chore(Release): v4.96.8 --- package.json | 2 +- .../src/assets/locales/en.json | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index cabe532d39f..fde28e7d3bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-v4", - "version": "4.96.7", + "version": "4.96.8", "license": "AGPL-3.0-or-later", "private": true, "author": { diff --git a/packages/blockchain-wallet-v4-frontend/src/assets/locales/en.json b/packages/blockchain-wallet-v4-frontend/src/assets/locales/en.json index aded4554abf..391f98953d1 100644 --- a/packages/blockchain-wallet-v4-frontend/src/assets/locales/en.json +++ b/packages/blockchain-wallet-v4-frontend/src/assets/locales/en.json @@ -2178,6 +2178,7 @@ "scenes.earn.table.type": "{product} Rewards", "scenes.earnhistory.empty.description": "Once you start earning, those details will show up here.", "scenes.earnhistory.empty.title": "Your transactions go here", + "scenes.email.login.lowercase": "Email addresses are case sensitive", "scenes.exchange.changeinput": "Change Input", "scenes.exchange.confirm.oopsheader": "Oops! Something went wrong.", "scenes.exchange.connectnow": "Connect Now", @@ -2257,11 +2258,12 @@ "scenes.login._device_verification_expired.copy": "The device approval link has expired, please try again.", "scenes.login.account_recovery_options.title": "Account Recovery Options", "scenes.login.account_signup": "Don't have a Blockchain Account?", - "scenes.login.checkemail": "If you have an account registered with this email address, you will receive an email with a link to verify your device.", + "scenes.login.checkemail": "Check your email and click the button or link to verify your email address. Open the link on this device.", + "scenes.login.checkemail_2": "Come back here after verifying your email.", "scenes.login.device_verification_expired": "Verification link expired.", "scenes.login.device_verification_rejected": "Device verification rejected.", - "scenes.login.device_verified": "Your device is verified!", - "scenes.login.device_verified.copy": "Return to previous browser to continue logging in.", + "scenes.login.device_verified": "Device verified!", + "scenes.login.device_verified.copy": "You can safely close this tab or page. Go back to the other Blockchain.com tab or page to continue.", "scenes.login.email_guid": "Email or Wallet ID", "scenes.login.enter_password.setting_goal.title": "Log Into Your Wallet to Continue", "scenes.login.enter_password.settings_goal.subtitle": "For your security, we ask you to enter your password to continue to update your settings.", @@ -2733,7 +2735,9 @@ "scenes.sofi.signup.success.mobile.title": "Your account was created successfully. Go to the Blockchain.com App to keep enjoying your crypto experience.", "scenes.sofi.signup.success.title": "Your account was successfully created. Your crypto balances have been migrated.", "scenes.sofi.signup.welcome.body": "Migrating your crypto from SoFi is super quick. Choose how you’d like to continue. We’ll take care of migrating your crypto.", + "scenes.sofi.signup.welcome.body.pending": "Your account migration is already pending.", "scenes.sofi.signup.welcome.existing": "Already have a Blockchain account?", + "scenes.sofi.signup.welcome.existing.login": "Log into your account", "scenes.sofi.signup.welcome.new": "New to Blockchain.com?", "scenes.sofi.welcome.header": "Welcome to Blockchain.com!", "scenes.sofi.welcome.modal.awaiting": "You`re almost there! We have just verify your SoFi account before the migration is finished.", @@ -2826,6 +2830,8 @@ "scenes.verifyaccountrecovery.loading": "We're approving your request. Please wait...", "scenes.verifyaccountrecovery.previous": "Return to the previous tab to continue recovering your Blockchain.com Account.", "scenes.verifyemail.description": "We sent a verification email to {email}. Please click the link in the email to continue.", + "scenes.verifyemail.description_1": "Check your email and click the button or link to verify your email address.", + "scenes.verifyemail.description_2": "Come back here after verifying your email.", "scenes.verifyemail.do_it_later": "I’ll Do This Later.", "scenes.verifyemail.title": "Verify Your Email", "scenes.verifyemailtoken.error": "Something went wrong.", @@ -2833,8 +2839,8 @@ "scenes.verifyemailtoken.error.alreadyverified.title": "Your email is already verified.", "scenes.verifyemailtoken.error.tryagain": "Try logging in again or contact support.", "scenes.verifyemailtoken.loading": "We're verifying your email address. Please wait...", - "scenes.verifyemailtoken.return_new": "Return to the previous tab to access your Blockchain.com Account.", - "scenes.verifyemailtoken.verified": "Your email is verified!", + "scenes.verifyemailtoken.return_new": "You can safely close this tab or page. Go back to the other Blockchain.com tab or page to continue.", + "scenes.verifyemailtoken.verified": "Email Verified", "scenes.wallet.menutop.balance.totalbalance": "Total Balance", "scenes.wallet.menutop.balance.totalbalance.total": "Total Balance", "scenes.walletguidreminder.error": "We were unable to process your request at this time. Please try again or contact support if the issue persists.", From 924f0891c347bd1ef8990f8c8c9a3d072c5de5dd Mon Sep 17 00:00:00 2001 From: leora Date: Tue, 19 Dec 2023 08:48:05 -0700 Subject: [PATCH 16/20] feat(sofi): fix referral code --- .../src/data/modules/profile/sagas.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts index f48bfdc21b4..b2934d6432e 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts @@ -269,7 +269,11 @@ export default ({ api, coreSagas, networks }) => { const { token: nabuLifetimeToken, userId: nabuUserId } = yield call( api.createOrGetUser, retailToken, - isSofi ? 'sofi' : partnerReferralCodeFromCookie + isSofi + ? 'SOFI_MIGRATION' + : partnerReferralCodeFromCookie === 'sofi' + ? 'SOFI_MIGRATION' + : partnerReferralCodeFromCookie ) // write to both to support legacy mobile clients // TODO: in future, consider just writing to unifiedCredentials entry From d423041dd6668b167e8527c6467e69b7a684808b Mon Sep 17 00:00:00 2001 From: leora Date: Tue, 19 Dec 2023 09:44:41 -0700 Subject: [PATCH 17/20] fix(balances): correctly set balances after migration --- .../src/data/modules/profile/sagas.ts | 9 +++++---- .../src/modals/Sofi/MigratedBalances/index.tsx | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts index b2934d6432e..1e823db425f 100644 --- a/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts +++ b/packages/blockchain-wallet-v4-frontend/src/data/modules/profile/sagas.ts @@ -817,11 +817,12 @@ export default ({ api, coreSagas, networks }) => { const userStatusResponse = yield call(api.sofiMigrationStatusNabuToken) - if (userStatusResponse.migration_status === SofiUserMigrationStatus.SUCCESS) { - yield put(A.setSofiMigratedBalances(response.balances)) + if (userStatusResponse.migrationStatus === SofiUserMigrationStatus.SUCCESS) { + yield put(A.setSofiMigratedBalances(userStatusResponse.balances)) } - if (userStatusResponse.migration_status === SofiUserMigrationStatus.PENDING) { - yield call(fetchSofiUserStatus) + if (userStatusResponse.migrationStatus === SofiUserMigrationStatus.PENDING) { + yield put(A.setSofiMigratedBalances(userStatusResponse?.balances)) + yield put(A.fetchSofiUserStatus()) } yield put(A.migrateSofiUserSuccess(response)) yield put(A.setSofiUserStatus(response.migration_status)) diff --git a/packages/blockchain-wallet-v4-frontend/src/modals/Sofi/MigratedBalances/index.tsx b/packages/blockchain-wallet-v4-frontend/src/modals/Sofi/MigratedBalances/index.tsx index 780212a3ee1..b283ace5bc2 100644 --- a/packages/blockchain-wallet-v4-frontend/src/modals/Sofi/MigratedBalances/index.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/modals/Sofi/MigratedBalances/index.tsx @@ -30,7 +30,6 @@ const SofiMigratedBalances = (props: Props) => { const balances = useSelector( selectors.modules.profile.getSofiMigrationTransferedBalances ).getOrElse([]) as Array<{ amount: number; currency: string }> - const sofiMigrationUserStatus = useSelector( (state: RootState) => state.profile.sofiUserMigrationStatus ) From 3b0d38baef787f9c6623c2dce9194db2e1b696f6 Mon Sep 17 00:00:00 2001 From: leora Date: Tue, 19 Dec 2023 10:00:05 -0700 Subject: [PATCH 18/20] chore(Release): v4.96.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fde28e7d3bd..9125782d300 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-v4", - "version": "4.96.8", + "version": "4.96.9", "license": "AGPL-3.0-or-later", "private": true, "author": { From ba003e619d0f108cdd82bd1f8130d08f60ed0a3c Mon Sep 17 00:00:00 2001 From: leora Date: Tue, 19 Dec 2023 11:07:38 -0700 Subject: [PATCH 19/20] feat(sofi): add back mobile link --- .../VerifyEmailToken/template.success.tsx | 57 +++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/packages/blockchain-wallet-v4-frontend/src/scenes/VerifyEmailToken/template.success.tsx b/packages/blockchain-wallet-v4-frontend/src/scenes/VerifyEmailToken/template.success.tsx index 66d5092aded..8f157f64cb5 100644 --- a/packages/blockchain-wallet-v4-frontend/src/scenes/VerifyEmailToken/template.success.tsx +++ b/packages/blockchain-wallet-v4-frontend/src/scenes/VerifyEmailToken/template.success.tsx @@ -27,40 +27,39 @@ const Success = () => { - {/* commenting out mobile links for now since it's confusing - for sofi flow and don't know another workaround - (no sofi context on this landing page) */} - {/* {isMobile() ? ( + {isMobile() ? ( - ) : ( */} - - - - {/* )} - -