# Family Safety Tracker API REST API для обмена геолокацией между членами семьи. ## Аутентификация Сервис использует JWT токены для авторизации. ### JWT Токен При успешном `POST /login` возвращается JWT токен: ```json { "user": {...}, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` **Структура токена:** - `issuer: "family_safety_tracker"` - `payload: {"user_id": N, "login": "user"}` ### Авторизация Защищённые эндпоинты (`/watch`, `/geo`, `/share`) требуют JWT в заголовке: ```http Authorization: Bearer ``` --- ## Таблица эндпоинтов | Метод | URL | Описание | Защита | |-------|-----|----------|--------| | `POST` | `/login` | Вход в систему | — | | `POST` | `/reg` | Регистрация нового пользователя | — | | `GET` | `/watch?unique_id=...` | Получить последнюю позицию по share-ссылке | ✅ | | `PUT` | `/geo?id=N` | Обновить геопозицию | ✅ | | `POST` | `/share` | Создать share-ссылку | ✅ | --- ## Эндпоинты ### `POST /login` — Вход #### Запрос ```bash curl -X POST http://localhost:9090/reg \ -H "Content-Type: application/json" \ -d '{"login": "ivan", "password": "secret123"}' ``` #### PowerShell ```powershell $body = @{ login = "ivan"; password = "secret123" } | ConvertTo-Json Invoke-RestMethod -Uri http://localhost:9090/reg -Method Post -Body $body -ContentType "application/json" ``` #### Успешный ответ (200) ```json "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` #### Ошибки | Код | Сообщение | |-----|-----------| | `401` | `Invalid credentials` — неверный логин или пароль | --- ### `POST /reg` — Регистрация #### Запрос ```http Content-Type: application/json {"login": "maria", "password": "newpass"} ``` #### Успешный ответ (201) Ничего не возвращается. --- ### `GET /watch?unique_id=...` — Получить позицию #### Запрос ```http Authorization: Bearer GET /watch?unique_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890 ``` #### Успешный ответ (200) ```json { "id": 42, "x": 55.7558, "y": 37.6173, "created_at": "2024-01-01T12:00:00Z", "expires_at": "2024-01-01T12:05:00Z" } ``` #### Ошибки | Код | Сообщение | |-----|-----------| | `404` | `Share link not found` — неверный `unique_id` | | `404` | `No position available` — share-ссылка создана, но позиция не была добавлена | --- ### `PUT /geo?id=N` — Обновить позицию #### Запрос ```http Authorization: Bearer Content-Type: application/json PUT /geo?id=1 { "x": 55.7558, "y": 37.6173 } ``` #### Успешный ответ (200) Ничего не возвращается. --- ### `POST /share` — Создать share-ссылку #### Запрос ```http Authorization: Bearer Content-Type: application/json { "x": 55.7558, "y": 37.6173 } ``` #### Успешный ответ (201) ```json { "geo_id": 5, "share_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" } ``` --- ## Примеры запросов ### Регистрация ```bash curl -X POST http://localhost:8080/reg \ -H "Content-Type: application/json" \ -d '{"login": "ivan", "password": "secret123"}' ``` ### Вход ```bash curl -X POST http://localhost:9090/login \ -H "Content-Type: application/json" \ -d '{"login": "ivan", "password": "secret123"}' ``` #### PowerShell ```powershell $body = @{ login = "ivan"; password = "secret123" } | ConvertTo-Json Invoke-RestMethod -Uri http://localhost:9090/login -Method Post -Body $body -ContentType "application/json" ``` ### Создание share-ссылки ```bash TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." curl -X POST http://localhost:9090/share \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"x": 55.7558, "y": 37.6173}' ``` #### PowerShell ```powershell $token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." $body = @{ x = 55.7558; y = 37.6173 } | ConvertTo-Json Invoke-RestMethod -Uri http://localhost:9090/share -Method Post -Headers @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" } -Body $body ``` ### Получение позиции ```bash TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." SHARE_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" curl "http://localhost:9090/watch?unique_id=$SHARE_ID" \ -H "Authorization: Bearer $TOKEN" ``` #### PowerShell ```powershell $token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." $shareId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890" Invoke-RestMethod -Uri "http://localhost:9090/watch?unique_id=$shareId" -Method Get -Headers @{ Authorization = "Bearer $token" } ``` ### Обновление позиции ```bash TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." curl -X PUT "http://localhost:9090/geo?id=1" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"x": 55.7558, "y": 37.6173}' ``` #### PowerShell ```powershell $token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." $body = @{ x = 55.7558; y = 37.6173 } | ConvertTo-Json Invoke-RestMethod -Uri "http://localhost:9090/geo?id=1" -Method Put -Headers @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" } -Body $body ``` --- ## Технические детали ### Сервер - Порт: `9090` (изменяется через `PORT`) ### Технологии - **Dart** (SDK `^3.10.1`) - **Shelf** + **Shelf Router** — HTTP фреймворк - **PostgreSQL** — база данных - **bcrypt** — хэширование паролей - **dart_jsonwebtoken** — JWT-токены - **dotenv** — переменные окружения ### Переменные окружения | Переменная | Описание | |------------|----------| | `PORT` | Порт сервера (по умолчанию 8080) | | `POSTGRES_HOST` | Хост PostgreSQL | | `POSTGRES_DB` | База данных | | `POSTGRES_USER` | Пользователь | | `POSTGRES_PASSWORD` | Пароль | | `JWT_SECRET` | Секрет для JWT-токенов | ### Автоматическая миграция При запуске сервера таблицы создаются автоматически: - `users` — пользователи - `geopositions` — геопозиции - `logs` — логи --- ## Структура проекта ``` bin/ ├── server.dart # Точка входа ├── routes/ │ ├── auth_routes.dart # Маршруты авторизации │ └── geo_routes.dart # Маршруты геолокации ├── repositories/ │ ├── user_repo.dart │ └── geoposition_repo.dart ├── models/ │ ├── user.dart │ ├── geoposition.dart │ └── log.dart └── database/ └── database_provider.dart ``` --- ## Запуск ```bash dart pub get dart run bin/server.dart ``` ## Лицензия MIT