openapi: 3.0.0
x-project-id: 'Number_Verify'
info:
  title: NumberVerify (CAMARA)
  description: |-
    Number Verify (CAMARA) enables you to check if the mobile number of a device accessing an online service or app matches the one provided by the customer.
 
  version: 0.0.1

servers:
  - url: https://api-sandbox.vf-dmp.engineering.vodafone.com
    description: "Sandbox"
  # - url: https://api.vf-dmp.engineering.vodafone.com
  #   description: "Production"
 

paths:


  /mobileconnect/deviceinitiated/v1/authorize:
    get:
      tags:
        - Authorization Flow
      summary: Authorize
      description: |-
        This endpoint is used by the MobileConnect client to request authentication. As the result of the process, the user will obtain a randomly generated code that will be returned to the MobileConnect client via HTTP redirect.

        The destination of the HTTP redirect will be the redirect_uri parameter that you have provided and configured. As part of the security model, if you pass on a redirect_uri that has not been configured initially, the OIDC platform will respond with an error. This is to protect the API so that others are not able to hijack the authentication URL and replace the redirect_uri with their own address to obtain the code.
      
      parameters:

        - $ref: "#/components/parameters/vf-trace-transaction-id"

        - in: query
          name: redirect_uri
          schema:
            type: string
          required: true
          example : https://api.vf-dmp.engineering.vodafone.com/mobileconnect/deviceinitiated/v1/consent
          description: Apigee validates this against the list of original redirect URIs registered by the developer for that application. The URL list is separated by characters and provided in the app custom attribute "openid_redirect_uris".

        - in: query
          name: client_id
          schema:
            type: string
          required: true
          example : Xi4O6uUjXvRwTqrBjLTFGlNkGvuvPCMaoDbLIAPJocR555gZ
          description: Given when Developer App is created from the Discovery endpoint.

        - in: query
          name: scope
          schema:
            type: string
          required: true
          example : openid number-verification-verifyread
          description: MUST contain the scope value **openid number-verification-verifyread** (url encoded).

        - in: query
          name: response_type
          schema:
            type: string
          required: true
          example : code
          description: In phase-I one only 'code' is supported. In future we would support all the different flow types as described in openid spec. It must be contain **code**

        - in: query
          name: state
          schema:
            type: string
          required: true
          example : 9c4b31dd-0d79-4489-993a-97e48ec37eaf
          description: Generally state is used to maintain state between request and callback.

        - in: query
          name: correlation_id
          schema:
            type: string
          required: false
