diff --git a/apps/console/app/routes/apps/$clientId/team.tsx b/apps/console/app/routes/apps/$clientId/team.tsx index 57aef6a56c..cd17da8407 100644 --- a/apps/console/app/routes/apps/$clientId/team.tsx +++ b/apps/console/app/routes/apps/$clientId/team.tsx @@ -128,7 +128,7 @@ export const action: ActionFunction = getRollupReqFunctionErrorWrapper( ) export default () => { - useConnectResult(['SUCCESS', 'ALREADY_CONNECTED', 'CANCEL']) + useConnectResult() const submit = useSubmit() diff --git a/apps/passport/app/routes/authorize.tsx b/apps/passport/app/routes/authorize.tsx index 357e88b571..a0bcc768c6 100644 --- a/apps/passport/app/routes/authorize.tsx +++ b/apps/passport/app/routes/authorize.tsx @@ -28,7 +28,6 @@ import { } from '~/utils/authorize.server' import { useEffect, useState } from 'react' import { BadRequestError, InternalServerError } from '@proofzero/errors' -import { JsonError } from '@proofzero/utils/errors' import { AuthorizationControlSelection } from '@proofzero/types/application' import useConnectResult from '@proofzero/design-system/src/hooks/useConnectResult' @@ -418,7 +417,7 @@ export default function Authorize() { const navigate = useNavigate() const transition = useTransition() - useConnectResult(['ALREADY_CONNECTED', 'CANCEL']) + useConnectResult() const cancelCallback = () => { const redirectURL = new URL(redirectUri) diff --git a/apps/passport/app/routes/connect/$address/sign.tsx b/apps/passport/app/routes/connect/$address/sign.tsx index 43ba878887..e07d6869be 100644 --- a/apps/passport/app/routes/connect/$address/sign.tsx +++ b/apps/passport/app/routes/connect/$address/sign.tsx @@ -8,9 +8,10 @@ import { CryptoAddressType, NodeType } from '@proofzero/types/address' import { getAuthzCookieParams, getUserSession } from '../../../session.server' import { getAuthzRedirectURL } from '../../../utils/authenticate.server' -import { signMessageTemplate } from '@proofzero/packages/utils' +import { parseJwt, signMessageTemplate } from '@proofzero/packages/utils' import { BadRequestError } from '@proofzero/errors' import { getRollupReqFunctionErrorWrapper } from '@proofzero/utils/errors' +import type { AccountURN } from '@proofzero/urns/account' export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper( async ({ request, context, params }) => { @@ -49,6 +50,7 @@ export const loader: LoaderFunction = getRollupReqFunctionErrorWrapper( export const action: ActionFunction = getRollupReqFunctionErrorWrapper( async ({ request, context, params }) => { const appData = await getAuthzCookieParams(request, context.env) + const jwt = await getUserSession(request, context.env, params.clientId) const { address } = params if (!address) @@ -74,8 +76,15 @@ export const action: ActionFunction = getRollupReqFunctionErrorWrapper( forceAccountCreation: !appData || appData.rollup_action !== 'connect', }) + const accountURNFromAddress = await addressClient.getAccount.query() + + if (appData?.rollup_action === 'connect' && existing) { - return redirect(getAuthzRedirectURL(appData, 'ALREADY_CONNECTED')) + const accountURN = parseJwt(jwt).sub! as AccountURN + if (accountURN === accountURNFromAddress) { + return redirect(getAuthzRedirectURL(appData, 'ALREADY_CONNECTED_ERROR')) + } + return redirect(getAuthzRedirectURL(appData, 'ACCOUNT_CONNECT_ERROR')) } // TODO: handle the error case diff --git a/apps/passport/app/utils/authenticate.server.ts b/apps/passport/app/utils/authenticate.server.ts index 3172c4c394..053a66dc86 100644 --- a/apps/passport/app/utils/authenticate.server.ts +++ b/apps/passport/app/utils/authenticate.server.ts @@ -2,7 +2,6 @@ import { AddressURNSpace } from '@proofzero/urns/address' import type { AddressURN } from '@proofzero/urns/address' import type { AccountURN } from '@proofzero/urns/account' -import { JsonError } from '@proofzero/utils/errors' import { GrantType, ResponseType } from '@proofzero/types/access' import { @@ -13,6 +12,7 @@ import { import { createUserSession, getAuthzCookieParamsSession, + getUserSession, parseJwt, } from '~/session.server' import { generateGradient } from './gradient.server' @@ -40,15 +40,25 @@ export const authenticateAddress = async ( }) } + const jwt = await getUserSession(request, env, appData?.clientId) if ( appData.rollup_action && ['connect', 'reconnect'].includes(appData?.rollup_action) ) { + let result = undefined + + if (existing && appData.rollup_action === 'connect') { + const loggedInAccount = parseJwt(jwt).sub + if (account !== loggedInAccount) { + result = 'ACCOUNT_CONNECT_ERROR' + } else { + result = 'ALREADY_CONNECTED_ERROR' + } + } + const redirectURL = getAuthzRedirectURL( appData, - existing && appData.rollup_action === 'connect' - ? 'ALREADY_CONNECTED' - : undefined + result ) return redirect(redirectURL) diff --git a/packages/design-system/src/hooks/useConnectResult.tsx b/packages/design-system/src/hooks/useConnectResult.tsx index 21321a692e..2318f5536d 100644 --- a/packages/design-system/src/hooks/useConnectResult.tsx +++ b/packages/design-system/src/hooks/useConnectResult.tsx @@ -2,7 +2,12 @@ import { ToastType, toast } from '../atoms/toast' import { useEffect } from 'react' export default ( - handledMessageTypes: string[] = ['SUCCESS', 'ALREADY_CONNECTED', 'CANCEL'] + handledMessageTypes: string[] = [ + 'SUCCESS', + 'ACCOUNT_CONNECT_ERROR', + 'ALREADY_CONNECTED_ERROR', + 'CANCEL' + ] ) => { useEffect(() => { const url = new URL(window.location.href) @@ -18,10 +23,21 @@ export default ( { duration: 2000 } ) break - case 'ALREADY_CONNECTED': + case 'ACCOUNT_CONNECT_ERROR': toast( ToastType.Error, - { message: 'Account already connected' }, + { + message: 'Could not connect this account to your identity.\ + It may be connected to another identity.' }, + { duration: 2000 } + ) + break + case 'ALREADY_CONNECTED_ERROR': + toast( + ToastType.Error, + { + message: 'Account is already connected to your identity.' + }, { duration: 2000 } ) break