remove user-secrets approach & prepare a pilot deploy

This commit is contained in:
hamid
2026-07-28 23:18:54 +03:30
parent 630c7907ec
commit 5885280b49
28 changed files with 639 additions and 142 deletions
+20 -9
View File
@@ -1,15 +1,17 @@
# balinyaar-telegram-otp-bot
A **standalone, dev-only** Telegram relay. It is not part of `client/` or `server/` — it is its own
tiny Node project with **zero dependencies** (Node 18+ built-ins only: `node:http` + global `fetch`).
A **standalone** Telegram relay. It is not part of `client/` or `server/` — it is its own tiny Node
project with **zero dependencies** (Node 18+ built-ins only: `node:http` + global `fetch`).
Its whole job: expose an HTTP endpoint that the .NET API calls, and forward the message to a fixed
list of Telegram chat ids. That replaces "read the OTP out of the server log" during manual testing —
you get the code on your phone instead, without paying an Iranian SMS gateway.
list of Telegram chat ids. That replaces "read the OTP out of the server log" — you get the code on
your phone instead, without an Iranian SMS gateway contract.
> **Development only.** There is no per-user routing: *every* configured recipient receives *every*
> OTP, regardless of which phone number requested it. That is fine for a test group; it is not an SMS
> gateway. Do not point a real environment at this.
> **Broadcast, not routing.** *Every* configured recipient receives *every* OTP, regardless of which
> phone number requested it. That makes this a shared inbox for a small trusted group, not an SMS
> gateway. It is the OTP rail for local development **and** for the pre-launch `balinyaar.ir` demo
> deployment — it must be swapped for `Seams:Sms:Provider = kavenegar` before anyone outside that
> trusted group can request a code.
---
@@ -93,7 +95,7 @@ The two POST routes mirror the server's `ISmsSender` (`SendOtpAsync` / `SendAsyn
| `API_KEY` | — | **Required**, min 16 chars. Shared secret expected in `X-Api-Key`. Process exits without it. |
| `TELEGRAM_CHAT_IDS` | — | Comma-separated recipient chat ids. Empty ⇒ every send returns `503`. |
| `PORT` | `5010` | HTTP port. |
| `HOST` | `127.0.0.1` | Bind address. Keep it loopback unless the API runs on another machine. |
| `HOST` | `127.0.0.1` | Bind address. Loopback locally; the Dockerfile sets `0.0.0.0` so the API container can reach it. |
| `REDACT_CODE_IN_LOGS` | `false` | Keep the code out of *this process's* stdout (still delivered). |
| `TELEGRAM_PROXY_URL` | — | Optional outbound proxy for the Telegram hop — see below. |
@@ -101,7 +103,16 @@ The API key is the only access control — there is no IP allow-list and no TLS.
loopback when the API runs on the same machine; if you must expose it, put it behind something that
terminates TLS, or the key travels in clear text.
Values come from `.env` (git-ignored) or from real environment variables, which take precedence.
Values come from `.env` (git-ignored) or from real environment variables, which take precedence. In the
deployed stack there is no `.env` at all — the root `docker-compose.yml` supplies every variable directly
(and `.dockerignore` keeps a local `.env` out of the image, so it can't silently win).
## Running in Docker
The [`Dockerfile`](Dockerfile) here is built by the root [`docker-compose.yml`](../docker-compose.yml) as
the `otp-relay` service. Nothing is published to the host: the API reaches it as
`http://balinyaar-otp-relay:5010` over the shared `caddy_net` network, and its own hop to Telegram goes
through the proxy container on that same network. See [DEPLOY.md](../DEPLOY.md).
## Troubleshooting