#          example: 42da5b19-457a-4d30-a5c4-038c62dccbb0
          description: Value generated by the SP to uniquely identify a transaction across multiple API calls to the APIx and the IDGW (so we can see the association between /authorize, /token and /premiuminfo requests/responses). example 42da5b19-457a-4d30-a5c4-038c62dccbb0

        - in: query
          name: acr_values
          schema:
            type: string
          required: true
          example: 2
          description: Authentication Context class Reference. Space separated string that specifies the Authentication Context Reference to be used during authentication processing. The LOA required by the RP/Client for the use case can be used here. The values appear as order of preference. The acr satisfied during authentication is returned as acr claim value. The recommended values are the LOAs as specified in ISO/IEC 29115 Clause 6 – 1, 2, 3, 4 – representing the LOAs of LOW, MEDIUM, HIGH and VERY HIGH. It’s important to note that mobile connect currently only supports LOAs 2 & 3.The acr_values are indication of what authentication methods to used by the IDP. The authentication methods to be used are linked to the LOA value passed in the acr_values. The IDP configures the authentication method selection logic based on the acr_values. It must be contain **2**

        - in: query
          name: version
          schema:
            type: string
          required: true
          example: mc_di_r2_v2.3
          description: A string value used to identify the profile version. It must be contain **mc_di_r2_v2.3**.

        - in: query
          name: nonce
          schema:
            type: string
          required: true
          example: 42da5b19-457a-4d30-a5c4-038c62dccbb0
          description: String value used to associate a client session with the ID Token. It is passed unmodified from Authorisation Request to ID Token. The value SHOULD be unique per session to mitigate replay attacks.

      responses:
        '302':
          description: |-
            **Found**
            Redirects to either Vodafone ID page of redirect uri of client

            in **Location** Header:
            - Included in success and error scenarios:
              - The “redirect_uri” as provided in the request parameter
              - “state”, as a query parameter
              - “correlation_id” (if provided, the value of the request parameter), as a query parameter
              
                    https://www.example.com/consent?error=interaction_required&error_description=customerData_not_found_during_networkLogin_for_MSISDN&state=ee07fc69-0f9d-43d6-b93a-bcb4c7e6be20&correlation_id=42da5b19-457a-4d30-a5c4-038c62dccbb0

            - In success cases a 302 response would contain a **code** to be used in the token api request

                  https://www.example.com/consent?code=gRIk9pak&state=9c4b31dd-0d79-4489-993a-97e48ec37eaf

            - In failure cases a 302 response would contain **error** and **error_description** fields in query parameter

                  https://www.example.com/consent?error=interaction_required&error_description=customerData_not_found_during_networkLogin_for_MSISDN&state=ee07fc69-0f9d-43d6-b93a-bcb4c7e6be20
        '500':
          description : |-
            **Internal Server Error** 
            HTTP response code other than “302 Found”, with error detail - along with state and correlation_id if provided in the request - are provided in the response body which is presented as JSON. Thisformat is used when the client_id or redirect_uri parameters are not valid
          content:
            application/json:
             examples:
              Invalid client_id or redirect_uri:
                value: {
                          "error": "server_error",
                          "error_description": "Error encountered accessing the KVM",
                          "state": "9c4b31dd-0d79-4489-993a-97e48ec37eaf",
                          "correlation_id": "42da5b19-457a-4d30-a5c4-038c62dccbb0"
                        }

  /mobileconnect/deviceinitiated/v1/token:
    post:
      tags:
        - Authorization Flow
      summary: Token

      # security:
      #   - BasicAuth: []

      description: |-
            The service provide a one-time **access_token** that must be used to call the premiuminfo endpoint.

            Basic Authorization is required to perform the request: an Authorization header with "Basic <base64(clientId:secret)>", e.g.:

              **Authorization: Basic ajBXV1B5eWRrTFFpN0FvRk5GfjyrQTZwcTZwZFVsSjA6IHI1OGdpdUJMbGRHSEIxMmQ**

      operationId: getToken

      parameters:
        - $ref: "#/components/parameters/authorization-basic"
        - $ref: "#/components/parameters/vf-trace-transaction-id"

      requestBody:
        description: |-
          Token end point is used to generate oauth2 access token.

        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - code
                - redirect_uri
                - grant_type
              properties:
                redirect_uri:
                  type: string
                  example: https://api.vf-dmp.engineering.vodafone.com/mobileconnect/deviceinitiated/v1/consent
                  description: The redirect_uri value must match the one sent in the authorization request.
                grant_type:
                  type: string
                  example: authorization_code
                  description: The value must always be “authorization_code”.
                code:
                  type: string
                  example: SplxlOBeZQQYbYS6WxSbIA
                  description: The authorization code received from the authorization server, as a result of the successful authorization request.
                correlation_id:
                  type: string
                  example: 42da5b19-457a-4d30-a5c4-038c62dccbb0
                  description: The correlation_id submitted through in the /authorize request (if provided). example 42da5b19-457a-4d30-a5c4-038c62dccbb0

      responses:
        '200':
          description: |
            **OK**
          content:
            application/json:
             examples:
              Token response:
                value: {
                      "access_token": "bGzoVULW9RiZGBK1CLC4lZGsNuVm",
                      "correlation_id": "42da5b19-457a-4d30-a5c4-038c62dccbb0",
                      "token_type": "Bearer",
                      "expires_in": 3599,
                      "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FwaWRldi5kZXZlbG9wZXIudm9kYWZvbmUuY29tIiwic3ViIjoiODhlMzk5ZWUtYmE5Zi00ZmVmLTk0NDUtMDE2YjAzNjU5OTkxIiwiYXVkIjoiODN0RmVzQmhJVEJBVEExa2hxbzJvekYzQ01Mb0k3blUiLCJleHAiOjM1OTkwMDEsImlhdCI6MSwiYXV0aF90aW1lIjoiMS41MjAzMTQ5NDhFOSIsIm5vbmNlIjoiMTIzNCIsImFjciI6IjMiLCJuYW1lIjoiSmFuZSBEb2UiLCJnaXZlbl9uYW1lIjoiSmFuZSIsImZhbWlseV9uYW1lIjoiRG9lIiwibWlkZGxlX25hbWUiOiJydXRoIiwibmlja25hbWUiOiJqb2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJqLmRvZSIsInByb2ZpbGUiOiJodHRwczovL2dvb2dsZS5jb20iLCJwaWN0dXJlIjoiaHR0cHM6Ly9waWN0dXJlcy5jb20iLCJ3ZWJzaXRlIjoiaHR0cHM6Ly93ZWJzaXRlLmNvbSIsImdlbmRlciI6Ik1hbGUiLCJ6b25laW5mbyI6IkV1cm9wZS9QYXJpcyIsImxvY2FsZSI6IkVOIiwidXBkYXRlZF9hdCI6IjEyMzQ1Njc4OTAiLCJhZGRyZXNzIjp7InN0cmVldF9hZGRyZXNzIjoiU0JJIENvbG9ueSIsImxvY2FsaXR5IjoiS29yYW1hbmdsYSIsInJlZ2lvbiI6IkJhbmdhbG9yZSIsInBvc3RhbF9jb2RlIjoiNTYwMDM0IiwiY291bnRyeSI6IkluZGlhIn0sImVtYWlsIjoiamFuZWRvZUBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjoidHJ1ZSIsInBob25lX251bWJlciI6IjkzNzg2NTM0MTIiLCJwaG9uZV9udW1iZXJfdmVyaWZpZWQiOiJ0cnVlIiwiY3JpZCI6IjEyMzQiLCJsb2NhbF9zdWIiOiIwOTIyYmQ3Zi1kZDhkLTRjYTAtODEzNS05M2RkOTUxMjZjODMifQ.GwHvOTBbpcO-Y2aXOmuruXl8qQthkpOssHyTxFjpZTw"
                    }
        '400':
            description: |
              **Bad Request**
            content:
              application/json:
                example:
                    {
                            "error": "invalid_request",
                            "error_description": "The request contains the same parameter multiple times"
                    }
        '401':
            description: |
              **Unauthorized**
            content:
              application/json:
                example:
                    {
                     "error": "invalid_request",
                      "error_description": "Missing or invalid client_id or client_secret"
                    }
        '404':
            description: |
              **Not Found**
            content:
              application/json:
                example:
                    {
                     "error": "Resource Not Found",
                      "error_description": "URI does not represent a recognised resource"
                    }
        '405':
            description: |
              **Method Not Allowed**
            content:
              application/json:
                example:
                    {
                     "error": "Method Not Allowed",
                      "error_description": "The request method is not supported by this resource"
                    }
        '406':
            description: |
              **Not Acceptable**
            content:
              application/json:
                example:
                    {
                     "error": "invalid_request",
                      "error_description": "Accept header is invalid"
                    }
        '413':
            description: |
              **Payload Too Large**
            content:
              application/json:
                example:
                    {
                     "error": "Payload Too Large",
                      "error_description": "The request payload exceeds a maximum size"
                    }
        '414':
            description: |
              **Request URI Too Long**
            content:
              application/json:
                example:
                    {
                     "error": "Request URI Too Long",
                      "error_description": "Request-URI is too long"
                    }
        '415':
            description: |
              **Unsupported Media Type**
            content:
              application/json:
                example:
                    {
                     "error": "invalid_request",
                      "error_description": "The value of the Content-Type header is invalid"
                    }
        '422':
            description: |
              **Unprocessable Content**
            content:
              application/json:
                example:
                    {
                     "error": "invalid_request",
                      "error_description": "The request was well-formed but was unable to be followed due to semantic errors"
                    }
        '429':
            description: |
              **Too Many Requests**
            content:
              application/json:
                example:
                    {
                     "error": "invalid_request",
                      "error_description": "Api Quota limit reached"
                    }
        '500':
            description: |
              **Internal Server Error**
            content:
              application/json:
                example:
                    {
                     "error": "Internal Server Error",
                      "error_description": "The authorization server encountered an unexpected condition that prevented it from fulfilling the request"
                    }


  /camara/number-verification/v0/verify:
    post:
      tags:
        - Number Verify API
      summary: number-verification

      description: |-
        This endpoint is a protected resource which returns claims about the authenticated end-user.

        Bearer Authentication is required to perform the request: an Authorization header with the access_token retrieved with the token API request, e.g.:

          **Authorization: Bearer alEw85xBVY83owVraNwNxzsfmpXu**

      # security:
      #   - BearerAuth: []

      operationId: number-verification

      parameters:
        - $ref: "#/components/parameters/authorization-bearer"
        - $ref: "#/components/parameters/vf-trace-transaction-id"
        - $ref: "#/components/parameters/vf_ext_bp_id"
        - $ref: "#/components/parameters/X-Correlator"
        
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/verifyReq"

      responses:
        '200':
          description: "**OK**"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/verifyRes"
        '400':
          $ref: '#/components/responses/Generic400'
        '401':
          $ref: '#/components/responses/Generic401'
        '403':
          $ref: '#/components/responses/PhoneNumberVerificationPermissionDenied403'
        '500':
          $ref: '#/components/responses/Generic500'
        '503':
          $ref: '#/components/responses/Generic503'
        '504':
          $ref: '#/components/responses/Generic504'


