major: kestrel is now a tak server #6
@@ -1,20 +1,11 @@
|
||||
# KestrelOS documentation
|
||||
# KestrelOS Documentation
|
||||
|
||||
KestrelOS is a Tactical Operations Center (TOC) for OSINT feeds: map view, cameras/devices, live sharing, and ATAK/iTAK integration.
|
||||
Tactical Operations Center (TOC) for OSINT feeds: map view, cameras/devices, live sharing, and ATAK/iTAK integration.
|
||||
|
||||
## Documentation index
|
||||
## Quick Start
|
||||
|
||||
| Topic | Description |
|
||||
|-------|-------------|
|
||||
| [Installation](installation.md) | Install via npm, Docker, or Helm (Kubernetes) |
|
||||
| [Authentication](auth.md) | Local login, OIDC config, and sign up |
|
||||
| [Map and cameras](map-and-cameras.md) | Using the map, adding and viewing cameras (IPTV, ALPR, CCTV, NVR, etc.) |
|
||||
| [ATAK and iTAK](atak-itak.md) | Connect ATAK (Android) and iTAK (iOS) to KestrelOS as a TAK Server |
|
||||
| [Share live](live-streaming.md) | Add your mobile device as a live camera (WebRTC) |
|
||||
|
||||
## Quick links
|
||||
|
||||
- **First run**: [Installation](installation.md) → [Authentication](auth.md) (bootstrap admin or OIDC).
|
||||
- **Add a camera**: [Map and cameras](map-and-cameras.md) (API or future UI).
|
||||
- **Stream from phone**: [Share live](live-streaming.md) (HTTPS required).
|
||||
- **Use ATAK/iTAK**: [ATAK and iTAK](atak-itak.md) (Server connection, port 8089 for CoT).
|
||||
1. [Installation](installation.md) — npm, Docker, or Helm
|
||||
2. [Authentication](auth.md) — First login (bootstrap admin or OIDC)
|
||||
3. [Map and cameras](map-and-cameras.md) — Add devices and view streams
|
||||
4. [ATAK and iTAK](atak-itak.md) — Connect TAK clients (port 8089)
|
||||
5. [Share live](live-streaming.md) — Stream from mobile device (HTTPS required)
|
||||
|
||||
@@ -1,188 +1,79 @@
|
||||
# ATAK and iTAK usage
|
||||
# ATAK and iTAK
|
||||
|
||||
KestrelOS can act as a **TAK Server**: ATAK (Android) and iTAK (iOS) devices connect to it the same way they connect to any TAK Server. No plugins are required. Once connected, devices relay Cursor on Target (CoT) to each other so team members see each other on the ATAK/iTAK map, and their positions appear on the KestrelOS web map.
|
||||
KestrelOS acts as a **TAK Server**. ATAK (Android) and iTAK (iOS) connect on **port 8089** (CoT). Devices relay positions to each other and appear on the KestrelOS map.
|
||||
|
||||
---
|
||||
## Connection
|
||||
|
||||
## Overview
|
||||
**Host:** KestrelOS hostname/IP
|
||||
**Port:** `8089` (CoT)
|
||||
**SSL:** Enable if server uses TLS (`.dev-certs/` or production cert)
|
||||
|
||||
- **ATAK** — Android Team Awareness Kit.
|
||||
- **iTAK** — iOS version; uses the same TAK Server connection flow.
|
||||
- **KestrelOS** — Web app and API use **port 3000**. CoT (TAK) uses **port 8089** (TLS when `.dev-certs/` or `COT_SSL_*` are set, else plain TCP). In ATAK/iTAK you connect to host and port **8089**; enable SSL if the server uses TLS.
|
||||
|
||||
You add KestrelOS as a **Server** connection in ATAK or iTAK (host + port **8089**). If authentication is enabled, you use your **KestrelOS username** and a **password** (local users: login password; OIDC users: ATAK password set in the web app).
|
||||
|
||||
---
|
||||
**Authentication:**
|
||||
- **Username:** KestrelOS identifier
|
||||
- **Password:** Login password (local) or ATAK password (OIDC; set in **Account**)
|
||||
|
||||
## ATAK (Android)
|
||||
|
||||
### 1. Add the server
|
||||
|
||||
1. Open **ATAK**.
|
||||
2. Go to **Settings** (or **Configuration**) → **Network** → **Connections** (or **Server Connections**).
|
||||
3. Add a new connection:
|
||||
- **Type:** TAK Server / Server.
|
||||
- **Host:** Your KestrelOS hostname or IP (e.g. `kestrelos.example.com` or `192.168.1.10`).
|
||||
- **Port:** **8089** (CoT port). Use SSL if the server runs with TLS (e.g. `.dev-certs/` or production cert).
|
||||
4. If your KestrelOS instance requires authentication:
|
||||
- Enable **Use Authentication** (or equivalent).
|
||||
- **Username:** Your KestrelOS identifier (email or username).
|
||||
- **Password:**
|
||||
- **Local account:** Your KestrelOS login password.
|
||||
- **OIDC account:** The **ATAK password** you set under **Account** in the KestrelOS web app (you must set it once before connecting).
|
||||
5. Save and connect.
|
||||
|
||||
### 2. Verify
|
||||
|
||||
- After connecting, your device and other connected ATAK/iTAK devices should appear on the ATAK map.
|
||||
- In KestrelOS, open the **Map** in a browser; you should see amber markers for connected TAK devices. They disappear after about 90 seconds without updates.
|
||||
|
||||
---
|
||||
1. **Settings** → **Network** → **Connections** → Add **TAK Server**
|
||||
2. Set **Host** and **Port** (`8089`)
|
||||
3. Enable **Use Authentication**, enter username/password
|
||||
4. Save and connect
|
||||
|
||||
## iTAK (iOS)
|
||||
|
||||
### 1. Add the server
|
||||
**Option A — QR code (easiest):**
|
||||
1. KestrelOS **Settings** → **TAK Server** → Scan QR with iTAK
|
||||
2. Enter username/password when prompted
|
||||
|
||||
**Option A — Scan QR code (easiest)**
|
||||
In KestrelOS, open **Settings** and find the **TAK Server (ATAK / iTAK)** section. Scan the QR code with iTAK (Add Connection → Scan QR). iTAK will add the server; you’ll be prompted for your KestrelOS username and password. If the server uses a self-signed certificate, import the trust store first (see [Self-signed certificate: import the trust store](#2-self-signed-certificate-import-the-trust-store-required-for-ssl)).
|
||||
**Option B — Manual:**
|
||||
1. **Settings** → **Network** → Add **TAK Server**
|
||||
2. Set **Host**, **Port** (`8089`), enable SSL if needed
|
||||
3. Enable **Use Authentication**, enter username/password
|
||||
4. Save and connect
|
||||
|
||||
**Option B — Manual**
|
||||
1. Open **iTAK**.
|
||||
2. Go to **Settings** → **Network** / **Connections** (wording may vary by version).
|
||||
3. Add a **TAK Server** (or **Server**) connection:
|
||||
- **Host:** KestrelOS hostname or IP.
|
||||
- **Port:** **8089** (CoT port). Use SSL when the server uses TLS.
|
||||
4. If authentication is required:
|
||||
- Turn on **Use Authentication**.
|
||||
- **Username:** Your KestrelOS identifier.
|
||||
- **Password:** KestrelOS login password (local) or ATAK password (OIDC; set in KestrelOS **Account**).
|
||||
5. Save and connect.
|
||||
## Self-Signed Certificate (iTAK)
|
||||
|
||||
### 2. Self-signed certificate (required for SSL)
|
||||
If server uses self-signed cert (`.dev-certs/`):
|
||||
|
||||
If KestrelOS uses a **self-signed certificate** (e.g. `.dev-certs/`), the client must trust it or the TLS handshake never completes. You’ll see “Error authenticating with the server” and **no `[cot]` logs** on the server.
|
||||
**Upload server package:**
|
||||
1. KestrelOS **Settings** → **TAK Server** → **Download server package (zip)**
|
||||
2. Transfer to iPhone (AirDrop, email, Safari)
|
||||
3. iTAK: **Settings** → **Network** → **Servers** → **+** → **Upload server package**
|
||||
4. Enter username/password
|
||||
|
||||
**iTAK (iOS) — Upload server package (recommended):**
|
||||
Many iTAK builds only offer “Connect with credentials”, “Upload server package”, and “Scan QR”; there is no “Import Trust Store” or “Enroll with Preconfigured Trust”. Use the server package:
|
||||
**Or use plain TCP:**
|
||||
1. Stop KestrelOS, remove `.dev-certs/`, restart
|
||||
2. Add server with **SSL disabled**
|
||||
|
||||
1. In **KestrelOS**, open **Settings** → **TAK Server (ATAK / iTAK)** and click **Download server package (zip)**.
|
||||
2. Transfer the zip to your iPhone (e.g. AirDrop, email, or open KestrelOS in Safari on the phone, log in, and download there).
|
||||
3. In **iTAK**: **Settings** → **Network** → **Servers** → **+** → **Upload server package** → select the zip.
|
||||
4. When prompted, enter your KestrelOS **username** and **password**. The package includes the server cert so iTAK can complete the TLS handshake.
|
||||
**ATAK (Android):** Download trust store from `https://your-server/api/cot/truststore`, import `.p12` (password: `kestrelos`), or use server package/plain TCP.
|
||||
|
||||
**iTAK — Plain TCP (no SSL):**
|
||||
If the server package does not work, run CoT without TLS: stop KestrelOS, rename or remove the `.dev-certs` folder, then restart. The CoT server will listen on 8089 with plain TCP. In **Settings** → TAK Server, the QR will show `tcp`. Scan it or add the server manually with **SSL disabled**. You won’t get a cert prompt and the connection should reach the server.
|
||||
## OIDC Users
|
||||
|
||||
**ATAK (Android):** If your build has **Enroll with Preconfigured Trust** and **Import Trust Store**, you can download the trust store from **https://your-server/api/cot/truststore** (when logged in), import the `.p12`, password `kestrelos`, then connect. Otherwise use the **server package** from Settings the same way as iTAK, or use plain TCP as above.
|
||||
OIDC users must set an **ATAK password** first:
|
||||
1. Sign in with OIDC
|
||||
2. **Account** → **ATAK / device password** → set password
|
||||
3. Use KestrelOS username + ATAK password in TAK client
|
||||
|
||||
### 3. Verify
|
||||
## Configuration
|
||||
|
||||
- Other TAK clients (ATAK and iTAK) that are connected to the same KestrelOS instance appear on your iTAK map.
|
||||
- KestrelOS web map shows all connected TAK devices as amber markers (position only; no video).
|
||||
|
||||
---
|
||||
|
||||
## OIDC users: set ATAK password first
|
||||
|
||||
If you sign in to KestrelOS with **OIDC** (SSO), you do not have a KestrelOS login password. To use “Use Authentication” in ATAK/iTAK:
|
||||
|
||||
1. Sign in to the **KestrelOS web app** with OIDC.
|
||||
2. Open **Account** (sidebar).
|
||||
3. Under **ATAK / device password**, set and confirm a password, then save.
|
||||
4. In ATAK or iTAK, use your **KestrelOS username** (identifier) and this **ATAK password**.
|
||||
|
||||
If you haven’t set an ATAK password, the TAK Server will reject your connection.
|
||||
|
||||
---
|
||||
|
||||
## Server configuration (optional)
|
||||
|
||||
| Environment variable | Default | Description |
|
||||
|----------------------|---------|-------------|
|
||||
| `PORT` | `3000` | Port for the web app and API. |
|
||||
| `COT_PORT` | `8089` | Port for the CoT (TAK) server. |
|
||||
| `COT_TTL_MS` | `90000` | How long (ms) a device stays on the map without updates (~90 s). |
|
||||
| `COT_REQUIRE_AUTH` | `true` | Require username/password before relaying. |
|
||||
| `COT_SSL_CERT` | — | Path to TLS cert for CoT (optional; default: `.dev-certs/cert.pem`). |
|
||||
| `COT_SSL_KEY` | — | Path to TLS key (optional; default: `.dev-certs/key.pem`). |
|
||||
|
||||
When `.dev-certs/` exists (e.g. `./scripts/gen-dev-cert.sh`), the CoT server uses TLS on port 8089. For **Docker**, expose ports 3000 and 8089:
|
||||
|
||||
```bash
|
||||
docker run -p 3000:3000 -p 8089:8089 kestrelos:latest
|
||||
```
|
||||
|
||||
For **Helm**, expose ports 3000 and 8089 in the service or ingress.
|
||||
|
||||
---
|
||||
|
||||
## Testing the CoT endpoint
|
||||
|
||||
The web app is on **port 3000**, CoT on **port 8089**. From the same device (or any host with network access), you can confirm both work.
|
||||
|
||||
**Health (API):** `curl -k https://localhost:3000/health` (or `http://localhost:3000/health` if no TLS).
|
||||
|
||||
**CoT on port 8089:** If the server uses TLS (e.g. `.dev-certs/`), connect with TLS to port 8089 and send a CoT auth message:
|
||||
|
||||
```bash
|
||||
echo '<event><detail><auth username="itak" password="yourpassword"/></detail></event>' | \
|
||||
openssl s_client -connect localhost:8089 -quiet 2>/dev/null
|
||||
```
|
||||
|
||||
If the server runs without TLS (plain TCP), use:
|
||||
|
||||
```bash
|
||||
echo '<event><detail><auth username="itak" password="yourpassword"/></detail></event>' | \
|
||||
nc localhost 8089
|
||||
```
|
||||
|
||||
Replace `localhost` with your server host if testing remotely. **What to expect:** Server logs show `[cot] client connected`, `[cot] frame parsed as traditional`, `[cot] auth attempt username= itak`, and either `auth result valid= true` or `password match= false`.
|
||||
|
||||
---
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `COT_PORT` | `8089` | CoT server port |
|
||||
| `COT_TTL_MS` | `90000` | Device timeout (~90s) |
|
||||
| `COT_REQUIRE_AUTH` | `true` | Require authentication |
|
||||
| `COT_SSL_CERT` | `.dev-certs/cert.pem` | TLS cert path |
|
||||
| `COT_SSL_KEY` | `.dev-certs/key.pem` | TLS key path |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Error authenticating with the server" and no `[cot]` logs on the server
|
||||
**"Error authenticating" with no `[cot]` logs:**
|
||||
- Connection not reaching server (TLS handshake failed or firewall blocking)
|
||||
- Check server logs show `[cot] CoT server listening on 0.0.0.0:8089`
|
||||
- Verify port `8089` (not `3000`) and firewall allows it
|
||||
- For TLS: trust cert (server package) or use plain TCP
|
||||
|
||||
If iTAK shows this message but you see **no** `[cot]` lines in the server log, the connection is almost certainly **not reaching** the CoT process.
|
||||
**"Error authenticating" with `[cot]` logs:**
|
||||
- Username must be KestrelOS identifier
|
||||
- Password must match (local: login password; OIDC: ATAK password)
|
||||
|
||||
**With SSL (TLS) and a self-signed cert:** The server only runs your connection handler **after** the TLS handshake completes. If the client does not trust the server’s certificate (e.g. self-signed and not imported), the handshake fails on the client side and never completes, so the server never logs “client connected”. **Fix:** Use **Upload server package** (download from KestrelOS Settings) or import the trust store in iTAK (see [Self-signed certificate](#2-self-signed-certificate-required-for-ssl) above). No server logs until the client trusts the cert and the handshake succeeds.
|
||||
|
||||
1. **Confirm CoT is listening**
|
||||
- When the app starts you must see: `[cot] CoT server listening on 0.0.0.0:8089 (TLS)` or `(plain TCP)`.
|
||||
- If you don’t see that, the CoT server didn’t start (e.g. port 8089 in use, or you’re viewing logs for a different process).
|
||||
|
||||
2. **Port and host**
|
||||
- In iTAK the **port must be 8089** (not 3000). Host = your server IP (e.g. 192.168.2.214).
|
||||
|
||||
3. **Reachability from the device**
|
||||
- From the same network as your phone, run: `nc -zv 192.168.2.214 8089` (or use a "port check" app). If it doesn’t connect, the firewall or network is blocking 8089.
|
||||
|
||||
4. **SSL and self-signed cert**
|
||||
- If the server log says **(TLS)**, iTAK must trust the cert: use **Upload server package** (download the zip from KestrelOS Settings) or run CoT without TLS and add the server with SSL disabled (see [Self-signed certificate](#2-self-signed-certificate-required-for-ssl)).
|
||||
- If the server says **(plain TCP)**, in iTAK **disable** SSL.
|
||||
|
||||
5. **Where to look for logs**
|
||||
- Same terminal where you ran `npm run dev` or `node .output/server/index.mjs`. If you use Docker/systemd, check that process’s stdout/stderr.
|
||||
|
||||
Once the connection reaches the server you’ll see at least: `[cot] client connected (TLS) from <ip>`.
|
||||
|
||||
---
|
||||
|
||||
- **Connection refused:** Ensure ports 3000 (web/API) and 8089 (CoT) are open on the server and in any firewall.
|
||||
- **"Error authenticating" but you do see `[cot]` logs:** Username must be the KestrelOS **identifier** (login name) and password must match (local: login password; OIDC: ATAK password set in **Account**).
|
||||
- **Authentication failed (OIDC user):** Set an **ATAK password** in KestrelOS under **Account**.
|
||||
- **Devices not on KestrelOS map:** They appear only while sending position updates; they drop off after the TTL (~90 s) with no updates.
|
||||
- **SSL:** If the server uses TLS (`.dev-certs/` or production cert), connect to port 8089 with SSL enabled in ATAK/iTAK.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Step | ATAK / iTAK |
|
||||
|------|-------------|
|
||||
| Add server | **QR:** KestrelOS **Settings** → scan TAK Server QR with iTAK/ATAK. Or add manually: **Host** = KestrelOS, **Port** = 8089 (CoT). |
|
||||
| Self-signed SSL (iTAK) | **Settings** → Download **server package (zip)** → in iTAK: **Upload server package** and select it. Or run CoT without TLS (remove `.dev-certs`, restart) and add server with SSL disabled. |
|
||||
| Auth | Enable “Use Authentication”; **Username** = KestrelOS identifier; **Password** = login password (local) or ATAK password (OIDC). |
|
||||
| OIDC users | Set **ATAK password** once in KestrelOS **Account** before connecting. |
|
||||
| Result | CoT is relayed between all connected TAK clients; positions show on the KestrelOS web map as amber markers. |
|
||||
**Devices not on map:** They appear only while sending updates; drop off after TTL (~90s).
|
||||
|
||||
111
docs/auth.md
111
docs/auth.md
@@ -1,106 +1,39 @@
|
||||
# Authentication
|
||||
|
||||
KestrelOS supports **local login** (username/email + password) and optional **OIDC** (single sign-on with an identity provider). All users must sign in to use the app.
|
||||
KestrelOS supports **local login** (username/email + password) and optional **OIDC** (SSO). All users must sign in.
|
||||
|
||||
---
|
||||
## Local Login
|
||||
|
||||
## Local login
|
||||
**First run:** On first start, KestrelOS creates an admin account:
|
||||
- If `BOOTSTRAP_EMAIL` and `BOOTSTRAP_PASSWORD` are set → that account is created
|
||||
- Otherwise → default admin (`admin`) with random password printed in terminal
|
||||
|
||||
### First run: bootstrap admin
|
||||
**Sign in:** Open `/login`, enter identifier and password. Change password or add users via **Members** (admin only).
|
||||
|
||||
On first start, if the database has no users, KestrelOS creates an **admin** account:
|
||||
## OIDC (SSO)
|
||||
|
||||
- **If you set env vars:**
|
||||
`BOOTSTRAP_EMAIL` and `BOOTSTRAP_PASSWORD`
|
||||
→ That account is created (identifier = email, role = admin).
|
||||
**Enable:** Set `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`. Optional: `OIDC_LABEL`, `OIDC_REDIRECT_URI`, `OIDC_SCOPES`.
|
||||
|
||||
- **If you do not set them:**
|
||||
A default admin is created with identifier **`admin`** and a **random password**.
|
||||
The password is printed in the terminal—copy it and sign in at **/login**.
|
||||
**IdP setup:**
|
||||
1. Create OIDC client in your IdP (Keycloak, Auth0, etc.)
|
||||
2. Set redirect URI: `https://<your-host>/api/auth/oidc/callback`
|
||||
3. Copy Client ID and Secret to env vars
|
||||
|
||||
After first login, change the password or add users via **Members** (admin only).
|
||||
**Sign up:** Users sign up at the IdP. First OIDC login in KestrelOS creates their account automatically.
|
||||
|
||||
### Signing in (local)
|
||||
**Redirect URI:** Defaults to `{APP_URL}/api/auth/oidc/callback` (uses `NUXT_APP_URL`/`APP_URL` or falls back to `HOST`/`PORT`).
|
||||
|
||||
1. Open **/login** (or you’ll be redirected there when visiting a protected page).
|
||||
2. Enter **Email or username** (identifier) and **Password**.
|
||||
3. Click **Sign in**. You’re redirected to the map or the page you came from.
|
||||
## OIDC Users and ATAK/iTAK
|
||||
|
||||
Local users can always use this form. Their password is stored hashed in the database.
|
||||
|
||||
---
|
||||
|
||||
## OIDC config and sign up
|
||||
|
||||
OIDC lets users sign in with an external identity provider (IdP), e.g. Keycloak, Auth0, or your organization’s IdP. There is **no “sign up” inside KestrelOS** for OIDC: accounts are created when a user signs in for the first time (first-time OIDC login creates a KestrelOS user linked to that IdP identity).
|
||||
|
||||
### Enabling OIDC
|
||||
|
||||
Set these environment variables:
|
||||
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `OIDC_ISSUER` | Yes | IdP issuer URL (e.g. `https://auth.example.com/realms/myrel`). |
|
||||
| `OIDC_CLIENT_ID` | Yes | OIDC client ID. |
|
||||
| `OIDC_CLIENT_SECRET` | Yes | OIDC client secret. |
|
||||
| `OIDC_LABEL` | No | Button label (default: "Sign in with OIDC"). |
|
||||
| `OIDC_REDIRECT_URI` | No | Callback URL (default: `{APP_URL}/api/auth/oidc/callback`). |
|
||||
| `OIDC_SCOPES` | No | Scopes (default: `openid profile email`). |
|
||||
|
||||
The app derives the redirect URI if not set:
|
||||
|
||||
- Prefer **`NUXT_APP_URL`** or **`APP_URL`** (e.g. `https://kestrelos.example.com`).
|
||||
Callback = `{that base}/api/auth/oidc/callback`.
|
||||
- Otherwise it uses **`HOST`**, **`PORT`**, and **`NODE_ENV`** (e.g. `http://localhost:3000/api/auth/oidc/callback`).
|
||||
|
||||
### IdP configuration
|
||||
|
||||
In your IdP:
|
||||
|
||||
1. Create an **OIDC client** (confidential, or public with PKCE if supported).
|
||||
2. Set **Redirect URI** to:
|
||||
`https://<your-kestrelos-host>/api/auth/oidc/callback`
|
||||
(or the same with `http` for local dev).
|
||||
3. Copy **Client ID** and **Client Secret** into `OIDC_CLIENT_ID` and `OIDC_CLIENT_SECRET`.
|
||||
4. Set **Issuer** in `OIDC_ISSUER` (issuer URL from the IdP’s discovery document).
|
||||
|
||||
### OIDC sign-in flow
|
||||
|
||||
1. User opens **/login** and clicks the OIDC button (e.g. “Sign in with OIDC”).
|
||||
2. They are redirected to the IdP to sign in (and sign up at the IdP if needed).
|
||||
3. After success, the IdP redirects back to KestrelOS with an authorization code.
|
||||
4. KestrelOS exchanges the code for tokens and creates or finds the user (by `oidc_issuer` + `oidc_sub`), then logs them in.
|
||||
|
||||
**Sign up:** Done at the IdP. The first time a user completes OIDC login, KestrelOS creates a new user; no separate “sign up” page in KestrelOS.
|
||||
|
||||
### OIDC and ATAK/iTAK
|
||||
|
||||
OIDC users don’t have a KestrelOS password. To use **ATAK or iTAK** with “Use Authentication,” they must set an **ATAK password** once in the web app:
|
||||
|
||||
1. Sign in with OIDC.
|
||||
2. Go to **Account**.
|
||||
3. Under **ATAK / device password**, set and confirm a password, then save.
|
||||
|
||||
They then use their **KestrelOS username** (identifier) and this **ATAK password** in the TAK client. See [ATAK and iTAK](atak-itak.md).
|
||||
|
||||
---
|
||||
OIDC users don't have a KestrelOS password. To use ATAK/iTAK:
|
||||
1. Sign in with OIDC
|
||||
2. Go to **Account** → set **ATAK password**
|
||||
3. Use KestrelOS username + ATAK password in TAK client
|
||||
|
||||
## Roles
|
||||
|
||||
- **Admin** — Can manage users (add, edit, delete, change roles), edit POIs, and add/edit devices (via API).
|
||||
- **Leader** — Can edit POIs and add/edit devices (via API). Cannot change user roles.
|
||||
- **Member** — Can view map, cameras, and POIs; can use Share live. Cannot edit POIs or manage devices.
|
||||
- **Admin** — Manage users, edit POIs, add/edit devices (API)
|
||||
- **Leader** — Edit POIs, add/edit devices (API)
|
||||
- **Member** — View map/cameras/POIs, use Share live
|
||||
|
||||
Only admins can change roles (Members page).
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Goal | Action |
|
||||
|------|--------|
|
||||
| First-time setup | Set `BOOTSTRAP_EMAIL` / `BOOTSTRAP_PASSWORD` or use printed default admin password. |
|
||||
| Local sign-in | Use **/login** with identifier and password. |
|
||||
| Enable SSO | Set `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET` (and optional `OIDC_LABEL`, `OIDC_REDIRECT_URI`). |
|
||||
| “Sign up” with OIDC | Users sign up at the IdP; first OIDC login in KestrelOS creates their account. |
|
||||
| Use ATAK/iTAK as OIDC user | Set **ATAK password** under **Account** in the web app. |
|
||||
|
||||
@@ -1,128 +1,61 @@
|
||||
# Installation
|
||||
|
||||
You can run KestrelOS from source (npm), as a Docker container, or on Kubernetes with Helm.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js** 20+ (for npm install)
|
||||
- **Docker** (optional, for container run)
|
||||
- **Kubernetes** and **Helm 3** (optional, for Helm install)
|
||||
|
||||
---
|
||||
Run KestrelOS from source (npm), Docker, or Kubernetes (Helm).
|
||||
|
||||
## npm (from source)
|
||||
|
||||
Best for development or a single server.
|
||||
|
||||
1. **Clone and install**
|
||||
```bash
|
||||
git clone <repository-url> kestrelos
|
||||
cd kestrelos
|
||||
npm install
|
||||
```
|
||||
|
||||
2. **Start the app**
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
Open **http://localhost:3000**. The app will create a SQLite database at `data/kestrelos.db` on first run and bootstrap an admin user if none exist (see [Authentication](auth.md)).
|
||||
|
||||
3. **Production build**
|
||||
Open **http://localhost:3000**. First run creates `data/kestrelos.db` and bootstraps an admin (see [Authentication](auth.md)).
|
||||
|
||||
**Production:**
|
||||
```bash
|
||||
npm run build
|
||||
npm run preview
|
||||
```
|
||||
Or run the built app with Node:
|
||||
```bash
|
||||
# or
|
||||
node .output/server/index.mjs
|
||||
```
|
||||
For production, set `HOST=0.0.0.0` and `PORT` as needed (e.g. `PORT=3000`).
|
||||
|
||||
### Environment (npm)
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `HOST` | Bind address (default from Nuxt; use `0.0.0.0` for all interfaces). |
|
||||
| `PORT` | Port (default `3000`). |
|
||||
| `DB_PATH` | Path to SQLite file (default `data/kestrelos.db`). |
|
||||
|
||||
See [Authentication](auth.md) for `BOOTSTRAP_EMAIL`, `BOOTSTRAP_PASSWORD`, and OIDC variables. See [Map and cameras](map-and-cameras.md) and [ATAK and iTAK](atak-itak.md) for device and CoT options.
|
||||
|
||||
---
|
||||
Set `HOST=0.0.0.0` and `PORT` for production.
|
||||
|
||||
## Docker
|
||||
|
||||
Best for a single server or CI.
|
||||
|
||||
1. **Build the image**
|
||||
```bash
|
||||
docker build -t kestrelos:latest .
|
||||
```
|
||||
|
||||
2. **Run the container**
|
||||
```bash
|
||||
docker run -p 3000:3000 -p 8089:8089 kestrelos:latest
|
||||
```
|
||||
Open **http://localhost:3000**.
|
||||
|
||||
3. **Persist data and set env**
|
||||
```bash
|
||||
docker run -p 3000:3000 -p 8089:8089 \
|
||||
-v kestrelos-data:/app/data \
|
||||
-e HOST=0.0.0.0 \
|
||||
-e BOOTSTRAP_EMAIL=admin@example.com \
|
||||
-e BOOTSTRAP_PASSWORD=yourpassword \
|
||||
kestrelos:latest
|
||||
```
|
||||
Use a volume so the SQLite DB and any uploaded data survive restarts.
|
||||
|
||||
### Docker environment
|
||||
|
||||
Same as npm; pass with `-e`. CoT (ATAK/iTAK) uses port 8089; expose both 3000 and 8089:
|
||||
```bash
|
||||
docker run -p 3000:3000 -p 8089:8089 -v kestrelos-data:/app/data kestrelos:latest
|
||||
```
|
||||
|
||||
---
|
||||
Expose ports **3000** (web/API) and **8089** (CoT for ATAK/iTAK).
|
||||
|
||||
## Helm (Kubernetes)
|
||||
|
||||
Best for production or multi-replica deployments.
|
||||
|
||||
### From a Helm registry (e.g. Gitea)
|
||||
|
||||
**From registry:**
|
||||
```bash
|
||||
helm repo add keligrubb --username YOUR_USER --password YOUR_TOKEN https://git.keligrubb.com/api/packages/keligrubb/helm
|
||||
helm repo update
|
||||
helm repo add keligrubb --username USER --password TOKEN \
|
||||
https://git.keligrubb.com/api/packages/keligrubb/helm
|
||||
helm install kestrelos keligrubb/kestrelos
|
||||
```
|
||||
|
||||
### From source
|
||||
|
||||
**From source:**
|
||||
```bash
|
||||
helm install kestrelos ./helm/kestrelos
|
||||
```
|
||||
|
||||
### Configuration
|
||||
Configure in `helm/kestrelos/values.yaml`. Health: `GET /health`, `/health/live`, `/health/ready`.
|
||||
|
||||
- Edit **`helm/kestrelos/values.yaml`** for image, replica count, resources, and Ingress.
|
||||
- Health endpoints: `GET /health` (overview), `GET /health/live` (liveness), `GET /health/ready` (readiness). The chart configures liveness and readiness probes.
|
||||
- To expose the app, set **`ingress.enabled: true`** and set `ingress.host` (and TLS if needed).
|
||||
- For ATAK/iTAK, expose port 8089 (CoT) in addition to 3000 (web/API) on the service or via Ingress.
|
||||
## Environment Variables
|
||||
|
||||
### Upgrade
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `HOST` | Nuxt default | Bind address (use `0.0.0.0` for all interfaces) |
|
||||
| `PORT` | `3000` | Web/API port |
|
||||
| `DB_PATH` | `data/kestrelos.db` | SQLite database path |
|
||||
|
||||
```bash
|
||||
helm upgrade kestrelos keligrubb/kestrelos
|
||||
# or
|
||||
helm upgrade kestrelos ./helm/kestrelos
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Authentication](auth.md) — First login (local or OIDC).
|
||||
- [Map and cameras](map-and-cameras.md) — Add devices and use the map.
|
||||
- [ATAK and iTAK](atak-itak.md) — Connect TAK clients.
|
||||
- [Share live](live-streaming.md) — Stream from your phone.
|
||||
See [Authentication](auth.md) for auth variables. See [ATAK and iTAK](atak-itak.md) for CoT options.
|
||||
|
||||
@@ -1,105 +1,44 @@
|
||||
# Share live (mobile device as a live camera)
|
||||
# Share Live
|
||||
|
||||
**Share live** lets you stream your phone’s camera and location to KestrelOS. You appear as a **live session** on the map and in the **Cameras** list; others can click your marker to watch the stream in real time. Uses **WebRTC** (Mediasoup) and requires **HTTPS** when using the app from a phone.
|
||||
Stream your phone's camera and location to KestrelOS. Appears as a **live session** on the map and in **Cameras**. Uses **WebRTC** (Mediasoup) and requires **HTTPS** on mobile.
|
||||
|
||||
---
|
||||
## Usage
|
||||
|
||||
## How it works
|
||||
1. Open **Share live** (sidebar → **Share live** or `/share-live`)
|
||||
2. Tap **Start sharing**, allow camera/location permissions
|
||||
3. Device appears on map and in **Cameras**
|
||||
4. Tap **Stop sharing** to end
|
||||
|
||||
1. You open the **Share live** page on your mobile browser (sidebar → **Share live**; or **/share-live**).
|
||||
2. You tap **Start sharing**. The app requests camera and location permission.
|
||||
3. A **live session** is created on the server and your video/location is sent over WebRTC.
|
||||
4. Your device appears on the **map** and in **Cameras**. Others click your marker or select you in the list to view the stream.
|
||||
5. Tap **Stop sharing** to end the stream.
|
||||
|
||||
Only **admin** and **leader** roles see the **Share live** item in the sidebar; they are the ones who can start a live share. Any signed-in user can view live sessions on the map and Cameras page.
|
||||
|
||||
---
|
||||
**Permissions:** Admin/leader can start sharing. All users can view live sessions.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **HTTPS** when using the app from a phone. Browsers require a secure context for camera and geolocation. Use:
|
||||
- A server with a real TLS certificate, or
|
||||
- For local testing: a self-signed cert and your machine’s LAN IP (see below).
|
||||
- **Camera and location permission** in the browser when prompted.
|
||||
- **Network:** Server must be reachable from the phone. For WebRTC, **UDP and TCP ports 40000–49999** must be open on the server (or the ports Mediasoup is configured to use).
|
||||
- **HTTPS** (browsers require secure context for camera/geolocation)
|
||||
- **Camera and location permissions**
|
||||
- **WebRTC ports:** UDP/TCP `40000–49999` open on server
|
||||
|
||||
---
|
||||
## Local Development
|
||||
|
||||
## Using Share live on your phone
|
||||
|
||||
### 1. Open the app over HTTPS
|
||||
|
||||
- **Production:** Open `https://your-kestrelos.example.com`, sign in, then go to **Share live** (sidebar).
|
||||
- **Local / LAN:** Use the same HTTPS URL you use for the server (e.g. `https://192.168.1.10:3000`). If you use a self-signed cert, accept the browser warning once (e.g. Advanced → Proceed).
|
||||
|
||||
### 2. Start sharing
|
||||
|
||||
1. Tap **Share live** in the sidebar (or open `/share-live`).
|
||||
2. Tap **Start sharing**.
|
||||
3. Allow **camera** and **location** when the browser asks.
|
||||
4. Wait for “Live — you appear on the map.” Your marker and stream are now visible to others.
|
||||
|
||||
### 3. View yourself on the map
|
||||
|
||||
- On another device (or in another tab), open the KestrelOS **map**. Your device appears as a live-session marker; click it to open the stream panel.
|
||||
- Or open **Cameras** and select your session from the list (shown as “Live”).
|
||||
|
||||
### 4. Stop sharing
|
||||
|
||||
Tap **Stop sharing** on the Share live page. The session ends and your marker disappears after a short time.
|
||||
|
||||
---
|
||||
|
||||
## Local development: HTTPS and LAN
|
||||
|
||||
To test Share live from a phone on your LAN without a public domain or cert:
|
||||
|
||||
1. **Generate a self-signed cert** (once) using your machine’s LAN IP:
|
||||
**Generate self-signed cert:**
|
||||
```bash
|
||||
chmod +x scripts/gen-dev-cert.sh
|
||||
./scripts/gen-dev-cert.sh 192.168.1.123
|
||||
```
|
||||
Use your machine’s actual LAN IP instead of `192.168.1.123`.
|
||||
|
||||
2. **Start the dev server** (it will use HTTPS if `.dev-certs/` exists):
|
||||
```bash
|
||||
./scripts/gen-dev-cert.sh 192.168.1.123 # Your LAN IP
|
||||
npm run dev
|
||||
```
|
||||
|
||||
3. **On your phone**, open **https://192.168.1.123:3000** (same IP as above). Accept the “untrusted certificate” warning once, then sign in and go to **Share live**.
|
||||
**On phone:** Open `https://192.168.1.123:3000`, accept cert warning, sign in, use Share live.
|
||||
|
||||
If you see a warning about `NODE_TLS_REJECT_UNAUTHORIZED=0`, you can ignore it in local dev; the server still works.
|
||||
## WebRTC Configuration
|
||||
|
||||
---
|
||||
|
||||
## WebRTC and firewall
|
||||
|
||||
- The server uses **Mediasoup** and needs **UDP and TCP in the range 40000–49999** (by default) open for WebRTC.
|
||||
- The server tries to detect the LAN IP for WebRTC. If you run in **Docker** or have multiple NICs, set **`MEDIASOUP_ANNOUNCED_IP`** to the IP or hostname that clients use to reach the server.
|
||||
- **Wrong host:** If the Share live page shows “Wrong host” (server hostname vs. client hostname), open the app using the same hostname the server reports, or set `MEDIASOUP_ANNOUNCED_IP` so the server advertises the correct address.
|
||||
|
||||
---
|
||||
- Server auto-detects LAN IP for WebRTC
|
||||
- **Docker/multiple NICs:** Set `MEDIASOUP_ANNOUNCED_IP` to client-reachable IP/hostname
|
||||
- **"Wrong host" error:** Use same URL on phone/server, or set `MEDIASOUP_ANNOUNCED_IP`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | What to do |
|
||||
|-------|------------|
|
||||
| “HTTPS required” or camera/location not available | Open the app over **https://** (not http). On a phone, use a tunnel (e.g. ngrok) or a server with TLS. |
|
||||
| “Media devices not available” | Ensure you’re on HTTPS and that the browser has permission for camera (and location if needed). |
|
||||
| “WebRTC: failed” / “Wrong host” | Use the same URL on phone and server, or set `MEDIASOUP_ANNOUNCED_IP`. Open firewall for ports 40000–49999. |
|
||||
| Stream doesn’t appear for others | Check that the server is reachable and that no firewall blocks WebRTC ports. |
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Step | Action |
|
||||
|------|--------|
|
||||
| 1 | Open KestrelOS over **HTTPS** on your phone and sign in. |
|
||||
| 2 | Go to **Share live** (sidebar). |
|
||||
| 3 | Tap **Start sharing** and allow camera and location. |
|
||||
| 4 | Your device appears on the **map** and **Cameras**; others click your marker or entry to view. |
|
||||
| 5 | Tap **Stop sharing** when done. |
|
||||
|
||||
For local testing, use the dev cert script with your LAN IP and open `https://<LAN-IP>:3000` on the phone. For production, use a proper TLS setup and ensure WebRTC ports (40000–49999) are open on the server.
|
||||
| Issue | Fix |
|
||||
|-------|-----|
|
||||
| "HTTPS required" | Use `https://` (not `http://`) |
|
||||
| "Media devices not available" | Ensure HTTPS and browser permissions |
|
||||
| "WebRTC: failed" / "Wrong host" | Set `MEDIASOUP_ANNOUNCED_IP`, open firewall ports `40000–49999` |
|
||||
| Stream not visible | Check server reachability and firewall |
|
||||
|
||||
@@ -1,128 +1,52 @@
|
||||
# Map and cameras
|
||||
# Map and Cameras
|
||||
|
||||
KestrelOS shows a **map** with **devices** (cameras, ALPR, NVR, etc.), **POIs**, **live sessions** (Share live), and **ATAK/iTAK** positions. You view streams by clicking markers or using the **Cameras** page.
|
||||
KestrelOS shows a **map** with devices, POIs, live sessions (Share live), and ATAK/iTAK positions. Click markers or use **Cameras** page to view streams.
|
||||
|
||||
---
|
||||
## Map Layers
|
||||
|
||||
## Using the map
|
||||
- **Devices** — Fixed feeds (IPTV, ALPR, CCTV, NVR, etc.) added via API
|
||||
- **POIs** — Points of interest (admin/leader can edit)
|
||||
- **Live sessions** — Mobile devices streaming via Share live
|
||||
- **CoT (ATAK/iTAK)** — Amber markers for connected TAK devices (position only)
|
||||
|
||||
- **Home:** The main view is the map (**/**). It uses OpenStreetMap-style tiles and supports offline tile caching (Leaflet.offline).
|
||||
- **Layers:**
|
||||
- **Devices** — Cameras and feeds you’ve added (API). Click a device marker to open the live stream in a side panel.
|
||||
- **POIs** — Points of interest (admin/leader can add/edit from **POI** page).
|
||||
- **Live sessions** — Mobile devices streaming via **Share live**. Click to view the live stream.
|
||||
- **CoT (ATAK/iTAK)** — Amber markers for connected ATAK/iTAK devices (position only; no stream).
|
||||
- **Actions:** Pan and zoom as usual. If you have permission, you can add/edit POIs from the **POI** page; device editing is via API (see below).
|
||||
## Cameras
|
||||
|
||||
---
|
||||
A **camera** is either:
|
||||
1. A **device** — Fixed feed with stream URL
|
||||
2. A **live session** — Mobile device streaming via Share live
|
||||
|
||||
## What counts as a “camera”
|
||||
View via map markers or **Cameras** page (sidebar).
|
||||
|
||||
In KestrelOS, a **camera** is either:
|
||||
## Device Types
|
||||
|
||||
1. A **device** — A fixed feed (IPTV, ALPR, CCTV, NVR, doorbell, traffic cam, etc.) with a **stream URL** and optional config.
|
||||
2. A **live session** — A mobile device streaming via **Share live** (WebRTC). These appear automatically while sharing.
|
||||
| device_type | Use case |
|
||||
|-------------|----------|
|
||||
| `alpr`, `nvr`, `doorbell`, `feed`, `traffic`, `ip`, `drone` | Labeling/filtering |
|
||||
|
||||
The **Cameras** page (sidebar → **Cameras**) lists both: select an entry to view its stream in the panel. The map shows the same sources as markers; clicking a marker also opens the stream.
|
||||
**source_type:** `mjpeg` (MJPEG over HTTP) or `hls` (HLS `.m3u8` playlist)
|
||||
|
||||
---
|
||||
Stream URLs must be `http://` or `https://`.
|
||||
|
||||
## Device types and stream types
|
||||
## API: Devices
|
||||
|
||||
When you add a **device** (via API), you set:
|
||||
|
||||
- **device_type** — One of: `alpr`, `nvr`, `doorbell`, `feed`, `traffic`, `ip`, `drone`. Used for labeling and filtering (e.g. “ALPR”, “NVR”).
|
||||
- **source_type** — How the stream is delivered:
|
||||
- **`mjpeg`** — MJPEG over HTTP (single image or MJPEG stream URL).
|
||||
- **`hls`** — HLS (HTTP Live Streaming); use an `https://` or `http://` URL to an `.m3u8` playlist.
|
||||
|
||||
Stream URLs must be **http://** or **https://**; other protocols are rejected.
|
||||
|
||||
Examples by use case:
|
||||
|
||||
| Use case | device_type | source_type | stream_url example |
|
||||
|----------|-------------|-------------|---------------------|
|
||||
| IP camera / CCTV | `ip` or `feed` | `mjpeg` or `hls` | `http://192.168.1.10/mjpg/video.mjpg` |
|
||||
| ALPR camera | `alpr` | `mjpeg` or `hls` | `https://alpr.example.com/stream.m3u8` |
|
||||
| NVR feed | `nvr` | `mjpeg` or `hls` | `http://nvr.local/cam1/video.mjpeg` |
|
||||
| Traffic camera | `traffic` | `mjpeg` or `hls` | `https://traffic.gov/cam123.m3u8` |
|
||||
| Doorbell | `doorbell` | `mjpeg` or `hls` | As provided by vendor. |
|
||||
| IPTV channel | `feed` | `hls` | `https://iptv.example.com/channel.m3u8` |
|
||||
| Drone feed | `drone` | `mjpeg` or `hls` | As provided. |
|
||||
|
||||
---
|
||||
|
||||
## Adding and editing devices (API)
|
||||
|
||||
Only **admin** or **leader** can create or update devices. There is no “Add camera” form in the UI yet; use the HTTP API (e.g. from a script or tool).
|
||||
|
||||
### Create a device
|
||||
|
||||
**POST** `/api/devices`
|
||||
Requires auth (session cookie). Body (JSON):
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `name` | string | Yes | Display name. |
|
||||
| `device_type` | string | No | One of: `alpr`, `nvr`, `doorbell`, `feed`, `traffic`, `ip`, `drone`. Default `feed`. |
|
||||
| `lat` | number | Yes | Latitude. |
|
||||
| `lng` | number | Yes | Longitude. |
|
||||
| `stream_url` | string | No | HTTP(S) URL for MJPEG or HLS. |
|
||||
| `source_type` | string | No | `mjpeg` or `hls`. Default `mjpeg`. |
|
||||
| `vendor` | string | No | Optional vendor/label. |
|
||||
| `config` | string or object | No | Optional JSON config (stored as string). |
|
||||
|
||||
Example (curl, after logging in and saving cookie):
|
||||
|
||||
```bash
|
||||
curl -X POST https://your-kestrelos.example.com/api/devices \
|
||||
-H "Content-Type: application/json" \
|
||||
-b "kestrelos.session=YOUR_SESSION_COOKIE" \
|
||||
-d '{
|
||||
**Create:** `POST /api/devices` (admin/leader)
|
||||
```json
|
||||
{
|
||||
"name": "Main gate ALPR",
|
||||
"device_type": "alpr",
|
||||
"lat": 37.7749,
|
||||
"lng": -122.4194,
|
||||
"stream_url": "https://alpr.example.com/stream.m3u8",
|
||||
"source_type": "hls"
|
||||
}'
|
||||
}
|
||||
```
|
||||
|
||||
### List devices
|
||||
**List:** `GET /api/devices`
|
||||
**Update:** `PATCH /api/devices/:id`
|
||||
**Delete:** `DELETE /api/devices/:id`
|
||||
|
||||
**GET** `/api/devices`
|
||||
Returns all devices (auth required). The map and Cameras page use **GET** `/api/cameras`, which returns devices plus live sessions and CoT entities.
|
||||
**Cameras endpoint:** `GET /api/cameras` returns devices + live sessions + CoT entities.
|
||||
|
||||
### Update a device
|
||||
## POIs
|
||||
|
||||
**PATCH** `/api/devices/:id`
|
||||
Auth required. Send only the fields you want to change (e.g. `name`, `stream_url`, `lat`, `lng`, `device_type`, `source_type`).
|
||||
|
||||
### Delete a device
|
||||
|
||||
**DELETE** `/api/devices/:id`
|
||||
Auth required.
|
||||
|
||||
---
|
||||
|
||||
## Viewing cameras
|
||||
|
||||
- **Map:** Click a device or live-session marker to open the stream in the side panel. Close the panel to return to the map.
|
||||
- **Cameras page:** Open **Cameras** from the sidebar. The list shows all devices and live sessions; select one to view its stream in the right-hand panel. “Live” badge indicates an active Share live stream.
|
||||
|
||||
---
|
||||
|
||||
## POIs (points of interest)
|
||||
|
||||
Admins and leaders can add and edit POIs from the **POI** page (sidebar → **POI**). POIs appear on the map as pins. They are for reference only (no stream). Use **Map** for viewing and **POI** for managing the list and coordinates.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Task | How |
|
||||
|------|-----|
|
||||
| View map and streams | Open **/** and click markers, or use **Cameras** page. |
|
||||
| Add IPTV/ALPR/CCTV/NVR/etc. | **POST** `/api/devices` with `name`, `lat`, `lng`, `stream_url`, `source_type` (`mjpeg` or `hls`), and optional `device_type`, `vendor`. |
|
||||
| Edit or delete a device | **PATCH** or **DELETE** `/api/devices/:id` (admin/leader). |
|
||||
| Add your phone as a live feed | Use **Share live** — see [Share live](live-streaming.md). |
|
||||
Admins/leaders add/edit from **POI** page (sidebar). POIs appear as map pins (reference only, no stream).
|
||||
|
||||
Reference in New Issue
Block a user