Notifications (web push now, Android FCM ready, iOS prepared): - device_tokens / notification_settings / conversation_mutes (migration 006) - REST: register/list/unregister devices, get/update settings (quiet hours, timezone, enable), mute/unmute conversation, VAPID public key - BullMQ queue: backend enqueues a job per new message; a dedicated stateless `notifications` worker service drains it - Delivery gating: skip sender, muted chats, disabled users, quiet hours, and ONLINE users (they get the message live + an in-app toast) — offline → push - Providers behind one interface: Web Push (VAPID/web-push) + FCM (firebase-admin, HTTP v1; Android + iOS via the same path). Dead tokens (404/410/unregistered) auto-retired; transient failures recorded - Web: service worker (push display + tap-to-open the originating chat), push registration/unregistration, in-app toast stack, deep-link via ?conversation= In-app voice & video messages: MediaRecorder capture in the composer (mic/video), live preview + timer, upload via the existing presigned-media path. No emojis anywhere: replaced all glyphs with inline SVG icons (shared/ui) so the UI renders identically across web/desktop/mobile; notification text is plain. Chores: dedupe ioredis (BullMQ) + pin uuid>=11.1.1 (audit clean) via pnpm overrides; reusable Centrifugo client factory for the worker. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFRyKxkKEjfAgpXygzoNiD
84 lines
3.3 KiB
Text
84 lines
3.3 KiB
Text
# ============================================================================
|
|
# Altricade Messenger — environment template.
|
|
# Copy to `.env` (gitignored) and replace every value below.
|
|
# The values here are CLEARLY-FAKE dev placeholders — NEVER use in production.
|
|
# ============================================================================
|
|
|
|
# --- General ---
|
|
NODE_ENV=development
|
|
|
|
# --- Backend (Fastify) ---
|
|
BACKEND_PORT=4000
|
|
# Public base URL nginx exposes the API under (used for CORS, links).
|
|
PUBLIC_API_URL=http://localhost:8080
|
|
|
|
# --- App auth tokens (Phase 1) ---
|
|
# Signing key for short-lived access JWTs. Generate: `openssl rand -base64 48`
|
|
JWT_ACCESS_SECRET=dev-CHANGE-ME-access-secret-not-for-prod
|
|
ACCESS_TOKEN_TTL=15m
|
|
REFRESH_TOKEN_TTL=30d
|
|
|
|
# --- Centrifugo connection token (SEPARATE from app tokens) ---
|
|
# HMAC secret SHARED between backend (mints) and Centrifugo (verifies).
|
|
# Generate: `openssl rand -base64 48`
|
|
CENTRIFUGO_TOKEN_HMAC_SECRET=dev-CHANGE-ME-centrifugo-hmac-not-for-prod
|
|
# API key the backend uses to call Centrifugo's server HTTP API (publish, etc).
|
|
CENTRIFUGO_API_KEY=dev-CHANGE-ME-centrifugo-api-key
|
|
# Internal URL of the Centrifugo HTTP API (service name on the compose network).
|
|
CENTRIFUGO_API_URL=http://centrifugo:8000/api
|
|
# Lifetime of the Centrifugo connection token the backend mints.
|
|
CENTRIFUGO_TOKEN_TTL=1h
|
|
|
|
# --- CORS (comma-separated allowlist; credentials mode, no wildcard) ---
|
|
CORS_ORIGINS=http://localhost:5173,http://localhost:8080
|
|
|
|
# --- Postgres ---
|
|
POSTGRES_HOST=postgres
|
|
POSTGRES_PORT=5432
|
|
POSTGRES_DB=altricade
|
|
POSTGRES_USER=altricade
|
|
POSTGRES_PASSWORD=dev-CHANGE-ME-postgres-password
|
|
# Full URL derived from the above (used by backend + migrations).
|
|
DATABASE_URL=postgres://altricade:dev-CHANGE-ME-postgres-password@postgres:5432/altricade
|
|
|
|
# --- Redis (Centrifugo scaling + history/recovery; auth rate-limiting later) ---
|
|
REDIS_HOST=redis
|
|
REDIS_PORT=6379
|
|
REDIS_URL=redis://redis:6379
|
|
|
|
# --- MinIO (object storage: media messages + avatars) ---
|
|
MINIO_ROOT_USER=altricade
|
|
MINIO_ROOT_PASSWORD=dev-CHANGE-ME-minio-password
|
|
MINIO_ENDPOINT=minio
|
|
MINIO_PORT=9000
|
|
MINIO_USE_SSL=false
|
|
MINIO_BUCKET_MEDIA=media
|
|
MINIO_BUCKET_AVATARS=avatars
|
|
# Browser-facing MinIO URL — presigned upload/download URLs are signed for this
|
|
# host, so it must match what the browser uses (dev: the exposed host port).
|
|
MINIO_PUBLIC_URL=http://localhost:9000
|
|
# S3 region used for SigV4 presigning (MinIO default is us-east-1). Set explicitly
|
|
# so presigning never makes a network region-lookup call.
|
|
MINIO_REGION=us-east-1
|
|
|
|
# --- notifications (Phase 6.5) ---
|
|
# Web Push (VAPID). Generate a keypair once with:
|
|
# node -e "console.log(require('web-push').generateVAPIDKeys())"
|
|
# The public key is safe to expose to the browser; keep the private key secret.
|
|
VAPID_PUBLIC_KEY=
|
|
VAPID_PRIVATE_KEY=
|
|
VAPID_SUBJECT=mailto:admin@altricade.com
|
|
# Firebase Cloud Messaging (Android now, iOS later — same code path). Point this
|
|
# at the service-account JSON mounted into the worker; leave empty to disable FCM.
|
|
FCM_SERVICE_ACCOUNT_FILE=
|
|
# iOS push is prepared but off until an APNs key is uploaded to Firebase.
|
|
APNS_ENABLED=false
|
|
# BullMQ queue name for the notifications worker.
|
|
NOTIFICATIONS_QUEUE=notifications
|
|
|
|
# --- nginx (public entrypoint) ---
|
|
NGINX_HTTP_PORT=8080
|
|
|
|
# --- Web (Vite) ---
|
|
# Base URL the web client points at for REST + realtime.
|
|
VITE_API_URL=http://localhost:8080
|