openapi: 3.1.0
info:
  title: Wunder Authentication User API
  description: auth_service User API
  version: 1.0.0
  contact:
    name: Wunder Mobility GmbH
    url: 'https://wundermobility.com'
    email: info@wundermobility.com
servers:
  - url: 'https://{environment}.api.gourban.services/v1/{tenant}/auth'
    description: Wunder Auth User API
    variables:
      environment:
        default: go
        enum:
          - go
          - go-staging
      tenant:
        default: demo
        description: Tenant identifier of your system. Usually 8 characters.
paths:
  /logout:
    post:
      summary: 'POST /logout'
      operationId: logout
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LogoutRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Void'
  /refresh-token:
    post:
      summary: 'POST /refresh-token'
      operationId: refreshToken
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshTokenRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignInResponse'
  '/set-password/{code}':
    post:
      summary: 'POST /set-password/{code}'
      operationId: setPassword
      parameters:
        - name: code
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetPasswordRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Void'
  /sign-in-api-client:
    post:
      summary: 'POST /sign-in-api-client'
      operationId: apiClientSignIn
      description: |
        Server-to-server sign-in using API client credentials (`clientId` / `clientKey`).
        Returns a fresh access token and refresh token.

        **Token lifecycle**

        - Each successful call issues a new pair of tokens. Previously issued
          access and refresh tokens for the same API client remain valid until
          they expire on their own — signing in again does **not** invalidate
          earlier tokens. There is no concept of a single active session per
          API client.

        **Sharing credentials across services**

        - The same API client credentials may be used by multiple backend
          services concurrently; each service can maintain its own token cache
          and authenticate independently. This is a supported pattern.
        - When services serve different user journeys, domains, or require
          different permissions, prefer creating a separate API client per
          service so that scopes, rotation, and revocation can be managed
          independently.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ApiClientSignInRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignInResponse'
  /sign-in-email:
    post:
      summary: 'POST /sign-in-email'
      operationId: signInEmail
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignInEmailRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignInResponse'
  /sign-in-gaiyo:
    post:
      summary: 'POST /sign-in-gaiyo'
      operationId: signInGaiyo
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignInGaiyoRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignInResponse'
  /sign-in-phone-number:
    post:
      summary: 'POST /sign-in-phone-number'
      operationId: signInPhoneNumber
      parameters:
        - name: Accept-Language
          in: header
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignInPhoneNumberRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignInResponse'
  /sign-in-email-code:
    post:
      summary: 'POST /sign-in-email-code'
      operationId: signInEmailCode
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignInEmailCodeRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignInResponse'

  /social-login:
    post:
      summary: 'POST /social-login'
      operationId: socialLogin
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SocialLoginRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignInResponse'
  /user/2fa-code-validate:
    post:
      summary: 'POST /user/2fa-code-validate'
      operationId: validate2faCode
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Validate2faCodeRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignInResponse'
  /user/2fa-enable:
    post:
      summary: 'POST /user/2fa-enable'
      operationId: enable2fa
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Enable2faRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Void'
  /user/2fa-qr-code:
    post:
      summary: 'POST /user/2fa-qr-code'
      operationId: getUser2faQrCode
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyPasswordRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            image/png:
              schema:
                type: array
                items:
                  type: string
                  format: byte
  /user/2fa-secret:
    post:
      summary: 'POST /user/2fa-secret'
      operationId: getUser2faSecret
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyPasswordRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Get2faSecretResponse'
  /user/openid-token-exchange:
    post:
      summary: 'POST /user/openid-token-exchange'
      operationId: openIdTokenExchange
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OpenIdTokenExchangeRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenIdTokenExchangeResponse'
components:
  schemas:
    LogoutRequest:
      type: object
      properties:
        refreshToken:
          type: string
    Void:
      type: object
      properties: {}
    RefreshTokenRequest:
      type: object
      properties:
        refreshToken:
          type: string
    SignInResponse:
      type: object
      properties:
        accessToken:
          type: string
        accessTokenExpireDate:
          type: string
          format: date-time
        refreshToken:
          type: string
        refreshTokenExpireDate:
          type: string
          format: date-time
        mfaRequired:
          type: boolean
        mfaStatus:
          type: string
          enum:
            - CONFIGURED
            - REQUIRED
            - AVAILABLE
            - NOT_AVAILABLE
        uuid:
          type: string
    SetPasswordRequest:
      type: object
      properties:
        password:
          type: string
        reEnteredPassword:
          type: string
    ApiClientSignInRequest:
      type: object
      properties:
        clientId:
          type: string
        clientKey:
          type: string
    SignInEmailRequest:
      type: object
      properties:
        email:
          type: string
        password:
          type: string
    SignInGaiyoRequest:
      type: object
      properties:
        token:
          type: string
    SignInPhoneNumberRequest:
      type: object
      properties:
        phoneNumber:
          type: string
        code:
          type: string
    SignInEmailCodeRequest:
      type: object
      properties:
        email:
          type: string
        code:
          type: string
    SocialLoginRequest:
      type: object
      properties:
        token:
          type: string
        socialLoginType:
          type: string
          enum:
            - GOOGLE
            - APPLE
            - FACEBOOK
            - PIM_OPENID
            - GAIYO
    Validate2faCodeRequest:
      type: object
      properties:
        code:
          type: string
    Enable2faRequest:
      type: object
      properties:
        code:
          type: string
    VerifyPasswordRequest:
      type: object
      properties:
        password:
          type: string
    Get2faSecretResponse:
      type: object
      properties:
        secret:
          type: string
        totpUrl:
          type: string
        encodedQRCodeImage:
          type: array
          items:
            type: string
            format: byte
    OpenIdTokenExchangeRequest:
      type: object
      properties:
        code:
          type: string
        type:
          type: string
          enum:
            - PIM_OPENID
    OpenIdTokenExchangeResponse:
      type: object
      properties:
        token:
          type: string
