From 0a9759f2154aa5ad4469eda6cad253d7bc6623d4 Mon Sep 17 00:00:00 2001 From: Oleksii Serdiukov Date: Tue, 5 May 2020 20:37:25 +0300 Subject: [PATCH] Fixes after running tests, solved issue why enrollments won't be removed --- .../verification/__tests__/verificationAPI.js | 14 +++---- src/server/verification/api/ZoomAPI.js | 7 ++-- .../verification/api/__tests__/ZoomAPI.js | 2 +- .../api/__tests__/__util__/index.js | 41 ++++++++++--------- .../processor/EnrollmentSession.js | 25 +++++++---- .../__tests__/EnrollmentProcessor.js | 3 +- .../provider/__tests__/ZoomProvider.js | 15 ++++--- src/server/verification/verificationAPI.js | 11 +++-- 8 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/server/verification/__tests__/verificationAPI.js b/src/server/verification/__tests__/verificationAPI.js index 140e2d39..1ab03dd6 100644 --- a/src/server/verification/__tests__/verificationAPI.js +++ b/src/server/verification/__tests__/verificationAPI.js @@ -146,14 +146,14 @@ describe('verificationAPI', () => { // to check has user been updated in the database expect(isVerified).toBeTruthy() // in the GUN session - expect(updateSessionMock).toHaveBeenCalledWith({ isEnrolled: true }) + expect(updateSessionMock).toHaveBeenCalledWith({ isLive: true, isEnrolled: true }) expect(updateSessionMock).toHaveBeenCalledWith({ isWhitelisted: true }) // and in the waller expect(whitelistUserMock).toHaveBeenCalledWith(address.toLowerCase(), profilePublickey) }) test("PUT /verify/face/:enrollmentIdentifier returns 200 and success: false when verification wasn't successfull", async () => { - helper.mockDuplicatesFound() + helper.mockDuplicateFound() await request(server) .put(enrollmentUri) @@ -168,13 +168,13 @@ describe('verificationAPI', () => { ok: true, code: 200, mode: 'dev', - message: 'The search request was processed successfully.', - sourceFaceMap: { - isReplayFaceMap: false - } + message: 'The search request was processed successfully.' } }) + // checking that duplicate flag was set in the session + expect(updateSessionMock).toHaveBeenCalledWith({ isDuplicate: true }) + // to check that user hasn't beed updated nowhere // in the database @@ -183,7 +183,7 @@ describe('verificationAPI', () => { expect(isVerified).toBeFalsy() // in the session - expect(updateSessionMock).not.toHaveBeenCalledWith({ isEnrolled: true }) + expect(updateSessionMock).not.toHaveBeenCalledWith({ isLive: true, isEnrolled: true }) expect(updateSessionMock).not.toHaveBeenCalledWith({ isWhitelisted: true }) // and in the wallet diff --git a/src/server/verification/api/ZoomAPI.js b/src/server/verification/api/ZoomAPI.js index c0817bba..9c32aaf5 100644 --- a/src/server/verification/api/ZoomAPI.js +++ b/src/server/verification/api/ZoomAPI.js @@ -81,7 +81,6 @@ class ZoomAPI { async faceSearch(payload, minimalMatchLevel: number = null) { const { http, defaultMinimalMatchLevel } = this const response = await http.post('/search', payload) - console.log({ response }) let minMatchLevel = minimalMatchLevel if (null === minMatchLevel) { @@ -121,7 +120,7 @@ class ZoomAPI { return { ...config, params: searchParams, - url: (url || '').replace(/:(\w[\w\d]*?)/g, substituteParameter) + url: (url || '').replace(/:(\w[\w\d]+)/g, substituteParameter) } }) } @@ -139,9 +138,9 @@ class ZoomAPI { } _responseInterceptor(response) { - log('Received response from Zoom API:', response) + log.debug('Received response from Zoom API:', response) - return this.transformedResponse(response) + return this._responseTransformer(response) } _exceptionInterceptor(exception) { diff --git a/src/server/verification/api/__tests__/ZoomAPI.js b/src/server/verification/api/__tests__/ZoomAPI.js index a2f33b7f..49715f7b 100644 --- a/src/server/verification/api/__tests__/ZoomAPI.js +++ b/src/server/verification/api/__tests__/ZoomAPI.js @@ -166,7 +166,7 @@ describe('ZoomAPI', () => { }) test("disposeEnrollment() should throw error if enrollment isn't found", async () => { - helper.mockFailedRemoval() + helper.mockFailedRemoval(enrollmentIdentifier) const wrappedResponse = expect(ZoomAPI.disposeEnrollment(enrollmentIdentifier)).rejects diff --git a/src/server/verification/api/__tests__/__util__/index.js b/src/server/verification/api/__tests__/__util__/index.js index 3e77c64e..82eab62b 100644 --- a/src/server/verification/api/__tests__/__util__/index.js +++ b/src/server/verification/api/__tests__/__util__/index.js @@ -22,23 +22,24 @@ export default zoomServiceMock => { } }) - const mockDuplicatesFound = zoomServiceMock.onPost('/search').reply(200, { - meta: { - ok: true, - code: 200, - mode: 'dev', - message: 'The search request was processed successfully.' - }, - data: { - results: [ - { - enrollmentIdentifier: duplicateEnrollmentIdentifier, - matchLevel: '1', - auditTrailImage: 'data:image/png:FaKEimagE==' - } - ] - } - }) + const mockDuplicateFound = () => + zoomServiceMock.onPost('/search').reply(200, { + meta: { + ok: true, + code: 200, + mode: 'dev', + message: 'The search request was processed successfully.' + }, + data: { + results: [ + { + enrollmentIdentifier: duplicateEnrollmentIdentifier, + matchLevel: '1', + auditTrailImage: 'data:image/png:FaKEimagE==' + } + ] + } + }) const mockSuccessEnrollment = enrollmentIdentifier => zoomServiceMock.onPost('/enrollment').reply(200, { @@ -85,8 +86,8 @@ export default zoomServiceMock => { } }) - const mockFailedRemoval = () => - zoomServiceMock.onDelete(/\/enrollment\/.+/).reply(200, { + const mockFailedRemoval = enrollmentIdentifier => + zoomServiceMock.onDelete(enrollmentUri(enrollmentIdentifier)).reply(200, { meta: { ok: true, code: 200, @@ -99,7 +100,7 @@ export default zoomServiceMock => { enrollmentUri, mockEmptyResultsFaceSearch, - mockDuplicatesFound, + mockDuplicateFound, duplicateEnrollmentIdentifier, duplicateFoundMessage, diff --git a/src/server/verification/processor/EnrollmentSession.js b/src/server/verification/processor/EnrollmentSession.js index 065bb43f..97c1deea 100644 --- a/src/server/verification/processor/EnrollmentSession.js +++ b/src/server/verification/processor/EnrollmentSession.js @@ -12,6 +12,7 @@ export default class EnrollmentSession { provider = null storage = null adminApi = null + sessionRef = null constructor(user, provider, storage, adminApi, gun, customLogger = null) { this.gun = gun @@ -25,17 +26,15 @@ export default class EnrollmentSession { } async enroll(enrollmentIdentifier, payload: any): Promise { - const { log, gun, provider, onEnrollmentProcessing } = this - const { sessionId } = payload - const sessionRef = gun.session(sessionId) + const { log, provider, onEnrollmentProcessing } = this let result = { success: true } log.info('Enrollment session started', { enrollmentIdentifier, payload }) - this.sessionRef = sessionRef - this.onEnrollmentStarted() - try { + this.initialize(payload) + this.onEnrollmentStarted() + const enrollmentResult = await provider.enroll(enrollmentIdentifier, payload, onEnrollmentProcessing) log.info('Enrollment session completed with result:', enrollmentResult) @@ -61,6 +60,16 @@ export default class EnrollmentSession { return result } + initialize(payload: any) { + const { gun } = this + const { sessionId } = payload + + this.sessionRef = gun.session(sessionId) + // returning this to allow initialize & + // get sessionRef via destructuring in a single call + return this + } + onEnrollmentStarted() { const { sessionRef } = this @@ -71,11 +80,11 @@ export default class EnrollmentSession { const { sessionRef, log } = this if ('isDuplicate' in processingPayload) { - log('Checked for duplicates:', processingPayload) + log.info('Checked for duplicates:', processingPayload) } if ('isEnrolled' in processingPayload) { - log('Checked for liveness and tried to enroll:', processingPayload) + log.info('Checked for liveness and tried to enroll:', processingPayload) } sessionRef.put(processingPayload) diff --git a/src/server/verification/processor/__tests__/EnrollmentProcessor.js b/src/server/verification/processor/__tests__/EnrollmentProcessor.js index d42b737f..74d609d9 100644 --- a/src/server/verification/processor/__tests__/EnrollmentProcessor.js +++ b/src/server/verification/processor/__tests__/EnrollmentProcessor.js @@ -96,7 +96,7 @@ describe('EnrollmentProcessor', () => { }) test("enroll() proxies provider's error and sets error + non-whitelisted state in the session", async () => { - helper.mockDuplicatesFound() + helper.mockDuplicateFound() const wrappedResponse = expect(enrollmentProcessor.enroll(user, enrollmentIdentifier, payload)).resolves @@ -111,6 +111,7 @@ describe('EnrollmentProcessor', () => { expect(updateSessionMock).toHaveBeenNthCalledWith(3, { isLive: false, isDuplicate: true, + isEnrolled: false, isWhitelisted: false, isError: helper.duplicateFoundMessage }) diff --git a/src/server/verification/processor/provider/__tests__/ZoomProvider.js b/src/server/verification/processor/provider/__tests__/ZoomProvider.js index 8561f539..40dc7e2e 100644 --- a/src/server/verification/processor/provider/__tests__/ZoomProvider.js +++ b/src/server/verification/processor/provider/__tests__/ZoomProvider.js @@ -103,8 +103,8 @@ describe('ZoomProvider', () => { }) test('enroll() throws if duplicates found', async () => { - helper.mockSuccessLivenessCheck() - helper.mockDuplicatesFound() + helper.mockEmptyResultsFaceSearch() + helper.mockDuplicateFound() const onEnrollmentProcessing = jest.fn() const wrappedResponse = expect(ZoomProvider.enroll(enrollmentIdentifier, payload, onEnrollmentProcessing)).rejects @@ -114,8 +114,7 @@ describe('ZoomProvider', () => { await wrappedResponse.toHaveProperty('response.isDuplicate', true) await wrappedResponse.toHaveProperty('response.isVerified', false) - expect(onEnrollmentProcessing).toHaveBeenNthCalledWith(1, { isLive: true }) - expect(onEnrollmentProcessing).toHaveBeenNthCalledWith(2, { isDuplicate: true }) + expect(onEnrollmentProcessing).toHaveBeenNthCalledWith(1, { isDuplicate: true }) }) test('enroll() throws if liveness check fails', async () => { @@ -137,9 +136,9 @@ describe('ZoomProvider', () => { test('enroll() throws on any Zoom service error and terminates without returning any response or calling callback', async () => { zoomServiceMock - .onPost('/liveness') + .onPost('/search') .replyOnce(500) - .onPost('/liveness') + .onPost('/search') .networkErrorOnce() await testEnrollmentServiceError('Request failed with status code 500') @@ -194,8 +193,8 @@ describe('ZoomProvider', () => { }) test('dispose() not throws trying to remove non-existing enrollment', async () => { - helper.mockFailedRemoval() + helper.mockFailedRemoval(enrollmentIdentifier) - await expect(ZoomProvider.dispose(enrollmentIdentifier)).resolve.toBeUndefined() + await expect(ZoomProvider.dispose(enrollmentIdentifier)).resolves.toBeUndefined() }) }) diff --git a/src/server/verification/verificationAPI.js b/src/server/verification/verificationAPI.js index d3df22b4..08b37c22 100644 --- a/src/server/verification/verificationAPI.js +++ b/src/server/verification/verificationAPI.js @@ -78,10 +78,12 @@ const setup = (app: Router, verifier: VerificationAPI, storage: StorageAPI) => { // if user is already verified, we're skipping enroillment logic if (user.isVerified || skipFaceVerification) { - const { sessionId } = payload - const sessionRef = GunDBPublic.session(sessionId) + // creating enrollment session manually for this user + const enrollmentSession = enrollmentProcessor.createEnrollmentSession(user, log) + // to access user's session reference in the Gun + const { sessionRef } = enrollmentSession.initialize(payload) - // and immediately publishing isEnrolled to subscribers + // immediately publishing isEnrolled to subscribers sessionRef.put({ isDuplicate: false, isLive: true, isEnrolled: true }) enrollmentResult = { success: true, enrollmentResult: { isVerified: true, alreadyEnrolled: true } } @@ -92,9 +94,6 @@ const setup = (app: Router, verifier: VerificationAPI, storage: StorageAPI) => { // so we trust that we already whitelisted him in the past // and whitelist him again in the new contract if (!skipFaceVerification) { - // creating enrollment session manually for this user - const enrollmentSession = enrollmentProcessor.createEnrollmentSession(user, log) - try { // in the session's lifecycle onEnrollmentCompleted() is called // after enrollment was successfull