# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
#
# SPDX-License-Identifier: AGPL-3.0-or-later

openapi: 3.0.0
info:
  version: 0.1.0
  title: mCaptcha/guard
servers:
  - url: /
paths:
  /api/v1/signup:
    post:
      summary: Registration endpoint
      operationId: registerUser
      tags:
        - user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterUser'
            example:
              username: 'testuser'
              password: 'mysuperlongandsecurepassword'
              email: 'testuser@example.com'
      responses:
        '200':
          description: Successful registration
        '400':
          description: >-
            Bad request: username contains profainity/blacklisted words or email
            not acceptable or password too long/short or duplicate
            username/password
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/signin:
    post:
      summary: Login endpoint
      operationId: loginUser
      tags:
        - user
        - authentication
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginUser'
            example:
              username: 'testuser'
              password: 'mysuperlongandsecurepassword'
      responses:
        '200':
          description: Successful authentication
        '401':
          description: 'authentication failed, wrong password'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: username not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/signout:
    post:
      security:
        - cookieAuth: []
      summary: Signout endpoint
      operationId: signoutUser
      tags:
        - user
        - authentication
      responses:
        '200':
          description: OK
  /api/v1/account/delete:
    post:
      security:
        - cookieAuth: []
      summary: Delete account
      operationId: deleteAccount
      tags:
        - user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeleteUser'
            example:
              password: 'mysuperlongandsecurepassword'
      responses:
        '200':
          description: OK
        '401':
          description: (cookie)authentication required or wrong password
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: username not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/account/username/exists:
    post:
      summary: Check if username exists
      operationId: usernameExists
      tags:
        - user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserDetailCheck'
            example:
              val: 'testuser'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserDetailCheckRes'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/account/email/exists:
    post:
      summary: Check if email exists
      operationId: emailExists
      tags:
        - user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserDetailCheck'
            example:
              val: 'testuser@example.com'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserDetailCheckRes'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/meta/health:
    get:
      summary: Health check
      operationId: healthCheck
      tags:
        - meta
        - health
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Health'
  /api/v1/meta/build:
    get:
      summary: Get server binary build details
      operationId: buildDetails
      tags:
        - meta
        - build
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BuildDetails'
  /api/v1/mcaptcha/domain/token/add:
    post:
      security:
        - cookieAuth: []
      summary: Add token for registered domain
      operationId: addToken
      tags:
        - mcaptcha
        - domain
        - token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MCaptchaID'

      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MCaptchaDetails'

        '400':
          description: 'Bad request: Submited URI is not a URI or duplicate token name'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'authentication failed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/v1/mcaptcha/domain/token/update:
    post:
      security:
        - cookieAuth: []
      summary: Update token key
      operationId: updateTokenKey
      tags:
        - mcaptcha
        - domain
        - token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MCaptchaID'

      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MCaptchaDetails'

        '400':
          description: 'Bad request: Submited URI is not a URI or duplicate token name'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'authentication failed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/v1/mcaptcha/domain/token/get:
    post:
      security:
        - cookieAuth: []
      summary: Get token key
      operationId: getTokenKey
      tags:
        - mcaptcha
        - domain
        - token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MCaptchaID'

      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MCaptchaDetails'

        '400':
          description: 'Bad request: Submited URI is not a URI'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'authentication failed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: token name not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/v1/mcaptcha/domain/token/delete:
    post:
      security:
        - cookieAuth: []
      summary: Delete token from mcaptcha
      operationId: deleteToken
      tags:
        - mcaptcha
        - domain
        - token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MCaptchaID'

      responses:
        '200':
          description: OK
        '401':
          description: 'authentication failed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/v1/mcaptcha/domain/token/levels/add:
    post:
      security:
        - cookieAuth: []
      summary: Add levels to a token
      operationId: addTokenLevels
      tags:
        - mcaptcha
        - domain
        - token
        - levels
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddLevels'

      responses:
        '200':
          description: OK
        '400':
          description: 'duplicate visitor count or difficulty_factor is zero or difficulty_factor decreases with increase in visitor count'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

        '401':
          description: 'authentication failed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/v1/mcaptcha/domain/token/levels/update:
    post:
      security:
        - cookieAuth: []
      summary: Update levels of a token
      operationId: updateTokenLevels
      tags:
        - mcaptcha
        - domain
        - token
        - levels
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddLevels'

      responses:
        '200':
          description: OK
        '400':
          description: 'duplicate visitor count or difficulty_factor is zero or difficulty_factor decreases with increase in visitor count'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

        '401':
          description: 'authentication failed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/v1/mcaptcha/domain/token/levels/delete:
    post:
      security:
        - cookieAuth: []
      tags:
        - mcaptcha
        - domain
        - token
        - levels
      summary: Delete levels of a token
      operationId: deleteTokenLevels
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddLevels'
      responses:
        '200':
          description: OK
        '401':
          description: (cookie)authentication required or wrong password
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/mcaptcha/domain/token/levels/get:
    post:
      security:
        - cookieAuth: []
      tags:
        - mcaptcha
        - domain
        - token
        - levels
      summary: Get levels of a token
      operationId: getTokenLevels
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddLevels'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Levels'
        '401':
          description: (cookie)authentication required or wrong password
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/v1/mcaptcha/domain/token/token/get:
    post:
      security:
        - cookieAuth: []
      tags:
        - mcaptcha
        - domain
        - token
        - levels
        - duration
      summary: Get duration of a token
      operationId: getTokenDuration
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GetDuration'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Duration'
        '401':
          description: (cookie)authentication required or wrong password
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/v1/mcaptcha/domain/token/token/update:
    post:
      security:
        - cookieAuth: []
      tags:
        - mcaptcha
        - domain
        - token
        - levels
        - duration
      summary: update duration of a token
      operationId: updateTokenDuration
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDuration'
      responses:
        '200':
          description: OK
        '400':
          description: 'Bad request: Duration must be greater than 0'
        '401':
          description: (cookie)authentication required or wrong password
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

