# 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`