Підтвердження каналу зв’язку з користувачем

1. Загальний контекст

Для забезпечення вимог відправлення повідомлень користувачам про стан виконання замовлених послуг, на базі платформи реалізована підтримка концепції каналів зв’язку з можливістю їх налаштування на рівні профілю користувача (внесення адреси, активація / деактивація каналу зв’язку).

З детальною інформацією щодо управління налаштуваннями можна ознайомитись у розділі Управління каналами зв’язку користувача.

Внесення змін до адреси каналу зв’язку та його активація потребують проходження процедури підтвердження через використання автоматично згенерованого OTP-коду (One-Time-Password), який відправляється користувачу за вказаним каналом та використовується для перевірки внесених даних.

Даний механізм застосовується для підтвердження наступних каналів зв’язку:

  • email - Відправлення поштових повідомлень

  • diia - Відправлення push-котифікацій у мобільний застосунок Дія

2. Технічний дизайн рішення

contact verification

2.1. Компоненти системи та їх призначення

У даному розділі наведено перелік компонент системи, які задіяні або потребують змін/створення в рамках реалізації функціональних вимог згідно дизайну рішення.

Компонент Службова назва Призначення

Кабінет громадянина

citizen-portal

Внесення змін до адреси та активація каналу зв’язку.

Ініціювання процедури верифікації каналу зв’язку з відправленням OTP-коду для підтвердження

Сервіс повідомлень користувачів

notification-service

Відправлення службових повідомлення з OTP-кодом користувачу за вказаним каналом зв’язку

Сервіс управління налаштуваннями користувачів

user-settings-service

Генерація, збереження та відправлення OTP-коду через Сервіс повідомлень користувачів.

Верифікація співпадіння попередньо згенерованого та наданого користувачем OTP-кодів.

Застосування змін до налаштуваню каналів зв’язку користувача

Розподілене in-memory сховище даних

redis

Тимчасове зберігання згенерованих OTP-кодів з TTL

2.2. Налаштування політик міжсервісної взаємодії

В рамках реалізації вимог, необхідно додати відповідні мережеві політики NetworkPolicy, які дозволяють взаємодію для наступних компонентів:

  • user-settings-serviceredis

  • user-settings-servicekafka

2.3. Взаємодія компонентів системи

На даній діаграмі послідовності схематично зображено алгоритм підтвердження каналу зв’язку при його зміні / активації.

channel-confirmation-flow
  1. Користувач в налаштуваннях профілю вводить контактні дані (імейл, номер телефону, або інші контакти).

  2. Портал особи проводить валідацію введених даних на відповідність встановленому формату та в разі успішного проходження здійснює виклик Сервісу Налаштувань для збереження контактних даних.

  3. Сервісом налаштувань ініціює процес верифікації нового каналу звʼязку. Для цього генерується криптографічно безпечний 6-ти значний псевдовипадковий код підтвердження та зберігається в тимчасове сховище Redis. Ключем запису виступає композиція ідентифікатора користувача та ідентифікатора каналу звʼязку. При цьому для запису встановлюється час життя (TTL) рівний n секунд де n задається в загальних налаштуваннях.

  4. Після збереження подія з код підтвердження та ідентифікатором каналу звязку публікується в Kafka topic (4.а.) звідки потрапляє до Сервісу Відправки Повідомлень (4.b.).

  5. Сервіс Відправки Повідомлень формує повідомлення з кодом згідно шаблону та направляє його до відповідного Шлюзу Відправки Повідомлень в залежності від обраного каналу звєязку.

  6. Шлюз відправки повідомлень надсилає повідомлення з кодом користувачу.

  7. Користувач, отримавши код підтвердження, вводить його на сторінці налаштувань профіля.

  8. Портал особи проводить валідацію введених даних на відповідність встановленому формату (6-ти значне число) та в разі успішного проходження здійснює виклик Сервісу Налаштувань для підтвердження контактних даних.

  9. Сервіс Налаштувань Користувача, отримавши код підтвердження, вичитує з Тимчасового Сховища Даних збережений на кроці №3 код підтвердження згідно ключа та видаляє його в сховищі.

  10. Отримавши раніше збережений ключ сервіс звіряє його з отриманим від користувача.

    1. В разі співпадіння контактні дані зберігаються в профілі користувача як перевірені.

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

2.4. Зберігання згенерованих OTP-кодів

Для збереження автоматично згенерованих OTP-кодів використовується розподілене in-memory сховище Redis, дані в якому зберігаються у вигляді Hash-структури з сегрегацією об’єктів на рівні Keyspaces-префіксів (<keyspace>:<key>) та з встановленим TTL для записів згідно загальних налаштувань.

Для об’єктів OTP-кодів використовується префікс:

  • channel-verification-codes

Приклад паттерну генерації ключа для запису:
channel-verification-codes:{userId}/{channel}
Структура даних об’єктів у "channel-verification-codes" keyspace
{
  "address": "...",
  "verificationCode": "..."
}

