The identify verification process
Client side:
Process starts client side when the person clicks the verify identity button or a similar Goal Card.
The component on the Page has a 'Verify Identity' button and two modal boxes for success and failure.
OnClick for Verify Identity goes to /verification/conduct which when accepted goes to /verification/safety which then tries to call /api/verify
the handler for /api/verify is set in /server/api/PersonalVerification/PersonalVerification.routes.js
server.get('/api/verify', initVerify) server.get('/api/verify/live/callback', verifyLiveCallback)
Hence initVerify is called, on return from CloudCheck verifyLiveCallback is called which returns the resulting page to the browser.
Server side
initVerify PersonalVerification.controller.js
Initial check
Check the caller is signed in and found in the people collection.
create new PersonalVerification record
create a new PersonalVerification record with the person id and a unique identifier voluntarilyReference: reference
PersonalVerification has these fields initially
status: VerificationStatus: default NOT_VERIFIED, VERIFIED, IN_PROGRESS, FAILED
person: ref to person (_id)
voluntarilyReference: cuid for matching when person has multiple requests.(should be unique) - we perhaps should use the _id.
create and make the first cloud check live call
Generate a nonce (cuid) and timestamp In cryptography, a nonce is an arbitrary number that can be used just once in a cryptographic communication - to avoid replay attacks.
generate the request body and post to cloudcheck
postCloudcheck: /live
{
data: {
"callback":"http://localhost:3122/api/verify/live/callback","reference":"5bd85665-82d8-48ce-862a-f6af39ec9469"
},
key: 'XXXXXXXXXXXXXX',
nonce: '25a46c37-5e28-4d4f-9d44-e587c99081d5',
timestamp: 1588299443000
}
postCloudCheck signs the request parameters
crypto.createHmac 'sha256' with the cloudcheck secret
and sends request to CloudCheck.
which returns a json record giving the next step
liveResponse: {
capture: {
captureReference: '424c336f-4c76-4e3a-a88b-851630faa83d',
reference: '5bd85665-82d8-48ce-862a-f6af39ec9469',
status: 'PENDING',
createdDate: '2020-05-01 14:17',
completed: false,
url: 'https://api.cloudcheck.co.nz/live/xUQz4M8i70OZwTVo5MK4YLjh0iW5cx3xu5mfcA6clU0KWW0g/',
ipAddresses: [ '49.227.191.209' ],
images: [],
recognizedDocuments: []
}
}
record the information for use in the callback
update the PersonalVerification record matching the capture.reference == voluntarilyReference.
to update captureReference: liveResponse.capture.captureReference, status: PersonalVerificationStatus.IN_PROGRESS
update the Person record (I'm not sure this is useful. but if the cloud process is abandoned the records will be left in the person.)
finally the page request returns a redirect to the cloudcheck page
Using the URL in the liveResponse.capture record.
Cloudcheck now takes over.
take a photo of the person face on
take a photo of the person 45 degrees on
take a photo of the driver's licence document
redirect back to the callback page for voluntarily: http://localhost:3122/api/verify/live/callback with key information in the URL parameters.
verifyLiveCallback
On completing the cloudcheck process the browser is redirected back to our callback url with the result information in the url params
example request:
we receive back from cloudCheck these fields
Find and Update the PersonalVerification record
find a pv record matching the voluntarily and capture references.
update the fields { liveCaptured, liveToken }
The record now looks like:
This doesn't give us any actual information but provides keys to request the results of the capture.
get Driver's licence information
getCloudCheck getCloudcheck /live/response
create a new request with the usual reference, key, nonce, timestamp and sig
receive back a summary of the available information This includes whether the person matched their identity documents and the results of OCR on the document
We now know that the person's face matched the photo id but not that the ID is a real one.
extract the DL information
We check the recognised documents list for an NZ_DRIVER_LICENCE ( not sure what we do if its not NZ ) we now have a full name, dob and dl number
validate the details on the driver's licence with NZTA
verifyDriversLicence: We create another request to cloudcheck that contains the given information plus the address.
and receive back suitable validation.
Error example: verificationSuccess is false
handle errors
if there is no dl verify result or the result contains an error we update the PV record with status: PersonalVerificationStatus.FAILED, verificationObject: driversLicenceVerificationResult
and update the person with NAME, DOB, ADDRESS as PersonalVerificationStatus.FAILED,
handle good response but failed validation
the response may not be an error but may still not validate the requested fields
in this case we update the PersonalVerification record with status: VERIFIED or NOT_VERIFIED depending on the value of the validated field. along with the
handle good response and successful or partially successful validation
in this case the validated section includes
"verificationSuccess": true, "validated": { "dateofbirth": true, "address": false, "name": true },