{
  "openapi": "3.0.0",
  "info": {
    "description": "# ReČeK: přihlášení, obnova tokenu a odhlášení\n\nNávod pro ReČeK (FOLIO Eureka). Všechna volání jdou přes gateway (Kong) `https://<gateway>` a nesou hlavičku `X-Okapi-Tenant: <tenant>`. Tokeny vydává Keycloak přes tento modul (mod-login-keycloak); ReČeK frontend (ui-br-stripes-core) používá cookies.\n\n## Přihlášení – `POST /authn/login-with-expiry`\n\n```bash\ncurl -i -c cookies.txt -X POST 'https://<gateway>/authn/login-with-expiry' \\\n  -H 'X-Okapi-Tenant: <tenant>' -H 'Content-Type: application/json' \\\n  -d '{\"username\":\"<email>\",\"password\":\"<heslo>\"}'\n```\n\nÚspěch = **201** s tělem jen s časy expirace (ISO 8601, UTC) – samotné tokeny v těle nejsou:\n\n```json\n{ \"accessTokenExpiration\": \"2026-01-01T10:00:00Z\", \"refreshTokenExpiration\": \"2026-01-01T18:00:00Z\" }\n```\n\nTokeny přicházejí ve dvou `Set-Cookie` (vždy `HttpOnly; Secure; SameSite=None`, `Max-Age` = platnost tokenu):\n\n| Cookie | Path | Obsah |\n|---|---|---|\n| `folioAccessToken` | `/` | access token (JWT) – prohlížeč ho posílá na všechna API gateway |\n| `folioRefreshToken` | `/authn` | refresh token – prohlížeč ho posílá jen na `/authn/*` |\n\n- Cookies jsou `Secure` → posílají se jen přes HTTPS (curl je přes `http://` nepošle).\n- V prohlížeči volejte `fetch(..., { credentials: 'include' })`, jinak cookies neodejdou (cross-origin, proto `SameSite=None`).\n- Platnost neodhadujte, řiďte se `accessTokenExpiration` / `refreshTokenExpiration` z odpovědi.\n- Po přihlášení frontend načte uživatele a oprávnění přes `GET /br-users/_self`.\n\n## Volání ostatních API\n\n- **Prohlížeč / cookie jar:** cookie `folioAccessToken` stačí, gateway z ní token převezme.\n  ```bash\n  curl -b cookies.txt 'https://<gateway>/br-users/_self' -H 'X-Okapi-Tenant: <tenant>'\n  ```\n- **Klient bez cookies (skript, server-to-server):** na ReČeK je zapnuté `X_OKAPI_TOKEN_HEADER_ENABLED=true`, takže starší `POST /authn/login` (stejné tělo) vrací access token v hlavičce `x-okapi-token` a v těle `{\"okapiToken\",\"refreshToken\"}`. Token pak posílejte v hlavičce:\n  ```bash\n  curl 'https://<gateway>/br-users/_self' -H 'X-Okapi-Tenant: <tenant>' -H 'X-Okapi-Token: <access token>'\n  ```\n\n## Obnova tokenu – `POST /authn/refresh`\n\nBez těla; vstupem je jen cookie `folioRefreshToken` (povinná). Odpověď **201** má stejné tělo jako login a nastaví **nové** obě cookies – dál používejte ty nové.\n\n```bash\ncurl -i -b cookies.txt -c cookies.txt -X POST 'https://<gateway>/authn/refresh' \\\n  -H 'X-Okapi-Tenant: <tenant>' -H 'Content-Type: application/json'\n```\n\nKlient bez cookie jaru pošle refresh token ručně: `-H 'Cookie: folioRefreshToken=<refresh token>'`.\n\nJak to dělá ReČeK frontend (`FFetch.js`, `token-util.js`):\n- obnovu naplánuje na **80 %** zbývající platnosti access tokenu (`RTR_AT_TTL_FRACTION = 0.8`), jen pokud access token vyprší dřív než refresh token;\n- během obnovy ostatní požadavky počkají (souběh mezi záložkami hlídá příznak v `localStorage`, max. 20 s);\n- neúspěšná obnova (`RTR_ERROR_EVENT`) = konec relace a odhlášení;\n- refresh token má pevnou platnost: minutu před jeho koncem se zobrazí varování a relace skončí (nový login).\n\n## Odhlášení – `POST /authn/logout`\n\n```bash\ncurl -i -b cookies.txt -X POST 'https://<gateway>/authn/logout' -H 'X-Okapi-Tenant: <tenant>'\n```\n\n**204**; ukončí relaci aktuálního zařízení (podle `folioRefreshToken`) a vrátí obě cookies prázdné s `Max-Age=0` (zneplatní je i při chybě). `POST /authn/logout-all` odhlásí uživatele na všech zařízeních.\n\n## Neúspěšné přihlášení – `POST /br-users/login-diagnostics` (mod-br-users)\n\nKeycloak z bezpečnostních důvodů vrací pro neznámého uživatele i špatné heslo stejnou obecnou chybu (přes gateway typicky 400). ReČeK frontend proto po chybě loginu (400/401/422, ne 5xx/429) zavolá veřejný endpoint bez tokenu:\n\n```bash\ncurl -i -X POST 'https://<gateway>/br-users/login-diagnostics' \\\n  -H 'X-Okapi-Tenant: <tenant>' -H 'Content-Type: application/json' -d '{\"username\":\"<email>\"}'\n```\n\n| Odpověď | Význam | Hláška ve FE |\n|---|---|---|\n| 401 `{\"errors\":[{\"type\":\"-5\"}]}` | uživatel neexistuje | Neplatné uživatelské jméno |\n| 401 `{\"errors\":[{\"type\":\"-6\"}]}` | uživatel existuje a je aktivní → špatné heslo | Neplatné heslo |\n| 401 `{\"errors\":[{\"type\":\"-7\"}]}` | uživatel je deaktivovaný | Ztráta přístupu - ukončení činnosti garanta |\n| 204 | příčinu nelze určit | obecná chyba |\n\nEndpoint záměrně umožňuje zjistit existenci účtu (enumerace) – vědomě přijato kvůli zachování původního chování ReČeKu. Popis je ve specifikaci `users-*.json`.\n\n---\n\n## Upstream popis (folio-org)\n\nMod Login Keycloak API\n",
    "title": "Mod Login Keycloak API",
    "version": "3.0.0"
  },
  "tags": [
    {
      "description": "Stub implementation for `authtoken` and `authtoken2` interfaces.\n",
      "name": "authtoken"
    }
  ],
  "paths": {
    "/authn/loginAttempts/{userId}": {
      "get": {
        "description": "Get login attempts for a single user",
        "operationId": "getLoginAttempts",
        "parameters": [
          {
            "description": "User identifier",
            "explode": false,
            "in": "path",
            "name": "userId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/loginAttempts"
                }
              }
            },
            "description": "Number of login attempts for user"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response if entity is not found by id (in json format)"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "loginAttempts"
        ]
      }
    },
    "/authn/login": {
      "post": {
        "description": "Get a new login token",
        "operationId": "login",
        "parameters": [
          {
            "description": "Used to identify the Operating System and Browser of the web-server",
            "explode": false,
            "in": "header",
            "name": "userAgent",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "-< HTTP header field is a common method for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer",
            "explode": false,
            "in": "header",
            "name": "forwardedFor",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/loginCredentials"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/loginResponse"
                }
              }
            },
            "description": "Login response body with access/refresh tokens",
            "headers": {
              "x-okapi-token": {
                "description": "An X-Okapi-Token header",
                "explode": false,
                "required": true,
                "schema": {
                  "type": "string"
                },
                "style": "simple"
              },
              "refreshtoken": {
                "description": "A refresh token",
                "explode": false,
                "required": true,
                "schema": {
                  "type": "string"
                },
                "style": "simple"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for unprocessable entity."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "login"
        ]
      }
    },
    "/authn/login-with-expiry": {
      "post": {
        "description": "Get an expiring refresh and access token",
        "operationId": "loginWithExpiry",
        "parameters": [
          {
            "description": "Used to identify the Operating System and Browser of the web-server",
            "explode": false,
            "in": "header",
            "name": "userAgent",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "-< HTTP header field is a common method for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer",
            "explode": false,
            "in": "header",
            "name": "forwardedFor",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/loginCredentials"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/loginResponseWithExpiry"
                }
              }
            },
            "description": "Login response body with access/refresh tokens"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for unprocessable entity."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "login"
        ]
      }
    },
    "/authn/refresh": {
      "post": {
        "description": "Get a new refresh and access token",
        "operationId": "refreshToken",
        "parameters": [
          {
            "description": "Refresh token cookie",
            "explode": true,
            "in": "cookie",
            "name": "folioRefreshToken",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/loginResponseWithExpiry"
                }
              }
            },
            "description": "Refresh response body with access/refresh tokens"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for unprocessable entity."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "login"
        ]
      }
    },
    "/authn/logout": {
      "post": {
        "description": "Logs the user out on their current device",
        "operationId": "logout",
        "parameters": [
          {
            "description": "Refresh token cookie",
            "explode": true,
            "in": "cookie",
            "name": "folioRefreshToken",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "204": {
            "description": "The user has been logged out from their current devices."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for unprocessable entity."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "login"
        ]
      }
    },
    "/authn/logout-all": {
      "post": {
        "description": "Logs the user out on all of their devices",
        "operationId": "logoutAll",
        "responses": {
          "204": {
            "description": "The user has been logged out from all their devices."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for unprocessable entity."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "login"
        ]
      }
    },
    "/authn/token": {
      "get": {
        "description": "Get a new login token from the authorization code",
        "operationId": "token",
        "parameters": [
          {
            "description": "Used to identify the Operating System and Browser of the web-server",
            "explode": false,
            "in": "header",
            "name": "userAgent",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "-< HTTP header field is a common method for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer",
            "explode": false,
            "in": "header",
            "name": "forwardedFor",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "temporary authentication code",
            "explode": true,
            "in": "query",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "form"
          },
          {
            "description": "initial uri that was used as redirect uri for getting authentication code",
            "explode": true,
            "in": "query",
            "name": "redirect-uri",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/loginResponseWithExpiry"
                }
              }
            },
            "description": "Login response body with access token",
            "headers": {
              "x-okapi-token": {
                "description": "An X-Okapi-Token header",
                "explode": false,
                "required": true,
                "schema": {
                  "type": "string"
                },
                "style": "simple"
              },
              "refreshtoken": {
                "description": "A refresh token",
                "explode": false,
                "required": true,
                "schema": {
                  "type": "string"
                },
                "style": "simple"
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for unprocessable entity."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "login"
        ]
      }
    },
    "/authn/update": {
      "post": {
        "description": "Self-update existing credentials.",
        "operationId": "updateCredentials",
        "parameters": [
          {
            "description": "Used to identify the Operating System and Browser of the web-server",
            "explode": false,
            "in": "header",
            "name": "userAgent",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "-< HTTP header field is a common method for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer",
            "explode": false,
            "in": "header",
            "name": "forwardedFor",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/updateCredentials"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Self-update existing credentials."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format if user is not authorized to perform operation."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for unprocessable entity."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "credentials"
        ]
      }
    },
    "/authn/credentials": {
      "delete": {
        "description": "Delete credentials for user",
        "operationId": "deleteCredentials",
        "parameters": [
          {
            "description": "User identifier",
            "explode": true,
            "in": "query",
            "name": "userId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "204": {
            "description": "Credentials removed successfully"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "credentials"
        ]
      },
      "post": {
        "description": "Add a new login to the system.",
        "operationId": "createCredentials",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/loginCredentials"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Success string message"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for unprocessable entity."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "credentials"
        ]
      }
    },
    "/authn/password/repeatable": {
      "post": {
        "description": "Validate password for repeatability",
        "operationId": "validatePasswordRepeatability",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/password"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/validPassword"
                }
              }
            },
            "description": "Password validation result"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "password"
        ]
      }
    },
    "/authn/reset-password": {
      "post": {
        "description": "Resets password for user in record and deletes action record",
        "operationId": "resetPassword",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/passwordResetAction"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/responseResetAction"
                }
              }
            },
            "description": "Login response body with access/refresh tokens"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "password"
        ]
      }
    },
    "/authn/password-reset-action": {
      "post": {
        "description": "Saves password reset action to storage",
        "operationId": "createResetPasswordAction",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/passwordCreateAction"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/responseCreateAction"
                }
              }
            },
            "description": "Response to create a new password change action"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "password"
        ]
      }
    },
    "/authn/password-reset-action/{actionId}": {
      "get": {
        "description": "Retrieves action record by id",
        "operationId": "getPasswordActionById",
        "parameters": [
          {
            "description": "Action Identifier",
            "explode": false,
            "in": "path",
            "name": "actionId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/passwordCreateAction"
                }
              }
            },
            "description": "Number of login attempts for user"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response if entity is not found by id (in json format)"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "password"
        ]
      }
    },
    "/authn/log/events": {
      "get": {
        "description": "Returns a list of events retrieved from storage",
        "operationId": "getLogEvents",
        "parameters": [
          {
            "description": "The maximum number of results to return.",
            "example": 10,
            "explode": true,
            "in": "query",
            "name": "length",
            "required": false,
            "schema": {
              "default": 10,
              "minimum": 1,
              "type": "integer"
            },
            "style": "form"
          },
          {
            "description": "The starting index in a list of results (starts at one).",
            "explode": true,
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            },
            "style": "form"
          },
          {
            "description": "A query string to filter users based on matching criteria in fields.",
            "example": "10",
            "explode": true,
            "in": "query",
            "name": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/logEventCollection"
                }
              }
            },
            "description": "Log events"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response if entity is not found by id (in json format)"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "logEvents"
        ]
      },
      "post": {
        "description": "Saves received event into the storage",
        "operationId": "saveLogEvent",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/logEvent"
              }
            }
          }
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/logResponse"
                }
              }
            },
            "description": "Saved Log event"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for validation errors."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "logEvents"
        ]
      }
    },
    "/authn/log/events/{eventId}": {
      "delete": {
        "description": "Saves received event into the storage",
        "operationId": "deleteLogEvent",
        "parameters": [
          {
            "description": "Event Identifier",
            "explode": false,
            "in": "path",
            "name": "eventId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "204": {
            "description": "No content response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response if entity is not found by id (in json format)"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "logEvents"
        ]
      }
    },
    "/authn/credentials-existence": {
      "get": {
        "description": "Returns single property 'credentialsExist' with true, if user has local password",
        "operationId": "checkCredentialsExistence",
        "parameters": [
          {
            "description": "User identifier",
            "explode": true,
            "in": "query",
            "name": "userId",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/credentialsExistence"
                }
              }
            },
            "description": "Credentials existence response"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
          }
        },
        "tags": [
          "credentials"
        ]
      }
    },
    "/token": {
      "post": {
        "description": "***Not Implemented, Deprecated***\n\n_Will be removed in a future releases_\n\nPlease use `/token/sign` instead. Returns a signed, non-expiring legacy access token.\n",
        "operationId": "token-legacy",
        "parameters": [
          {
            "description": "Okapi Tenant",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Tenant",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "Okapi URL",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Url",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/signTokenPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/tokenResponseLegacy"
                }
              }
            },
            "description": "Created and signed token successfully"
          },
          "501": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for endpoints that are not implemented."
          }
        },
        "tags": [
          "authtoken"
        ]
      }
    },
    "/refreshtoken": {
      "post": {
        "description": "***Not Implemented***\n\nReturns a signed, expiring refresh token. This is a legacy endpoint and should not be\ncalled by new code and will soon be fully depreciated.\n",
        "operationId": "token-sign-legacy",
        "parameters": [
          {
            "description": "Okapi Tenant",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Tenant",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "Okapi URL",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Url",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/signRefreshToken"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/token"
                }
              }
            },
            "description": "Created and signed token successfully"
          },
          "501": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for endpoints that are not implemented."
          }
        },
        "tags": [
          "authtoken"
        ]
      }
    },
    "/token/sign": {
      "post": {
        "description": "***Not Implemented***\n\nReturns a signed, expiring access token and refresh token. Also returns the expiration\nof each token in the body of the response. The access token time to live is 10 minutes and\nthe refresh token is one week.\n",
        "operationId": "token-sign",
        "parameters": [
          {
            "description": "Okapi Tenant",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Tenant",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "Okapi URL",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Url",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/signTokenPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/tokenResponse"
                }
              }
            },
            "description": "Created and signed tokens successfully"
          },
          "501": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for endpoints that are not implemented."
          }
        },
        "tags": [
          "authtoken"
        ]
      }
    },
    "/token/refresh": {
      "post": {
        "description": "***Not Implemented***\n\nReturns a new refresh token and a new access token. Also returns the expiration of each token\nin the body of the response. Time to live is 10 minutes for the access token and one week for\nthe refresh token.\n",
        "operationId": "token-refresh",
        "parameters": [
          {
            "description": "Okapi Tenant",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Tenant",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "Okapi URL",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Url",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/refreshToken"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/tokenResponse"
                }
              }
            },
            "description": "Refreshed tokens successfully"
          },
          "501": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for endpoints that are not implemented."
          }
        },
        "tags": [
          "authtoken"
        ]
      }
    },
    "/token/invalidate": {
      "post": {
        "description": "***Not Implemented***\n\nInvalidate a single token\n",
        "operationId": "token-invalidate",
        "parameters": [
          {
            "description": "Okapi Tenant",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Tenant",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "Okapi URL",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Url",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/refreshToken"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Invalidated token successfully"
          },
          "501": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for endpoints that are not implemented."
          }
        },
        "tags": [
          "authtoken"
        ]
      }
    },
    "/token/invalidate-all": {
      "post": {
        "description": "***Not Implemented***\n\nInvalidate all tokens for a user\n",
        "operationId": "token-invalidate-all",
        "parameters": [
          {
            "description": "Okapi Tenant",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Tenant",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          },
          {
            "description": "Okapi URL",
            "explode": false,
            "in": "header",
            "name": "X-Okapi-Url",
            "required": true,
            "schema": {
              "type": "string"
            },
            "style": "simple"
          }
        ],
        "responses": {
          "204": {
            "description": "Invalidated tokens successfully"
          },
          "501": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            },
            "description": "Error response in JSON format for endpoints that are not implemented."
          }
        },
        "tags": [
          "authtoken"
        ]
      }
    }
  },
  "components": {
    "parameters": {
      "actionId": {
        "description": "Action Identifier",
        "explode": false,
        "in": "path",
        "name": "actionId",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "simple"
      },
      "userId": {
        "description": "User identifier",
        "explode": true,
        "in": "query",
        "name": "userId",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "form"
      },
      "eventId": {
        "description": "Event Identifier",
        "explode": false,
        "in": "path",
        "name": "eventId",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "simple"
      },
      "pathUserId": {
        "description": "User identifier",
        "explode": false,
        "in": "path",
        "name": "userId",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "simple"
      },
      "userAgentHeader": {
        "description": "Used to identify the Operating System and Browser of the web-server",
        "explode": false,
        "in": "header",
        "name": "userAgent",
        "required": false,
        "schema": {
          "type": "string"
        },
        "style": "simple"
      },
      "xForwardedForHeader": {
        "description": "-< HTTP header field is a common method for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer",
        "explode": false,
        "in": "header",
        "name": "forwardedFor",
        "required": false,
        "schema": {
          "type": "string"
        },
        "style": "simple"
      },
      "folioRefreshToken": {
        "description": "Refresh token cookie",
        "explode": true,
        "in": "cookie",
        "name": "folioRefreshToken",
        "required": false,
        "schema": {
          "type": "string"
        },
        "style": "form"
      },
      "folioRefreshTokenRequired": {
        "description": "Refresh token cookie",
        "explode": true,
        "in": "cookie",
        "name": "folioRefreshToken",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "form"
      },
      "length": {
        "description": "The maximum number of results to return.",
        "example": 10,
        "explode": true,
        "in": "query",
        "name": "length",
        "required": false,
        "schema": {
          "default": 10,
          "minimum": 1,
          "type": "integer"
        },
        "style": "form"
      },
      "start": {
        "description": "The starting index in a list of results (starts at one).",
        "explode": true,
        "in": "query",
        "name": "start",
        "required": false,
        "schema": {
          "default": 1,
          "minimum": 1,
          "type": "integer"
        },
        "style": "form"
      },
      "query": {
        "description": "A query string to filter users based on matching criteria in fields.",
        "example": "10",
        "explode": true,
        "in": "query",
        "name": "query",
        "required": false,
        "schema": {
          "type": "string"
        },
        "style": "form"
      },
      "code": {
        "description": "temporary authentication code",
        "explode": true,
        "in": "query",
        "name": "code",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "form"
      },
      "redirect-uri": {
        "description": "initial uri that was used as redirect uri for getting authentication code",
        "explode": true,
        "in": "query",
        "name": "redirect-uri",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "form"
      },
      "okapi-token-required": {
        "description": "Okapi Tenant",
        "explode": false,
        "in": "header",
        "name": "X-Okapi-Tenant",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "simple"
      },
      "okapi-url-required": {
        "description": "Okapi URL",
        "explode": false,
        "in": "header",
        "name": "X-Okapi-Url",
        "required": true,
        "schema": {
          "type": "string"
        },
        "style": "simple"
      }
    },
    "responses": {
      "badRequestResponse": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errorResponse"
            }
          }
        },
        "description": "Error response in JSON format for validation errors."
      },
      "unauthorizedResponse": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errorResponse"
            }
          }
        },
        "description": "Error response in JSON format if user is not authorized to perform operation."
      },
      "entityNotFoundResponse": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errorResponse"
            }
          }
        },
        "description": "Error response if entity is not found by id (in json format)"
      },
      "unprocessableEntityResponse": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errorResponse"
            }
          }
        },
        "description": "Error response in JSON format for unprocessable entity."
      },
      "notImplementedEntityResponse": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errorResponse"
            }
          }
        },
        "description": "Error response in JSON format for endpoints that are not implemented."
      },
      "internalServerErrorResponse": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errorResponse"
            }
          }
        },
        "description": "Error response for unhandled or critical server exceptions, e.g. NullPointerException."
      }
    },
    "schemas": {
      "loginAttempts": {
        "description": "An object describing a login attempt",
        "properties": {
          "id": {
            "description": "Unique id",
            "type": "string"
          },
          "userId": {
            "description": "Unique user id",
            "type": "string"
          },
          "lastAttempt": {
            "description": "Last attempt date",
            "format": "date-time",
            "type": "string"
          },
          "attemptCount": {
            "description": "Number of user login attempts",
            "type": "integer"
          }
        },
        "title": "Login Attempts Schema",
        "type": "object"
      },
      "loginCredentials": {
        "description": "An entity that describes the basic credentials for a user to log on to the system",
        "properties": {
          "username": {
            "description": "Username in the system, case insensitive",
            "type": "string"
          },
          "userId": {
            "description": "Unique user id",
            "type": "string"
          },
          "password": {
            "description": "User password",
            "type": "string"
          }
        },
        "required": [
          "password"
        ],
        "title": "Login Credentials Schema",
        "type": "object"
      },
      "loginResponse": {
        "description": "Successful login response ",
        "properties": {
          "okapiToken": {
            "description": "session token (X-Okapi-Token format)",
            "type": "string"
          },
          "refreshToken": {
            "description": "refresh token",
            "type": "string"
          }
        },
        "required": [
          "okapiToken"
        ],
        "title": "Login Response Schema",
        "type": "object"
      },
      "loginResponseWithExpiry": {
        "description": "Object returned on successful login or on token refresh",
        "properties": {
          "accessTokenExpiration": {
            "description": "The time in UTC after which the access token will be considered expired. Time format is ISO 8601.",
            "type": "string"
          },
          "refreshTokenExpiration": {
            "description": "The time in UTC after which the refresh token will be considered expired. Time format is ISO 8601.",
            "type": "string"
          }
        },
        "required": [
          "accessTokenExpiration",
          "refreshTokenExpiration"
        ],
        "title": "Login Response With Expiry Schema",
        "type": "object"
      },
      "updateCredentials": {
        "description": "An entity that describes the necessary data to update a user password",
        "properties": {
          "username": {
            "description": "username",
            "type": "string"
          },
          "userId": {
            "description": "Unique user id",
            "type": "string"
          },
          "password": {
            "description": "The current password of the user who will be replaced by the new one",
            "type": "string"
          },
          "newPassword": {
            "description": "New user password",
            "type": "string"
          }
        },
        "required": [
          "newPassword",
          "password",
          "username"
        ],
        "title": "Update Credentials Schema",
        "type": "object"
      },
      "password": {
        "description": "Object with password property",
        "properties": {
          "password": {
            "description": "Password",
            "type": "string"
          },
          "userId": {
            "description": "User Id",
            "type": "string"
          }
        },
        "required": [
          "password",
          "userId"
        ],
        "title": "Password Schema",
        "type": "object"
      },
      "passwordCreateAction": {
        "description": "A password create action response",
        "properties": {
          "id": {
            "description": "ID of the password reset action received in the API request",
            "type": "string"
          },
          "userId": {
            "description": "User ID to register password reset action",
            "type": "string"
          },
          "expirationTime": {
            "description": "password expiration time",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "expirationTime",
          "id",
          "userId"
        ],
        "title": "Password Create Action Schema",
        "type": "object"
      },
      "passwordResetAction": {
        "description": "Reset password entity",
        "properties": {
          "passwordResetActionId": {
            "description": "Action id for reset password",
            "type": "string"
          },
          "newPassword": {
            "description": "New password for update",
            "type": "string"
          }
        },
        "required": [
          "newPassword",
          "passwordResetActionId"
        ],
        "title": "Password Reset Action Schema",
        "type": "object"
      },
      "responseCreateAction": {
        "description": "Response entity to create a new password change action",
        "properties": {
          "passwordExists": {
            "description": "Check if the user has an existing password or credential",
            "type": "boolean"
          }
        },
        "title": "Password Create Action Response Schema",
        "type": "object"
      },
      "responseResetAction": {
        "description": "Response entity to reset the password",
        "properties": {
          "isNewPassword": {
            "description": "Indicates the presence of a new password for the user",
            "type": "boolean"
          }
        },
        "title": "Password Reset Action Response Schema",
        "type": "object"
      },
      "logEvent": {
        "additionalProperties": false,
        "description": "A logging event that describes the event code and basic information for logging events",
        "properties": {
          "id": {
            "description": "The system assigned unique ID of the instance record; UUID",
            "type": "string"
          },
          "eventType": {
            "$ref": "#/components/schemas/logEventType"
          },
          "tenant": {
            "description": "The tenant for which the event occurred",
            "type": "string"
          },
          "userId": {
            "description": "User ID for which the event is registered.",
            "type": "string"
          },
          "ip": {
            "description": "Client IP address of registered user Okapi",
            "type": "string"
          },
          "browserInformation": {
            "description": "Client's browser information obtained from User-Agent http header",
            "type": "string"
          },
          "timestamp": {
            "description": "Event registration time",
            "format": "date-time",
            "type": "string"
          },
          "metadata": {
            "$ref": "#/components/schemas/metadata"
          }
        },
        "required": [
          "eventType",
          "tenant",
          "userId"
        ],
        "title": "Log Event Schema",
        "type": "object"
      },
      "logEventCollection": {
        "description": "Event List",
        "properties": {
          "loggingEvent": {
            "description": "Event log with a list of events",
            "items": {
              "$ref": "#/components/schemas/logEvent"
            },
            "type": "array"
          },
          "totalRecords": {
            "description": "Number of entries in the event log",
            "type": "integer"
          }
        },
        "required": [
          "loggingEvent",
          "totalRecords"
        ],
        "title": "Log Event Collection Schema",
        "type": "object"
      },
      "logResponse": {
        "description": "The log event object containing the message received from LoginAPI",
        "properties": {
          "message": {
            "description": "The message containing API response information",
            "type": "string"
          }
        },
        "required": [
          "message"
        ],
        "title": "Log Response Schema",
        "type": "object"
      },
      "credentialsExistence": {
        "description": "Credentials existence response",
        "properties": {
          "credentialsExist": {
            "description": "True if user has local password",
            "type": "boolean"
          }
        },
        "required": [
          "credentialsExist"
        ],
        "title": "Credential Existence Schema",
        "type": "object"
      },
      "token": {
        "additionalProperties": false,
        "description": "The signed JWT token based on the payload",
        "properties": {
          "token": {
            "description": "The JWT token",
            "type": "string"
          }
        },
        "required": [
          "token"
        ],
        "type": "object"
      },
      "tokenResponse": {
        "additionalProperties": false,
        "description": "A signed JWT token when used in the context of a dummy token. Otherwise, a signed JWT access token and a signed JWE refresh token.",
        "properties": {
          "token": {
            "description": "A dummy token",
            "type": "string"
          },
          "refreshToken": {
            "description": "A refresh token",
            "type": "string"
          },
          "accessToken": {
            "description": "An access token",
            "type": "string"
          }
        },
        "type": "object"
      },
      "tokenResponseLegacy": {
        "additionalProperties": false,
        "description": "The signed JWT token based on the payload",
        "properties": {
          "token": {
            "description": "The JWT token",
            "type": "string"
          }
        },
        "required": [
          "token"
        ],
        "type": "object"
      },
      "refreshToken": {
        "additionalProperties": false,
        "description": "The refresh token being presented to get a new refresh token and access token",
        "properties": {
          "refreshToken": {
            "description": "The JWE refresh token",
            "type": "string"
          }
        },
        "required": [
          "refreshToken"
        ],
        "type": "object"
      },
      "signRefreshToken": {
        "additionalProperties": false,
        "description": "The request to sign a new refresh token",
        "properties": {
          "userId": {
            "description": "The user id of the request",
            "format": "uuid",
            "type": "string"
          },
          "sub": {
            "description": "The subject (user id) of the request",
            "type": "string"
          }
        },
        "required": [
          "sub",
          "userId"
        ],
        "type": "object"
      },
      "signTokenPayload": {
        "additionalProperties": false,
        "description": "The POST body for the request to generate a signed token",
        "properties": {
          "payload": {
            "$ref": "#/components/schemas/signTokenPayload_payload"
          }
        },
        "required": [
          "payload"
        ],
        "type": "object"
      },
      "errorResponse": {
        "description": "A set of errors",
        "properties": {
          "errors": {
            "description": "List of errors",
            "items": {
              "$ref": "#/components/schemas/error"
            },
            "type": "array"
          },
          "total_records": {
            "description": "Total number of errors",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "validPassword": {
        "description": "Password success validation result",
        "properties": {
          "result": {
            "description": "Password validation result message",
            "type": "string"
          }
        },
        "required": [
          "result"
        ],
        "title": "Password validation result",
        "type": "object"
      },
      "errors": {
        "description": "A set of errors",
        "properties": {
          "errors": {
            "description": "List of errors",
            "items": {
              "$ref": "#/components/schemas/error"
            },
            "type": "array"
          },
          "total_records": {
            "description": "Total number of errors",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "logEventType": {
        "description": "Log event type",
        "enum": [
          "PASSWORD_RESET",
          "PASSWORD_CREATE",
          "PASSWORD_CHANGE",
          "SUCCESSFUL_LOGIN_ATTEMPT",
          "FAILED_LOGIN_ATTEMPT",
          "USER_BLOCK"
        ],
        "title": "Log Event Type Schema",
        "type": "string"
      },
      "metadata": {
        "description": "Record metadata",
        "properties": {
          "createdDate": {
            "description": "Date and time when the record was created",
            "type": "string"
          },
          "createdByUserId": {
            "description": "ID of the user who created the record (when available)",
            "type": "string"
          },
          "createdByUsername": {
            "description": "Username of the user who created the record (when available)",
            "type": "string"
          },
          "updatedDate": {
            "description": "Date and time when the record was last updated",
            "type": "string"
          },
          "updatedByUserId": {
            "description": "ID of the user who last updated the record (when available)",
            "type": "string"
          },
          "updatedByUsername": {
            "description": "Username of the user who last updated the record (when available)",
            "type": "string"
          }
        },
        "title": "Metadata Schema",
        "type": "object"
      },
      "error": {
        "description": "An error object",
        "properties": {
          "message": {
            "description": "Error message text",
            "type": "string"
          },
          "type": {
            "description": "Error message type",
            "type": "string"
          },
          "code": {
            "$ref": "#/components/schemas/errorCode"
          },
          "parameters": {
            "$ref": "#/components/schemas/parameters"
          }
        },
        "title": "Error Schema",
        "type": "object"
      },
      "errorCode": {
        "description": "Error message code",
        "enum": [
          "unknown_error",
          "service_error",
          "validation_error",
          "not_found_error",
          "found_error",
          "token.parse.failure",
          "token.refresh.unprocessable",
          "token.logout.unprocessable",
          "unauthorized_error"
        ],
        "title": "Error Code Schema",
        "type": "string"
      },
      "parameters": {
        "description": "List of key/value parameters of an error",
        "items": {
          "$ref": "#/components/schemas/parameter"
        },
        "title": "List of Parameters Schema",
        "type": "array"
      },
      "parameter": {
        "description": "List of key/value parameters of an error",
        "properties": {
          "key": {
            "description": "Parameter key",
            "type": "string"
          },
          "value": {
            "description": "Parameter value",
            "type": "string"
          }
        },
        "title": "Key/Value Parameter Schema",
        "type": "object"
      },
      "signTokenPayload_payload": {
        "additionalProperties": true,
        "description": "The payload of the token signing request",
        "properties": {
          "sub": {
            "description": "The subject (the username) for the user",
            "type": "string"
          }
        },
        "required": [
          "sub"
        ],
        "type": "object"
      }
    }
  }
}
