From 4b7833dc8ebe4bdede7a4532da6c3201979248f6 Mon Sep 17 00:00:00 2001 From: Samidy Date: Thu, 12 Mar 2026 02:03:36 +0300 Subject: [PATCH] update outdated self-hosting shit --- .env.example | 5 ++- DOCKER.md | 27 ++++++++++++++ docker-compose.yml | 4 +-- index.html | 37 ++++++++++++------- js/accounts/auth.js | 8 ++--- js/accounts/config.js | 22 ++++++++---- js/settings.js | 76 +++++++++++++++++++++------------------- styles.css | 11 +++--- vite-plugin-auth-gate.js | 42 +++++++--------------- 9 files changed, 131 insertions(+), 101 deletions(-) diff --git a/.env.example b/.env.example index d51cf88..da95031 100644 --- a/.env.example +++ b/.env.example @@ -9,12 +9,11 @@ MONOCHROME_DEV_PORT=5173 # Set AUTH_ENABLED=true to enable the auth gate entirely (login required) AUTH_ENABLED=false AUTH_SECRET=change-me-to-a-random-string -FIREBASE_PROJECT_ID=monochrome-database +APPWRITE_ENDPOINT=https://auth.yourdomain.com/v1 +APPWRITE_PROJECT_ID=auth-for-monochrome # Optional: toggle login providers (defaults to true when unset) # AUTH_GOOGLE_ENABLED=true # AUTH_EMAIL_ENABLED=true -# Optional: override the Firebase config for the login page (JSON string) -# FIREBASE_CONFIG={"apiKey":"...","authDomain":"...","projectId":"...","storageBucket":"...","messagingSenderId":"...","appId":"..."} # Optional: set PocketBase URL (hides the field in settings when set) # POCKETBASE_URL=https://monodb.samidy.com # SESSION_MAX_AGE=604800000 # 7 days in ms (default) diff --git a/DOCKER.md b/DOCKER.md index f6bd93e..9e8426d 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -92,6 +92,33 @@ Override files can extend existing services (add labels, env vars, networks) and --- +## Configuration + +The application is configured via environment variables. Copy `.env.example` to `.env` and edit it to match your setup. + +### Authentication (Appwrite) + +Monochrome uses Appwrite for user authentication. While it defaults to official instances, you can use your own self-hosted Appwrite instance: + +1. Create a project in Appwrite. +2. Enable the **Google** or **Email/Password** providers in the Appwrite Console. +3. Set these variables in your `.env`: + - `APPWRITE_ENDPOINT`: Your Appwrite API endpoint (e.g., `https://auth.yourdomain.com/v1`). + - `APPWRITE_PROJECT_ID`: Your Appwrite project ID (e.g., `auth-for-monochrome`). + +### Database (PocketBase) + +Monochrome uses PocketBase to store user data (playlists, favorites, profiles, etc.). You can run it alongside Monochrome using the `pocketbase` profile: + +```bash +docker compose --profile pocketbase up -d +``` + +#### PocketBase Schema Note +If you are setting up a new PocketBase collection for user data, ensure it has a field named `firebase_id` (this is a legacy name we use when we first started the accounts system, we used firebase. and im too lazy to change it so yea fuck you). + +--- + ## Portainer Deployment Portainer can deploy directly from your GitHub fork with auto-updates on push. diff --git a/docker-compose.yml b/docker-compose.yml index f4602cc..02fe95e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,8 +10,8 @@ services: environment: AUTH_ENABLED: ${AUTH_ENABLED:-false} AUTH_SECRET: ${AUTH_SECRET:-} - FIREBASE_PROJECT_ID: ${FIREBASE_PROJECT_ID:-monochrome-database} - FIREBASE_CONFIG: ${FIREBASE_CONFIG:-} + APPWRITE_ENDPOINT: ${APPWRITE_ENDPOINT:-https://auth.yourdomain.com/v1} + APPWRITE_PROJECT_ID: ${APPWRITE_PROJECT_ID:-auth-for-monochrome} POCKETBASE_URL: ${POCKETBASE_URL:-} SESSION_MAX_AGE: ${SESSION_MAX_AGE:-604800000} restart: unless-stopped diff --git a/index.html b/index.html index 5a253c3..43e8baf 100644 --- a/index.html +++ b/index.html @@ -1276,11 +1276,11 @@

- Configure custom PocketBase and Firebase instances. Leave empty to use defaults. + Configure custom PocketBase and Appwrite instances. Leave empty to use defaults.
A Guide To Set This Up Can Be Found Here. @@ -1296,14 +1296,25 @@

Appwrite Endpoint - + placeholder="https://auth.samidy.com/v1" + /> +
+
+ +
- @@ -5530,19 +5541,19 @@ flex-wrap: wrap; " > - + -

+

Sync your library across devices

` : null; @@ -109,11 +98,8 @@ export default function authGatePlugin() { process.exit(1); } - console.log(`Auth gate enabled (Firebase project: ${PROJECT_ID})`); + console.log(`Auth gate enabled (Project: ${APPWRITE_PROJECT_ID})`); - const JWKS = createRemoteJWKSet( - new URL('https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com') - ); server.middlewares.use( cookieSession({ @@ -148,26 +134,22 @@ export default function authGatePlugin() { if (url === '/api/auth/login' && req.method === 'POST') { try { const body = await parseBody(req); - if (!body.token) { + if (!body.userId) { res.statusCode = 400; res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ error: 'Missing token' })); + res.end(JSON.stringify({ error: 'Missing userId' })); return; } - const { payload } = await jwtVerify(body.token, JWKS, { - issuer: `https://securetoken.google.com/${PROJECT_ID}`, - audience: PROJECT_ID, - }); - req.session.uid = payload.sub; - req.session.email = payload.email; + req.session.uid = body.userId; + req.session.email = body.email; req.session.iat = Date.now(); res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ ok: true })); } catch (err) { - console.error('Token verification failed:', err.message); + console.error('Login session creation failed:', err.message); res.statusCode = 401; res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ error: 'Invalid token' })); + res.end(JSON.stringify({ error: 'Login failed' })); } return; }