components:
  schemas:
    verifyReq:
      type: object
      required: 
        - hashedPhoneNumber
      properties:
        hashedPhoneNumber: 
          type: string
          
          description: | 
            A hash of the MSISDN to be “matched”. For Vodafone the hash must be performed using the SHA256 hash algorithm and presented in hexadecimal format (NOT base64 encoded). The MSISDN is in E.164 format including the country code and may be optionally prefixed with “+”. Example: MSISDN “+447767787999” hashed gives “73e5578761e35869a6a97cc9a30d93f32c695c82aa4aa0e6cbdffadb52f5ac8c”
          example: 6dd5d20f257c1f3620662454064e3aa25ba9a6c7a4d1e99e965bbadd3a7e07d6

    verifyRes:
      type: object
      required: 
        - devicePhoneNumberVerified
      properties:
        devicePhoneNumberVerified: 
          type: boolean
          description: | 
            This is a boolean value denoting the result of the match: “true” or “false”
          example: false

    ErrorInfo:
      type: object
      required:
        - status
        - code
        - message
      properties:
        status:
          type: integer
          description: HTTP response status code
        code:
          type: string
          description: Code given to this error
        message:
          type: string
          description: Detailed error description
  responses:
    Generic400:
      description: |
        **Bad Request**
      headers:
        X-Correlator:
          description: Correlation id for the different services
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 400
            code: INVALID_ARGUMENT
            message: Client specified an invalid argument, request body or query param
    Generic401:
      description: "**Unauthorized**"
      headers:
        X-Correlator:
          description: Correlation id for the different services
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 401
            code: UNAUTHENTICATED
            message: Request not authenticated due to missing, invalid, or expired credentials
    PhoneNumberVerificationPermissionDenied403:
      description: |
        **Forbidden** Client does not have sufficient permission.
        In addition to regular scenario of `PERMISSION_DENIED`, other scenarios may exist:
          - Client authentication was not via mobile network. In order to check the authentication method, AMR parameter value in the 3-legged user's access token can be used and make sure that the authentication was not either by SMS+OTP nor username/password (`{"code": "NUMBER_VERIFICATION.USER_NOT_AUTHENTICATED_BY_MOBILE_NETWORK","message": "Client must authenticate via the mobile network to use this service"}`)
          - Phone number cannot be deducted from access token context.(`{"code": "NUMBER_VERIFICATION.INVALID_TOKEN_CONTEXT","message": "Phone number cannot be deducted from access token context"}`)
      headers:
        X-Correlator:
          description: Correlation id for the different services
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            PermissionDenied:
              value:
                status: 403
                code: PERMISSION_DENIED
                message: Client does not have sufficient permissions to perform this action
            UserNotAuthenticatedByMobileNetwork:
              value:
                status: 403
                code: NUMBER_VERIFICATION.USER_NOT_AUTHENTICATED_BY_MOBILE_NETWORK
                message: Client must authenticate via the mobile network to use this service
            InvalidTokenContext:
              value:
                status: 403
                code: NUMBER_VERIFICATION.INVALID_TOKEN_CONTEXT
                message: Phone number cannot be deducted from access token context
    Generic500:
      description: "**Internal Server Error**"
      headers:
        X-Correlator:
          description: Correlation id for the different services
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 500
            code: INTERNAL
            message: Server error
    Generic503:
      description: "**Service Unavailable**"
      headers:
        X-Correlator:
          description: Correlation id for the different services
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 503
            code: UNAVAILABLE
            message: Service unavailable
    Generic504:
      description: "**Gateway Timeout Error**"
      headers:
        X-Correlator:
          description: Correlation id for the different services
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 504
            code: TIMEOUT
            message: Request timeout exceeded. Try later.


  # securitySchemes:
  #   BasicAuth:
  #       type: http
  #       scheme: basic
  #   BearerAuth:
  #     type: http
  #     scheme: bearer

  parameters:
    authorization-basic:
      name: Authorization
      in: header
      required: true
      description: |
        “Basic “ + base_64_encode (client_id + “:” + client_secret)
      schema:
        type: string
        example: | 
          Basic ZTcxNWE2OTYtYTY3OS00YmFhLTk3ODctYTU0ZmYlMTFhNmQ4OjdhMzM3OGI5LWZkMTQtNGNhYy1hZTc3LTkwZGVmZmZkYWQ5Yg==
          
    authorization-bearer:
      name: Authorization
      in: header
      required: true
      description: |
        “Bearer ” concatenated with the access token obtained from the token endpoint response.
      schema:
        type: string
        example: | 
          Bearer OohPZluqx9NYtkTA3Ok6yfRmIECi
    vf-trace-transaction-id:
      name: vf-trace-transaction-id
      in: header
      required: false
      description: A unique identifier for each request (typically a GUID).  Not defined as part of the standard but can be utilized by the SP to set a value which could assist in troubleshooting.  Note that if this header is not set in the request, Vodafone generates this value upon receipt of the message and returns the value in the response as a header.
      schema:
        type: string
    vf_ext_bp_id:
      name: vf_ext_bp_id
      in: header
      required: false
      description: The "VF_EXT_BP_ID" header holds the Client Origin Id. This is a means for identifying the originating customer. The value of Client Origin Id can be up to 12 characters in length, and it can contain a combination of A-Z, a-z, underscore and hyphen characters as permitted values. (No other special characters/white space is permitted). The value of the Client Origin ID will be assigned by Vodafone and communicated to the appropriate customer team.
      schema:
        type: string
        example: AcmeCorp
    X-Correlator:
      name: X-Correlator
      in: header
      required: false
      description: Correlation UUID that will be included in the response to request.
      schema:
        type: string

