Add cors stuff

This commit is contained in:
Joey Yakimowich-Payne 2026-01-14 19:44:13 -07:00
commit 9363f643f0
No known key found for this signature in database
GPG key ID: 6BFE655FA5ABD1E1
10 changed files with 116 additions and 49 deletions

View file

@ -4,6 +4,14 @@
PG_PASS= PG_PASS=
AUTHENTIK_SECRET_KEY= AUTHENTIK_SECRET_KEY=
# ==============================================================================
# HOST CONFIGURATION
# Set this to your machine's IP or domain for mobile/network access
# Examples: localhost, 192.168.1.100, kaboot.example.com
# ==============================================================================
KABOOT_HOST=localhost
KABOOT_FRONTEND_PORT=5173
# ============================================================================== # ==============================================================================
# OPTIONAL - Authentik Database # OPTIONAL - Authentik Database
# ============================================================================== # ==============================================================================
@ -29,17 +37,6 @@ AUTHENTIK_ERROR_REPORTING=false
AUTHENTIK_BOOTSTRAP_PASSWORD= AUTHENTIK_BOOTSTRAP_PASSWORD=
AUTHENTIK_BOOTSTRAP_TOKEN= AUTHENTIK_BOOTSTRAP_TOKEN=
# ==============================================================================
# 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
# ============================================================================== # ==============================================================================
# OPTIONAL - Logging # OPTIONAL - Logging
# ============================================================================== # ==============================================================================

View file

@ -83,16 +83,35 @@ If you want to run the frontend in development mode with hot-reloading:
``` ```
The frontend will be available at `http://localhost:5173`. The frontend will be available at `http://localhost:5173`.
### Mobile/Network Access
To access the dev server from other devices (phones, tablets):
1. **Run setup script** - it auto-detects your IP:
```bash
./scripts/setup.sh
```
2. **Update Authentik redirect URIs** to include your IP (e.g., `http://192.168.1.100:5173/callback`)
3. **Start dev server with host binding**:
```bash
npm run dev -- --host
```
4. **Access from mobile** via `http://<your-ip>:5173`
## Configuration ## Configuration
Kaboot uses environment variables for configuration. Refer to `.env.example` for a complete list. Kaboot uses environment variables for configuration. Refer to `.env.example` for a complete list.
| Variable | Description | Default | | Variable | Description | Default |
|----------|-------------|---------| |----------|-------------|---------|
| `KABOOT_HOST` | Host IP/domain for network access | `localhost` |
| `KABOOT_FRONTEND_PORT` | Port for the frontend dev server | `5173` |
| `KABOOT_BACKEND_PORT` | Port for the Express backend | `3001` | | `KABOOT_BACKEND_PORT` | Port for the Express backend | `3001` |
| `AUTHENTIK_PORT_HTTP` | Port for Authentik web interface | `9000` | | `AUTHENTIK_PORT_HTTP` | Port for Authentik web interface | `9000` |
| `GEMINI_API_KEY` | Your Google Gemini API key | (Required) | | `GEMINI_API_KEY` | Your Google Gemini API key | (Required) |
| `CORS_ORIGIN` | Allowed origin for API requests | `http://localhost:5173` |
| `PG_PASS` | PostgreSQL password for Authentik | (Generated) | | `PG_PASS` | PostgreSQL password for Authentik | (Generated) |
| `AUTHENTIK_SECRET_KEY` | Secret key for Authentik | (Generated) | | `AUTHENTIK_SECRET_KEY` | Secret key for Authentik | (Generated) |

View file

@ -14,9 +14,10 @@ export const AuthButton: React.FC = () => {
} }
if (auth.error) { if (auth.error) {
console.error('Auth error:', auth.error);
return ( return (
<div className="flex items-center gap-2 bg-red-500/20 px-4 py-2 rounded-xl text-sm"> <div className="flex items-center gap-2 bg-red-500/20 px-4 py-2 rounded-xl text-sm" title={auth.error.message}>
<span>Auth Error</span> <span>Auth Error: {auth.error.message}</span>
</div> </div>
); );
} }

View file

@ -108,10 +108,10 @@ services:
NODE_ENV: production NODE_ENV: production
PORT: 3001 PORT: 3001
DATABASE_PATH: /data/kaboot.db DATABASE_PATH: /data/kaboot.db
OIDC_ISSUER: http://localhost:9000/application/o/kaboot/ OIDC_ISSUER: http://${KABOOT_HOST:-localhost}:${AUTHENTIK_PORT_HTTP:-9000}/application/o/kaboot/
OIDC_JWKS_URI: http://localhost:9000/application/o/kaboot/jwks/ OIDC_JWKS_URI: http://${KABOOT_HOST:-localhost}:${AUTHENTIK_PORT_HTTP:-9000}/application/o/kaboot/jwks/
OIDC_INTERNAL_JWKS_URI: http://authentik-server:9000/application/o/kaboot/jwks/ OIDC_INTERNAL_JWKS_URI: http://authentik-server:9000/application/o/kaboot/jwks/
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:5173} CORS_ORIGIN: http://localhost:${KABOOT_FRONTEND_PORT:-5173},http://${KABOOT_HOST:-localhost}:${KABOOT_FRONTEND_PORT:-5173}
volumes: volumes:
- ./data:/data - ./data:/data
ports: ports:

