From bf09e224c92c1c77ee3ea6f4ac23959039ba2a2a Mon Sep 17 00:00:00 2001 From: alexz Date: Mon, 29 Jun 2026 12:23:15 -0700 Subject: [PATCH] Add be9700-api: TP-Link BE9700 router API proxy + Scalar docs --- apps/be9700-api/build/README.md | 34 ++++++++++++++++++++ apps/be9700-api/build/build.sh | 26 +++++++++++++++ apps/be9700-api/config.json | 21 +++++++++++++ apps/be9700-api/docker-compose.json | 24 ++++++++++++++ apps/be9700-api/metadata/description.md | 40 ++++++++++++++++++++++++ apps/be9700-api/metadata/logo.jpg | Bin 0 -> 28639 bytes 6 files changed, 145 insertions(+) create mode 100644 apps/be9700-api/build/README.md create mode 100644 apps/be9700-api/build/build.sh create mode 100644 apps/be9700-api/config.json create mode 100644 apps/be9700-api/docker-compose.json create mode 100644 apps/be9700-api/metadata/description.md create mode 100644 apps/be9700-api/metadata/logo.jpg diff --git a/apps/be9700-api/build/README.md b/apps/be9700-api/build/README.md new file mode 100644 index 0000000..a5bab50 --- /dev/null +++ b/apps/be9700-api/build/README.md @@ -0,0 +1,34 @@ +# be9700-api — Build Notes + +## Image + +`git.alexzaw.dev/alexz/be9700-api:` + +## Source + +`/home/alexz/be9700-api` (also mirrored to `https://git.alexzaw.dev/alexz/be9700-api`) + +The Dockerfile lives in the root of the source directory alongside `server.js`. + +## Architecture + +- **amd64 only** — the app is pure Node.js (no native addons) but the image is + only built and tested on the amd64 host. Add `--platform linux/arm64` to the + build command and push a separate tag to add arm64 support. + +## Security + +`.dockerignore` excludes `.env`, `.env.*`, `.git`, `scripts/`, `*.log`, `*.curl`, +`network-captures.js`. The image contains no router credentials. + +## Build + +```bash +# From this directory: +bash build.sh + +# Or with overrides: +IMAGE_TAG=1.0.1 bash build.sh --no-cache +``` + +Requires the Docker daemon to be authenticated to `git.alexzaw.dev`. diff --git a/apps/be9700-api/build/build.sh b/apps/be9700-api/build/build.sh new file mode 100644 index 0000000..42b14ba --- /dev/null +++ b/apps/be9700-api/build/build.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Build and push the be9700-api Docker image from the source in /home/alexz/be9700-api. +# The Dockerfile lives alongside the source (not in this build/ dir). + +set -euo pipefail + +IMAGE_NAME="${IMAGE_NAME:-git.alexzaw.dev/alexz/be9700-api}" +IMAGE_TAG="${IMAGE_TAG:-1.0.0}" +SOURCE_DIR="${SOURCE_DIR:-/home/alexz/be9700-api}" + +echo "==> Building ${IMAGE_NAME}:${IMAGE_TAG}" +docker build "$@" \ + -t "${IMAGE_NAME}:${IMAGE_TAG}" \ + -t "${IMAGE_NAME}:latest" \ + "${SOURCE_DIR}" + +echo "==> Pushing ${IMAGE_NAME}:${IMAGE_TAG}" +docker push "${IMAGE_NAME}:${IMAGE_TAG}" +echo "==> Pushing ${IMAGE_NAME}:latest" +docker push "${IMAGE_NAME}:latest" + +echo "" +echo "Done. To update on Runtipi:" +echo " cd /etc/runtipi/repos/runtipi && sudo git add . && sudo git commit -m 'be9700-api: bump' && sudo git push origin main" +echo " sudo /etc/runtipi/runtipi-cli appstore update" +echo " sudo /etc/runtipi/runtipi-cli app update be9700-api:runtipi" diff --git a/apps/be9700-api/config.json b/apps/be9700-api/config.json new file mode 100644 index 0000000..8c4d858 --- /dev/null +++ b/apps/be9700-api/config.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schemas.runtipi.io/app-info.json", + "name": "BE9700 Router API", + "id": "be9700-api", + "available": true, + "short_desc": "Stateless proxy + Scalar API docs for the TP-Link BE9700 WiFi 7 router", + "author": "alexz", + "port": 8347, + "categories": ["network", "utilities"], + "description": "A stateless Node.js proxy server that exposes the TP-Link BE9700 WiFi 7 router's internal API as a clean REST surface with interactive Scalar docs at /docs. Credentials are never stored — callers pass X-Router-Host and X-Router-Password (or X-Router-Session) per request. Covers 203 endpoints: wireless bands (2.4 GHz / 5 GHz / 6 GHz), LAN/DHCP, NAT, UPnP, time, and diagnostics.", + "tipi_version": 1, + "version": "1.0.0", + "source": "https://git.alexzaw.dev/alexz/be9700-api", + "website": "https://git.alexzaw.dev/alexz/be9700-api", + "exposable": true, + "dynamic_config": true, + "no_gui": false, + "form_fields": [], + "supported_architectures": ["amd64"], + "min_tipi_version": "4.0.0" +} diff --git a/apps/be9700-api/docker-compose.json b/apps/be9700-api/docker-compose.json new file mode 100644 index 0000000..7c48f2e --- /dev/null +++ b/apps/be9700-api/docker-compose.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://schemas.runtipi.io/dynamic-compose.json", + "schemaVersion": 2, + "services": [ + { + "name": "be9700-api", + "image": "git.alexzaw.dev/alexz/be9700-api:1.0.0", + "isMain": true, + "internalPort": 3000, + "environment": [ + { "key": "PORT", "value": "3000" }, + { "key": "TZ", "value": "${TZ}" }, + { "key": "NODE_ENV", "value": "production" } + ], + "healthCheck": { + "test": "wget -qO- http://127.0.0.1:3000/ >/dev/null 2>&1 || exit 1", + "interval": "30s", + "timeout": "5s", + "retries": 3, + "startPeriod": "15s" + } + } + ] +} diff --git a/apps/be9700-api/metadata/description.md b/apps/be9700-api/metadata/description.md new file mode 100644 index 0000000..b5eb036 --- /dev/null +++ b/apps/be9700-api/metadata/description.md @@ -0,0 +1,40 @@ +# BE9700 Router API + +A stateless Node.js proxy and interactive API documentation server for the +**TP-Link BE9700 WiFi 7** router. + +## What it does + +- Exposes the router's internal API as a clean, resource-oriented REST surface + (`/api/*`) covering **203 endpoints** across wireless bands (2.4 GHz / 5 GHz / + 6 GHz), LAN/DHCP, NAT, UPnP, system time, and diagnostics. +- Serves **interactive Scalar API docs** at `/docs` — explore and try every + endpoint directly in the browser. +- Returns the OpenAPI 3.1 specification at `/openapi.json` for use with any + compatible tooling. +- Health/status JSON at `/`. + +## Stateless header-auth model + +No router credentials are stored in the container or in Runtipi form fields. +Every request to `/api/*` must carry: + +| Header | Purpose | +|--------|---------| +| `X-Router-Host` | Router IP or hostname (e.g. `192.168.0.1`) | +| `X-Router-Password` | Router admin password (for fresh sessions) | +| `X-Router-Session` | Reuse a session token returned by a previous call (JSON) | + +This means the container itself holds no secrets and is safe to expose via +Traefik without any additional auth middleware — just use the API from clients +that supply the headers. + +## Quick start + +Once installed, open the **Scalar docs** at `http://:8347/docs` +and authenticate each request with the `X-Router-Host` and +`X-Router-Password` headers. + +## Source + +`https://git.alexzaw.dev/alexz/be9700-api` diff --git a/apps/be9700-api/metadata/logo.jpg b/apps/be9700-api/metadata/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..11647ccd149c37be84e01599c9cbd3f2327f6824 GIT binary patch literal 28639 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�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 KnmU39!~X?mehDoA literal 0 HcmV?d00001