Phase 1 done
This commit is contained in:
parent
5cdafc7a4d
commit
9a3fc97a34
14 changed files with 496 additions and 33 deletions
34
.env.example
Normal file
34
.env.example
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# ==============================================================================
|
||||||
|
# REQUIRED - Generate with: openssl rand -base64 36 | tr -d '\n'
|
||||||
|
# ==============================================================================
|
||||||
|
PG_PASS=
|
||||||
|
AUTHENTIK_SECRET_KEY=
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# OPTIONAL - Authentik Database
|
||||||
|
# ==============================================================================
|
||||||
|
PG_USER=authentik
|
||||||
|
PG_DB=authentik
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# OPTIONAL - Ports
|
||||||
|
# ==============================================================================
|
||||||
|
AUTHENTIK_PORT_HTTP=9000
|
||||||
|
AUTHENTIK_PORT_HTTPS=9443
|
||||||
|
KABOOT_BACKEND_PORT=3001
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# OPTIONAL - Authentik Settings
|
||||||
|
# ==============================================================================
|
||||||
|
AUTHENTIK_ERROR_REPORTING=false
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# OPTIONAL - OIDC (Override if using custom domain)
|
||||||
|
# ==============================================================================
|
||||||
|
OIDC_ISSUER=http://localhost:9000/application/o/kaboot/
|
||||||
|
OIDC_JWKS_URI=http://localhost:9000/application/o/kaboot/jwks/
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# OPTIONAL - CORS (Frontend origin for backend API)
|
||||||
|
# ==============================================================================
|
||||||
|
CORS_ORIGIN=http://localhost:5173
|
||||||
15
.gitignore
vendored
15
.gitignore
vendored
|
|
@ -22,3 +22,18 @@ dist-ssr
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
# Environment secrets
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Authentik volumes (keep structure, ignore data)
|
||||||
|
authentik/media/*
|
||||||
|
!authentik/media/.gitkeep
|
||||||
|
authentik/certs/*
|
||||||
|
!authentik/certs/.gitkeep
|
||||||
|
|
||||||
|
# Backend data
|
||||||
|
server/data/
|
||||||
|
*.db
|
||||||
|
|
|
||||||
|
|
@ -31,40 +31,40 @@ Add user accounts via Authentik (OIDC) and persist quizzes to SQLite database. U
|
||||||
## Phase 1: Infrastructure Setup
|
## Phase 1: Infrastructure Setup
|
||||||
|
|
||||||
### 1.1 Docker Compose Configuration
|
### 1.1 Docker Compose Configuration
|
||||||
- [ ] Create `docker-compose.yml` with all services:
|
- [x] Create `docker-compose.yml` with all services:
|
||||||
- [ ] PostgreSQL (Authentik database)
|
- [x] PostgreSQL (Authentik database)
|
||||||
- [ ] Redis (Authentik cache)
|
- [x] Redis (Authentik cache)
|
||||||
- [ ] Authentik server
|
- [x] Authentik server
|
||||||
- [ ] Authentik worker
|
- [x] Authentik worker
|
||||||
- [ ] Kaboot backend service
|
- [x] Kaboot backend service
|
||||||
- [ ] Create `.env.example` with required variables:
|
- [x] Create `.env.example` with required variables:
|
||||||
- [ ] `PG_PASS` - PostgreSQL password
|
- [x] `PG_PASS` - PostgreSQL password
|
||||||
- [ ] `AUTHENTIK_SECRET_KEY` - Authentik secret
|
- [x] `AUTHENTIK_SECRET_KEY` - Authentik secret
|
||||||
- [ ] `PG_USER`, `PG_DB` - Optional customization
|
- [x] `PG_USER`, `PG_DB` - Optional customization
|
||||||
- [ ] Create setup script to generate secrets (`scripts/setup.sh`)
|
- [x] Create setup script to generate secrets (`scripts/setup.sh`)
|
||||||
- [ ] Add `authentik/` directory structure for volumes:
|
- [x] Add `authentik/` directory structure for volumes:
|
||||||
- [ ] `authentik/media/`
|
- [x] `authentik/media/`
|
||||||
- [ ] `authentik/certs/`
|
- [x] `authentik/certs/`
|
||||||
- [ ] `authentik/custom-templates/`
|
- [x] `authentik/custom-templates/`
|
||||||
- [ ] Update `.gitignore` for new files:
|
- [x] Update `.gitignore` for new files:
|
||||||
- [ ] `.env`
|
- [x] `.env`
|
||||||
- [ ] `authentik/media/*`
|
- [x] `authentik/media/*`
|
||||||
- [ ] `authentik/certs/*`
|
- [x] `authentik/certs/*`
|
||||||
- [ ] `server/data/`
|
- [x] `server/data/`
|
||||||
|
|
||||||
### 1.2 Authentik Configuration Documentation
|
### 1.2 Authentik Configuration Documentation
|
||||||
- [ ] Document initial setup steps in `docs/AUTHENTIK_SETUP.md`:
|
- [x] Document initial setup steps in `docs/AUTHENTIK_SETUP.md`:
|
||||||
- [ ] Navigate to `http://localhost:9000/if/flow/initial-setup/`
|
- [x] Navigate to `http://localhost:9000/if/flow/initial-setup/`
|
||||||
- [ ] Create admin account
|
- [x] Create admin account
|
||||||
- [ ] Create OAuth2/OIDC Application + Provider:
|
- [x] Create OAuth2/OIDC Application + Provider:
|
||||||
- [ ] Application name: `Kaboot`
|
- [x] Application name: `Kaboot`
|
||||||
- [ ] Application slug: `kaboot`
|
- [x] Application slug: `kaboot`
|
||||||
- [ ] Provider type: `OAuth2/OIDC`
|
- [x] Provider type: `OAuth2/OIDC`
|
||||||
- [ ] Client type: `Public` (SPA with PKCE)
|
- [x] Client type: `Public` (SPA with PKCE)
|
||||||
- [ ] Client ID: `kaboot-spa`
|
- [x] Client ID: `kaboot-spa`
|
||||||
- [ ] Redirect URIs: `http://localhost:5173/callback`, `http://localhost:5173/silent-renew.html`
|
- [x] Redirect URIs: `http://localhost:5173/callback`, `http://localhost:5173/silent-renew.html`
|
||||||
- [ ] Scopes: `openid`, `profile`, `email`, `offline_access`
|
- [x] Scopes: `openid`, `profile`, `email`, `offline_access`
|
||||||
- [ ] Note down OIDC endpoints (issuer, JWKS URI, etc.)
|
- [x] Note down OIDC endpoints (issuer, JWKS URI, etc.)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -400,7 +400,7 @@ kaboot/
|
||||||
|
|
||||||
| Phase | Status | Notes |
|
| Phase | Status | Notes |
|
||||||
|-------|--------|-------|
|
|-------|--------|-------|
|
||||||
| Phase 1 | Not Started | |
|
| Phase 1 | **COMPLETE** | Docker Compose, .env, setup script, Authentik docs |
|
||||||
| Phase 2 | Not Started | |
|
| Phase 2 | Not Started | |
|
||||||
| Phase 3 | Not Started | |
|
| Phase 3 | Not Started | |
|
||||||
| Phase 4 | Not Started | |
|
| Phase 4 | Not Started | |
|
||||||
|
|
|
||||||
0
authentik/certs/.gitkeep
Normal file
0
authentik/certs/.gitkeep
Normal file
0
authentik/custom-templates/.gitkeep
Normal file
0
authentik/custom-templates/.gitkeep
Normal file
0
authentik/media/.gitkeep
Normal file
0
authentik/media/.gitkeep
Normal file
129
docker-compose.yml
Normal file
129
docker-compose.yml
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
services:
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
# AUTHENTIK - Identity Provider
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
image: docker.io/library/postgres:16-alpine
|
||||||
|
container_name: kaboot-postgresql
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
||||||
|
start_period: 20s
|
||||||
|
interval: 30s
|
||||||
|
retries: 5
|
||||||
|
timeout: 5s
|
||||||
|
volumes:
|
||||||
|
- postgresql-data:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
|
||||||
|
POSTGRES_USER: ${PG_USER:-authentik}
|
||||||
|
POSTGRES_DB: ${PG_DB:-authentik}
|
||||||
|
networks:
|
||||||
|
- kaboot-network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: docker.io/library/redis:alpine
|
||||||
|
container_name: kaboot-redis
|
||||||
|
command: --save 60 1 --loglevel warning
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||||
|
start_period: 20s
|
||||||
|
interval: 30s
|
||||||
|
retries: 5
|
||||||
|
timeout: 3s
|
||||||
|
volumes:
|
||||||
|
- redis-data:/data
|
||||||
|
networks:
|
||||||
|
- kaboot-network
|
||||||
|
|
||||||
|
authentik-server:
|
||||||
|
image: ghcr.io/goauthentik/server:2025.2
|
||||||
|
container_name: kaboot-authentik-server
|
||||||
|
restart: unless-stopped
|
||||||
|
command: server
|
||||||
|
environment:
|
||||||
|
AUTHENTIK_REDIS__HOST: redis
|
||||||
|
AUTHENTIK_POSTGRESQL__HOST: postgresql
|
||||||
|
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
|
||||||
|
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
|
||||||
|
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||||
|
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?authentik secret key required}
|
||||||
|
AUTHENTIK_ERROR_REPORTING__ENABLED: ${AUTHENTIK_ERROR_REPORTING:-false}
|
||||||
|
volumes:
|
||||||
|
- ./authentik/media:/media
|
||||||
|
- ./authentik/custom-templates:/templates
|
||||||
|
ports:
|
||||||
|
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
|
||||||
|
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
|
||||||
|
depends_on:
|
||||||
|
postgresql:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- kaboot-network
|
||||||
|
|
||||||
|
authentik-worker:
|
||||||
|
image: ghcr.io/goauthentik/server:2025.2
|
||||||
|
container_name: kaboot-authentik-worker
|
||||||
|
restart: unless-stopped
|
||||||
|
command: worker
|
||||||
|
environment:
|
||||||
|
AUTHENTIK_REDIS__HOST: redis
|
||||||
|
AUTHENTIK_POSTGRESQL__HOST: postgresql
|
||||||
|
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
|
||||||
|
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
|
||||||
|
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||||
|
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
|
||||||
|
user: root
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./authentik/media:/media
|
||||||
|
- ./authentik/certs:/certs
|
||||||
|
- ./authentik/custom-templates:/templates
|
||||||
|
depends_on:
|
||||||
|
postgresql:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- kaboot-network
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
# KABOOT - Application Backend
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
kaboot-backend:
|
||||||
|
build:
|
||||||
|
context: ./server
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: kaboot-backend
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: 3001
|
||||||
|
DATABASE_PATH: /data/kaboot.db
|
||||||
|
# OIDC Configuration - points to Authentik
|
||||||
|
OIDC_ISSUER: ${OIDC_ISSUER:-http://authentik-server:9000/application/o/kaboot/}
|
||||||
|
OIDC_JWKS_URI: ${OIDC_JWKS_URI:-http://authentik-server:9000/application/o/kaboot/jwks/}
|
||||||
|
# CORS - allow frontend origin
|
||||||
|
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:5173}
|
||||||
|
volumes:
|
||||||
|
- kaboot-data:/data
|
||||||
|
ports:
|
||||||
|
- "${KABOOT_BACKEND_PORT:-3001}:3001"
|
||||||
|
depends_on:
|
||||||
|
- authentik-server
|
||||||
|
networks:
|
||||||
|
- kaboot-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgresql-data:
|
||||||
|
redis-data:
|
||||||
|
kaboot-data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
kaboot-network:
|
||||||
|
driver: bridge
|
||||||
159
docs/AUTHENTIK_SETUP.md
Normal file
159
docs/AUTHENTIK_SETUP.md
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
# Authentik Setup Guide for Kaboot
|
||||||
|
|
||||||
|
This guide walks through configuring Authentik as the OAuth2/OIDC identity provider for Kaboot.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Docker and Docker Compose installed
|
||||||
|
- Kaboot stack running (`docker compose up -d`)
|
||||||
|
- Access to `http://localhost:9000`
|
||||||
|
|
||||||
|
## Step 1: Initial Authentik Setup
|
||||||
|
|
||||||
|
1. Navigate to `http://localhost:9000/if/flow/initial-setup/`
|
||||||
|
- **Important**: Include the trailing slash `/`
|
||||||
|
|
||||||
|
2. Create the admin account:
|
||||||
|
- Email: Your email address
|
||||||
|
- Password: Choose a strong password
|
||||||
|
|
||||||
|
3. Log in with the credentials you just created
|
||||||
|
|
||||||
|
## Step 2: Create the Kaboot Application
|
||||||
|
|
||||||
|
1. In the Authentik admin interface, go to **Applications** > **Applications**
|
||||||
|
|
||||||
|
2. Click **Create with provider**
|
||||||
|
|
||||||
|
3. **Application Settings**:
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| Name | `Kaboot` |
|
||||||
|
| Slug | `kaboot` |
|
||||||
|
| Launch URL | `http://localhost:5173` |
|
||||||
|
|
||||||
|
4. Click **Next**
|
||||||
|
|
||||||
|
## Step 3: Configure OAuth2/OIDC Provider
|
||||||
|
|
||||||
|
1. Select **OAuth2/OIDC** as the Provider Type
|
||||||
|
|
||||||
|
2. Click **Next**
|
||||||
|
|
||||||
|
3. **Provider Configuration**:
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| Name | `Kaboot OAuth2` |
|
||||||
|
| Authorization flow | `default-provider-authorization-implicit-consent` |
|
||||||
|
| Client type | `Public` |
|
||||||
|
| Client ID | `kaboot-spa` |
|
||||||
|
|
||||||
|
4. **Redirect URIs** (one per line):
|
||||||
|
```
|
||||||
|
http://localhost:5173/callback
|
||||||
|
http://localhost:5173/silent-renew.html
|
||||||
|
http://localhost:5173
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Advanced Settings**:
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| Subject mode | `Based on the User's hashed ID` |
|
||||||
|
| Include claims in id_token | `Yes` |
|
||||||
|
| Issuer mode | `Each provider has a different issuer` |
|
||||||
|
|
||||||
|
6. **Scopes** - Ensure these are selected:
|
||||||
|
- `openid`
|
||||||
|
- `profile`
|
||||||
|
- `email`
|
||||||
|
- `offline_access` (for refresh tokens)
|
||||||
|
|
||||||
|
7. Click **Submit**
|
||||||
|
|
||||||
|
## Step 4: Verify OIDC Endpoints
|
||||||
|
|
||||||
|
After creation, go to **Applications** > **Providers** > **Kaboot OAuth2**
|
||||||
|
|
||||||
|
Note these endpoints (you'll need them for frontend configuration):
|
||||||
|
|
||||||
|
| Endpoint | URL |
|
||||||
|
|----------|-----|
|
||||||
|
| Issuer | `http://localhost:9000/application/o/kaboot/` |
|
||||||
|
| Authorization | `http://localhost:9000/application/o/authorize/` |
|
||||||
|
| Token | `http://localhost:9000/application/o/token/` |
|
||||||
|
| UserInfo | `http://localhost:9000/application/o/userinfo/` |
|
||||||
|
| JWKS | `http://localhost:9000/application/o/kaboot/jwks/` |
|
||||||
|
|
||||||
|
## Step 5: Test the Configuration
|
||||||
|
|
||||||
|
1. Open the OpenID Configuration URL in your browser:
|
||||||
|
```
|
||||||
|
http://localhost:9000/application/o/kaboot/.well-known/openid-configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
2. You should see a JSON response with all OIDC endpoints
|
||||||
|
|
||||||
|
## Step 6: Create a Test User (Optional)
|
||||||
|
|
||||||
|
1. Go to **Directory** > **Users**
|
||||||
|
|
||||||
|
2. Click **Create**
|
||||||
|
|
||||||
|
3. Fill in user details:
|
||||||
|
- Username: `testuser`
|
||||||
|
- Name: `Test User`
|
||||||
|
- Email: `test@example.com`
|
||||||
|
|
||||||
|
4. After creation, click on the user and go to the **Credentials** tab
|
||||||
|
|
||||||
|
5. Click **Set password** to create a password
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
Ensure your `.env` file has the correct OIDC configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
OIDC_ISSUER=http://localhost:9000/application/o/kaboot/
|
||||||
|
OIDC_JWKS_URI=http://localhost:9000/application/o/kaboot/jwks/
|
||||||
|
```
|
||||||
|
|
||||||
|
For the frontend OIDC config (`src/config/oidc.ts`):
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export const oidcConfig = {
|
||||||
|
authority: 'http://localhost:9000/application/o/kaboot/',
|
||||||
|
client_id: 'kaboot-spa',
|
||||||
|
redirect_uri: `${window.location.origin}/callback`,
|
||||||
|
// ... rest of config
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "Invalid redirect URI" error
|
||||||
|
- Ensure all redirect URIs are added exactly as configured in the provider
|
||||||
|
- Check for trailing slashes - they must match exactly
|
||||||
|
|
||||||
|
### "Client not found" error
|
||||||
|
- Verify the Client ID matches `kaboot-spa`
|
||||||
|
- Ensure the application is enabled (not archived)
|
||||||
|
|
||||||
|
### CORS errors
|
||||||
|
- Authentik handles CORS automatically for configured redirect URIs
|
||||||
|
- Ensure your frontend origin (`http://localhost:5173`) is in the redirect URIs
|
||||||
|
|
||||||
|
### Token validation fails on backend
|
||||||
|
- Verify `OIDC_ISSUER` and `OIDC_JWKS_URI` are correct
|
||||||
|
- The backend must be able to reach Authentik at `http://authentik-server:9000` (Docker network)
|
||||||
|
|
||||||
|
## Production Notes
|
||||||
|
|
||||||
|
For production deployment:
|
||||||
|
|
||||||
|
1. Use HTTPS everywhere
|
||||||
|
2. Update all URLs from `localhost` to your domain
|
||||||
|
3. Update redirect URIs in Authentik
|
||||||
|
4. Update frontend OIDC config with production URLs
|
||||||
|
5. Update `.env` with production OIDC endpoints
|
||||||
|
6. Consider enabling Authentik error reporting
|
||||||
|
7. Configure email settings in Authentik for password recovery
|
||||||
4
features.md
Normal file
4
features.md
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
- [ ] All data stored in sqlite db.
|
||||||
|
- [ ] AI generated content based on document upload
|
||||||
|
- [ ] Moderation (kick player, lock game, filter names)
|
||||||
|
- [ ] Persistent game urls while game is active
|
||||||
48
scripts/setup.sh
Executable file
48
scripts/setup.sh
Executable file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ENV_FILE=".env"
|
||||||
|
ENV_EXAMPLE=".env.example"
|
||||||
|
|
||||||
|
echo "Kaboot Setup Script"
|
||||||
|
echo "==================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ -f "$ENV_FILE" ]; then
|
||||||
|
read -p ".env file already exists. Overwrite? (y/N): " -n 1 -r
|
||||||
|
echo ""
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Aborting. Existing .env file preserved."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ENV_EXAMPLE" ]; then
|
||||||
|
echo "Error: .env.example not found. Run this script from the project root."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Generating secrets..."
|
||||||
|
|
||||||
|
PG_PASS=$(openssl rand -base64 36 | tr -d '\n')
|
||||||
|
AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')
|
||||||
|
|
||||||
|
cp "$ENV_EXAMPLE" "$ENV_FILE"
|
||||||
|
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
sed -i '' "s|^PG_PASS=.*|PG_PASS=${PG_PASS}|" "$ENV_FILE"
|
||||||
|
sed -i '' "s|^AUTHENTIK_SECRET_KEY=.*|AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}|" "$ENV_FILE"
|
||||||
|
else
|
||||||
|
sed -i "s|^PG_PASS=.*|PG_PASS=${PG_PASS}|" "$ENV_FILE"
|
||||||
|
sed -i "s|^AUTHENTIK_SECRET_KEY=.*|AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}|" "$ENV_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Created .env file with generated secrets."
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Review .env and adjust settings if needed"
|
||||||
|
echo " 2. Run: docker compose up -d"
|
||||||
|
echo " 3. Open: http://localhost:9000/if/flow/initial-setup/"
|
||||||
|
echo " 4. Follow docs/AUTHENTIK_SETUP.md to configure the OAuth2 provider"
|
||||||
|
echo ""
|
||||||
15
server/Dockerfile
Normal file
15
server/Dockerfile
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
FROM node:22-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk add --no-cache python3 make g++
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
EXPOSE 3001
|
||||||
|
|
||||||
|
CMD ["npm", "start"]
|
||||||
28
server/package.json
Normal file
28
server/package.json
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "kaboot-backend",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "tsx watch src/index.ts",
|
||||||
|
"build": "tsc",
|
||||||
|
"start": "node dist/index.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"better-sqlite3": "^11.7.0",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^4.21.2",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"jwks-rsa": "^3.1.0",
|
||||||
|
"uuid": "^11.0.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/better-sqlite3": "^7.6.12",
|
||||||
|
"@types/cors": "^2.8.17",
|
||||||
|
"@types/express": "^5.0.0",
|
||||||
|
"@types/jsonwebtoken": "^9.0.7",
|
||||||
|
"@types/node": "^22.10.7",
|
||||||
|
"@types/uuid": "^10.0.0",
|
||||||
|
"tsx": "^4.19.2",
|
||||||
|
"typescript": "^5.7.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
16
server/src/index.ts
Normal file
16
server/src/index.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import express from 'express';
|
||||||
|
import cors from 'cors';
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const PORT = process.env.PORT || 3001;
|
||||||
|
|
||||||
|
app.use(cors({ origin: process.env.CORS_ORIGIN || 'http://localhost:5173' }));
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
app.get('/health', (_req, res) => {
|
||||||
|
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(PORT, () => {
|
||||||
|
console.log(`Kaboot backend running on port ${PORT}`);
|
||||||
|
});
|
||||||
15
server/tsconfig.json
Normal file
15
server/tsconfig.json
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src",
|
||||||
|
"declaration": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue