Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

Table of Contents
Specification


Apiary
authorize
2fa
via
otp
Status
titlepatch
mithril/api/users/
{user_id}/
actions/
create
init_
otp
factor
Scopeuser:request_factor
Request json-schema

Purpose

Verify OTP & prolongation authentication process (return access_token for getting approvals) Collect factor from user,  save factor & type into token, create OTP for approval factor.

Request parameters

  • user_idtoken
  • otpfactor
  • tokentype


Logic WS

  • Validate token
(2fa_access_token) - ???? 
  • If invalid - return error 4xx 
  • Validate user id & user status
  • Get active 2FA item for
    • & scope
    • Validate request JSON-Schema for $.type=SMS
    • Search user by token, validate user is blocked
    • Get 2FA item by $.type  for non-blocked user by $.user_id

    • Code Block
      languagesql
      SELECT *
      FROM authentication_factors AS 2FA
      
    WHERE
    • 	INNER JOIN user AS U
      		ON 2FA.user_id = U.id
      WHERE 
      	U.id = $.user_id
      		AND 2FA.type = $.type
      		AND U.is_active = TRUE
    • If not found - return 409 error "Not found 2FA data for user"
  • Extract type & factor from 2FA item for user
  • Invoke internal function `verify OTP (key, code)`, for 2FA.type = SMS, with params:
    • key = 2FA.faсtor
    • code = $.otp
  • Get result of call `verify OTP()`  
  • If result = VERIFIED
    • Update user (set values) by $.user_id
      • users.priv_settings.otp_error_counter = 0

    • Update 2fa_access_token (set `tokens.details.used`=true)
    • Create & return new access_token (as a existing standart process without 2FA)
    • Return 200
  • If result = UNVERIFIED
    • Update user (set values) by $.user_id
      • Increment `users.priv_settings.otp_error_counter` (+1)
    • If `users.priv_settings.otp_error_counter` > USER_OTP_ERROR_MAX
      • Blocked user - update user (set values) by $.user_id
        • is_blocked = TRUE
        • block_reason = "OTP verify attempts more then USER_OTP_ERROR_MAX"
        • updated_at = now()
    • return 401 error
  • Internal logic for `verify OTP()`

    • Find 1 active OTP (status = NEW) for $.key
      • If not found - return 409 error "Not found active OTP" - ??? or 401 ?
      • If found -  increment  `attempts_count` (+1) for this OTP
        • If OTP.code = $.code - update OTP item:
          • OTP status  ( NEW → VERIFIED)
          • updated_at = now()
        • If (OTP.code <> $.code ) AND (OTP.attempts_countOTP_ERROR_MAX 
          • Update OTP item
            • status ( NEW → UNVERIFIED)
            • updated_at = now()

    Response

    200 if OTP successful create & send 
    • 
      		AND U.is_blocked = FALSE
      • For this valid conditions:

        PurposeConditions
        User change factor (from OLD on NEW) after
        successful authorization and getting access_token_type
        (exist 2FA item for user) AND (token_type = access_token_type) AND (2FA.factor != "" AND  2FA.factor != NULL) 
        User setting factor (from NULL on NEW, after Reset factor )
        after successful getting 2fa_access_token_type
        (exist 2FA item for user) AND (token_type = 2fa_access_token_type) AND (2FA.factor = "" OR  2FA.factor = NULL)
        • Update exist token (for token_type = 2fa_access_token_type) OR create new 2fa_access_token_type (if token_type in payload = access_token_type)
          • insert into `tokens.details` this attributes:
            • `request_authentication_factor` = $.factor
            • `request_authentication_factor_type` = $.type
        • invoke OTP timeout procedure
        • If successful - invoke internal function `create OTP (key)`, for 2FA.type = SMS, with params:
          • key = 2FA.faсtor
          • Get result of call `create OTP()` as `OTP_value` 
        • Sending (delivery) OTP via channel communication 
          • for 2FA.type = SMS - via SMS gateway API
            • mobile phone = 2FA.factor
            • SMS text = OTP_value 
            • ...
    • Return 201
    • ...

    Response

    • 201 if 2FA successful set new.factor  + 2FA_object_view
    • 4xx in other case