diff --git a/packages/account/src/Constants/routes-config.tsx b/packages/account/src/Constants/routes-config.tsx index 4f739697a4a8..2cf07a647da7 100644 --- a/packages/account/src/Constants/routes-config.tsx +++ b/packages/account/src/Constants/routes-config.tsx @@ -5,7 +5,7 @@ import { routes, moduleLoader, makeLazyLoader } from '@deriv/shared'; import { localize } from '@deriv/translations'; import { PersonalDetails, - ProofOfIdentity, + ProofOfIdentityFlow, ProofOfAddress, ProofOfOwnership, Account, @@ -155,7 +155,7 @@ const initRoutesConfig = () => [ subroutes: [ { path: routes.proof_of_identity, - component: ProofOfIdentity, + component: ProofOfIdentityFlow, getTitle: () => localize('Proof of identity'), }, { diff --git a/packages/account/src/Sections/Verification/ProofOfIdentity/index.js b/packages/account/src/Sections/Verification/ProofOfIdentity/index.js index 1043968d3b3d..466e7f8a395d 100644 --- a/packages/account/src/Sections/Verification/ProofOfIdentity/index.js +++ b/packages/account/src/Sections/Verification/ProofOfIdentity/index.js @@ -1,2 +1,3 @@ export { default as ProofOfIdentity } from './proof-of-identity.jsx'; export { default as ProofOfIdentityContainer } from './proof-of-identity-container.jsx'; +export { default as ProofOfIdentityFlow } from './proof-of-identity-flow'; diff --git a/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-flow.tsx b/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-flow.tsx new file mode 100644 index 000000000000..9dbc1d58ec15 --- /dev/null +++ b/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-flow.tsx @@ -0,0 +1,58 @@ +import React from 'react'; + +import { Loading } from '@deriv/components'; +import { useGrowthbookGetFeatureValue } from '@deriv/hooks'; +import { ACCOUNTS_OS_POI_STATUS_URL, ACCOUNTS_OS_POI_URL, getAppId, getSocketURL } from '@deriv/shared'; +import { observer, useStore } from '@deriv/stores'; + +import { useKycAuthStatus } from '../../../hooks'; + +import ProofOfIdentity from './proof-of-identity'; + +const ProofOfIdentityFlow = observer(() => { + const { + client: { getToken, residence }, + common: { is_from_tradershub_os }, + } = useStore(); + const { kyc_auth_status } = useKycAuthStatus({ country: residence }); + const [shouldRedirectToAccountsOSApp, isRedirectToAccountsOSAppFFLoaded] = useGrowthbookGetFeatureValue({ + featureFlag: 'redirect_to_poi_in_accounts_os', + }); + + const getFormattedURL = url_link => { + const url = new URL(url_link); + const urlParams = new URLSearchParams(location.search); + const platform = urlParams.get('platform') ?? (is_from_tradershub_os ? 'tradershub_os' : 'deriv_app'); + + const params = { + platform, + appid: getAppId(), + lang: 'en', + server: getSocketURL(), + token: getToken(), + }; + + Object.entries(params).forEach(([key, value]) => { + url.searchParams.append(key, value); + }); + + return url.toString(); + }; + + if (isRedirectToAccountsOSAppFFLoaded) { + if (shouldRedirectToAccountsOSApp && kyc_auth_status) { + const { identity } = kyc_auth_status; + const redirect_url = + identity.status === 'none' || identity.status === 'required' + ? ACCOUNTS_OS_POI_URL + : ACCOUNTS_OS_POI_STATUS_URL; + window.location.href = getFormattedURL(redirect_url); + } else { + return ; + } + } + + return ; +}); + +export default ProofOfIdentityFlow; diff --git a/packages/account/src/Sections/index.js b/packages/account/src/Sections/index.js index 2af32204659a..41965233c601 100644 --- a/packages/account/src/Sections/index.js +++ b/packages/account/src/Sections/index.js @@ -1,5 +1,5 @@ import PersonalDetails from 'Sections/Profile/PersonalDetails'; -import { ProofOfIdentityContainer, ProofOfIdentity } from 'Sections/Verification/ProofOfIdentity'; +import { ProofOfIdentityContainer, ProofOfIdentity, ProofOfIdentityFlow } from 'Sections/Verification/ProofOfIdentity'; import ProofOfAddress from 'Sections/Verification/ProofOfAddress'; import ProofOfOwnership from 'Sections/Verification/ProofOfOwnership'; import ProofOfIncome from 'Sections/Verification/ProofOfIncome'; @@ -11,6 +11,7 @@ export { PersonalDetails, ProofOfIdentityContainer, ProofOfIdentity, + ProofOfIdentityFlow, ProofOfAddress, ProofOfOwnership, ProofOfIncome, diff --git a/packages/api/types.ts b/packages/api/types.ts index 82fb2351565a..e98a2a70cf4a 100644 --- a/packages/api/types.ts +++ b/packages/api/types.ts @@ -281,7 +281,7 @@ type KycAuthStatus = { /** * Current POI status. */ - status?: 'none' | 'pending' | 'rejected' | 'verified' | 'expired' | 'suspected'; + status?: 'none' | 'pending' | 'rejected' | 'verified' | 'expired' | 'suspected' | 'required'; /** * Supported documents per service. */ @@ -3105,18 +3105,19 @@ export type TSocketPaginatateableRequestCleaned = Partial> extends TSocketRequestCleaned - ? { - payload?: T extends TSocketPaginateableEndpointNames - ? TSocketPaginatateableRequestCleaned - : TSocketRequestCleaned; - } - : { - payload: T extends TSocketPaginateableEndpointNames - ? TSocketPaginatateableRequestCleaned - : TSocketRequestCleaned; - }; + T extends TSocketEndpointNames | TSocketPaginateableEndpointNames = TSocketEndpointNames, +> = + Partial> extends TSocketRequestCleaned + ? { + payload?: T extends TSocketPaginateableEndpointNames + ? TSocketPaginatateableRequestCleaned + : TSocketRequestCleaned; + } + : { + payload: T extends TSocketPaginateableEndpointNames + ? TSocketPaginatateableRequestCleaned + : TSocketRequestCleaned; + }; export type TSocketRequestQueryOptions = Parameters< typeof useQuery, TSocketError> @@ -3133,7 +3134,7 @@ export type TSocketRequestMutationOptions = Para type TSocketRequestWithOptions< T extends TSocketEndpointNames, O extends boolean = false, - OT extends 'useQuery' | 'useInfiniteQuery' = 'useQuery' + OT extends 'useQuery' | 'useInfiniteQuery' = 'useQuery', > = Omit< TSocketRequestPayload & { options?: OT extends 'useQuery' ? TSocketRequestQueryOptions : TSocketRequestInfiniteQueryOptions; @@ -3148,18 +3149,19 @@ type TNever = T extends Record ? never : T; type TSocketRequestProps< T extends TSocketEndpointNames, O extends boolean = false, - OT extends 'useQuery' | 'useInfiniteQuery' = 'useQuery' + OT extends 'useQuery' | 'useInfiniteQuery' = 'useQuery', > = TNever>; export type TSocketAcceptableProps< T extends TSocketEndpointNames, O extends boolean = false, - OT extends 'useQuery' | 'useInfiniteQuery' = 'useQuery' -> = TSocketRequestProps extends never - ? [undefined?] - : Partial> extends TSocketRequestProps - ? [TSocketRequestProps?] - : [TSocketRequestProps]; + OT extends 'useQuery' | 'useInfiniteQuery' = 'useQuery', +> = + TSocketRequestProps extends never + ? [undefined?] + : Partial> extends TSocketRequestProps + ? [TSocketRequestProps?] + : [TSocketRequestProps]; export type TSocketPaginateableEndpointNames = KeysMatching< TSocketEndpoints, diff --git a/packages/core/src/Stores/client-store.js b/packages/core/src/Stores/client-store.js index 9cfc441eba95..afc5cc639261 100644 --- a/packages/core/src/Stores/client-store.js +++ b/packages/core/src/Stores/client-store.js @@ -382,6 +382,7 @@ export default class ClientStore extends BaseStore { setNewEmail: action.bound, setDeviceData: action.bound, getSignupParams: action.bound, + getToken: action.bound, onSetResidence: action.bound, onSetCitizen: action.bound, onSignup: action.bound, diff --git a/packages/shared/src/utils/routes/routes.ts b/packages/shared/src/utils/routes/routes.ts index 281b1bf31f9d..b59948790390 100644 --- a/packages/shared/src/utils/routes/routes.ts +++ b/packages/shared/src/utils/routes/routes.ts @@ -119,3 +119,12 @@ export const isDisabledLandscapeBlockerRoute = (path: string) => { if (path === routes.traders_hub) return true; return DISABLE_LANDSCAPE_BLOCKER_ROUTES.some(route => path.startsWith(route)); }; + +export const ACCOUNTS_OS_POI_URL = + process.env.NODE_ENV === 'production' + ? 'https://hub.deriv.com/Accounts/ProofOfIdentity' + : 'https://staging-hub.deriv.com/Accounts/ProofOfIdentity'; +export const ACCOUNTS_OS_POI_STATUS_URL = + process.env.NODE_ENV === 'production' + ? 'https://hub.deriv.com/Accounts/ProofOfIdentityStatus' + : 'https://staging-hub.deriv.com/Accounts/ProofOfIdentityStatus'; diff --git a/packages/stores/src/mockStore.ts b/packages/stores/src/mockStore.ts index 36e8b3ceaecb..8cb09c7b748f 100644 --- a/packages/stores/src/mockStore.ts +++ b/packages/stores/src/mockStore.ts @@ -208,6 +208,7 @@ const mock = (): TStores & { is_mock: boolean } => { document_status: '', identity_status: '', }, + getToken: jest.fn(), phone_settings: { carriers: [], countries: [ diff --git a/packages/stores/types.ts b/packages/stores/types.ts index a7d63eee9a5f..51d7a7419ae9 100644 --- a/packages/stores/types.ts +++ b/packages/stores/types.ts @@ -710,6 +710,7 @@ export type TClientStore = { poi_status: string; valid_tin: 0 | 1; }; + getToken: () => string; should_show_trustpilot_notification: boolean; };