mirror of
https://github.com/temetro/temetro.git
synced 2026-07-26 20:08:14 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 01dbc07e92 |
+14
-1
@@ -7,7 +7,20 @@ for how releases are cut and published.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.8.1] — 2026-07-05
|
||||
## [0.8.2] — 2026-07-05
|
||||
|
||||
### Fixed
|
||||
- **`RELAY_URL` now defaults to the hosted relay** (`https://network.temetro.com`) instead of
|
||||
`http://localhost:8080`. The old default silently failed for anyone who joined the network without
|
||||
explicitly setting `RELAY_URL` — the backend's hub connection could never reach the relay (inside
|
||||
Docker `localhost` is the container itself), so it never authenticated and QR pairing generated a
|
||||
QR pointing at an unreachable `localhost`. Self-hosters running their own relay still override
|
||||
`RELAY_URL`. Updated `.env.example` accordingly.
|
||||
|
||||
### Changed
|
||||
- Generating a pairing QR (`POST /api/patients/wallet/pair`) now ensures the clinic's relay hub is
|
||||
connected before pre-registering the request, so the routing is set up even if the connection was
|
||||
opened lazily.
|
||||
|
||||
### Fixed
|
||||
- **QR "scan to connect" pairing** was broken by the multi-clinic relay routing (v0.8.0): pairing
|
||||
|
||||
@@ -40,7 +40,11 @@ FRONTEND_PORT=3000
|
||||
# /hub with its own Ed25519 signing key, so no shared secret is needed.
|
||||
# RELAY_TOKEN is OPTIONAL/LEGACY — set it only for a private relay that also
|
||||
# gates on a shared token (then use the SAME value here and on the relay).
|
||||
RELAY_URL=http://localhost:8080
|
||||
# Defaults to the hosted relay (https://network.temetro.com) when unset, so
|
||||
# "Join Temetro Network" works out of the box; set RELAY_URL only to point at
|
||||
# your own relay. Do NOT use http://localhost — inside Docker that's the
|
||||
# container itself and the relay connection will silently fail.
|
||||
RELAY_URL=https://network.temetro.com
|
||||
RELAY_TOKEN=
|
||||
|
||||
# (Legacy, pre-relay self-hosting.) A phone-reachable URL for the QR when NOT
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "temetro-backend",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.2",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "temetro backend — Express + Postgres API with Better Auth (email/password, organizations) and org-scoped patient records.",
|
||||
|
||||
+5
-1
@@ -35,7 +35,11 @@ const schema = z.object({
|
||||
// its own Ed25519 signing key, so no shared secret is needed. RELAY_TOKEN is
|
||||
// now *optional/legacy* — set it only for a private relay that also gates on a
|
||||
// shared token (must then match the relay's RELAY_TOKEN).
|
||||
RELAY_URL: z.string().min(1).default("http://localhost:8080"),
|
||||
//
|
||||
// Defaults to the hosted relay so "Join Temetro Network" works out of the box;
|
||||
// override only when running your own relay. (A `localhost` default silently
|
||||
// fails inside Docker, where localhost is the container itself.)
|
||||
RELAY_URL: z.string().min(1).default("https://network.temetro.com"),
|
||||
RELAY_TOKEN: z.string().default(""),
|
||||
// Public, device-reachable URL of this backend's wallet relay, baked into the
|
||||
// QR a patient scans. Optional — when unset we derive it from the request host
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from "../middleware/auth.js";
|
||||
import { emitToWallet } from "../realtime.js";
|
||||
import { recordActivity } from "../services/activity.js";
|
||||
import { expectResponse } from "../services/relay-client.js";
|
||||
import { connectOrg, expectResponse } from "../services/relay-client.js";
|
||||
import * as patientService from "../services/patients.js";
|
||||
import { awaitQuickTunnelUrl } from "../services/relay-url.js";
|
||||
import { getNetworkEnabled } from "../services/signing.js";
|
||||
@@ -95,6 +95,9 @@ patientsWalletRouter.post(
|
||||
);
|
||||
// No wallet number to `wallet:send` to yet, so pre-register the request id
|
||||
// with the relay so the scanning device's response routes back to us.
|
||||
// Ensure the hub is (re)connected first; if it's still mid-handshake the
|
||||
// on-auth re-registration of pending requests will catch this one.
|
||||
await connectOrg(req.organizationId!);
|
||||
expectResponse(req.organizationId!, view.id);
|
||||
res.status(201).json({
|
||||
...view,
|
||||
|
||||
@@ -49,7 +49,9 @@ export function expectResponse(orgId: string, requestId: string): void {
|
||||
}
|
||||
|
||||
// Open (and authenticate) a hub connection for a clinic, if not already open.
|
||||
// Idempotent — safe to call on startup and again when an org joins the network.
|
||||
// Idempotent — safe to call on startup, when an org joins the network, and
|
||||
// before generating a pairing QR. The socket auto-reconnects on its own, so an
|
||||
// existing entry is left as-is.
|
||||
export async function connectOrg(orgId: string): Promise<void> {
|
||||
if (hubs.has(orgId)) return;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "temetro",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.2",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"shadcn": "^4.11.0"
|
||||
|
||||
Reference in New Issue
Block a user