View file

@ -363,24 +363,33 @@ Create a service account that can obtain tokens programmatically for automated t
## Environment Variables ## Environment Variables
Ensure your `.env` file has the correct OIDC configuration: ### Development (localhost only)
For local development on a single machine:
```bash ```bash
OIDC_ISSUER=http://localhost:9000/application/o/kaboot/ KABOOT_HOST=localhost
OIDC_JWKS_URI=http://localhost:9000/application/o/kaboot/jwks/
``` ```
For the frontend OIDC config (`src/config/oidc.ts`): ### Development (network/mobile access)
```typescript To access from other devices (phones, tablets), set `KABOOT_HOST` to your machine's IP:
export const oidcConfig = {
authority: 'http://localhost:9000/application/o/kaboot/', ```bash
client_id: 'kaboot-spa', KABOOT_HOST=192.168.1.100
redirect_uri: `${window.location.origin}/callback`,
// ... rest of config
};
``` ```
The setup script (`./scripts/setup.sh`) auto-detects your IP and configures:
- `.env` - Backend CORS and docker-compose variables
- `.env.local` - Frontend Vite environment variables
**Important**: You must also update redirect URIs in Authentik to include:
- `http://<your-ip>:5173/callback`
- `http://<your-ip>:5173/silent-renew.html`
- `http://<your-ip>:5173`
Then run the dev server with `npm run dev -- --host` to bind to all interfaces.
## Troubleshooting ## Troubleshooting
### "Invalid redirect URI" error ### "Invalid redirect URI" error
@ -401,12 +410,4 @@ export const oidcConfig = {
## Production Notes ## Production Notes
For production deployment: For production deployment, see [PRODUCTION.md](./PRODUCTION.md) for full instructions.
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

View file

@ -1,2 +1,4 @@
- [ ] Moderation (kick player, lock game, filter names) - [ ] Moderation (kick player, lock game, filter names)
- [ ] Persistent game urls while game is active - [ ] Persistent game urls while game is active
- Make UI for scoreboard mobile friendly. The badges for the points and extra points are getting cut off and the colored meters are invisible because the width of the board is so small on mobile

16
index.css Normal file
View file

@ -0,0 +1,16 @@
html, body, #root {
height: 100%;
min-height: 100dvh;
}
.h-screen {
height: 100dvh;
}
.min-h-screen {
min-height: 100dvh;
}
.max-h-screen {
max-height: 100dvh;
}

View file

