Skip to content

Commit

Permalink
[ES-1160] added websocket connection in verification sreen (mosip#241)
Browse files Browse the repository at this point in the history
* [ADDED] websocket connection for camdgc-dev1 env

Signed-off-by: Zeeshan Mehboob <[email protected]>

* [ADDED] verification screen with websocket

Signed-off-by: Zeeshan Mehboob <[email protected]>

---------

Signed-off-by: Zeeshan Mehboob <[email protected]>
  • Loading branch information
zesu22 authored Jul 8, 2024
1 parent 1a9f7fa commit bdabc39
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
kycProviderSelector,
setCriticalErrorSelector,
setStepSelector,
setSlotIdSelector,
useEkycVerificationStore,
} from "../useEkycVerificationStore";
import { SlotCheckingLoading } from "./components/SlotCheckingLoading";
Expand All @@ -22,12 +23,13 @@ export const SlotChecking = ({ settings }: DefaultEkyVerificationProp) => {
retryDelay: settings.configs["slot.request.delay"],
});

const { kycProvider, setStep, setCriticalError } = useEkycVerificationStore(
const { kycProvider, setStep, setCriticalError, setSlotId } = useEkycVerificationStore(
useCallback(
(state) => ({
kycProvider: kycProviderSelector(state),
setStep: setStepSelector(state),
setCriticalError: setCriticalErrorSelector(state),
setSlotId: setSlotIdSelector(state)
}),
[]
)
Expand All @@ -45,7 +47,7 @@ export const SlotChecking = ({ settings }: DefaultEkyVerificationProp) => {
};

slotAvailabilityMutation.mutate(slotAvailabilityRequestDto, {
onSuccess: ({ errors }) => {
onSuccess: ({ response, errors }) => {
if (errors.length > 0) {
switch (errors[0].errorCode) {
case "invalid_transaction":
Expand All @@ -55,6 +57,7 @@ export const SlotChecking = ({ settings }: DefaultEkyVerificationProp) => {
break;
}
} else {
setSlotId(response.slotId)
setStep(EkycVerificationStep.VerificationScreen);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@ import { PUBLISH_TOPIC, SUBSCRIBE_TOPIC, WS_URL } from "~constants/routes";
import { Button } from "~components/ui/button";
import useStompClient from "~pages/shared/stompWs";
import { WS_BASE_URL } from "~services/api.service";
import { DefaultEkyVerificationProp } from "~typings/types";
import {
DefaultEkyVerificationProp,
IdentityVerificationRequestDto,
IdentityVerificationResponseDto,
IdentityVerificationState,
IdvFrames,
} from "~typings/types";

import {
EkycVerificationStore,
errorBannerMessageSelector,
setErrorBannerMessageSelector,
setIsNoBackgroundSelector,
slotIdSelector,
useEkycVerificationStore,
} from "../useEkycVerificationStore";
import { EkycStatusAlert } from "./components/EkycStatusAlert";

type frameObj = {
frame: string | null;
order: number;
};

export const VerificationScreen = ({
cancelPopup,
settings,
Expand All @@ -35,16 +37,36 @@ export const VerificationScreen = ({
const [alertConfig, setAlertConfig] = useState<object | null>(null);
const [colorVerification, setColorVerification] = useState<boolean>(false);
const [bgColor, setBgColor] = useState<string | null>(null);
const [imageFrames, setImageFrames] = useState<frameObj[]>([]);
const [imageFrames, setImageFrames] = useState<IdvFrames[]>([]);
const [identityVerification, setIdentityVerification] =
useState<IdentityVerificationState | null>(null);
let captureFrameInterval: any = null;
const slotId = "123456";
// temporary button ref variable
const buttonRef = useRef(null);

// getting stored data from the store
const {
setIsNoBackground,
setErrorBannerMessage,
errorBannerMessage,
slotId,
} = useEkycVerificationStore(
useCallback(
(state: EkycVerificationStore) => ({
setIsNoBackground: setIsNoBackgroundSelector(state),
setErrorBannerMessage: setErrorBannerMessageSelector(state),
errorBannerMessage: errorBannerMessageSelector(state),
slotId: slotIdSelector(state),
}),
[]
)
);

const webSocketUrl = `${WS_BASE_URL}${WS_URL}?slotId=${slotId}`;

const { client, connected, publish, subscribe } =
useStompClient(webSocketUrl);
// const slotId = "123456";
// temporary button ref variable
const buttonRef = useRef(null);

// capturing frame from the web camera
const captureFrame = useCallback(() => {
Expand All @@ -64,19 +86,6 @@ export const VerificationScreen = ({

const isError = false;

// getting stored data from the store
const { setIsNoBackground, setErrorBannerMessage, errorBannerMessage } =
useEkycVerificationStore(
useCallback(
(state: EkycVerificationStore) => ({
setIsNoBackground: setIsNoBackgroundSelector(state),
setErrorBannerMessage: setErrorBannerMessageSelector(state),
errorBannerMessage: errorBannerMessageSelector(state),
}),
[]
)
);

/**
* Sending message to web socket
* @param request
Expand All @@ -86,20 +95,9 @@ export const VerificationScreen = ({
"*****************************Sending Message*****************************"
);
console.log(request);
// request.frames = imageFrames;
request.frames = imageFrames;
publish(PUBLISH_TOPIC, JSON.stringify(request));
setImageFrames([]);

if (request.stepCode < 5) {
setTimeout(() => {
request.stepCode = request.stepCode
? (parseInt(request.stepCode) + 1).toString()
: "0";
sendMessage(request);
}, 10000);
} else {
client?.deactivate();
}
};

// timer useEffect
Expand Down Expand Up @@ -134,21 +132,44 @@ export const VerificationScreen = ({

// stompjs connection established
const onConnect = () => {
const request = {
slotId: "123456",
stepCode: "0",
const request: IdentityVerificationRequestDto = {
slotId: slotId ?? "",
stepCode: "START",
frames: [],
};

publish(PUBLISH_TOPIC, JSON.stringify(request));
// as soon as we establish the connection, we will send the process frame request
sendMessage(request);
};

const checkPreviousState = (
res: IdentityVerificationResponseDto
): IdentityVerificationState | null => {
let temp = identityVerification;
if (res.step?.code !== temp?.stepCode) {
temp = {
...temp,
stepCode: res.step?.code ?? null,
fps: res.step?.framesPerSecond ?? null,
totalDuration: res.step?.durationInSeconds ?? null,
startupDelay: res.step?.startupDelayInSeconds ?? null,
feedbackType: res.feedback?.type ?? null,
feedbackCode: res.feedback?.code ?? null,
};
setIdentityVerification(temp);
}
return temp;
};

/**
* Getting response from the web socket
* @param response
*/
const gettingResponseFromSocket = (response: any) => {
const receiveMessage = (response: any) => {
const res = JSON.parse(response.body);
const currentState = checkPreviousState(res);

console.log(
"******************************Getting Response from Socket******************************"
);
Expand Down Expand Up @@ -211,7 +232,7 @@ export const VerificationScreen = ({
// then subscribe to the topic and call onConnect
useEffect(() => {
if (connected) {
subscribe(`${SUBSCRIBE_TOPIC}${slotId}`, gettingResponseFromSocket);
subscribe(`${SUBSCRIBE_TOPIC}${slotId}`, receiveMessage);

onConnect();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export type EkycVerificationStore = {
setIsNoBackground: (isNoBackground: boolean) => void;
errorBannerMessage: string | null;
setErrorBannerMessage: (errorBannerMessage: string | null) => void;
slotId: string | null;
setSlotId: (slotId: string | null) => void;
};

export const useEkycVerificationStore = create<EkycVerificationStore>()(
Expand Down Expand Up @@ -75,6 +77,12 @@ export const useEkycVerificationStore = create<EkycVerificationStore>()(
if (isEqual(current.errorBannerMessage, errorBannerMessage)) return;
set((state) => ({ errorBannerMessage }));
},
slotId: null,
setSlotId: (slotId: string | null) => {
const current = get();
if (isEqual(current.slotId, slotId)) return;
set((state) => ({ slotId }));
},
}))
);

Expand Down Expand Up @@ -133,3 +141,11 @@ export const errorBannerMessageSelector = (
export const setErrorBannerMessageSelector = (
state: EkycVerificationStore
): EkycVerificationStore["setErrorBannerMessage"] => state.setErrorBannerMessage;

export const slotIdSelector = (
state: EkycVerificationStore
): EkycVerificationStore["slotId"] => state.slotId;

export const setSlotIdSelector = (
state: EkycVerificationStore
): EkycVerificationStore["setSlotId"] => state.setSlotId;
19 changes: 18 additions & 1 deletion signup-ui/src/pages/shared/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ import {
VerifyChallengeRequestDto,
} from "~typings/types";

/**
* retrieves cookie from the browser
* @param {string} key
* @returns cookie value
*/
export const getCookie = (key: string): string | any => {
console.log(document.cookie);
var b = document.cookie.match("(^|;)\\s*" + key + "\\s*=\\s*([^;]+)");
console.log(b)
return b ? b.pop() : "";
}

export const getSettings = async (): Promise<SettingsDto> => {
return ApiService.get<SettingsDto>("/settings").then(({ data }) => data);
};
Expand Down Expand Up @@ -81,7 +93,12 @@ export const getKycProvidersList = async (
): Promise<KycProvidersResponseDto> => {
return ApiService.post(
"/identity-verification/initiate",
updateProcessRequestDto
updateProcessRequestDto,
{
headers:{
"X-XSRF-TOKEN": getCookie('XSRF-TOKEN'),
}
}
).then(({ data }) => data);
};

Expand Down
41 changes: 41 additions & 0 deletions signup-ui/src/typings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,47 @@ export interface KycProvider {
resumeOnSuccess: boolean;
}

export interface IdvStep {
code: string;
framesPerSecond: number;
durationInSeconds: number;
startupDelayInSeconds: number;
retryOnTimeout: boolean;
retryableErrorCodes: string[];
}

export type IdvFeedbackType = "MESSAGE" | "ERROR" | "COLOR";

export interface IdvFeedback {
type: IdvFeedbackType | string ;
code: string;
}

export interface IdvFrames {
frame: string;
order: number;
}
export interface IdentityVerificationResponseDto {
slotId: string;
step?: IdvStep | null;
feedback?: IdvFeedback | null;
}

export interface IdentityVerificationRequestDto {
slotId: string;
stepCode?: string | null;
frames?: IdvFrames[];
}

export interface IdentityVerificationState {
stepCode: string | null;
fps: number | null;
totalDuration: number | null;
startupDelay: number | null;
feedbackType: string | null;
feedbackCode: string | null;
}

export interface DefaultEkyVerificationProp {
settings: Settings;
cancelPopup: (cancelProp: CancelPopup) => any;
Expand Down

0 comments on commit bdabc39

Please sign in to comment.