dependabot[bot] 214e64e996 Bump turbo in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [turbo](https://github.com/vercel/turborepo).


Updates `turbo` from 2.9.1 to 2.9.14
- [Release notes](https://github.com/vercel/turborepo/releases)
- [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md)
- [Commits](https://github.com/vercel/turborepo/compare/v2.9.1...v2.9.14)

---
updated-dependencies:
- dependency-name: turbo
  dependency-version: 2.9.14
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-28 17:51:16 +00:00
wip
2026-03-30 21:08:20 -05:00
wip
2026-03-30 21:08:20 -05:00
2026-04-27 19:36:39 -05:00
2026-04-27 20:50:16 -05:00
wip
2026-03-30 21:08:20 -05:00
wip
2026-03-30 21:08:20 -05:00
2026-04-27 17:51:37 -05:00
2026-04-27 20:50:16 -05:00
wip
2026-03-31 21:28:12 -05:00
wip
2026-03-30 21:08:20 -05:00
2026-04-27 17:51:37 -05:00
wip
2026-03-30 21:08:20 -05:00
wip
2026-03-30 21:08:20 -05:00
wip
2026-03-30 21:08:20 -05:00
2026-04-27 17:51:37 -05:00
2026-04-27 17:51:37 -05:00
wip
2026-03-30 21:08:20 -05:00
wip
2026-03-31 20:34:43 -05:00
wip
2026-03-30 21:08:20 -05:00
2026-04-27 17:51:37 -05:00
wip
2026-03-31 21:28:12 -05:00
wip
2026-03-30 21:08:20 -05:00

Stoat Admin

Stoat Admin is a lightweight self-hosted moderation and invite dashboard for a Stoat chat instance. It runs as a separate Podman Compose stack, joins the Stoat network to talk to MongoDB directly, and now ships with a dedicated admin-proxy Caddy service that terminates HTTPS for the admin stack with Caddy's internal CA.

Features

  • Single-admin login with Argon2id password hashing and SQLite-backed sessions
  • Invite creation, revocation, and acceptance tracking
  • User listing, lookup, ban, unban, and scheduled deletion actions
  • Dashboard stats for users, pending invites, and recent bans
  • pnpm workspace with Turborepo coordinating cross-package tasks
  • Example Podman Compose, s6 service directories, and GitHub Actions workflows

Project Layout

.
├── api/                  # Express + TypeScript backend
├── proxy/                # Caddy + Coraza reverse proxy image
├── web/                  # Vite + React frontend and static image build
├── deploy/s6/            # Example s6 service directories and systemd unit
├── compose.yml           # Production-oriented compose file
├── compose.override.example.yml
├── docs/                 # Design and task references
└── .env.example

Admin Setup

To create the admin user, run this command inside the admin container

node dist/seed.js --username admin --password <your-password>

Prerequisites

  • Node 22+
  • pnpm via Corepack
  • Turborepo is installed through the workspace dependencies
  • A Stoat deployment with MongoDB reachable on the shared container network
  • invite_only = true in Stoat's Revolt.toml
  • Podman or Docker-compatible compose support
  • A hostname for the admin dashboard that resolves on your WireGuard/private network
  • A way to trust Caddy's internal root CA on the admin devices that will access the dashboard

Quick Start

  1. Enable pnpm:
corepack enable
  1. Install dependencies:
pnpm install
  1. Copy the environment template and fill in the real values:
cp .env.example .env
  1. Seed the admin account from the root workspace:
pnpm seed -- --username admin --password '<strong-password>'
  1. Run both packages together through Turborepo:
pnpm dev

Useful targeted variants:

pnpm dev:api
pnpm dev:web

Configuration

Variable Description
MONGODB MongoDB connection string for the Stoat database
RESEND_API_KEY Resend API key for invite delivery
RESEND_FROM_EMAIL Sender address for invite messages
SESSION_SECRET Express session signing secret
INSTANCE_URL Public Stoat URL used in invite links
INSTANCE_NAME Human-readable instance name used in copy
ADMIN_API_PORT Listen port for admin-api
ADMIN_WEB_ORIGIN Exact HTTPS browser origin allowed by CORS
ADMIN_HOSTNAME Hostname served by the dedicated Caddy proxy
ADMIN_BIND_IP Compose bind IP for the proxy's published ports
ADMIN_HTTP_PORT Published HTTP port for redirect handling
ADMIN_HTTPS_PORT Published HTTPS port for the admin dashboard
ADMIN_WEB_API_URL Optional frontend API override outside compose

Deployment

The repo ships with a standalone compose.yml that expects an external stoat_default network. Update the network name if your Stoat stack uses a different one.

For local compose use, the proxy defaults to https://localhost:9443 and http://localhost:9080. For deployed hosts, set ADMIN_HOSTNAME to the real admin name and switch ADMIN_HTTP_PORT/ADMIN_HTTPS_PORT to 80/443 or use compose.override.example.yml as a starting point.

The deployment topology is:

  • admin-proxy is built from proxy/Dockerfile, publishes the configured HTTP and HTTPS ports, issues a private certificate from Caddy's internal CA, applies Coraza, and reverse-proxies /api/* to admin-api and everything else to admin-web.
  • admin-web and admin-api are no longer published directly on the host.
  • admin-web serves the built Vite bundle privately on the admin network.
  • admin-api stays attached to the shared Stoat network for MongoDB access and also joins a private admin network used by the proxy.

Before starting the stack, point ADMIN_HOSTNAME at the host running admin-proxy on your WireGuard/private network and set ADMIN_WEB_ORIGIN to https://<that-hostname>.

After the proxy has started once, install Caddy's root CA on each admin device before browsing to the dashboard. One way to export it is:

docker compose exec admin-proxy sh -c 'cat /data/caddy/pki/authorities/local/root.crt' > admin-proxy-root.crt

Then import admin-proxy-root.crt into the OS/browser trust store for the devices that should access the dashboard.

For supervised deployments:

  1. Install s6
  2. Copy deploy/s6/stoat and deploy/s6/stoat-admin into /etc/s6-services
  3. Adjust service paths and network names
  4. Copy deploy/s6/s6-services.service into /etc/systemd/system/
  5. Enable the unit:
sudo systemctl daemon-reload
sudo systemctl enable --now s6-services

Common operations:

s6-svc -r /etc/s6-services/stoat-admin
s6-svc -d /etc/s6-services/stoat-admin
s6-svc -u /etc/s6-services/stoat-admin
s6-svstat /etc/s6-services/stoat-admin
tail -f /var/log/s6/stoat-admin/current | s6-tai64nlocal

Development Notes

  • The backend uses SQLite for admin credentials, audit logs, and invite metadata, and MongoDB for Stoat state.
  • In the composed deployment, the frontend always uses same-origin /api requests through admin-proxy; VITE_API_URL is only useful outside compose.
  • Root task orchestration is handled by Turborepo through turbo.json.
  • The current repo state is a first implementation slice based on the design docs in docs/stoat-admin-design.md and docs/stoat-admin-tasks.md.

Contributing

Keep infrastructure-specific values out of committed files. Prefer changes that preserve the split between the standalone admin stack and the main Stoat stack.

S
Description
No description provided
Readme
205 KiB
Languages
TypeScript 86.4%
Shell 6.2%
JavaScript 3.8%
Dockerfile 1.3%
CSS 1.2%
Other 1.1%