SHA256
Добавить временную бесплатную загрузку аватаров в Arweave
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
| `AddUser` | `01_User_Registration_API.md` | отключено (`410 / ADD_USER_DISABLED`) |
|
||||
| `GetUser` | `01_User_Registration_API.md` | чтение/проверка пользователя + server-состояние его блокчейна |
|
||||
| `SearchUsers` | `01_User_Registration_API.md` | поиск логинов по префиксу |
|
||||
| `TestGetFreeAvatarQuota` | `14_Test_Free_Avatar_Upload_API.md` | временный тестовый просмотр остатка бесплатных загрузок аватара |
|
||||
| `TestUploadFreeAvatar` | `14_Test_Free_Avatar_Upload_API.md` | временная тестовая бесплатная загрузка маленького аватара в Arweave |
|
||||
| `AuthChallenge` | `02_Authentication_API.md` | challenge для создания новой сессии |
|
||||
| `CreateAuthSession` | `02_Authentication_API.md` | создание новой авторизованной сессии |
|
||||
| `SessionChallenge` | `02_Authentication_API.md` | challenge для входа в существующую сессию |
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
# Временное Test API для бесплатной загрузки аватаров в Arweave
|
||||
|
||||
> Статус: **временное тестовое решение**.
|
||||
> Все операции из этого файла начинаются с `Test...`, чтобы это было видно сразу и в коде, и в UI.
|
||||
|
||||
## Назначение
|
||||
|
||||
Этот временный API даёт пользователю ограниченную бесплатную загрузку маленьких аватаров в Arweave:
|
||||
|
||||
- загрузка идёт через **серверный Arweave-кошелёк**;
|
||||
- лимит на пользователя: по умолчанию `3` загрузки за всё время;
|
||||
- лимит хранится в SQLite-таблице `test_free_avatar_uploads`;
|
||||
- если лимит исчерпан, сервер возвращает понятную ошибку;
|
||||
- загружать можно только маленький итоговый файл аватара, по умолчанию до `128 KB`.
|
||||
|
||||
## Настройки сервера
|
||||
|
||||
В `application.properties`:
|
||||
|
||||
```properties
|
||||
test.freeAvatar.enabled=true
|
||||
test.freeAvatar.gateway=https://arweave.net
|
||||
test.freeAvatar.limitPerUser=3
|
||||
test.freeAvatar.maxBytes=131072
|
||||
test.freeAvatar.walletAddress=
|
||||
test.freeAvatar.walletJwkPath=
|
||||
```
|
||||
|
||||
Пояснения:
|
||||
|
||||
- `test.freeAvatar.enabled` - включить или выключить временный API;
|
||||
- `test.freeAvatar.gateway` - Arweave gateway для `price/tx/wallet`;
|
||||
- `test.freeAvatar.limitPerUser` - пожизненный бесплатный лимит на пользователя;
|
||||
- `test.freeAvatar.maxBytes` - максимальный размер итогового файла;
|
||||
- `test.freeAvatar.walletAddress` - публичный адрес серверного Arweave-кошелька;
|
||||
- `test.freeAvatar.walletJwkPath` - путь к приватному JWK-файлу серверного кошелька.
|
||||
|
||||
Важно:
|
||||
|
||||
- приватный JWK хранится вне кода;
|
||||
- если `walletAddress` указан и не совпадает с адресом, вычисленным из JWK, сервер вернёт ошибку настройки.
|
||||
|
||||
## `TestGetFreeAvatarQuota`
|
||||
|
||||
Возвращает остаток бесплатных загрузок для текущего авторизованного пользователя.
|
||||
|
||||
### Запрос
|
||||
|
||||
```json
|
||||
{
|
||||
"op": "TestGetFreeAvatarQuota",
|
||||
"requestId": "req-test-avatar-quota-1",
|
||||
"payload": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Успешный ответ
|
||||
|
||||
```json
|
||||
{
|
||||
"op": "TestGetFreeAvatarQuota",
|
||||
"requestId": "req-test-avatar-quota-1",
|
||||
"status": 200,
|
||||
"ok": true,
|
||||
"payload": {
|
||||
"enabled": true,
|
||||
"limit": 3,
|
||||
"usedCount": 1,
|
||||
"remainingCount": 2,
|
||||
"maxBytes": 131072
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Поля ответа
|
||||
|
||||
- `enabled` - временный API сейчас включён на сервере или нет;
|
||||
- `limit` - полный лимит бесплатных загрузок;
|
||||
- `usedCount` - сколько уже израсходовано;
|
||||
- `remainingCount` - сколько ещё осталось;
|
||||
- `maxBytes` - максимальный размер итогового файла.
|
||||
|
||||
### Ошибки
|
||||
|
||||
- `422 NOT_AUTHENTICATED` - требуется авторизация.
|
||||
|
||||
## `TestUploadFreeAvatar`
|
||||
|
||||
Временная бесплатная загрузка маленькой аватарки в Arweave через серверный кошелёк.
|
||||
|
||||
### Правила
|
||||
|
||||
- операция требует авторизованную сессию;
|
||||
- сервер использует текущий login из сессии;
|
||||
- сервер принимает только:
|
||||
- `image/jpeg`
|
||||
- `image/png`
|
||||
- `image/webp`
|
||||
- размер итогового файла должен быть не больше `maxBytes` из квоты;
|
||||
- если пользователь уже сделал `limit` бесплатных загрузок, операция запрещена.
|
||||
|
||||
### Запрос
|
||||
|
||||
`fileBytesBase64` - это обычный Base64 байт итогового подготовленного файла.
|
||||
|
||||
```json
|
||||
{
|
||||
"op": "TestUploadFreeAvatar",
|
||||
"requestId": "req-test-avatar-upload-1",
|
||||
"payload": {
|
||||
"contentType": "image/webp",
|
||||
"fileBytesBase64": "UklGRiQAAABXRUJQVlA4WAoAAAAQAAAA...",
|
||||
"sha256Hex": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Успешный ответ
|
||||
|
||||
```json
|
||||
{
|
||||
"op": "TestUploadFreeAvatar",
|
||||
"requestId": "req-test-avatar-upload-1",
|
||||
"status": 200,
|
||||
"ok": true,
|
||||
"payload": {
|
||||
"txId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
"sha256Hex": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
||||
"usedCount": 2,
|
||||
"remainingCount": 1,
|
||||
"limit": 3,
|
||||
"gateway": "https://arweave.net"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Поля ответа
|
||||
|
||||
- `txId` - Arweave Transaction ID загруженного файла;
|
||||
- `sha256Hex` - SHA-256 загруженного файла;
|
||||
- `usedCount` - сколько бесплатных загрузок уже израсходовано после этой операции;
|
||||
- `remainingCount` - сколько бесплатных загрузок осталось;
|
||||
- `limit` - общий лимит;
|
||||
- `gateway` - gateway, через который сервер отправлял транзакцию.
|
||||
|
||||
### Ошибки
|
||||
|
||||
- `422 NOT_AUTHENTICATED` - требуется авторизация;
|
||||
- `400 BAD_FIELDS` - не переданы `contentType` или `fileBytesBase64`;
|
||||
- `400 BAD_BASE64` - `fileBytesBase64` не декодируется;
|
||||
- `400 BAD_AVATAR_FILE` - файл не проходит ограничения сервера;
|
||||
- `400 FREE_AVATAR_LIMIT_EXHAUSTED` - бесплатный лимит аватарок исчерпан;
|
||||
- `501 FREE_AVATAR_TEMP_DISABLED` - временная функция выключена или сервер не настроен;
|
||||
- `500 INTERNAL_ERROR` - внутренняя ошибка сервера.
|
||||
|
||||
## Как это используется в UI
|
||||
|
||||
На экране редактирования профиля в мастере смены аватара есть временный сценарий:
|
||||
|
||||
- `Залить аватар бесплатно`
|
||||
|
||||
UI:
|
||||
|
||||
1. вызывает `TestGetFreeAvatarQuota`;
|
||||
2. показывает остаток лимита;
|
||||
3. локально подготавливает уменьшенный файл аватара;
|
||||
4. проверяет, что итоговый файл не превышает `maxBytes`;
|
||||
5. вызывает `TestUploadFreeAvatar`;
|
||||
6. после получения `txId` обычным путём записывает `avatar.ar` в профиль через `AddBlock`.
|
||||
|
||||
## Почему решение временное
|
||||
|
||||
- используется общий серверный Arweave-кошелёк;
|
||||
- лимит хранится отдельной технической таблицей;
|
||||
- операции имеют префикс `Test...`;
|
||||
- сценарий нужен как переходный бесплатный путь для маленьких аватаров.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Временная бесплатная загрузка аватара в Arweave
|
||||
|
||||
- краткое описание фичи:
|
||||
Добавлены два временных `Test...` API для бесплатной загрузки маленьких аватаров в Arweave через серверный кошелёк с лимитом `3` загрузки на пользователя. В UI мастера смены аватара добавлен пункт `Залить аватар бесплатно`.
|
||||
|
||||
- что именно проверять:
|
||||
1. Пользователь с активной сессией открывает редактирование профиля.
|
||||
2. По нажатию на аватар открывается мастер `Сменить аватар`.
|
||||
3. В мастере есть пункт `Залить аватар бесплатно`.
|
||||
4. До первой загрузки UI показывает остаток `3 из 3`.
|
||||
5. Маленький JPEG/PNG/WebP после уменьшения до файла <= `128 KB` успешно уходит через `TestUploadFreeAvatar`.
|
||||
6. После загрузки приходит `txId`, и аватар сохраняется в профиль как `avatar.ar`.
|
||||
7. Остаток уменьшается: `2`, `1`, `0`.
|
||||
8. На четвёртой попытке сервер отвечает понятной ошибкой про исчерпанный бесплатный лимит.
|
||||
9. Если итоговый уменьшенный файл всё ещё > `128 KB`, UI не отправляет его и показывает понятную ошибку.
|
||||
10. Если серверный Arweave JWK/path не настроен, UI получает понятную ошибку временной функции.
|
||||
|
||||
- ожидаемый результат:
|
||||
- первые 3 маленькие аватарки загружаются через серверный Arweave-кошелёк;
|
||||
- после каждой успешной загрузки `ava` в профиле указывает на новый `txId`;
|
||||
- после исчерпания лимита дальнейшая бесплатная загрузка блокируется без записи в профиль;
|
||||
- обычная загрузка через свой Arweave-кошелёк продолжает работать отдельно.
|
||||
|
||||
- статус:
|
||||
pending
|
||||
Reference in New Issue
Block a user