@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-content" />
<title>Kaboot</title> <title>Kaboot</title>
<script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.tailwindcss.com"></script>
<script> <script>
@ -34,7 +34,7 @@
background: linear-gradient(180deg, var(--theme-primary) 0%, var(--theme-primary-darker) 100%); background: linear-gradient(180deg, var(--theme-primary) 0%, var(--theme-primary-darker) 100%);
color: white; color: white;
overflow-x: hidden; overflow-x: hidden;
min-height: 100vh; min-height: 100dvh;
} }
h1, h2, h3, h4, h5, h6, .font-display { h1, h2, h3, h4, h5, h6, .font-display {

View file

@ -3,6 +3,7 @@ set -e
ENV_FILE=".env" ENV_FILE=".env"
ENV_EXAMPLE=".env.example" ENV_EXAMPLE=".env.example"
ENV_LOCAL=".env.local"
echo "Kaboot Setup Script" echo "Kaboot Setup Script"
echo "===================" echo "==================="
@ -22,6 +23,23 @@ if [ ! -f "$ENV_EXAMPLE" ]; then
exit 1 exit 1
fi fi
# Detect host IP for network access
detect_host_ip() {
if [[ "$OSTYPE" == "darwin"* ]]; then
ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || echo "localhost"
else
hostname -I 2>/dev/null | awk '{print $1}' || echo "localhost"
fi
}
echo "Detecting network configuration..."
DETECTED_IP=$(detect_host_ip)
echo " Detected IP: $DETECTED_IP"
echo ""
read -p "Enter host IP/domain for network access [$DETECTED_IP]: " KABOOT_HOST
KABOOT_HOST=${KABOOT_HOST:-$DETECTED_IP}
echo ""
echo "Generating secrets..." echo "Generating secrets..."
PG_PASS=$(openssl rand -base64 36 | tr -d '\n') PG_PASS=$(openssl rand -base64 36 | tr -d '\n')
@ -36,28 +54,40 @@ if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s|^AUTHENTIK_SECRET_KEY=.*|AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}|" "$ENV_FILE" sed -i '' "s|^AUTHENTIK_SECRET_KEY=.*|AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}|" "$ENV_FILE"
sed -i '' "s|^AUTHENTIK_BOOTSTRAP_PASSWORD=.*|AUTHENTIK_BOOTSTRAP_PASSWORD=${AUTHENTIK_BOOTSTRAP_PASSWORD}|" "$ENV_FILE" sed -i '' "s|^AUTHENTIK_BOOTSTRAP_PASSWORD=.*|AUTHENTIK_BOOTSTRAP_PASSWORD=${AUTHENTIK_BOOTSTRAP_PASSWORD}|" "$ENV_FILE"
sed -i '' "s|^AUTHENTIK_BOOTSTRAP_TOKEN=.*|AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}|" "$ENV_FILE" sed -i '' "s|^AUTHENTIK_BOOTSTRAP_TOKEN=.*|AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}|" "$ENV_FILE"
sed -i '' "s|^KABOOT_HOST=.*|KABOOT_HOST=${KABOOT_HOST}|" "$ENV_FILE"
else else
sed -i "s|^PG_PASS=.*|PG_PASS=${PG_PASS}|" "$ENV_FILE" 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" sed -i "s|^AUTHENTIK_SECRET_KEY=.*|AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}|" "$ENV_FILE"
sed -i "s|^AUTHENTIK_BOOTSTRAP_PASSWORD=.*|AUTHENTIK_BOOTSTRAP_PASSWORD=${AUTHENTIK_BOOTSTRAP_PASSWORD}|" "$ENV_FILE" sed -i "s|^AUTHENTIK_BOOTSTRAP_PASSWORD=.*|AUTHENTIK_BOOTSTRAP_PASSWORD=${AUTHENTIK_BOOTSTRAP_PASSWORD}|" "$ENV_FILE"
sed -i "s|^AUTHENTIK_BOOTSTRAP_TOKEN=.*|AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}|" "$ENV_FILE" sed -i "s|^AUTHENTIK_BOOTSTRAP_TOKEN=.*|AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}|" "$ENV_FILE"
sed -i "s|^KABOOT_HOST=.*|KABOOT_HOST=${KABOOT_HOST}|" "$ENV_FILE"
fi fi
# Create .env.local for Vite frontend
cat > "$ENV_LOCAL" << EOF
# Auto-generated by setup.sh - Frontend environment variables
VITE_BACKEND_URL=http://${KABOOT_HOST}:3001
VITE_AUTHENTIK_URL=http://${KABOOT_HOST}:9000
EOF
echo "" echo ""
echo "Created .env file with generated secrets." echo "Created .env and .env.local files."
echo ""
echo "Host configuration:"
echo " KABOOT_HOST: ${KABOOT_HOST}"
echo " Frontend: http://${KABOOT_HOST}:5173"
echo " Backend: http://${KABOOT_HOST}:3001"
echo " Authentik: http://${KABOOT_HOST}:9000"
echo "" echo ""
echo "Authentik admin credentials (save these):" echo "Authentik admin credentials (save these):"
echo " Username: akadmin" echo " Username: akadmin"
echo " Password: ${AUTHENTIK_BOOTSTRAP_PASSWORD}" echo " Password: ${AUTHENTIK_BOOTSTRAP_PASSWORD}"
echo "" echo ""
echo "Next steps:" echo "Next steps:"
echo " 1. Review .env and adjust settings if needed" echo " 1. Run: docker compose up -d"
echo " 2. Run: docker compose up -d" echo " 2. Wait for Authentik to start (~30 seconds)"
echo " 3. Wait for Authentik to start (~30 seconds)" echo " 3. For development: npm run dev -- --host"
echo " 4. The Kaboot application is auto-configured via blueprint!" echo " 4. Access from other devices via http://${KABOOT_HOST}:5173"
echo "" echo ""
echo "Remaining manual steps:" echo "Note: Update Authentik redirect URIs to include http://${KABOOT_HOST}:5173/callback"
echo " - Set password for test user: docker compose exec authentik-server ak set_password kaboottest"
echo " - Create app password for service account via Authentik UI"
echo " - See docs/AUTHENTIK_SETUP.md for details"
echo "" echo ""

View file

@ -9,8 +9,9 @@ import gamesRouter from './routes/games.js';
const app = express(); const app = express();
const PORT = process.env.PORT || 3001; const PORT = process.env.PORT || 3001;
const corsOrigins = (process.env.CORS_ORIGIN || 'http://localhost:5173').split(',').map(o => o.trim());
app.use(cors({ app.use(cors({
origin: process.env.CORS_ORIGIN || 'http://localhost:5173', origin: corsOrigins.length === 1 ? corsOrigins[0] : corsOrigins,
credentials: true, credentials: true,
})); }));