162 lines
5.5 KiB
Markdown
162 lines
5.5 KiB
Markdown
|
|
# Lic Decoder API
|
|||
|
|
|
|||
|
|
## Endpoints
|
|||
|
|
|
|||
|
|
### `GET /api/status`
|
|||
|
|
|
|||
|
|
Проверка готовности системы (JRE и Ring).
|
|||
|
|
|
|||
|
|
- **Аутентификация:** не требуется
|
|||
|
|
- **Rate limit:** не применяется
|
|||
|
|
|
|||
|
|
**Пример ответа:**
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"jre": { "installed": true, "version": "11.0.21", "valid": true },
|
|||
|
|
"ring": { "installed": true, "version": "0.19.5+12", "valid": true },
|
|||
|
|
"ready": true
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `POST /api/decode`
|
|||
|
|
|
|||
|
|
Декодирование файла лицензии 1С (.lic).
|
|||
|
|
|
|||
|
|
- **Content-Type:** `multipart/form-data`
|
|||
|
|
- **Аутентификация:** опционально (Bearer JWT) — см. ниже
|
|||
|
|
- **Rate limit:** 3 запроса в час на IP (без JWT)
|
|||
|
|
|
|||
|
|
**Параметры:**
|
|||
|
|
|
|||
|
|
| Поле | Тип | Обязательный | Описание |
|
|||
|
|
|-----------|--------|--------------|--------------------------------------------------|
|
|||
|
|
| `license` | file | да | .lic файл (макс. 5 МБ) |
|
|||
|
|
| `detailed`| string | нет | `"true"` — добавить сравнение аппаратной конфигурации |
|
|||
|
|
|
|||
|
|
**Заголовки:**
|
|||
|
|
|
|||
|
|
| Заголовок | Обязательный | Описание |
|
|||
|
|
|-----------------|--------------|---------------------------------------------|
|
|||
|
|
| `Authorization` | нет | `Bearer <JWT>` — обходит rate limit |
|
|||
|
|
|
|||
|
|
**Пример ответа:**
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"licName": "XXXXXXXXXXXXXXX",
|
|||
|
|
"pinCode": "XXXX-XXX-XXX-XXX-X",
|
|||
|
|
"licData": "Данные лицензии...",
|
|||
|
|
"validateData": "Результат валидации...",
|
|||
|
|
"licHWConfig": null,
|
|||
|
|
"currentHWConfig": null
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
При `detailed=true` поля `licHWConfig` и `currentHWConfig` содержат текст аппаратных конфигураций.
|
|||
|
|
|
|||
|
|
**Коды ошибок:**
|
|||
|
|
|
|||
|
|
| Код | Описание |
|
|||
|
|
|-----|-----------------------------------------------|
|
|||
|
|
| 400 | Файл не загружен или неверный тип (.lic only) |
|
|||
|
|
| 413 | Файл слишком большой (макс 5 МБ) |
|
|||
|
|
| 422 | Не удалось декодировать файл лицензии |
|
|||
|
|
| 429 | Превышен rate limit |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### `GET /api/docs`
|
|||
|
|
|
|||
|
|
Возвращает данную документацию в формате JSON.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Rate Limits
|
|||
|
|
|
|||
|
|
| Параметр | Значение |
|
|||
|
|
|--------------------|-------------------------------------|
|
|||
|
|
| Окно | 1 час |
|
|||
|
|
| Максимум запросов | 3 |
|
|||
|
|
| Ключ | IP-адрес (из X-Forwarded-For) |
|
|||
|
|
| Обход | Валидный JWT токен в Authorization |
|
|||
|
|
|
|||
|
|
Сервер читает IP из заголовков реверс-прокси (`X-Forwarded-For`). Убедитесь что `trust proxy` включён (по умолчанию `true`).
|
|||
|
|
|
|||
|
|
**Заголовки ответа:**
|
|||
|
|
|
|||
|
|
| Заголовок | Описание |
|
|||
|
|
|------------------------|------------------------------------|
|
|||
|
|
| `X-RateLimit-Limit` | Максимум запросов в окне |
|
|||
|
|
| `X-RateLimit-Remaining`| Оставшиеся запросы в текущем окне |
|
|||
|
|
| `X-RateLimit-Reset` | Секунды до сброса окна |
|
|||
|
|
|
|||
|
|
**Пример ответа 429:**
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"error": "Rate limit exceeded",
|
|||
|
|
"message": "Maximum 3 decode requests per hour. Retry after 2453s.",
|
|||
|
|
"retryAfter": 2453
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Аутентификация (JWT)
|
|||
|
|
|
|||
|
|
Аутентификация **опциональна**. Предоставление валидного JWT токена в заголовке `Authorization` снимает rate limit.
|
|||
|
|
|
|||
|
|
### Использование
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Authorization: Bearer <ваш_JWT_токен>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Генерация токена
|
|||
|
|
|
|||
|
|
Токен подписывается алгоритмом HS256 с секретом из переменной окружения `JWT_SECRET`:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Генерация токена (серверный JWT_SECRET должен совпадать)
|
|||
|
|
JWT_SECRET="your-secret-key" node -e "
|
|||
|
|
const jwt = require('jsonwebtoken');
|
|||
|
|
console.log(jwt.sign({}, process.env.JWT_SECRET, { expiresIn: '30d' }));
|
|||
|
|
"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Переменные окружения
|
|||
|
|
|
|||
|
|
| Переменная | Описание |
|
|||
|
|
|----------------|---------------------------------------------|
|
|||
|
|
| `JWT_SECRET` | Секрет для проверки JWT |
|
|||
|
|
| `PORT` | Порт сервера (по умолчанию 3000) |
|
|||
|
|
| `UPLOAD_DIR` | Директория для загрузок |
|
|||
|
|
| `TMP_BASE` | Базовая директория для временных файлов |
|
|||
|
|
| `RING_CMD` | Путь к команде ring |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Примеры запросов
|
|||
|
|
|
|||
|
|
### Без JWT (с rate limit)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl -F "license=@license.lic" http://localhost:3000/api/decode
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### С JWT (без rate limit)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
|
|||
|
|
-F "license=@license.lic" \
|
|||
|
|
http://localhost:3000/api/decode
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Подробный режим
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl -F "license=@license.lic" -F "detailed=true" http://localhost:3000/api/decode
|
|||
|
|
```
|