Skip to content

Commit

Permalink
fix: use new window (#1676)
Browse files Browse the repository at this point in the history
* fix: use new window

* use query param

* fix data sharing agreement text

* genericize

* rename
  • Loading branch information
JP authored Nov 3, 2023
1 parent 5acb85c commit b9f8294
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 39 deletions.
24 changes: 19 additions & 5 deletions centrifuge-app/src/components/OnboardingAuthProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ export const OnboardingAuthContext = React.createContext<{
session?: { signed: string; payload: any } | null
login: () => void
isLoggingIn: boolean
isOnboardingExternally: boolean
setIsOnboardingExternally: React.Dispatch<React.SetStateAction<boolean>>
}>(null as any)

const AUTHORIZED_ONBOARDING_PROXY_TYPES = ['Any', 'Invest', 'NonTransfer', 'NonProxy']

export function OnboardingAuthProvider({ children }: { children: React.ReactNode }) {
const [isOnboardingExternally, setIsOnboardingExternally] = React.useState(false)
const {
substrate: { selectedWallet, selectedProxies, selectedAccount, evmChainId },
evm: { selectedAddress, ...evm },
Expand All @@ -24,13 +27,20 @@ export function OnboardingAuthProvider({ children }: { children: React.ReactNode
const cent = useCentrifuge()
const utils = useCentrifugeUtils()
const provider = useEvmProvider()

// onboarding-api expects the wallet address in the native substrate format
const address = selectedAccount?.address ? utils.formatAddress(selectedAccount?.address) : selectedAddress
const proxy = selectedProxies?.[0]

const { data: session, refetch: refetchSession } = useQuery(
['session', selectedAccount?.address, proxy?.delegator, selectedAddress],
['session', selectedAccount?.address, proxy?.delegator, selectedAddress, isOnboardingExternally],
() => {
// if user comes from external app
if (isOnboardingExternally) {
const externalSignatureSession = sessionStorage.getItem('external-centrifuge-onboarding-auth')
if (externalSignatureSession) return JSON.parse(externalSignatureSession)
}

if (address) {
if (proxy) {
const rawItem = sessionStorage.getItem(`centrifuge-onboarding-auth-${address}-${proxy.delegator}`)
Expand All @@ -45,7 +55,7 @@ export function OnboardingAuthProvider({ children }: { children: React.ReactNode
}
}
},
{ enabled: !!selectedAccount?.address || !!selectedAddress }
{ enabled: !!selectedAccount?.address || !!selectedAddress || isOnboardingExternally }
)

const { mutate: login, isLoading: isLoggingIn } = useMutation(async () => {
Expand All @@ -69,8 +79,10 @@ export function OnboardingAuthProvider({ children }: { children: React.ReactNode
session,
login,
isLoggingIn,
isOnboardingExternally,
setIsOnboardingExternally,
}),
[session, login, isLoggingIn]
[session, login, isLoggingIn, isOnboardingExternally, setIsOnboardingExternally]
)

return <OnboardingAuthContext.Provider value={ctx}>{children}</OnboardingAuthContext.Provider>
Expand All @@ -83,7 +95,7 @@ export function useOnboardingAuth() {
} = useWallet()
const ctx = React.useContext(OnboardingAuthContext)
if (!ctx) throw new Error('useOnboardingAuth must be used within OnboardingAuthProvider')
const { session } = ctx
const { session, isOnboardingExternally } = ctx
const authToken = session?.signed ? session.signed : ''

const {
Expand Down Expand Up @@ -116,7 +128,7 @@ export function useOnboardingAuth() {
}
},
{
enabled: (!!selectedAccount?.address || !!selectedAddress) && !!authToken,
enabled: (!!selectedAccount?.address || !!selectedAddress || isOnboardingExternally) && !!authToken,
retry: 1,
}
)
Expand All @@ -128,6 +140,8 @@ export function useOnboardingAuth() {
refetchAuth,
isAuthFetched: isFetched,
isLoading: ctx.isLoggingIn,
isOnboardingExternally: ctx.isOnboardingExternally,
setIsOnboardingExternally: ctx.setIsOnboardingExternally,
}
}

Expand Down
30 changes: 25 additions & 5 deletions centrifuge-app/src/components/OnboardingProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ interface OnboardingContextType<User, Pool> {
previousStep: () => void
isLoadingStep: boolean
setPool: React.Dispatch<React.SetStateAction<OnboardingPool | undefined>>
setIsOnboardingExternally: React.Dispatch<React.SetStateAction<boolean>>
isOnboardingExternally: boolean
}

const OnboardingContext = React.createContext<OnboardingContextType<OnboardingUser, OnboardingPool> | null>(null)
Expand All @@ -36,7 +38,7 @@ export function OnboardingProvider({ children }: { children: React.ReactNode })
evm: { selectedAddress: evmAddress },
connectedType,
} = useWallet()
const { isAuth, isAuthFetched, authToken } = useOnboardingAuth()
const { isAuth, isAuthFetched, authToken, setIsOnboardingExternally, isOnboardingExternally } = useOnboardingAuth()
const [activeStep, setActiveStep] = React.useState<number>(0)
const [pool, setPool] = React.useState<OnboardingPool>()

Expand Down Expand Up @@ -76,23 +78,29 @@ export function OnboardingProvider({ children }: { children: React.ReactNode })
},
{
refetchOnWindowFocus: false,
enabled: connectedType === 'evm' ? !!evmAddress : !!substrateAccount,
enabled: (connectedType === 'evm' ? !!evmAddress : !!substrateAccount) || isOnboardingExternally,
retry: 1,
}
)

React.useEffect(() => {
// tried to connect but no wallet is connected
if (!isConnecting && !(substrateAccount || evmAddress)) {
if (!isConnecting && !(substrateAccount || evmAddress || isOnboardingExternally)) {
return setActiveStep(1)
}
// wallet finished connection attempt, authentication was attempted, and user is not authenticated
if (!isConnecting && isOnboardingUserFetched && !isAuth) {
return setActiveStep(1)
}

const isIframe = window.self !== window.top

// wallet finished connection attempt, user was fetched
if (!isConnecting && isOnboardingUserFetched) {
if (
!isConnecting &&
isOnboardingUserFetched &&
(!isIframe || onboardingUser?.globalSteps?.verifyIdentity?.completed)
) {
const isPendingManualKybReview = onboardingUser?.manualKybStatus === 'review.pending'

const activeOnboardingStep = getActiveOnboardingStep(
Expand All @@ -104,7 +112,17 @@ export function OnboardingProvider({ children }: { children: React.ReactNode })

return setActiveStep(activeOnboardingStep)
}
}, [onboardingUser, isConnecting, isOnboardingUserFetched, isAuth, isAuthFetched, substrateAccount, evmAddress, pool])
}, [
onboardingUser,
isConnecting,
isOnboardingUserFetched,
isAuth,
isAuthFetched,
substrateAccount,
evmAddress,
pool,
isOnboardingExternally,
])

return (
<OnboardingContext.Provider
Expand All @@ -118,6 +136,8 @@ export function OnboardingProvider({ children }: { children: React.ReactNode })
previousStep,
setActiveStep,
isLoadingStep: activeStep === 0 || isConnecting || isOnboardingUserLoading,
setIsOnboardingExternally,
isOnboardingExternally,
}}
>
{children}
Expand Down
49 changes: 49 additions & 0 deletions centrifuge-app/src/pages/Onboarding/CompleteExternalOnboarding.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Button } from '@centrifuge/fabric'
import * as React from 'react'
import { ActionBar, Container, Content, ContentHeader, Header, Layout, PoolBranding } from '../../components/Onboarding'
import { useOnboarding } from '../../components/OnboardingProvider'

type Props = {
openNewTab: () => void
poolId: string | null
poolSymbol?: string
}

export const CompleteExternalOnboarding = ({ openNewTab, poolId, poolSymbol }: Props) => {
const { refetchOnboardingUser, isOnboardingExternally } = useOnboarding()

const onFocus = () => {
refetchOnboardingUser()
}

React.useEffect(() => {
window.addEventListener('focus', onFocus)

return () => {
window.removeEventListener('focus', onFocus)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

return (
<Layout>
<Header walletMenu={!isOnboardingExternally}>
{!!poolId && <PoolBranding poolId={poolId} symbol={poolSymbol} />}
</Header>

<Container>
<>
<Content>
<ContentHeader
title="Complete your onboarding in new tab"
body={'Once you are done, return back to this page.'}
/>
</Content>
<ActionBar>
<Button onClick={openNewTab}>Open in new tab</Button>
</ActionBar>
</>
</Container>
</Layout>
)
}
28 changes: 17 additions & 11 deletions centrifuge-app/src/pages/Onboarding/GlobalStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useOnboarding } from '../../components/OnboardingProvider'

export const GlobalStatus = () => {
const history = useHistory()
const { onboardingUser, refetchOnboardingUser } = useOnboarding()
const { onboardingUser, refetchOnboardingUser, isOnboardingExternally } = useOnboarding()

const onFocus = () => {
refetchOnboardingUser()
Expand Down Expand Up @@ -56,19 +56,25 @@ export const GlobalStatus = () => {
<Content>
<ContentHeader
title="Thanks for verifying your identity"
body="Please click the button below to access the pools available for investment."
body={
isOnboardingExternally
? 'Please close this tab and return back to the previous tab.'
: 'Please click the button below to access the pools available for investment.'
}
/>
</Content>

<ActionBar>
<Button
onClick={() => {
history.push('/pools')
}}
>
View Pools
</Button>
</ActionBar>
{!isOnboardingExternally && (
<ActionBar>
<Button
onClick={() => {
history.push('/pools')
}}
>
View Pools
</Button>
</ActionBar>
)}
</>
)
}
35 changes: 21 additions & 14 deletions centrifuge-app/src/pages/Onboarding/LinkWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,28 @@ export const LinkWallet = ({ globalOnboardingStatus }: Props) => {
checked={isAuth || formik.values.isAgreedToDataSharingAgreement}
disabled={isAuth}
errorMessage={formik.errors.isAgreedToDataSharingAgreement}
label={<Text style={{ cursor: 'pointer', paddingLeft: '6px' }}>I agree to the</Text>}
label={
<Shelf>
<Text style={{ cursor: 'pointer', paddingLeft: '6px' }}>I agree to the</Text>
<button
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
fontFamily: 'Inter,sans-serif',
paddingLeft: '4px',
lineHeight: '0',
}}
onClick={() => setIsDataSharingAgreementDialogOpen(true)}
>
<Text variant="body1" color="textInteractive">
data sharing agreement.
</Text>
</button>
</Shelf>
}
/>
<button
style={{
background: 'none',
border: 'none',
cursor: 'pointer',
fontFamily: 'Inter,sans-serif',
}}
onClick={() => setIsDataSharingAgreementDialogOpen(true)}
>
<Text variant="body1" color="textInteractive">
data sharing agreement.
</Text>
</button>

<DataSharingAgreementDialog
isDialogOpen={isDataSharingAgreementDialogOpen}
setIsDialogOpen={setIsDataSharingAgreementDialogOpen}
Expand Down
Loading

0 comments on commit b9f8294

Please sign in to comment.