montana/Russian/Site/messenger-backend
2026-05-18 18:05:32 +03:00
..
.env.example sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
app.py sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
montana-messenger.service sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
nginx-:8442.conf sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
nginx-snippet.conf sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
peers.frankfurt.json sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
peers.helsinki.json sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
peers.moscow.json sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
peers.newyork.json sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
README.md sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
requirements.txt sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00
schema.sql sync 2026-05-18T15:05:32Z 2026-05-18 18:05:32 +03:00

Montana Messenger Relay

Federated relay backend for Montana Messenger (montana.quest/messenger).

Stack

  • Flask 3 + gunicorn
  • PostgreSQL (table: accounts, sessions, messages)
  • PyNaCl for ed25519 signature verify
  • Listens on 127.0.0.1:5010 (proxied by nginx at /messenger/api/)

Setup (on montana-moscow)

# 1. PostgreSQL
sudo -u postgres createuser -P montana
sudo -u postgres createdb -O montana montana_messenger
sudo -u postgres psql montana_messenger < /opt/app/messenger/schema.sql

# 2. Virtualenv
cd /opt/app/messenger
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

# 3. .env
cp .env.example .env  # отредактировать DSN с реальным паролем

# 4. systemd
sudo cp montana-messenger.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now montana-messenger
sudo systemctl status montana-messenger

# 5. nginx
sudo cat nginx-snippet.conf
# скопировать содержимое в /etc/nginx/sites-available/montana_quest перед "location /"
sudo nginx -t && sudo systemctl reload nginx

API

  • POST /api/auth/challenge body {accountId}{challengeId, challenge, expiresAt}
  • POST /api/auth/verify body {accountId, challengeId, signature}{sessionToken, accountId, expiresAt}
  • POST /api/msg/send body {recipient, ciphertext, nonce} (Bearer) → {msgId, createdAt}
  • GET /api/msg/inbox?since=<ms> (Bearer) → {messages: [...]}
  • GET /api/msg/contacts (Bearer) → {contacts: [...]}
  • POST /api/msg/read body {msgIds} (Bearer) → {ok}
  • GET /api/health → liveness