ЕСОЗ - публічна документація

UA_PIS. Patient sign-up registration

Мета

Цей WS призначений для реєстрації пацієнта в системі на основі даних, отриманих з Інформаційної системи пацієнтів

Ключові положення

  1. Цей метод має використовуватися лише інтерфейсом Auth

  2. Перевіряє маркер сеансу (jwt), який було отримано в результаті підписаного вмісту, а також перевірки даних пацієнта по PIS. Patient sign-up validation та підписного контенту, пропустити повторну перевірку даних пацієнта.

  3. Створити в системі як користувача, так і пацієнта

  4. Генерує токен доступу для подальших дій

Специфікація

Apiary

Перевірити підписаний контент

  • Перевірити, що вказани signed_content та signed_content_encoding

    • в разі помилки - повернути 422 ('required property signed_content was not present' or ‘required property signed_content_encoding was not present')

  • Перевірити, що поле signed_content це валідна строка в форматі base64

    • в разі помилки - повернути 422 ('Invalid signed content')

  • Перевірити, що поле signed_content_encoding рівне 'base64'

    • в разі помилки - повернути 422 ('value is not allowed in enum')

  • Перевірити, що цифровий підпис валідний

    • в разі помилки - повернути 401 з текстом помилки валідації цифрового підпису

  • Перевірити, що значення drfo з цифрового підпису належить персоні в запиті на реєстрацію, на основі формату поля:

    • якщо значення рівне tax_id враховуючи regexp (^[0-9]{10}$), поле містить tax_id, використати поле tax_id з запиту на реєстрацію для порвіняння;

    • якщо значення рівне номеру national_id враховуючи regexp (^[0-9]{9}$), поле містить номер national_id, використовувати поле documents.number з documents.type = 'NATIONAL_ID' для порівняння;

    • якщо значення містить хоча б одну літеру, виконати зворотну транслітерацію поля, використовуючи існуючий алгоритм (описано тут), тоді перевірити, що значення рівне номеру паспорта враховуючи regexp (^((?![ЫЪЭЁ])([А-ЯҐЇІЄ])){2}[0-9]{6}$), якщо рівний, поле містить номер паспорту, використати поле documents.number з documents.type = 'PASSPORT' для порівняння;

      • в разі помилки - повернути 409 ('Registration person and person that sign should be the same')

  • Перевірити, що last_name з цифрового підпису належить персоні з запиту на реєстрацію, поле last_name

    • в разі помилки - повернути 422 ('Input name doesn't match name from digital signature')

  • Перевірити, що first_name з запиту на реєстрацію вказано в рядку given_nameз цифрового підпису

    • в разі помилки - повернути 422 ('Input name doesn't match name from digital signature')

Перевірити JWT

  • перевірити підпис JWT

  • перевірити емітента (iss = Ehealth)

  • перевірити aud (aud = pis-registration)

  • перевірити строк дії (exp в майбутньому)

    • в разі помилки - повернути 401 ('JWT is invalid.')

  • перевірити, що content_hash рівний значенню MD5 хеш закодований в полі signed_content

    • в разі будь-якої помилки - повернути 401 ('Unauthorized.')

Перевірити otp

  • Отримати значення з конфігураційного параметру PIS_VALIDATE_ALL_PHONES

    • якщо встановлено false - перевірити, що номер телефону з поля authentication_methods має бути перевірений (номер не вказано в таблиці verified_phones в базі даних верифікації), якщо телефон має бути верифікований, перевірити, що значення з поля $.otp в запиті рівний коду верифікації, що було направлено на телефон та хеш md5 hash закодований $.signed_content рівний значенню, що зберігається (через таблицю verifications в базі даних по верифікації)

    • якщо встановлене рівним true - перевірити, що значення з поля $.otp в запиті рівне коду верифікації, що було направлено на телефон та хеш md5 закодований $.signed_content рівне значенню, що зберігається (по таблиці verifications в базі даних верифікації)

      • в разі помилки - повернути 422 ('Invalid verification code')

Сервісна логіка

Оновити otp

  1. Якщо була викликана перевірка otp, оновіть запис для otp і номера телефону в таблиці verifications у базі даних verification, установіть:

    1. status = ‘verified’

  2. Якщо було викликано перевірку otp, перевірте наявність запису для номера телефону в таблиці verified_phones бази даних verification, якщо не існує - створіть запис, установіть:

    1. id = автогенерований uuid

    2. phone_number = номер верифікованого номеру телефону з запиту

    3. updated_at = now()

Знайти користувача

  1. Встановити значення drfo з цифрового підпису.

  2. Здійснити пошук існуючого користувача в базі даних mithril, таблиця users , де tax_id = drfo з цифрового підпису та is_active = true.

    1. якщо користувача знайдено - перевірити, що він не заблокований (is_blocked <> true)

      1. якщо заблокований - повернути 401 ('User is blocked.').

      2. якщо не заблокований - зберегтиuser_id та перейти до p.3.

    2. якщо користувача не було знайдено - перейти до PIS. Patient sign-up registration | Search or create person

  3. Здійснити пошук персони в базі даних mpi, таблиця persons, з id = person_id зі знайденого корис тувача, status = active та is_active = true

    1. в разі, якщо персону не було знайдено - повернути 401 ('Person not found.')

    2. в разі, якщо персону знайдено - перевірити, що його вік більше ніж значення глобального параметру no_self_auth_age

      1. в разі помилки - повернути 401 ('Incorrect person age for such an action.')

      2. в разі, якщо вік персони коректний - зберегти user_id та перейти до PIS. Patient sign-up registration | Generate authorization token

Знайти або створити персону

  1. Здійснити пошук активної персони в базі даних mpi з даними по персоні з запиту на реєстрацію у відповідності до існуючого процесу, описаного тут Create/Update person request | Search person
    Розразувати скор згідно результатів порівнянн між знайденою активною персоною та персоною з запиту на реєстрацію, використовуючи процес дедублікації, описаний тут Deduplication process
    Порівняти отриманий скор з конфіг параметром PIS_ONLINE_DEDUPLICATION_MATCH_SCORE, встановленим на рівні ‘0.95’:

    1. якщо одна активна персона з порівняльним скором > PIS_ONLINE_DEDUPLICATION_MATCH_SCORE була знайдена - перевірити, що її вік більше за значення глобального параметру no_self_auth_age

      1. в разі помилки - повернути 401 ('Incorrect person age for such an action.')

      2. в разі, якщо вік персони коректний - зберегти person_id та перейти до p.2.

    2. якщо більше одної персони з порівняльним скором > PIS_ONLINE_DEDUPLICATION_MATCH_SCORE було знайдено - повернути 401 ('It is impossible to uniquely identify the person.')

    3. якщо відсутністі активні персони з порівняльним скором > PIS_ONLINE_DEDUPLICATION_MATCH_SCORE було знайдено - перейти до p.3.

  2. Здійснити пошук активного користувача в базі даних mithril, таблиця users, з person_id = person_id знайденої персони та is_active = true.

    1. якщо користувача було знайдено - перевірити, що він не заблокований (is_blocked <> true)

      1. в разі якщо заблокований - повернути 401 ('User is blocked.').

      2. в разі, якщо не заблокований - оновити користувача, встановити tax_id = drfo з цифрового підпису, встановити settings.trusted_source = true, зберегти user_id та перейти до PIS. Patient sign-up registration | Generate authorization token

    2. якщо користувача не було знайдено - перейти до PIS. Patient sign-up registration | Create user

  3. Створити нову персону в базу даних mpi, встановит значення в наступних таблицях на основі персони з запиту на реєстрацію:

    1. persons таблиця

    2. person_phones таблиця

    3. person_addresses таблиця

    4. person_documents таблиця

    5. person_authentication_methods таблиця

  4. Зберегти підписаний контент до медіа-сховища

  5. Відправити персону на перевірку - створити запит в таблиці person_verifications для person_id, встановити значення для кожного стріма з верифікації:

    1. Ручна верифікація NHS

      1. якщо $.person.documents містить документи з типом = 'PERMANENT_RESIDENCE_PERMIT' або  $.person.unzr не пусто та перші 8 цифр $.person.unzr != $.person.birth_date
        або $.person.documents містить документ з типом з конфігураційного параметру PIS_PERSON_LEGAL_CAPACITY_DOCUMENT_TYPES
        - скан-копії документів персони мають бути завантажені до сховища даних після реєстрації персони по Initialize Person documents upload

        1. встановити nhs_verification_status = NOT_VERIFIED

        2. встановити nhs_verification_reason = DOCUMENTS_TRIGGERED

      2. в іншому випадку - скан-копії документів персони не потрібні, встановити статус верифікації у відповідності до логіки, описаної тут: Sign person request | Manual NHS verification

    2. верифікація з реєстром DRFO - у відповідності до логіки, описаної тут: Sign person request | DRFO registry verification

    3. верифікація з реєстром актів смерті DRACS -у відповідності до логіки, описаної тут: Sign person request | DRACS death acts registry verification

  6. Розрахувати кумулятивний статус верифікації у відповідності до логіки, описаної тут: Sign person request | Calculate cumulative verification status

Створити користувача

  1. Створорити користувача для активного пацієнта в базі даних mithril, таблиця users, встановити:

    1. id = автогенерований uuid

    2. settings = ‘{“trusted_source”: true}’

    3. priv_settings = ‘{"login_hstr": [], "otp_error_counter": 0}’

    4. inserted_at = now()

    5. updated_at = now()

    6. password_set_at = now()

    7. tax_id = значення drfo з цифрового підпису

    8. person_id = person_id персони, що була знайдена на кроці ‘Search or create patient’.

  2. Створити глобальну роль для створеного користувача в базі даних mithril, таблиця global_user_roles, встановити:

    1. id = автогенерований uuid

    2. user_id = user_id користувача, створеного на кроці p.4

    3. role_id = id ролі з назвою ‘PATIENT’

    4. inserted_at = now()

    5. updated_at = now()

Згенерувати авторизаційний токен

  1. Згенерувати auth_token зі скоупом app:authorize для user_id та client_id of Auth UI (from env)

  2. Зберегти токен до бази даних mithil, таблиця tokens, встановити:

    1. id = uuid токену

    2. name = назва токену (‘access_token’)

    3. value = захешований токен

    4. expires_at = дата та час, коли закінчується строк дії токену в форматі unix-time

    5. details = додаткові деталі по токену (scope, client_id, grant_type), де

      1. scope = ‘app:authorize’

      2. client_id = id клієнта для Auth UI

      3. grant_type = ‘pis_auth’

    6. user_id = id користувача

    7. inserted_at = now()

    8. updated_at = now()

  3. Відобразити відповідь у відповідності до специфікації.

ЕСОЗ - публічна документація