2.5. Відправлення повідомлень зі згенерованими OTP-кодами

Для відправлення повідомлення з OTP-кодом через Сервіс повідомлень користувачів необхідно опублікувати запит у відповідний Kafka-топік "user-notifications" та явно вказати необхідність ігнорування стану активності для каналу зв’язку за допомогою службового поля "ignoreChannelPreferences".

Канонічний вигляд структури повідомлення
{
 "context": {
  "system": "Low-code Platform",
  "application": "user-settings-service"
 },
 "notification": {
  "templateName": "channel-confirmation",
  "ignoreChannelPreferences": true
 },
 "recipients": [
   {
      "id": "{userId}",
      "channels": [
        {
          "channel": "email",
          "email": "{email}"
        }
      ],
      "parameters": [
        {
            "key": "verificationCode",
            "value": "{verificationCode}"
        }
      ]
   }
 ]
}
З детальною інформацією щодо інтеграції з Сервісом повідомлень користувачів можна ознайомитись у розділі Інтеграція механізмів відправлення повідомлень для службового використання сервісами реєстру.

3. Налаштування системних шаблонів формування повідомлень з OTP-кодом

Необхідно підтвердити / сформувати контент шаблонів для відправлення повідомлень.

В рамках реалізації рішення, необхідно розширити базовий репозиторій регламенту empty-regulation-template, який використовується для створення нових реєстрів, додатковими шаблонами повідомлень під служовою назвою channel-confirmation.

Структура репозиторію регламенту з системними шаблонами
Зображення 1. Структура репозиторію регламенту з системними шаблонами

3.1. Шаблон поштового повідомлення зі згенерованим OTP-кодом

Приклад файлу мета-даних notification.yml
title: "Підтвердження електронної пошти"
Приклад шаблону notification.ftlh:
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="center">
        Код підтвердження: ${verificationCode}
    </div>
</body>
</html>

3.2. Шаблон push-повідомлення у мобільний додаток Дія зі згенерованим OTP-кодом

Приклад файлу мета-даних notification.yml
title: "Підтвердження каналу зв'язку реєстру"
attributes:
  actionType: "message"
  templateType: "attention"
  shortText : "Підтвердження каналу зв'язку реєстру"
Приклад шаблону notification.diia:
Код підтвердження: ${verificationCode}

4. Розширення API Сервісу управління налаштуваннями

З детальною інформацією щодо дизайну сервісу можна ознайомитись у розділі Управління каналами зв’язку користувача.
Отримання доступу до API можливе лише в рамках виконання запиту автентифікованого користувача в системі

4.1. Верифікація вказаного каналу зв’язку через генерацію OTP

Данний API-роут є публічним та має бути опублікованим для зовнішнього доступу через окремий Kong Route для Кабінету Громадянина.

POST /api/settings/me/channels/{channel}/verify

Параметр Тип Частина запиту Опис

X-Access-Token

JWT

HTTP заголовок

Токен доступу користувача

channel

Текстовий

Параметр запиту

Назва каналу [email, diia]

Приклад тіла запиту
{
    "address": "<email>"
}
Приклад відповіді
{
    "verificationCodeExpirationSec": "60"
}
Таблиця 1. Коди помилок
Код Опис

202

Accepted з поверненням інформації про період дії OTP-коду

400

Некоректно сформований запит

401

Помилка автентифікації (відсутній токен доступу)

500

Серверна помилка обробки запиту

4.2. Активація вказаного каналу зв’язку з підтвердженням через OTP

Данний API-роут є публічним та має бути опублікованим для зовнішнього доступу через окремий Kong Route для Кабінету Громадянина.
Наразі кількість спроб на внесення OTP-коду для активації каналу не обмежено на час дії OTP-коду. В майбутньому розглянути необхідність можливості налаштуванням кількості спроб на рівні регламенту реєстру.

POST /api/settings/me/channels/{channel}/activate

Параметр Тип Частина запиту Опис

X-Access-Token

JWT

HTTP заголовок

Токен доступу користувача

channel

Текстовий

Параметр запиту

Назва каналу [email, diia]

Приклад тіла запиту
{
    "address": "<email>",
    "verificationCode": "<otp-code>"
}
Таблиця 2. Коди помилок
Код Опис

200

OK - OTP верифікацію пройдено успішно

400

Некоректно сформований запит

401

Помилка автентифікації (відсутній токен доступу)

403

Наданий OTP-код не відповідає адресі для активації

500

Серверна помилка обробки запиту

5. Загальні налаштування сервісу

Сервіс надає можливість налаштування TTL для записів зі згенерованими OTP-кодами, які зберігаються у сховищі Redis.

Канонічний приклад налаштувань
verification.otp.time-to-live: 60

6. Оновлення версії існуючих реєстрів

Для існуючих реєстрів, у процесі оновлення версії необхідно створити системні шаблони повідомлень, які використовуються для відправки OTP-кодів згідно правил, описаних у розділі Налаштування системних шаблонів повідомлень для формування повідомлень з OTP-кодом.