fix ignore
This commit is contained in:
+265
-538
@@ -1,619 +1,346 @@
|
||||
openapi: 3.0.0
|
||||
openapi: "3.0.3"
|
||||
info:
|
||||
title: Mesh backend REST API
|
||||
title: Family Safety Tracker API
|
||||
description: REST API for sharing geolocation with family members. Authentication via JWT tokens.
|
||||
version: 1.0.0
|
||||
description: Описание API
|
||||
contact:
|
||||
name: Family Safety Tracker
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8888/api
|
||||
- url: http://localhost:9090
|
||||
description: Local development server
|
||||
|
||||
security:
|
||||
- BearerAuth: []
|
||||
|
||||
paths:
|
||||
/info:
|
||||
get:
|
||||
tags:
|
||||
- Common
|
||||
summary: Запрос статуса сервера
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BackendInfo'
|
||||
/blockRule:
|
||||
get:
|
||||
tags:
|
||||
- BlockRule
|
||||
summary: Запрос правил блокировок
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/BlockPriorityRule'
|
||||
delete:
|
||||
tags:
|
||||
- BlockRule
|
||||
summary: Удалить правило
|
||||
requestBody:
|
||||
description: Удалить правило
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BlockPriorityRule'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
'404':
|
||||
description: Не найдено
|
||||
/login:
|
||||
post:
|
||||
summary: Authenticate user
|
||||
description: Login with login and password. Returns a JWT token on success.
|
||||
tags:
|
||||
- BlockRule
|
||||
summary: Добавить правило блокировки
|
||||
- Authentication
|
||||
security: []
|
||||
requestBody:
|
||||
description: Правило блокировки (объект json)
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BlockPriorityRule'
|
||||
required: true
|
||||
$ref: "#/components/schemas/LoginRequest"
|
||||
example:
|
||||
login: "john_doe"
|
||||
password: "secret123"
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
/priorityRule:
|
||||
get:
|
||||
tags:
|
||||
- PriorityRule
|
||||
summary: Запрос правил приоритета (Qos)
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
"200":
|
||||
description: Authentication successful
|
||||
headers:
|
||||
Access-Control-Allow-Origin:
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/BlockPriorityRule'
|
||||
delete:
|
||||
tags:
|
||||
- PriorityRule
|
||||
summary: Удалить правила приоритета
|
||||
requestBody:
|
||||
description: Удалить правило приоритета (Qos)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BlockPriorityRule'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
'404':
|
||||
description: Не найдено
|
||||
$ref: "#/components/schemas/LoginResponse"
|
||||
example:
|
||||
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
"401":
|
||||
description: Invalid credentials
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
example:
|
||||
error: "Invalid credentials"
|
||||
|
||||
/reg:
|
||||
post:
|
||||
summary: Register a new user
|
||||
description: Create a new user account. Password is hashed with bcrypt.
|
||||
tags:
|
||||
- PriorityRule
|
||||
summary: Добавить правило приоритета (Qos)
|
||||
- Authentication
|
||||
security: []
|
||||
requestBody:
|
||||
description: Правило приоритета (Qos) (объект json)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BlockPriorityRule'
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/RegisterRequest"
|
||||
example:
|
||||
login: "john_doe"
|
||||
password: "secret123"
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
/interface:
|
||||
get:
|
||||
tags:
|
||||
- Interface
|
||||
summary: Запрос сетевых интерфейсов
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
"201":
|
||||
description: User registered successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Interface'
|
||||
$ref: "#/components/schemas/RegisterResponse"
|
||||
example:
|
||||
message: "User registered"
|
||||
"400":
|
||||
description: Bad request (e.g. login already exists)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/geo:
|
||||
put:
|
||||
summary: Update geolocation position
|
||||
description: Update the coordinates of an existing geoposition record.
|
||||
tags:
|
||||
- Interface
|
||||
summary: Обновить интерфейс
|
||||
- Geolocation
|
||||
parameters:
|
||||
- name: interface
|
||||
- name: id
|
||||
in: query
|
||||
description: Interface object
|
||||
required: true
|
||||
description: UUID of the geoposition to update
|
||||
schema:
|
||||
$ref: '#/components/schemas/Interface'
|
||||
type: string
|
||||
format: uuid
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
requestBody:
|
||||
description: Обновить интерфейс
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Interface'
|
||||
required: true
|
||||
$ref: "#/components/schemas/PositionRequest"
|
||||
example:
|
||||
x: 55.7558
|
||||
y: 37.6173
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
/config:
|
||||
get:
|
||||
tags:
|
||||
- Config
|
||||
summary: Запрос настроек
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
"200":
|
||||
description: Position updated successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Config'
|
||||
put:
|
||||
tags:
|
||||
- Config
|
||||
summary: Обновить настройки
|
||||
parameters:
|
||||
- name: Config
|
||||
in: query
|
||||
description: Config object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/Config'
|
||||
requestBody:
|
||||
description: Обновить Config
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Config'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
/stats:
|
||||
get:
|
||||
tags:
|
||||
- Common
|
||||
summary: Запрос статистики сервера
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
$ref: "#/components/schemas/MessageResponse"
|
||||
example:
|
||||
message: "Position updated"
|
||||
"401":
|
||||
description: Unauthorized - invalid or missing token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Stat'
|
||||
/commandList:
|
||||
get:
|
||||
tags:
|
||||
- CommandList
|
||||
summary: Запрос списка команд
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"404":
|
||||
description: Geoposition not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Command'
|
||||
put:
|
||||
tags:
|
||||
- CommandList
|
||||
summary: Перезапись списка команд
|
||||
requestBody:
|
||||
description: Перезапись списка команд
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Command'
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
/commandRun/{id}:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/share:
|
||||
post:
|
||||
summary: Create a share link
|
||||
description: Create a new geoposition and generate a unique share link UUID for public viewing.
|
||||
tags:
|
||||
- CommandRun
|
||||
summary: Запустить команду
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: ID of command
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/CommandResult'
|
||||
'400':
|
||||
description: On error
|
||||
'404':
|
||||
description: Не найдено
|
||||
'405':
|
||||
description: Конфиг нельзя запустить
|
||||
delete:
|
||||
tags:
|
||||
- CommandRun
|
||||
summary: Остановить команду
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: ID of command
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/CommandResult'
|
||||
'400':
|
||||
description: On error
|
||||
/command:
|
||||
post:
|
||||
tags:
|
||||
- Command
|
||||
summary: Добавить команду
|
||||
parameters:
|
||||
- name: command
|
||||
in: query
|
||||
description: Command object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#'#/components/schemas/Command'
|
||||
- Sharing
|
||||
requestBody:
|
||||
description: Добавить команду
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Command'
|
||||
required: true
|
||||
$ref: "#/components/schemas/PositionRequest"
|
||||
example:
|
||||
x: 55.7558
|
||||
y: 37.6173
|
||||
responses:
|
||||
'200':
|
||||
description: Успех
|
||||
'400':
|
||||
description: ID занят
|
||||
'409':
|
||||
description: Конфиг или скрипт уже существуют
|
||||
get:
|
||||
tags:
|
||||
- Command
|
||||
summary: Запросить команду с телом
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
description: Command ID
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
delete:
|
||||
tags:
|
||||
- Command
|
||||
summary: Удалить команду
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
description: Command ID
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
'404':
|
||||
description: Не найдено
|
||||
put:
|
||||
tags:
|
||||
- Command
|
||||
summary: Обновить команду
|
||||
parameters:
|
||||
- name: command
|
||||
in: query
|
||||
description: Command object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#'#/components/schemas/Command'
|
||||
requestBody:
|
||||
description: Обновить команду
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Command'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
/commandStatuses:
|
||||
get:
|
||||
tags:
|
||||
- CommandStatus
|
||||
summary: Запрос статусов выполнения команд
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
"201":
|
||||
description: Share link created successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/CommandResult'
|
||||
'400':
|
||||
description: On error
|
||||
/graphInfo:
|
||||
get:
|
||||
tags:
|
||||
- NodeInfo
|
||||
summary: Запрос связей между точками
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
$ref: "#/components/schemas/ShareResponse"
|
||||
example:
|
||||
geo_id: "550e8400-e29b-41d4-a716-446655440000"
|
||||
share_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||||
"401":
|
||||
description: Unauthorized - invalid or missing token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/NodeInfo'
|
||||
'400':
|
||||
description: On error
|
||||
/hotspot:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/watch:
|
||||
get:
|
||||
summary: Get latest position via share link
|
||||
description: Retrieve the latest position for a given share link UUID. Share links are stored in-memory.
|
||||
tags:
|
||||
- Hotspot
|
||||
summary: Запросить информацию о точке
|
||||
- Sharing
|
||||
parameters:
|
||||
- name: id
|
||||
- name: share_id
|
||||
in: query
|
||||
description: Hotspot ID
|
||||
required: true
|
||||
description: UUID of the share link
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||||
responses:
|
||||
'200':
|
||||
description: On success
|
||||
'400':
|
||||
description: On error
|
||||
"200":
|
||||
description: Position retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PositionResponse"
|
||||
example:
|
||||
x: 55.7558
|
||||
y: 37.6173
|
||||
last_update: "2026-05-15T10:30:00.000Z"
|
||||
expires_at: "2026-05-15T11:30:00.000Z"
|
||||
"401":
|
||||
description: Unauthorized - invalid or missing token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"404":
|
||||
description: Share link not found or no position available
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
examples:
|
||||
linkNotFound:
|
||||
summary: Share link not found
|
||||
value:
|
||||
error: "Share link not found"
|
||||
noPosition:
|
||||
summary: No position available
|
||||
value:
|
||||
error: "No position available"
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
BearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: JWT token obtained from /login. Payload contains user_id, login, and iss="family_safety_tracker".
|
||||
|
||||
schemas:
|
||||
Interface:
|
||||
LoginRequest:
|
||||
type: object
|
||||
required:
|
||||
- login
|
||||
- password
|
||||
properties:
|
||||
login:
|
||||
type: string
|
||||
description: User login / username
|
||||
example: "john_doe"
|
||||
password:
|
||||
type: string
|
||||
format: password
|
||||
description: User password (verified against bcrypt hash)
|
||||
example: "secret123"
|
||||
|
||||
RegisterRequest:
|
||||
type: object
|
||||
required:
|
||||
- login
|
||||
- password
|
||||
properties:
|
||||
login:
|
||||
type: string
|
||||
description: Desired login / username
|
||||
example: "john_doe"
|
||||
password:
|
||||
type: string
|
||||
format: password
|
||||
description: Desired password (will be hashed with bcrypt)
|
||||
example: "secret123"
|
||||
|
||||
LoginResponse:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
token:
|
||||
type: string
|
||||
default: eth0
|
||||
ip:
|
||||
type: string
|
||||
default: 192.168.1.1
|
||||
netmask:
|
||||
type: string
|
||||
default: 255.255.255.0
|
||||
mac:
|
||||
type: string
|
||||
default: 4A:30:10:21:10:1A
|
||||
mtu:
|
||||
type: integer
|
||||
default: 0
|
||||
active:
|
||||
type: boolean
|
||||
default: true
|
||||
loopback:
|
||||
type: boolean
|
||||
default: false
|
||||
readonly:
|
||||
type: boolean
|
||||
default: false
|
||||
Config:
|
||||
description: JWT token for authenticated requests
|
||||
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
|
||||
RegisterResponse:
|
||||
type: object
|
||||
properties:
|
||||
secret:
|
||||
message:
|
||||
type: string
|
||||
default: error
|
||||
channel:
|
||||
type: integer
|
||||
default: 0
|
||||
width:
|
||||
type: integer
|
||||
default: 0
|
||||
power:
|
||||
type: integer
|
||||
default: 0
|
||||
distance:
|
||||
type: integer
|
||||
default: 0
|
||||
Command:
|
||||
example: "User registered"
|
||||
|
||||
PositionRequest:
|
||||
type: object
|
||||
required:
|
||||
- x
|
||||
- y
|
||||
properties:
|
||||
x:
|
||||
type: number
|
||||
format: double
|
||||
description: Longitude coordinate
|
||||
example: 55.7558
|
||||
y:
|
||||
type: number
|
||||
format: double
|
||||
description: Latitude coordinate
|
||||
example: 37.6173
|
||||
|
||||
PositionResponse:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
x:
|
||||
type: number
|
||||
format: double
|
||||
description: Longitude coordinate
|
||||
example: 55.7558
|
||||
y:
|
||||
type: number
|
||||
format: double
|
||||
description: Latitude coordinate
|
||||
example: 37.6173
|
||||
last_update:
|
||||
type: string
|
||||
default: error
|
||||
contentType:
|
||||
format: date-time
|
||||
description: Timestamp of the last position update (ISO 8601)
|
||||
example: "2026-05-15T10:30:00.000Z"
|
||||
expires_at:
|
||||
type: string
|
||||
default: error
|
||||
path:
|
||||
type: string
|
||||
default: error
|
||||
content:
|
||||
type: string
|
||||
default: error
|
||||
needConfirmation:
|
||||
type: boolean
|
||||
default: false
|
||||
CommandResult:
|
||||
format: date-time
|
||||
description: Expiration timestamp for the position (ISO 8601)
|
||||
example: "2026-05-15T11:30:00.000Z"
|
||||
|
||||
ShareResponse:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
geo_id:
|
||||
type: string
|
||||
default: "name unknown"
|
||||
exitCode:
|
||||
type: integer
|
||||
default: 0
|
||||
output:
|
||||
format: uuid
|
||||
description: UUID of the created geoposition record in the database
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
share_id:
|
||||
type: string
|
||||
default: "command stdout"
|
||||
format: uuid
|
||||
description: UUID of the share link for public viewing
|
||||
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||||
|
||||
MessageResponse:
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
example: "Position updated"
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
default: "command stderr"
|
||||
running:
|
||||
type: boolean
|
||||
default: false
|
||||
Stat:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
default: "unknown"
|
||||
spots:
|
||||
type: array
|
||||
items:
|
||||
type: number
|
||||
default: 0.0
|
||||
interval:
|
||||
type: integer
|
||||
default: 5
|
||||
units:
|
||||
type: string
|
||||
default: "db"
|
||||
min:
|
||||
type: number
|
||||
default: 0.0
|
||||
max:
|
||||
type: number
|
||||
default: 100.0
|
||||
HotspotInfo:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
default: "unknown"
|
||||
signal:
|
||||
type: number
|
||||
default: 0.0
|
||||
hops:
|
||||
type: integer
|
||||
default: 5
|
||||
rx:
|
||||
type: integer
|
||||
default: 5
|
||||
tx:
|
||||
type: integer
|
||||
default: 5
|
||||
bytesReceived:
|
||||
type: integer
|
||||
default: 5
|
||||
bytesSent:
|
||||
type: integer
|
||||
default: 5
|
||||
connectionTime:
|
||||
type: integer
|
||||
default: 5,
|
||||
inactiveTime:
|
||||
type: integer
|
||||
default: 5,
|
||||
stats:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Stat'
|
||||
BackendInfo:
|
||||
type: object
|
||||
properties:
|
||||
version:
|
||||
type: string
|
||||
default: "unknown"
|
||||
arch:
|
||||
type: string
|
||||
default: "unknown"
|
||||
uptime:
|
||||
type: integer
|
||||
default: 0
|
||||
hostname:
|
||||
type: string
|
||||
default: "unknown"
|
||||
buildNum:
|
||||
type: integer
|
||||
default: 9999
|
||||
buildType:
|
||||
type: string
|
||||
default: "unknown"
|
||||
buildDate:
|
||||
type: string
|
||||
default: "unknown"
|
||||
pipVersion:
|
||||
type: string
|
||||
default: "unknown"
|
||||
frontVersion:
|
||||
type: string
|
||||
default: "unknown"
|
||||
frontBuild:
|
||||
type: string
|
||||
default: "unknown"
|
||||
NodeInfo:
|
||||
type: object
|
||||
properties:
|
||||
mac:
|
||||
type: string
|
||||
default: "unknown"
|
||||
connections:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
default: node
|
||||
BlockPriorityRule:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
default: "unknown"
|
||||
protocol:
|
||||
type: string
|
||||
default: "tcp"
|
||||
port:
|
||||
type: integer
|
||||
default: 389
|
||||
allow:
|
||||
type: boolean
|
||||
default: false
|
||||
direction:
|
||||
type: boolean
|
||||
default: true
|
||||
priority:
|
||||
type: integer
|
||||
default: 0
|
||||
description: Error description
|
||||
example: "Invalid credentials"
|
||||
|
||||
tags:
|
||||
- name: Authentication
|
||||
description: User registration and login
|
||||
- name: Geolocation
|
||||
description: Create and update geolocation positions
|
||||
- name: Sharing
|
||||
description: Share links for public position viewing
|
||||
|
||||
Reference in New Issue
Block a user