267 lines
8.7 KiB
Markdown
267 lines
8.7 KiB
Markdown
# API Changes Required for Backend
|
|
|
|
## Overview
|
|
|
|
Frontend has been updated with two new features:
|
|
1. **Region/Location system** — catalog filtering by region
|
|
2. **Auth/Login system** — Telegram-based authentication required before payment
|
|
|
|
Base URLs:
|
|
- Dexar: `https://api.dexarmarket.ru:445`
|
|
- Novo: `https://api.novo.market:444`
|
|
|
|
---
|
|
|
|
## 1. Region / Location Endpoints
|
|
|
|
### 1.1 `GET /regions` — List available regions
|
|
|
|
Returns the list of regions where the marketplace operates.
|
|
|
|
**Response** `200 OK`
|
|
```json
|
|
[
|
|
{
|
|
"id": "moscow",
|
|
"city": "Москва",
|
|
"country": "Россия",
|
|
"countryCode": "RU",
|
|
"timezone": "Europe/Moscow"
|
|
},
|
|
{
|
|
"id": "spb",
|
|
"city": "Санкт-Петербург",
|
|
"country": "Россия",
|
|
"countryCode": "RU",
|
|
"timezone": "Europe/Moscow"
|
|
},
|
|
{
|
|
"id": "yerevan",
|
|
"city": "Ереван",
|
|
"country": "Армения",
|
|
"countryCode": "AM",
|
|
"timezone": "Asia/Yerevan"
|
|
}
|
|
]
|
|
```
|
|
|
|
**Region object:**
|
|
| Field | Type | Required | Description |
|
|
|---------------|--------|----------|------------------------------|
|
|
| `id` | string | yes | Unique region identifier |
|
|
| `city` | string | yes | City name (display) |
|
|
| `country` | string | yes | Country name (display) |
|
|
| `countryCode` | string | yes | ISO 3166-1 alpha-2 code |
|
|
| `timezone` | string | no | IANA timezone string |
|
|
|
|
> If this endpoint is unavailable, the frontend falls back to 6 hardcoded regions (Moscow, SPB, Yerevan, Minsk, Almaty, Tbilisi).
|
|
|
|
---
|
|
|
|
### 1.2 Region Query Parameter on Existing Endpoints
|
|
|
|
The following **existing** endpoints now accept an optional `?region=` query parameter:
|
|
|
|
| Endpoint | Example |
|
|
|---------------------------------|----------------------------------------------|
|
|
| `GET /category` | `GET /category?region=moscow` |
|
|
| `GET /category/:id` | `GET /category/5?count=50&skip=0®ion=spb` |
|
|
| `GET /item/:id` | `GET /item/123?region=yerevan` |
|
|
| `GET /searchitems` | `GET /searchitems?search=phone®ion=moscow` |
|
|
| `GET /randomitems` | `GET /randomitems?count=5®ion=almaty` |
|
|
|
|
**Behavior:**
|
|
- If `region` param is **present** → return only items/categories available in that region
|
|
- If `region` param is **absent** → return all items globally (current behavior, no change)
|
|
- The `region` value matches the `id` field from the `/regions` response
|
|
|
|
---
|
|
|
|
## 2. Auth / Login Endpoints
|
|
|
|
Authentication is **Telegram-based** with **cookie sessions** (HttpOnly, Secure, SameSite=None).
|
|
|
|
All auth endpoints must support CORS with `credentials: true`.
|
|
|
|
### 2.1 `GET /auth/session` — Check current session
|
|
|
|
Called on every page load to check if the user has an active session.
|
|
|
|
**Request:**
|
|
- Cookies: session cookie (set by backend)
|
|
- CORS: `withCredentials: true`
|
|
|
|
**Response `200 OK`** (authenticated):
|
|
```json
|
|
{
|
|
"sessionId": "sess_abc123",
|
|
"telegramUserId": 123456789,
|
|
"username": "john_doe",
|
|
"displayName": "John Doe",
|
|
"active": true,
|
|
"expiresAt": "2026-03-01T12:00:00Z"
|
|
}
|
|
```
|
|
|
|
**Response `200 OK`** (expired session):
|
|
```json
|
|
{
|
|
"sessionId": "sess_abc123",
|
|
"telegramUserId": 123456789,
|
|
"username": "john_doe",
|
|
"displayName": "John Doe",
|
|
"active": false,
|
|
"expiresAt": "2026-02-27T12:00:00Z"
|
|
}
|
|
```
|
|
|
|
**Response `401 Unauthorized`** (no session / invalid cookie):
|
|
```json
|
|
{
|
|
"error": "No active session"
|
|
}
|
|
```
|
|
|
|
**AuthSession object:**
|
|
| Field | Type | Required | Description |
|
|
|------------------|---------|----------|------------------------------------------|
|
|
| `sessionId` | string | yes | Unique session ID |
|
|
| `telegramUserId` | number | yes | Telegram user ID |
|
|
| `username` | string? | no | Telegram @username (can be null) |
|
|
| `displayName` | string | yes | User display name (first_name + last_name) |
|
|
| `active` | boolean | yes | Whether session is currently valid |
|
|
| `expiresAt` | string | yes | ISO 8601 expiration datetime |
|
|
|
|
---
|
|
|
|
### 2.2 `GET /auth/telegram/callback` — Telegram bot auth callback
|
|
|
|
This is the URL the Telegram bot redirects to after the user starts the bot.
|
|
|
|
**Flow:**
|
|
1. Frontend generates link: `https://t.me/{botUsername}?start=auth_{encodedCallbackUrl}`
|
|
2. User clicks → opens Telegram → starts the bot
|
|
3. Bot sends user data to this callback endpoint
|
|
4. Backend creates session, sets `Set-Cookie` header
|
|
5. Frontend polls `GET /auth/session` every 3 seconds to detect when session becomes active
|
|
|
|
**Request** (from Telegram bot / webhook):
|
|
```json
|
|
{
|
|
"id": 123456789,
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"username": "john_doe",
|
|
"photo_url": "https://t.me/i/userpic/...",
|
|
"auth_date": 1709100000,
|
|
"hash": "abc123def456..."
|
|
}
|
|
```
|
|
|
|
**Response:** Should set a session cookie and return:
|
|
```json
|
|
{
|
|
"sessionId": "sess_abc123",
|
|
"message": "Authenticated successfully"
|
|
}
|
|
```
|
|
|
|
**Cookie requirements:**
|
|
| Attribute | Value | Notes |
|
|
|------------|----------------|------------------------------------------|
|
|
| `HttpOnly` | `true` | Not accessible via JS |
|
|
| `Secure` | `true` | HTTPS only |
|
|
| `SameSite` | `None` | Required for cross-origin (API ≠ frontend) |
|
|
| `Path` | `/` | |
|
|
| `Max-Age` | `86400` (24h) | Or as needed |
|
|
| `Domain` | API domain | |
|
|
|
|
> **Important:** Since the API domain differs from the frontend domain, `SameSite=None` + `Secure=true` is required for the cookie to be sent cross-origin.
|
|
|
|
---
|
|
|
|
### 2.3 `POST /auth/logout` — End session
|
|
|
|
**Request:**
|
|
- Cookies: session cookie
|
|
- CORS: `withCredentials: true`
|
|
- Body: `{}` (empty)
|
|
|
|
**Response `200 OK`:**
|
|
```json
|
|
{
|
|
"message": "Logged out"
|
|
}
|
|
```
|
|
|
|
Should clear/invalidate the session cookie.
|
|
|
|
---
|
|
|
|
## 3. CORS Configuration
|
|
|
|
For auth cookies to work cross-origin, the backend CORS config must include:
|
|
|
|
```
|
|
Access-Control-Allow-Origin: https://dexarmarket.ru (NOT *)
|
|
Access-Control-Allow-Credentials: true
|
|
Access-Control-Allow-Headers: Content-Type, Authorization
|
|
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS
|
|
```
|
|
|
|
> `Access-Control-Allow-Origin` **cannot** be `*` when `Allow-Credentials: true`. Must be the exact frontend origin.
|
|
|
|
For Novo, also allow `https://novo.market`.
|
|
|
|
---
|
|
|
|
## 4. Session Refresh Behavior
|
|
|
|
The frontend automatically re-checks the session **60 seconds before `expiresAt`**. If the backend supports session extension (sliding expiration), it can re-set the cookie with a fresh `Max-Age` on every `GET /auth/session` call.
|
|
|
|
---
|
|
|
|
## 5. Auth Gate — Checkout Flow
|
|
|
|
The checkout button (`POST /cart` payment) now requires authentication:
|
|
- If the user is **not logged in** → frontend shows a Telegram login dialog instead of proceeding
|
|
- If the user **is logged in** → checkout proceeds normally
|
|
- The session cookie is sent automatically with the payment request
|
|
|
|
No backend changes needed for the payment endpoint itself — just ensure it reads the session cookie if needed for order association.
|
|
|
|
---
|
|
|
|
## Summary of New Endpoints
|
|
|
|
| Method | Path | Purpose | Auth Required |
|
|
|--------|----------------------------|-----------------------------|---------------|
|
|
| `GET` | `/regions` | List available regions | No |
|
|
| `GET` | `/auth/session` | Check current session | Cookie |
|
|
| `GET` | `/auth/telegram/callback` | Telegram bot auth callback | No (from bot) |
|
|
| `POST` | `/auth/logout` | End session | Cookie |
|
|
|
|
## Summary of Modified Endpoints
|
|
|
|
| Method | Path | Change |
|
|
|--------|-------------------|---------------------------------------|
|
|
| `GET` | `/category` | Added optional `?region=` param |
|
|
| `GET` | `/category/:id` | Added optional `?region=` param |
|
|
| `GET` | `/item/:id` | Added optional `?region=` param |
|
|
| `GET` | `/searchitems` | Added optional `?region=` param |
|
|
| `GET` | `/randomitems` | Added optional `?region=` param |
|
|
|
|
---
|
|
|
|
## Telegram Bot Setup
|
|
|
|
Each brand needs its own bot:
|
|
- **Dexar:** `@dexarmarket_bot`
|
|
- **Novo:** `@novomarket_bot`
|
|
|
|
The bot should:
|
|
1. Listen for `/start auth_{callbackUrl}` command
|
|
2. Extract the callback URL
|
|
3. Send the user's Telegram data (id, first_name, username, etc.) to that callback URL
|
|
4. The callback URL is `{apiUrl}/auth/telegram/callback`
|