feat: implement user authentication and admin management

- Add user management API endpoints for listing and creating users.
- Implement login and logout functionality with rate limiting.
- Create UI components for login form, logout button, and animated elements.
- Add session management with JWT and secure cookie handling.
- Seed initial admin user if no users exist.
- Introduce utility functions for password hashing and user authentication.
- Set up proxy middleware for route protection and security headers.
- Create a JSON file for user data storage.
- Add links configuration for external resources.
This commit is contained in:
Anders Böttcher
2026-05-12 14:58:11 +02:00
parent 50566f2a22
commit 0d58fafe4e
34 changed files with 4263 additions and 5012 deletions
+162
View File
@@ -0,0 +1,162 @@
# Setup Guide
This guide covers deploying Backerup Website with Docker, configuring authentication, and managing users.
---
## Table of Contents
1. [Environment Variables](#environment-variables)
2. [Docker Compose (recommended)](#docker-compose-recommended)
3. [Docker Run](#docker-run)
4. [Building the Image](#building-the-image)
5. [First Login](#first-login)
6. [Managing Users](#managing-users)
7. [Development Mode](#development-mode)
---
## Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
| `AUTH_SECRET` | **Yes (production)** | — | Secret used to sign session JWTs. Must be at least 32 characters. Generate with `openssl rand -base64 32`. |
| `ADMIN_PASSWORD` | First run only | — | Password for the initial `admin` account. Only used when no users exist yet. Safe to remove after first login. |
| `ADMIN_USERNAME` | No | `admin` | Username for the auto-seeded admin account. |
| `NODE_ENV` | No | `development` | Set to `production` in all deployed environments. |
| `NEXT_TELEMETRY_DISABLED` | No | — | Set to `1` to disable Next.js telemetry. |
| `PORT` | No | `3000` | Port the server listens on inside the container. |
> **Security note:** `AUTH_SECRET` is required in production. If it is missing the app will throw at startup. Auth is intentionally bypassed in development when `AUTH_SECRET` is unset so you can work without logging in.
---
## Docker Compose (recommended)
Create a `docker-compose.yml` (or copy from `docker/docker-compose.yml`) and add the auth environment variables:
```yaml
services:
backerup-website:
image: backerup-website:latest
container_name: backerup-website
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- backerup_data:/app/data
environment:
- NODE_ENV=production
- NEXT_TELEMETRY_DISABLED=1
- AUTH_SECRET=<your-random-secret-here> # required
- ADMIN_PASSWORD=<strong-password> # first run only
volumes:
backerup_data:
driver: local
```
Start the service:
```bash
docker compose up -d
```
After the first successful login you can remove `ADMIN_PASSWORD` from the compose file and restart:
```bash
docker compose up -d
```
---
## Docker Run
```bash
docker run -d \
--name backerup-website \
--restart unless-stopped \
-p 3000:3000 \
-v backerup_data:/app/data \
-e NODE_ENV=production \
-e AUTH_SECRET="$(openssl rand -base64 32)" \
-e ADMIN_PASSWORD=changeme \
backerup-website:latest
```
---
## Building the Image
From the repository root:
```bash
# Using the helper script
bash docker/build.sh
# Or directly
docker build -f docker/Dockerfile -t backerup-website:latest .
```
The Dockerfile uses a three-stage build:
1. **deps** — installs Node/Bun dependencies with a frozen lockfile
2. **builder** — runs `bun run build` (Next.js standalone output)
3. **runner** — slim `oven/bun:1-slim` image, non-root `nextjs` user, only the compiled output
---
## First Login
1. Start the container with `ADMIN_PASSWORD` set.
2. Open <http://your-host:3000/login>.
3. Sign in with username `admin` (or your `ADMIN_USERNAME`) and the password you set.
4. The account is created on the first login attempt if no users exist yet.
5. Go to **Admin → User Management** to create additional accounts.
6. Once your accounts are set up, remove `ADMIN_PASSWORD` from your environment and restart.
---
## Managing Users
The admin panel is at `/admin` and is only visible to accounts with the `admin` role.
From there you can:
- **Create users** — set a username, password (min 8 characters), and role (`user` or `admin`)
- **Reset passwords** — enter a new password in the field next to any user and click **Reset pw**
- **Delete users** — click the trash icon. You cannot delete your own account, and the last admin account cannot be deleted.
User data (hashed credentials only — no plaintext passwords) is stored in `data/users.json` inside the Docker volume.
---
## Development Mode
```bash
cd frontend
bun install
bun run dev
```
To test auth locally, pass both variables:
```bash
AUTH_SECRET="dev-secret-at-least-32-characters!!" ADMIN_PASSWORD=admin123 bun run dev
```
Then visit <http://localhost:3000/login> and sign in with `admin` / `admin123`.
---
## Data Persistence
All runtime data lives under `/app/data` in the container:
| Path | Contents |
|---|---|
| `/app/data/meta.json` | File record index (name, token, type, metadata) |
| `/app/data/users.json` | User accounts (hashed passwords only) |
| `/app/data/uploads/<token>/` | Uploaded files, organised by share token |
Mount a named Docker volume (or a host directory) to `/app/data` to persist data across container restarts and upgrades.