joshuaandClaude Opus 5.5 0c0666eb40 Release 1.0.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:39:11 +02:00
2026-10-27 13:39:11 +02:00
2026-10-27 13:39:11 +02:00
2026-10-27 13:39:11 +02:00

Cross Events Hub

Joshua's central management app for every Cross Events install: customers, licences, install health and usage, and alerts. Customers never log in here.

Naming: Cross Events was called Hope Events until October 2026. Older commits, the hope-events repo name and the hel1. licence-token prefix still use the old name. The prefix is part of the protocol, so it stays.

  • backend/ — Express + Prisma (Postgres) API, port 5200
  • frontend/ — Next.js dashboard, port 3200
  • docs/hub-protocol.md — the contract with Cross Events installs (a copy lives in the hope-events repo; change both together)

Installs only ever call the Hub (register, heartbeat); the Hub never reaches into an install and holds no church data — just versions, health and aggregate counts.

Run it locally

Needs Node 20+ and Postgres.

cd backend
cp .env.example .env            # set DATABASE_URL, JWT_SECRET, HUB_ENCRYPTION_KEY
npm install
npx prisma migrate deploy && npx prisma generate
npm run generate-keys           # licence signing key → keys/hub-signing-key.pem
npm run create-admin -- --email you@example.com --name "Your Name"
npm run dev                     # http://localhost:5200

cd ../frontend
cp .env.example .env.local      # NEXT_PUBLIC_API_URL=http://localhost:5200
npm install
npm run dev                     # http://localhost:3200

The first login sets up two-factor with an authenticator app (required).

To try it with Cross Events locally, point the install at the Hub with HUB_URL=http://localhost:5200 and HUB_PUBLIC_KEY (the public key shown in Hub → Settings) in Cross Events' backend/.env.

The licence signing key

Licences are tokens signed with an Ed25519 key. The private key exists only on the Hub server; installs check licences with the public key, which is built into Cross Events (backend/src/hub/publicKey.js).

  • Create the production key once, on the Hub server: npm run generate-keys. Back up keys/hub-signing-key.pem somewhere safe and offline.
  • Put the public key it prints into Cross Events (backend/src/hub/publicKey.js) and release.
  • Losing or replacing the key means every install needs a Cross Events update with the new public key before it can trust new licences — so don't.
  • HUB_ENCRYPTION_KEY encrypts install secrets: it must never change after installs register.

Deploying

Same pattern as Cross Events: on the server (events-hub.crosscode.co.za), behind nginx with HTTPS, two PM2 processes (backend: npm start; frontend: npm run build && npm start), TRUST_PROXY=1, FRONTEND_URL=https://events-hub.crosscode.co.za, and the frontend's NEXT_PUBLIC_API_URL set to the public API address (e.g. https://events-hub.crosscode.co.za with nginx routing /api to port 5200). Back up the database daily, plus the signing key.

Tests

cd backend && npm test — encryption, licence tokens, request signatures, two-factor codes (RFC 6238 vector) and alert rules.

S
Description
No description provided
Readme
1.7 MiB
Languages
JavaScript 50.9%
TypeScript 46.4%
Shell 2.3%
CSS 0.4%