1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
"""Hub info endpoints — /v1/hub/*"""
from fastapi import APIRouter
from meshbay_common import MNP_VERSION, MHP_VERSION
from meshbay_hub import __version__
from meshbay_hub.auth import hub_public_key_pem
from meshbay_hub.db.engine import get_engine
router = APIRouter(prefix="/v1/hub", tags=["hub"])
@router.get("/info")
async def hub_info():
engine = get_engine()
return {
"hub_version": __version__,
"mnp_version": MNP_VERSION,
"mhp_version": MHP_VERSION,
"db_dialect": engine.dialect.name,
}
@router.get("/pubkey")
async def hub_pubkey():
"""Hub Ed25519 public key PEM — cached by nodes on first contact."""
return {"pk_hub_pem": hub_public_key_pem().decode()}
# What an installed client must be, to talk to this hub.
#
# Until a client ships, the SPA and the hub deploy together and are always in
# sync: a /v1/ response shape changes and app.js is fixed in the same commit.
# The moment the interface is installed rather than served, an old client meets
# a new hub — for the first time in this project's life — and there is no way to
# fix it from here.
#
# `minimum` refuses; `recommended` warns. Both are stated so a client can tell a
# user "update to keep using this" before it becomes "this stopped working".
# Raise `minimum` only for a change a client genuinely cannot survive, and
# remember store review latency makes that expensive on Android.
MIN_CLIENT_VERSION = "0.1.0"
RECOMMENDED_CLIENT_VERSION = "0.1.0"
@router.get("/version")
async def hub_version():
"""Version check endpoint for clients to detect updates."""
return {
"hub": __version__,
"mnp": MNP_VERSION,
"mhp": MHP_VERSION,
# A client compares its own version against these before doing anything
# else. The browser SPA always matches the hub by construction and can
# ignore them.
"client": {
"minimum": MIN_CLIENT_VERSION,
"recommended": RECOMMENDED_CLIENT_VERSION,
},
}
|