diff --git a/k-tv-backend/compose.yml b/k-tv-backend/compose.yml index ba6ca5b..616a61f 100644 --- a/k-tv-backend/compose.yml +++ b/k-tv-backend/compose.yml @@ -4,86 +4,43 @@ services: ports: - "3000:3000" environment: - - SESSION_SECRET=dev_secret_key_12345 - - DATABASE_URL=sqlite:///app/data/notes.db - - CORS_ALLOWED_ORIGINS=http://localhost:8080,http://localhost:5173 + # Server - HOST=0.0.0.0 - PORT=3000 + # Database — SQLite by default; swap for a postgres:// URL to use PostgreSQL + - DATABASE_URL=sqlite:///app/data/k-tv.db?mode=rwc + # CORS — set to your frontend origin(s), comma-separated + - CORS_ALLOWED_ORIGINS=http://localhost:3001 + # Auth — CHANGE BOTH before going to production + # Generate JWT_SECRET with: openssl rand -hex 32 + # Generate COOKIE_SECRET with: openssl rand -base64 64 + - JWT_SECRET=change-me-generate-with-openssl-rand-hex-32 + - COOKIE_SECRET=change-me-must-be-at-least-64-characters-long-for-production!! + - JWT_EXPIRY_HOURS=24 + - SECURE_COOKIE=false # set to true when serving over HTTPS + - PRODUCTION=false + # Database pool - DB_MAX_CONNECTIONS=5 - DB_MIN_CONNECTIONS=1 - - SECURE_COOKIE=true + # Jellyfin media provider — all three are required to enable schedule generation + - JELLYFIN_BASE_URL=http://jellyfin:8096 + - JELLYFIN_API_KEY=your-jellyfin-api-key-here + - JELLYFIN_USER_ID=your-jellyfin-user-id-here volumes: - - ./data:/app/data + - ./data:/app/data # SQLite database + any other persistent files + restart: unless-stopped - # nats: - # image: nats:alpine + # ── Optional: PostgreSQL ──────────────────────────────────────────────────── + # Uncomment and set DATABASE_URL=postgres://ktv:password@db:5432/ktv above. + # + # db: + # image: postgres:16-alpine + # environment: + # POSTGRES_USER: ktv + # POSTGRES_PASSWORD: password + # POSTGRES_DB: ktv # ports: - # - "4222:4222" - # - "6222:6222" - # - "8222:8222" + # - "5432:5432" + # volumes: + # - db_data:/var/lib/postgresql/data # restart: unless-stopped - - db: - image: postgres:15-alpine - environment: - POSTGRES_USER: user - POSTGRES_PASSWORD: password - POSTGRES_DB: k_template_db - ports: - - "5439:5432" - volumes: - - db_data:/var/lib/postgresql/data - - zitadel-db: - image: postgres:16-alpine - container_name: zitadel_db - environment: - POSTGRES_USER: zitadel - POSTGRES_PASSWORD: zitadel_password - POSTGRES_DB: zitadel - healthcheck: - test: ["CMD-SHELL", "pg_isready -U zitadel -d zitadel"] - interval: 10s - timeout: 5s - retries: 5 - volumes: - - zitadel_db_data:/var/lib/postgresql/data - - zitadel: - image: ghcr.io/zitadel/zitadel:latest - container_name: zitadel_local - depends_on: - zitadel-db: - condition: service_healthy - ports: - - "8086:8080" - # USE start-from-init (Fixes the "relation does not exist" bug) - command: 'start-from-init --masterkey "MasterkeyNeedsToBeExactly32Bytes"' - environment: - # Database Connection - ZITADEL_DATABASE_POSTGRES_HOST: zitadel-db - ZITADEL_DATABASE_POSTGRES_PORT: 5432 - ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel - - # APPLICATION USER (Zitadel uses this to run) - ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel - ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel_password - ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable - - # ADMIN USER (Zitadel uses this to create tables/migrations) - # We use 'zitadel' because it is the owner of the DB in your postgres container. - ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: zitadel - ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: zitadel_password - ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable - - # General Config - ZITADEL_EXTERNALDOMAIN: localhost - ZITADEL_EXTERNALPORT: 8086 - ZITADEL_EXTERNALSECURE: "false" - ZITADEL_TLS_ENABLED: "false" - - ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED: "false" - -volumes: - db_data: - zitadel_db_data: \ No newline at end of file diff --git a/k-tv-frontend/app/(auth)/login/page.tsx b/k-tv-frontend/app/(auth)/login/page.tsx index 2c9b133..e069227 100644 --- a/k-tv-frontend/app/(auth)/login/page.tsx +++ b/k-tv-frontend/app/(auth)/login/page.tsx @@ -3,11 +3,13 @@ import Link from "next/link"; import { useState } from "react"; import { useLogin } from "@/hooks/use-auth"; +import { useConfig } from "@/hooks/use-channels"; export default function LoginPage() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const { mutate: login, isPending, error } = useLogin(); + const { data: config } = useConfig(); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); @@ -63,12 +65,14 @@ export default function LoginPage() { -
- No account?{" "} - - Create one - -
+ {config?.allow_registration !== false && ( ++ No account?{" "} + + Create one + +
+ )} ); } diff --git a/k-tv-frontend/app/(auth)/register/page.tsx b/k-tv-frontend/app/(auth)/register/page.tsx index ccd4f68..63abc71 100644 --- a/k-tv-frontend/app/(auth)/register/page.tsx +++ b/k-tv-frontend/app/(auth)/register/page.tsx @@ -3,11 +3,27 @@ import Link from "next/link"; import { useState } from "react"; import { useRegister } from "@/hooks/use-auth"; +import { useConfig } from "@/hooks/use-channels"; export default function RegisterPage() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const { mutate: register, isPending, error } = useRegister(); + const { data: config } = useConfig(); + + if (config && !config.allow_registration) { + return ( ++ The administrator has disabled new account registration. +
+ + Sign in instead + +No channels yet