Merge branch 'feature/H-3657' into 'master'
H-3657: добавил Personal Access Tokens в v2 swagger See merge request hrbox-public/api!34
This commit was merged in pull request #34.
This commit is contained in:
+457
-3
@@ -27,6 +27,86 @@ info:
|
|||||||
{sessionId} - you will get this form /mobile/auth method
|
{sessionId} - you will get this form /mobile/auth method
|
||||||
{sessionSecret} - you will get this form /mobile/auth method
|
{sessionSecret} - you will get this form /mobile/auth method
|
||||||
the last one (x-hrbox-embed) is for opening web pages in WebView to remove website footer and header
|
the last one (x-hrbox-embed) is for opening web pages in WebView to remove website footer and header
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Авторизация по личному API-токену (Personal Access Token, PAT)
|
||||||
|
|
||||||
|
Для серверных интеграций (web-zaim и т.п.) удобнее не держать сессию,
|
||||||
|
а использовать постоянный токен. Токен работает **только на `/api/v2/*`**
|
||||||
|
(для `/api/v1/*`, `/api/v3/*`, `/admin/*` и веб-страниц — игнорируется).
|
||||||
|
|
||||||
|
## Получение токена
|
||||||
|
|
||||||
|
1. Юзеру, от имени которого будет работать интеграция, нужно право
|
||||||
|
`api-tokens-manage` (выдаётся точечно администратором).
|
||||||
|
2. Юзер открывает `/profile/settings/api-tokens` в веб-интерфейсе и жмёт
|
||||||
|
«Создать токен» — задаёт название и (опционально) дату истечения.
|
||||||
|
Plain-секрет **показывается один раз** в этом окне, после закрытия
|
||||||
|
восстановить нельзя.
|
||||||
|
3. Альтернативно — `POST /api/v2/user-api-token` под session-авторизацией
|
||||||
|
(см. ниже про management-эндпоинты). Plain также возвращается
|
||||||
|
один раз в поле `data.plain`.
|
||||||
|
|
||||||
|
Формат plain-токена: `hrb_` + 32 url-safe символов = 36 символов всего.
|
||||||
|
В БД хранится только HMAC-SHA-256 хеш и видимый префикс (первые 12
|
||||||
|
символов с `hrb_`).
|
||||||
|
|
||||||
|
## Использование токена
|
||||||
|
|
||||||
|
Подписывайте каждый запрос заголовком `Authorization`:
|
||||||
|
|
||||||
|
```
|
||||||
|
Authorization: Bearer hrb_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
```
|
||||||
|
|
||||||
|
Tenant авторезолвится по `Host`-заголовку запроса, поэтому
|
||||||
|
`x-hrbox-tenant-id` / `x-hrbox-tenant-domain` **необязательны**.
|
||||||
|
Если всё же передаёте — будут строго провалидированы, невалидный
|
||||||
|
идентификатор тенанта → 400. `x-hrbox-session-id` / `x-hrbox-session-code`
|
||||||
|
при Bearer-аутентификации **не нужны**.
|
||||||
|
|
||||||
|
## Права и scopes
|
||||||
|
|
||||||
|
⚠️ **Гранулярных scopes у токена нет.** Токен наследует **все права того
|
||||||
|
юзера**, под которым выпущен. Это означает что для интеграции нужно
|
||||||
|
создать **отдельного системного пользователя** и выдать ему ровно те
|
||||||
|
права, которые требуются (например, `wallets-transactions` для нового
|
||||||
|
`/api/v2/admin/wallet*`). Не используйте свой личный аккаунт.
|
||||||
|
|
||||||
|
## Отзыв и жизненный цикл
|
||||||
|
|
||||||
|
- Юзер отзывает свой токен через `POST /api/v2/user-api-token/revoke`
|
||||||
|
(или из UI).
|
||||||
|
- Администратор с правом `api-tokens-admin` может посмотреть/отозвать
|
||||||
|
любой токен тенанта через `/api/v2/admin/user-api-token*`. Plain
|
||||||
|
админу **никогда не виден**, только префикс.
|
||||||
|
- При блокировке юзера (`reg_status_id = BLOCKED`) все его токены
|
||||||
|
автоматически отзываются. При разблокировке **обратно не восстанавливаются** —
|
||||||
|
нужно выпускать новые.
|
||||||
|
- Если у токена выставлен `expires_at` — после этой даты он перестаёт
|
||||||
|
работать сам (статус `EXPIRED`).
|
||||||
|
|
||||||
|
## Когда валидный токен всё равно даёт 401
|
||||||
|
|
||||||
|
`User::findIdentityByAccessToken` дополнительно вызывает
|
||||||
|
`User::isValidForDisplay()`, поэтому даже корректный live-токен
|
||||||
|
отдаёт `401 Login Required`, если у владельца:
|
||||||
|
|
||||||
|
- `is_hidden = true` (юзер скрыт администратором), либо
|
||||||
|
- `reg_status_id` **не входит** в `RegStatus::validForDisplay()`
|
||||||
|
(например `INVITED`, `BLOCKED` и пр.).
|
||||||
|
|
||||||
|
Для системного юзера-интегратора убедитесь, что он `is_hidden=false`
|
||||||
|
и в активном reg-статусе, иначе токен не пройдёт ни на одном
|
||||||
|
`/api/v2/*` эндпоинте.
|
||||||
|
|
||||||
|
## Управление токенами под Bearer запрещено
|
||||||
|
|
||||||
|
Management-эндпоинты (`/user-api-token*`, `/admin/user-api-token*`)
|
||||||
|
отдают `403`, если запрос аутентифицирован Bearer-токеном — нельзя
|
||||||
|
выпускать или отзывать токены от имени токена. Управляйте только
|
||||||
|
под обычной web-сессией.
|
||||||
contact:
|
contact:
|
||||||
email: yuriy@hrbox.io
|
email: yuriy@hrbox.io
|
||||||
|
|
||||||
@@ -67,6 +147,16 @@ tags:
|
|||||||
description: Админский API транзакций кошелька — проведение начислений/списаний (form/excel) и просмотр.
|
description: Админский API транзакций кошелька — проведение начислений/списаний (form/excel) и просмотр.
|
||||||
- name: file-processing
|
- name: file-processing
|
||||||
description: Статусы асинхронных обработок файлов (excel-импорт/экспорт, архивы). Видны только записи текущего пользователя.
|
description: Статусы асинхронных обработок файлов (excel-импорт/экспорт, архивы). Видны только записи текущего пользователя.
|
||||||
|
- name: user-api-token
|
||||||
|
description: |
|
||||||
|
Личные API-токены (Personal Access Tokens) для серверных интеграций.
|
||||||
|
Юзер управляет только своими токенами. Permission `api-tokens-manage`.
|
||||||
|
Management-эндпоинты доступны **только под обычной session-авторизацией**
|
||||||
|
(Bearer запрещён). См. секцию «Авторизация по личному API-токену» выше.
|
||||||
|
- name: admin-user-api-token
|
||||||
|
description: |
|
||||||
|
Админский обзор и отзыв любых PAT тенанта. Permission `api-tokens-admin`.
|
||||||
|
Plain-секрет недоступен — виден только `token_prefix`.
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/mobile/bind/{id}/{token}:
|
/mobile/bind/{id}/{token}:
|
||||||
@@ -7265,6 +7355,201 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/FileProcessing'
|
$ref: '#/components/schemas/FileProcessing'
|
||||||
|
|
||||||
|
/user-api-token:
|
||||||
|
get:
|
||||||
|
tags: [user-api-token]
|
||||||
|
summary: Список своих API-токенов
|
||||||
|
description: |
|
||||||
|
Возвращает PAT текущего юзера. Plain-секрет уже недоступен —
|
||||||
|
для идентификации используется `token_prefix` (первые 12 символов,
|
||||||
|
начинаются с `hrb_`).
|
||||||
|
operationId: userApiTokenIndex
|
||||||
|
security:
|
||||||
|
- SessionAuth: []
|
||||||
|
parameters:
|
||||||
|
- name: page
|
||||||
|
in: query
|
||||||
|
schema: { type: integer, minimum: 1, default: 1 }
|
||||||
|
- name: per-page
|
||||||
|
in: query
|
||||||
|
schema: { type: integer, minimum: 1, default: 20 }
|
||||||
|
- name: sort
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [created_at, "-created_at", last_used_at, "-last_used_at", expires_at, "-expires_at"]
|
||||||
|
description: По умолчанию `-created_at`.
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Список токенов
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UserApiTokenList'
|
||||||
|
403:
|
||||||
|
description: Запрос пришёл под Bearer-токеном (запрещено) или нет права `api-tokens-manage`.
|
||||||
|
|
||||||
|
/user-api-token/create:
|
||||||
|
post:
|
||||||
|
tags: [user-api-token]
|
||||||
|
summary: Создать новый API-токен (plain возвращается один раз)
|
||||||
|
description: |
|
||||||
|
Создаёт PAT для текущего юзера. **Plain-секрет (`data.plain`)
|
||||||
|
возвращается только в этом ответе и больше нигде не доступен** —
|
||||||
|
сохраните его сразу.
|
||||||
|
|
||||||
|
`expires_at` опционален; если задан, должен быть не в прошлом
|
||||||
|
(валидируется по началу текущего дня). Токен работает весь
|
||||||
|
указанный день включительно (23:59:59).
|
||||||
|
|
||||||
|
Доступно только под session-авторизацией (запрос под Bearer → 403).
|
||||||
|
operationId: userApiTokenCreate
|
||||||
|
security:
|
||||||
|
- SessionAuth: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UserApiTokenCreateForm'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Токен создан (либо ошибки валидации в стандартном формате `httpJsonResponse`).
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/httpJsonResponse'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/components/schemas/UserApiTokenCreated'
|
||||||
|
403:
|
||||||
|
description: Запрос пришёл под Bearer-токеном или нет права `api-tokens-manage`.
|
||||||
|
|
||||||
|
/user-api-token/revoke:
|
||||||
|
post:
|
||||||
|
tags: [user-api-token]
|
||||||
|
summary: Отозвать свой API-токен
|
||||||
|
description: |
|
||||||
|
Идемпотентно: повторный revoke уже отозванного токена просто ничего не делает.
|
||||||
|
Чужой токен отозвать нельзя — будет 403/404.
|
||||||
|
|
||||||
|
Доступно только под session-авторизацией (запрос под Bearer → 403).
|
||||||
|
operationId: userApiTokenRevoke
|
||||||
|
security:
|
||||||
|
- SessionAuth: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [id]
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Успех
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/httpJsonResponse'
|
||||||
|
400:
|
||||||
|
description: Параметр `id` не строка или не uuid.
|
||||||
|
403:
|
||||||
|
description: Токен принадлежит другому юзеру, либо запрос под Bearer, либо нет права `api-tokens-manage`.
|
||||||
|
404:
|
||||||
|
description: Токен не найден.
|
||||||
|
|
||||||
|
/admin/user-api-token:
|
||||||
|
get:
|
||||||
|
tags: [admin-user-api-token]
|
||||||
|
summary: Список API-токенов всех юзеров тенанта
|
||||||
|
description: |
|
||||||
|
Админский обзор PAT. Permission `api-tokens-admin`. Plain-секрет
|
||||||
|
здесь **никогда не возвращается** (только `token_prefix`).
|
||||||
|
|
||||||
|
Доступно только под session-авторизацией (запрос под Bearer → 403).
|
||||||
|
operationId: adminUserApiTokenIndex
|
||||||
|
security:
|
||||||
|
- SessionAuth: []
|
||||||
|
parameters:
|
||||||
|
- name: page
|
||||||
|
in: query
|
||||||
|
schema: { type: integer, minimum: 1, default: 1 }
|
||||||
|
- name: per-page
|
||||||
|
in: query
|
||||||
|
schema: { type: integer, minimum: 1, default: 20 }
|
||||||
|
- name: sort
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [created_at, "-created_at", last_used_at, "-last_used_at", expires_at, "-expires_at"]
|
||||||
|
- name: user_id
|
||||||
|
in: query
|
||||||
|
schema: { type: string, format: uuid }
|
||||||
|
description: Фильтр по владельцу токена.
|
||||||
|
- name: name
|
||||||
|
in: query
|
||||||
|
schema: { type: string, maxLength: 100 }
|
||||||
|
description: Like-поиск по названию токена.
|
||||||
|
- name: token_prefix
|
||||||
|
in: query
|
||||||
|
schema: { type: string, maxLength: 16 }
|
||||||
|
description: 'Like-поиск по префиксу (например `hrb_abc12345`).'
|
||||||
|
- name: status_id
|
||||||
|
in: query
|
||||||
|
schema: { type: string }
|
||||||
|
description: |
|
||||||
|
Comma-separated `UserApiTokenStatus`: `1` — Активен, `2` — Отозван,
|
||||||
|
`3` — Истёк. Без параметра — все статусы.
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Список
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UserApiTokenAdminList'
|
||||||
|
403:
|
||||||
|
description: Запрос под Bearer, либо нет права `api-tokens-admin`.
|
||||||
|
|
||||||
|
/admin/user-api-token/revoke:
|
||||||
|
post:
|
||||||
|
tags: [admin-user-api-token]
|
||||||
|
summary: Отозвать любой токен тенанта
|
||||||
|
description: |
|
||||||
|
Идемпотентно. Доступно только под session-авторизацией (Bearer → 403).
|
||||||
|
operationId: adminUserApiTokenRevoke
|
||||||
|
security:
|
||||||
|
- SessionAuth: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [id]
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Успех
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/httpJsonResponse'
|
||||||
|
400:
|
||||||
|
description: Параметр `id` не строка или не uuid.
|
||||||
|
403:
|
||||||
|
description: Запрос под Bearer, либо нет права `api-tokens-admin`.
|
||||||
|
404:
|
||||||
|
description: Токен не найден.
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
SessionAuth:
|
SessionAuth:
|
||||||
@@ -7277,6 +7562,16 @@ components:
|
|||||||
in: header
|
in: header
|
||||||
name: X-Hrbox-Client-Id
|
name: X-Hrbox-Client-Id
|
||||||
description: "Авторизация с использованием API-ключа. Требуемые заголовки: Content-Type, X-Hrbox-Client-Id, X-Hrbox-Client-Secret."
|
description: "Авторизация с использованием API-ключа. Требуемые заголовки: Content-Type, X-Hrbox-Client-Id, X-Hrbox-Client-Secret."
|
||||||
|
BearerAuth:
|
||||||
|
type: http
|
||||||
|
scheme: bearer
|
||||||
|
bearerFormat: PAT
|
||||||
|
description: |
|
||||||
|
Personal Access Token (постоянный API-токен пользователя). Заголовок:
|
||||||
|
`Authorization: Bearer hrb_<32 url-safe>`. Tenant авторезолвится по
|
||||||
|
`Host`, `x-hrbox-tenant-id` опционален. Работает только на `/api/v2/*`.
|
||||||
|
Токен наследует все права юзера, под которым выпущен (granular scopes
|
||||||
|
не поддерживаются). Подробности — в описании API.
|
||||||
schemas:
|
schemas:
|
||||||
httpJsonResponse:
|
httpJsonResponse:
|
||||||
type: object
|
type: object
|
||||||
@@ -12084,6 +12379,8 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/Wallet'
|
$ref: '#/components/schemas/Wallet'
|
||||||
|
_links:
|
||||||
|
$ref: '#/components/schemas/_links'
|
||||||
_meta:
|
_meta:
|
||||||
$ref: '#/components/schemas/_meta'
|
$ref: '#/components/schemas/_meta'
|
||||||
|
|
||||||
@@ -12116,6 +12413,8 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/WalletTransaction'
|
$ref: '#/components/schemas/WalletTransaction'
|
||||||
|
_links:
|
||||||
|
$ref: '#/components/schemas/_links'
|
||||||
_meta:
|
_meta:
|
||||||
$ref: '#/components/schemas/_meta'
|
$ref: '#/components/schemas/_meta'
|
||||||
|
|
||||||
@@ -12195,10 +12494,13 @@ components:
|
|||||||
1 — NEW, 2 — QUEUED, 3 — STARTED, 4 — FINISHED, 5 — ERROR, 6 — FATAL
|
1 — NEW, 2 — QUEUED, 3 — STARTED, 4 — FINISHED, 5 — ERROR, 6 — FATAL
|
||||||
arguments:
|
arguments:
|
||||||
type: array
|
type: array
|
||||||
result:
|
|
||||||
type: object
|
|
||||||
description: |
|
description: |
|
||||||
Результат. Для wallet-excel содержит:
|
Аргументы воркера. Для wallet-excel: `[WalletExcelProcessor::class, mappings]`.
|
||||||
|
Для excel-экспорта: `[ReportClass::class, params]`.
|
||||||
|
items: {}
|
||||||
|
result:
|
||||||
|
description: |
|
||||||
|
Результат. Для wallet-excel:
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"summary": { "totalRows": 4, "validCount": 1, "invalidCount": 3 },
|
"summary": { "totalRows": 4, "validCount": 1, "invalidCount": 3 },
|
||||||
@@ -12206,9 +12508,32 @@ components:
|
|||||||
"invalidRows": [{ "row": 2, "errors": {...} }, ...]
|
"invalidRows": [{ "row": 2, "errors": {...} }, ...]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
Для незавершённой обработки или экспорта — пустой массив `[]`.
|
||||||
|
oneOf:
|
||||||
|
- type: object
|
||||||
|
- type: array
|
||||||
|
items: {}
|
||||||
created_at: { type: string }
|
created_at: { type: string }
|
||||||
started_at: { type: string, nullable: true }
|
started_at: { type: string, nullable: true }
|
||||||
finished_at: { type: string, nullable: true }
|
finished_at: { type: string, nullable: true }
|
||||||
|
file:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
description: |
|
||||||
|
Метаданные файла-источника. Возвращается всегда (не нужно `?expand=`).
|
||||||
|
Содержит `id, name, ext, fid, url, file_type, mime_type, size,
|
||||||
|
file_status_id, user_id, created_at` и др.
|
||||||
|
created:
|
||||||
|
type: string
|
||||||
|
description: 'Локализованная `created_at` (например `04.05.2026 at 13:56`).'
|
||||||
|
started:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
description: Локализованная `started_at`.
|
||||||
|
finished:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
description: Локализованная `finished_at`.
|
||||||
|
|
||||||
FileProcessingList:
|
FileProcessingList:
|
||||||
type: object
|
type: object
|
||||||
@@ -12217,6 +12542,134 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/FileProcessing'
|
$ref: '#/components/schemas/FileProcessing'
|
||||||
|
_links:
|
||||||
|
$ref: '#/components/schemas/_links'
|
||||||
|
_meta:
|
||||||
|
$ref: '#/components/schemas/_meta'
|
||||||
|
|
||||||
|
UserApiTokenStatus:
|
||||||
|
type: integer
|
||||||
|
description: |
|
||||||
|
Статус личного API-токена (вычисляется по `revoked_at` / `expires_at`):
|
||||||
|
* `1` — Активен
|
||||||
|
* `2` — Отозван
|
||||||
|
* `3` — Истёк
|
||||||
|
enum: [1, 2, 3]
|
||||||
|
example: 1
|
||||||
|
|
||||||
|
UserApiToken:
|
||||||
|
type: object
|
||||||
|
description: |
|
||||||
|
Личный API-токен (PAT). Plain-секрет в этой схеме отсутствует — он
|
||||||
|
возвращается только в ответе на создание (см. `UserApiTokenCreated`).
|
||||||
|
properties:
|
||||||
|
id: { type: string, format: uuid }
|
||||||
|
user_id: { type: string, format: uuid }
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
maxLength: 100
|
||||||
|
description: Человекочитаемое название от юзера (HTML-теги вырезаются на бэке).
|
||||||
|
token_prefix:
|
||||||
|
type: string
|
||||||
|
description: |
|
||||||
|
Первые 12 символов токена с приставкой `hrb_`. Безопасно для отображения
|
||||||
|
и поиска (например `hrb_abc12345`).
|
||||||
|
example: "hrb_abc12345"
|
||||||
|
created_at: { type: string, format: date-time }
|
||||||
|
expires_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
nullable: true
|
||||||
|
description: Если null — без срока. Срок включает указанный день целиком (до 23:59:59).
|
||||||
|
last_used_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
nullable: true
|
||||||
|
description: Обновляется при использовании, не чаще раза в минуту.
|
||||||
|
revoked_at:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
nullable: true
|
||||||
|
description: Заполняется при revoke; если null — токен не отозван.
|
||||||
|
|
||||||
|
UserApiTokenList:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/UserApiToken'
|
||||||
|
_links:
|
||||||
|
$ref: '#/components/schemas/_links'
|
||||||
|
_meta:
|
||||||
|
$ref: '#/components/schemas/_meta'
|
||||||
|
|
||||||
|
UserApiTokenCreated:
|
||||||
|
description: |
|
||||||
|
Расширение `UserApiToken` дополнительным полем `plain` — это
|
||||||
|
единственный момент, когда секрет возвращается клиенту.
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/UserApiToken'
|
||||||
|
- type: object
|
||||||
|
required: [plain]
|
||||||
|
properties:
|
||||||
|
plain:
|
||||||
|
type: string
|
||||||
|
description: |
|
||||||
|
Полный plain-токен. Формат `hrb_<32 url-safe>`. **Сохраните
|
||||||
|
немедленно — повторно его получить невозможно.**
|
||||||
|
example: "hrb_aBcD3fGhIjKlMnOpQrStUvWxYz012345"
|
||||||
|
|
||||||
|
UserApiTokenCreateForm:
|
||||||
|
type: object
|
||||||
|
required: [name]
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
maxLength: 100
|
||||||
|
description: Название токена. Сохраняется после HTML-purify.
|
||||||
|
example: "Интеграция web-zaim — wallet"
|
||||||
|
expires_at:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
nullable: true
|
||||||
|
description: |
|
||||||
|
Дата истечения `yyyy-MM-dd`. Не может быть в прошлом (валидируется
|
||||||
|
по началу текущего дня). На бэке к ней приклеивается время
|
||||||
|
`23:59:59`, токен работает весь указанный день включительно.
|
||||||
|
Если опущено — токен бессрочный.
|
||||||
|
example: "2026-12-31"
|
||||||
|
|
||||||
|
UserApiTokenAdmin:
|
||||||
|
description: |
|
||||||
|
Запись токена в админском списке: к базовым полям добавляются вложенные
|
||||||
|
`user` и `updatedByUser` (последний — кто последним менял запись;
|
||||||
|
для авто-revoke при блокировке — система).
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/UserApiToken'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id: { type: string, format: uuid }
|
||||||
|
name: { type: string }
|
||||||
|
updatedByUser:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
properties:
|
||||||
|
id: { type: string, format: uuid }
|
||||||
|
name: { type: string }
|
||||||
|
|
||||||
|
UserApiTokenAdminList:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/UserApiTokenAdmin'
|
||||||
|
_links:
|
||||||
|
$ref: '#/components/schemas/_links'
|
||||||
_meta:
|
_meta:
|
||||||
$ref: '#/components/schemas/_meta'
|
$ref: '#/components/schemas/_meta'
|
||||||
|
|
||||||
@@ -12406,3 +12859,4 @@ components:
|
|||||||
security:
|
security:
|
||||||
- SessionAuth: [ ]
|
- SessionAuth: [ ]
|
||||||
- ApiKeyAuth: [ ]
|
- ApiKeyAuth: [ ]
|
||||||
|
- BearerAuth: [ ]
|
||||||
Reference in New Issue
Block a user