components:
  schemas:
    RegisterUser:
      type: object
      required:
        - username
        - password
        - email
      properties:
        username:
          type: string
        email:
          type: string
        password:
          type: string
          format: password
    LoginUser:
      type: object
      required:
        - username
        - password
      properties:
        username:
          type: string
        password:
          type: string
          format: password
    DeleteUser:
      type: object
      required:
        - password
      properties:
        password:
          type: string
          format: password
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
    User:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
    UserDetailCheck:
      type: object
      required:
        - val
      properties:
        val:
          type: string
    Health:
      type: object
      required:
        - db
      properties:
        db:
          type: boolean
    UserDetailCheckRes:
      type: object
      required:
        - exists
      properties:
        val:
          type: boolean
    BuildDetails:
      type: object
      required:
        - version
        - git_commit_hash
      properties:
        version:
          type: string
        git_commit_hash:
          type: string
    AddDomain:
      type: object
      required:
        - name
      properties:
        name:
          type: string
    DomainVerificationChallenge:
      type: object
      required:
        - verification_challenge
      properties:
        verification_challenge:
          type: string
    MCaptchaID:
      type: object
      required:
        - name
        - domain
      properties:
        name:
          type: string
        domain:
          type: string
    MCaptchaDetails:
      type: object
      required:
        - name
        - key
      properties:
        name:
          type: string
        key:
          type: string
    Level:
      type: object
      required:
        - visitor_threshold
        - difficulty_factor
      properties:
        visitor_threshold:
          type: number
          minimum: 1
          maximum: 2147483647
        difficulty_factor:
          type: number
          minimum: 1
    GetLevels:
      type: object
      required:
        - token
      properties:
        token:
          type: string
    Levels:
      type: array
      items:
        $ref: '#/components/schemas/Level'

    AddLevels:
      type: object
      required:
        - name
        - levels
      properties:
        name:
          type: string
        levels:
          type: array
          items:
            $ref: '#/components/schemas/Level'
    GetDuration:
      type: object
      required:
        - token
      properties:
        token:
          type: string
    Duration:
      type: object
      required:
        - duration
      properties:
        duration:
          type: number
          minimum: 1
          maximum: 2147483647

    UpdateDuration:
      type: object
      required:
        - duration
        - token_name
      properties:
        token_name:
          type: string
        duration:
          type: number
          minimum: 1
          maximum: 2147483647

  securitySchemes:
    cookieAuth:
      type: apiKey
      in: cookie
      name: Authorization