Purpose
This WS is designed to register patient in the system based on data received from Patient Information System
Key points
This method must be used only by Auth front-end
Validates session token (jwt) that was obtained as a result of signed content as well as patient data validation by https://e-health-ua.atlassian.net/wiki/spaces/PCAB/pages/17599399214 and signed content, skips revalidation of patient data.
Creates user as well as patient in the system
Generates access token for further actions
Specification
Validate signed content
Check
signed_content
andsigned_content_encoding
are submittedin case of error - return 422 ('required property signed_content was not present' or ‘required property signed_content_encoding was not present')
Check
signed_content
field is a valid base64 stringin case of error - return 422 ('Invalid signed content')
Check
signed_content_encoding
field value equals to 'base64'in case of error - return 422 ('value is not allowed in enum')
Check digital signature is valid
in case of error - return 401 with digital signature validation error message
Check that drfo from digital signature belongs to person in registration request, based on field format:
if value equals to tax_id regexp (
^[0-9]{10}$
), field contains tax_id, usetax_id
field from registration request to compare;if value equals to national_id number regexp (
^[0-9]{9}$
), field contains national_id number, usedocuments.number
field withdocuments.type = 'NATIONAL_ID'
to compare;if value contains at least one letter, perform reverse transliteration of field using existing algorithm (described here), then check that value equals to passport number regexp (
^((?![ЫЪЭЁ])([А-ЯҐЇІЄ])){2}[0-9]{6}$
), in case equals, field contains passport number, usedocuments.number
field withdocuments.type = 'PASSPORT'
to compare;in case of error - return 409 ('Registration person and person that sign should be the same')
Check that last_name from digital signature belongs to person in registration request, last_name field
in case of error - return 422 ('Input name doesn't match name from digital signature')
Check that first_name from registration request is present in string given_name from digital signature
in case of error - return 422 ('Input name doesn't match name from digital signature')
Validate JWT
validate JWT signature
validate issuer (
iss
= Ehealth)validate aud (
aud
= pis-registration)validate expiration (
exp
in the future)in case of any error - return 401 ('JWT is invalid.')
validate
content_hash
equals to MD5 hash value ofsigned_content
fieldin case of error - return 401 ('Unauthorized.')
Verify otp
Get value of PIS_VALIDATE_ALL_PHONES config parameter
if it set to false - check that phone from authentication_methods field must be verified (number does not exists in
verified_phones
table in verifications database), if phone must be verified, check that value from$.otp
field in request equals to verification code that was sent to phone and md5 hash of encoded$.signed_content
equals to stored value (throughverifications
table in verification database)if it set to true - check that value from
$.otp
field in request equals to verification code that was sent to phone and md5 hash of encoded$.signed_content
equals to stored value (throughverifications
table in verification database)in case of error - return 422 ('Invalid verification code')
Service logic
Update otp
If otp verification was invoked, update record for otp and phone number in
verifications
table in verification database, set:status = ‘verified’
If otp verification was invoked, check existance of record for phone number in
verified_phones
table in verification database, if not exists - create record, set:id = autogenerate uuid
phone_number = number of verified phone from request
updated_at = now()
Search user
Get drfo value from digital signature.
Search for existing user in mithril database,
users
table, with tax_id = drfo from digital signature and is_active = trueIf user is found - check it is not blocked (is_blocked <> true)
in case blocked - return 401 ('User is blocked.').
in case not blocked - save
user_id
and proceed to p.3.
If user is not found - proceed to https://e-health-ua.atlassian.net/wiki/spaces/PCAB/pages/17599399235/warranty_PIS.+Patient+sign-up+registration#Search-or-create-person
Search for existing person in mpi database,
persons
table, with id = person_id from found user, status = active and is_active = truein case person not found - return 401 ('Person not found.')
in case person found - check its age is greater then no_self_auth_age global parameter
in case of error - return 401 ('Incorrect person age for such an action.')
in case persons age is correct - save
user_id
and proceed to https://e-health-ua.atlassian.net/wiki/spaces/PCAB/pages/17599399235/warranty_PIS.+Patient+sign-up+registration#Generate-authorization-token
Search or create person
Search for existing active person in mpi database with data from person registration request according to existing process, described here https://e-health-ua.atlassian.net/wiki/spaces/PCAB/pages/17599399235/warranty_PIS.+Patient+sign-up+registration#Search-or-create-person
Calculate score of comparison between found active persons and person registration request using existing deduplication process, described here https://e-health-ua.atlassian.net/wiki/spaces/PCAB/pages/17599401059
Compare found score with PIS_ONLINE_DEDUPLICATION_MATCH_SCORE config parameter, set to ‘0.95’:If one active person with match score > PIS_ONLINE_DEDUPLICATION_MATCH_SCORE was found - check its age is greater then no_self_auth_age global parameter
in case of error - return 401 ('Incorrect person age for such an action.')
in case persons age is correct - save
person_id
and proceed to p.2.
If more than one active person with match score > PIS_ONLINE_DEDUPLICATION_MATCH_SCORE was found - return 401 ('It is impossible to uniquely identify the person.')
If no active person with match score > PIS_ONLINE_DEDUPLICATION_MATCH_SCORE was found - proceed to p.3.
Search for existing user in mithril database,
users
table, with person_id = person_id from found person and is_active = trueIf user is found - check it is not blocked (is_blocked <> true)
in case blocked - return 401 ('User is blocked.').
in case not blocked - update user, set tax_id = drfo from digital signature, set settings.trusted_source = true, save
user_id
and proceed to https://e-health-ua.atlassian.net/wiki/spaces/PCAB/pages/17599399235/warranty_PIS.+Patient+sign-up+registration#Generate-authorization-token
If user is not found - proceed to https://e-health-ua.atlassian.net/wiki/spaces/PCAB/pages/17599399235/warranty_PIS.+Patient+sign-up+registration#Create-user
Create new patient in mpi database, set values in following tables based on person registration request:
persons
tableperson_phones
tableperson_addresses
tableperson_documents table
person_authentication_methods
table
Save signed content to media storage
Submit person on verification - create record in
person_verifications
table forperson_id
, set values for each verification stream:Manual NHS verifiation
IF
$.person.documents
contains document with type = 'PERMANENT_RESIDENCE_PERMIT' or$.person.unzr
is not empty and first 8 digits of$.person.unzr
!=$.person.birth_date
or$.person.documents
contains document with type from PIS_PERSON_LEGAL_CAPACITY_DOCUMENT_TYPES config parameter
- scan copies of persons documents must be uploaded to media storage after persons registration using https://e-health-ua.atlassian.net/wiki/spaces/PCAB/pages/17599400482set nhs_verification_status = NOT_VERIFIED
set nhs_verification_reason = DOCUMENTS_TRIGGERED
else - scan copies of persons documents are not needed, set verification status according to logic, described here: https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18201706567/RC_Sign+person+request+v2+DRACS+2.0#Manual-NHS-verification
DRFO registry verification - according to logic, described here: https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18201706567/RC_Sign+person+request+v2+DRACS+2.0#DRFO-registry-verification
DRACS death acts registry verification - according to logic, described here: https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18201706567/RC_Sign+person+request+v2+DRACS+2.0#DRACS-death-acts-registry-verification
DRACS birth acts registry verification - according to logic, described here: https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18201706567/RC_Sign+person+request+v2+DRACS+2.0#DRACS-birth-acts-registry-verification
DRACS name change acts registry verification - according to logic, described here: https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18201706567/RC_Sign+person+request+v2+DRACS+2.0#DRACS-name-change-acts-registry-verification
Legal capacity verification - according to logic, described here: https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18201706567/RC_Sign+person+request+v2+DRACS+2.0#Legal-capacity-verification
Calculate cumulative person verifiation status according to logic, described here: https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18201706567/RC_Sign+person+request+v2+DRACS+2.0#Calculate-cumulative-verification-status
Create user
Create user for active patient in mithril database,
users
table, set:id = autogenerate uuid
settings = ‘{“trusted_source”: true}’
priv_settings = ‘{"login_hstr": [], "otp_error_counter": 0}’
inserted_at = now()
updated_at = now()
tax_id =
drfo
value from digital signatureperson_id =
person_id
of person that was found or created on ‘Search or create patient’ step.
Create global role for created user in mithril database,
global_user_roles
table, set:id = autogenerate uuid
user_id = user_id of user created on p.4
role_id = id of role with name ‘PATIENT’
inserted_at = now()
updated_at = now()
Generate authorization token
Generate auth_token with scope
app:authorize
foruser_id
andclient_id of Auth UI (from env)
Save token to mithil database,
tokens
table, set:id = token uuid
name = token name (‘access_token’)
value = hashed token
expires_at = date and time when token will be expired in unix-time format
details = additional details of token (scope, client_id, grant_type), where
scope = ‘app:authorize’
client_id = client id of Auth UI
grant_type = ‘pis_auth’
user_id = id of user
inserted_at = now()
updated_at = now()
Render a response according to specification.