openapi: 3.0.3
info:
  title: TOTP MFA
  description: 'The TOTP APIs provide functionality for clients to initiate and verify authentication challenge in order to proceed with unauthorised operations.'
  version: '1'
  x-plumery-audit-action-source: https://capabilities.plumery.com/totp/api
servers:
- url: 'https://api.plumery.com'
  description: Live Server
security:
- cookieAuth: [ ]
paths:
  '/internal/v1/mfa/totp-sms/{challengeId}:initiate':
    post:
      tags:
      - Challenge
      summary: Initiate time-based one-time password SMS challenge
      x-plumery-audit-action-type: TotpSmsChallengeInitiated
      x-plumery-audit-action-name: TOTP SMS Challenge Initiated
      x-plumery-audit-action-description: Time-based one-time password SMS challenge was initiated for multi-factor authentication
      description: |-
        Initiates time-based one-time password SMS challenge.

        This will initiate a time-based one-time password (TOTP) sent as an SMS to the user's phone number to authorise an operation request.

        Once the TOTP is verified, using the 'Verify' endpoint, user will be able to proceed with unauthorised operation.
      operationId: initiateSms
      parameters:
      - name: challengeId
        in: path
        required: true
        schema:
          type: string
        description: |
          The ID is challenge id received during operation initiation which required challenge.
      responses:
        '202':
          headers:
            Location:
              schema:
                type: string
                example: '/internal/v1/mfa/totp-sms/{challengeId}:verify'
              description: URL to verify authentication
          description: TOTP request accepted
        '400':
          description: Invalid challengeId
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
  '/internal/v1/mfa/totp-email/{challengeId}:initiate':
    post:
      tags:
      - Challenge
      summary: Initiate time-based one-time password email challenge
      x-plumery-audit-action-type: TotpEmailChallengeInitiated
      x-plumery-audit-action-name: TOTP Email Challenge Initiated
      x-plumery-audit-action-description: Time-based one-time password email challenge was initiated for multi-factor authentication
      description: |-
        Initiates time-based one-time password email challenge.

        This will initiate a time-based one-time password (TOTP) sent as an e-mail to the user's e-mail address to authorise an operation request.

        Once the TOTP is verified, using the 'Verify' endpoint, user will be able to proceed with unauthorised operation.
      operationId: initiateEmail
      parameters:
      - name: challengeId
        in: path
        required: true
        schema:
          type: string
        description: |
          The ID is challenge id received during operation initiation which required challenge.
      responses:
        '202':
          headers:
            Location:
              schema:
                type: string
                example: '/internal/v1/mfa/totp-email/{challengeId}:verify'
              description: URL to verify authentication
          description: TOTP request accepted
        '400':
          description: Invalid challengeId
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
  '/internal/v1/mfa/totp-sms/{challengeId}:verify':
    post:
      tags:
      - Challenge
      summary: Verify time-based one-time password SMS challenge
      x-plumery-audit-action-type: TotpSmsChallengeVerified
      x-plumery-audit-action-name: TOTP SMS Challenge Verified
      x-plumery-audit-action-description: Time-based one-time password SMS challenge was successfully verified
      description: |-
        Verifies the time-based one-time password sent to the user's phone number. 
        
        The unauthorised operations will be allowed to proceed once the TOTP verified successfully.
      operationId: verifySms
      parameters:
      - name: challengeId
        in: path
        required: true
        schema:
          type: string
        description: |
          The ID is challenge id received during operation initiation which required challenge.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                totp:
                  type: string
                  description: The Time-Based One-Time Password (TOTP) sent to the phone number for verification
                  example: '123456'
              required:
              - totp
      responses:
        '200':
          description: TOTP verified successfully. Unauthorised operation is allowed.
          headers:
            Location:
              schema:
                type: string
              description: Callback URL to get request result
        '400':
          description: Invalid TOTP code
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '410':
          description: TOTP validation has expired or is no longer available
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
  '/internal/v1/mfa/totp-email/{challengeId}:verify':
    post:
      tags:
      - Challenge
      summary: Verify time-based one-time password email challenge
      x-plumery-audit-action-type: TotpEmailChallengeVerified
      x-plumery-audit-action-name: TOTP Email Challenge Verified
      x-plumery-audit-action-description: Time-based one-time password email challenge was successfully verified
      description: |-
        Verifies the time-based one-time password sent to the user's mail address. 

        The unauthorised operations will be allowed to proceed once the TOTP verified successfully.
      operationId: verifyEmail
      parameters:
      - name: challengeId
        in: path
        required: true
        schema:
          type: string
        description: |
          The ID is challenge id received during operation initiation which required challenge.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                totp:
                  type: string
                  description: The Time-Based One-Time Password (TOTP) sent to the mail for verification
                  example: '123456'
              required:
              - totp
      responses:
        '200':
          description: TOTP verified successfully. Unauthorised operation is allowed.
          headers:
            Location:
              schema:
                type: string
              description: Callback URL to get request result
        '400':
          description: Invalid TOTP code
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '410':
          description: TOTP validation has expired or is no longer available
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error occurred
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        default:
          description: Unexpected error
      x-internal: false
components:
  schemas:
    ErrorCode:
      enum:
      - 'urn:plmr:mfa-totp:api:INTERNAL_SERVER_ERROR'
      - 'urn:plmr:mfa-totp:api:BAD_REQUEST'
      - 'urn:plmr:mfa-totp:api:RESOURCE_UNKNOWN'
      - 'urn:plmr:mfa-totp:api:UNAUTHORIZED'
      - 'urn:plmr:mfa-totp:api:FORBIDDEN'
      - 'urn:plmr:mfa-totp:api:USER_NOT_FOUND'
      - 'urn:plmr:mfa-totp:api:CHALLENGE_NOT_FOUND'
      - 'urn:plmr:mfa-totp:api:INVALID_OTP'
      - 'urn:plmr:mfa-totp:api:USER_ID_DOES_NOT_MATCH_WITH_CHALLENGE_SUBJECT_USER_ID'
      - 'urn:plmr:mfa-totp:api:STEP_UP_REQUEST_CONTEXT_NOT_FOUND'
      type: string
      example: 'urn:plmr:mfa-totp:api:UNAUTHORIZED'
    FieldErrorCode:
      enum:
      - 'urn:plmr:mfa-totp:api:NOT_BLANK'
      - 'urn:plmr:mfa-totp:api:NOT_NULL'
      type: string
    FieldError:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/FieldErrorCode'
        message:
          type: string
        field:
          type: string
    ErrorResponse:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
        requestId:
          type: string
        fieldErrors:
          type: array
          items:
            $ref: '#/components/schemas/FieldError'
  securitySchemes:
    cookieAuth:
      type: apiKey
      in: cookie
      name: auth-session