75146847f6
Self-hosters can now run: ./solitaire_server --reset-password <username> to update a player's password and invalidate all their refresh tokens (forcing re-login on every device). Password is read from stdin so it can be piped from scripts or a password manager without appearing in shell history. Implementation: - reset_password() in auth.rs: validates length, bcrypt-hashes new password, updates users.password_hash, deletes all refresh_tokens rows for the user. - main.rs: --reset-password dispatch before HTTP server startup; JWT_SECRET not required for this path. - 4 integration tests covering: login works after reset, old password rejected, refresh tokens invalidated, unknown user → NotFound, short password → BadRequest. - README_SERVER.md: admin password-reset section with examples. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2.0 KiB
2.0 KiB
Solitaire Quest — Self-Hosting Guide
Prerequisites
- Docker and Docker Compose
opensslfor generating a JWT secret
Quick start
- Clone the repo and enter it.
- Copy the example environment file and fill in your values:
cp .env.example .env # Edit .env: set JWT_SECRET and SOLITAIRE_DOMAIN - (First time only) Generate the sqlx query cache so the server builds without a live database:
cargo install sqlx-cli --no-default-features --features rustls,sqlite export DATABASE_URL=sqlite://solitaire.db sqlx database create sqlx migrate run --source solitaire_server/migrations cargo sqlx prepare --workspace rm solitaire.db # the real DB lives in ./data/ at runtime - Start everything:
docker compose up -d - The server is now reachable at
https://<SOLITAIRE_DOMAIN>.
Backups
The entire server state is one SQLite file at ./data/solitaire.db. Back it up with:
sqlite3 ./data/solitaire.db ".backup backup_$(date +%Y%m%d).db"
Updating
git pull
docker compose build
docker compose up -d
Admin — Password Reset
If a player loses access to their account, the server binary includes a
built-in password reset command. Run it on the host (or inside the container)
with DATABASE_URL pointing at your database:
# Interactive (prompts for the new password):
DATABASE_URL=sqlite://./data/solitaire.db \
./solitaire_server --reset-password <username>
# Non-interactive (piped from a script or password manager):
echo "new_password" | \
DATABASE_URL=sqlite://./data/solitaire.db \
./solitaire_server --reset-password <username>
# Inside a running Docker container:
docker compose exec server sh -c \
'echo "new_password" | ./solitaire_server --reset-password alice'
On success the user's password_hash is updated and all active refresh
tokens are deleted, so every open session must log in again with the new
password. JWT_SECRET does not need to be set for this command.