Files
BizGaze_Remote/server/config.js
T
Sravan a677675b8f Round 3: session longevity, in-chat tone, pin audit, older-msg loader, long-press sheet, draft fix
Session (New): stop the ~24h auto-logout. SESSION_TTL 24h -> 90d, and /api/me now
    SLIDES the session forward + re-stamps the cookie on every app load / focus /
    6h heartbeat — so an actively-used session never lapses; you only log out by
    choosing to. Login no longer depends on "remember me".
#2  A new message in the chat you're actively viewing now plays a soft, distinct
    in-chat tone (playMsgTone) — no popup — instead of being silent. A different
    chat / a backgrounded chat still gets the alert ping + notification.
#13 Pin/unpin is now written to the audit log (actor + which message, and whose pin
    was removed on an unpin) — the accountability gap when anyone can unpin.
Pagination: a floating "Loading earlier messages…" pill now shows while older
    history is being fetched (loadOlder had no visible indicator).
#9  Mobile long-press now opens a dimmed + blurred bottom ACTION SHEET (quick
    reactions + reply/edit/forward/copy/pin/delete) instead of the flaky hover-style
    reveal that hid behind images and broke after the lightbox opened.
#14 editTarget is cleared on conversation switch — starting an edit then switching
    chats used to leave editTarget set, which silently stopped ALL draft saving.
    Also added Edit to the shared action list so mobile long-press can edit too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-13 16:38:58 +05:30

79 lines
4.3 KiB
JavaScript

// Runtime config + filesystem paths. Reads process.env once at startup.
const fs = require('fs');
const path = require('path');
const PUBLIC_DIR = path.join(__dirname, 'public');
// Uploaded chat files, recordings and transcripts MUST live on the persistent volume (like the DB
// and downloads). With the old in-image path, every deploy.sh rebuild wiped them — old images/files
// then 404 ("broken image") while their DB rows survive. Overridable so prod points them at /data.
const REC_DIR = process.env.REC_DIR || path.join(__dirname, 'recordings');
const TRANS_DIR = process.env.TRANS_DIR || path.join(__dirname, 'transcripts');
const UPLOADS_DIR = process.env.UPLOADS_DIR || path.join(__dirname, 'uploads');
// Desktop installers + auto-update feed (latest.yml). Override with DOWNLOADS_DIR to point at a
// mounted volume in production; IT drops the electron-builder dist/ output here.
const DOWNLOADS_DIR = process.env.DOWNLOADS_DIR || path.join(__dirname, 'downloads');
try { fs.mkdirSync(REC_DIR, { recursive: true }); } catch (e) {}
try { fs.mkdirSync(TRANS_DIR, { recursive: true }); } catch (e) {}
try { fs.mkdirSync(UPLOADS_DIR, { recursive: true }); } catch (e) {}
try { fs.mkdirSync(DOWNLOADS_DIR, { recursive: true }); } catch (e) {}
// LiveKit SFU (scales meetings past the ~5-peer mesh ceiling). Entirely optional and config-gated:
// when LIVEKIT_URL/API_KEY/API_SECRET are all set the client uses LiveKit for meeting media; when
// they're unset the app falls back to the built-in P2P mesh, unchanged. The API secret is used
// ONLY server-side to mint per-user join tokens — it never reaches the browser.
const LIVEKIT_URL = process.env.LIVEKIT_URL || ''; // wss://livekit.bizgaze.com
const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY || '';
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET || '';
const LIVEKIT_ENABLED = !!(LIVEKIT_URL && LIVEKIT_API_KEY && LIVEKIT_API_SECRET);
// SMTP for outbound email (meeting invites to external participants, #4). Entirely optional and
// config-gated: email is only sent when SMTP_HOST/USER/PASS are set. Credentials stay server-side.
// PUBLIC_BASE_URL is the origin used to build guest meeting links in emails (e.g. https://remote.bizgaze.com).
const SMTP_HOST = process.env.SMTP_HOST || '';
const SMTP_PORT = Number(process.env.SMTP_PORT || 587);
const SMTP_SECURE = String(process.env.SMTP_SECURE || '').toLowerCase() === 'true' || SMTP_PORT === 465; // TLS on connect (465) vs STARTTLS
const SMTP_USER = process.env.SMTP_USER || '';
const SMTP_PASS = process.env.SMTP_PASS || '';
const SMTP_FROM = process.env.SMTP_FROM || (SMTP_USER ? ('Biz Connect <' + SMTP_USER + '>') : '');
const SMTP_ENABLED = !!(SMTP_HOST && SMTP_USER && SMTP_PASS);
const PUBLIC_BASE_URL = (process.env.PUBLIC_BASE_URL || 'https://remote.bizgaze.com').replace(/\/+$/, '');
// GIPHY GIF search (#5). Key is read from the server env only and never sent to the browser — the client
// calls our /api/gifs proxy. GIF picker is hidden when this isn't configured.
const GIPHY_API_KEY = process.env.GIPHY_API_KEY || '';
// Native CallKit / PushKit VoIP calling (iOS). Config-gated so it can be flipped WITHOUT an app rebuild:
// OFF (default) → calls use the WebView flow (works today); ON → iOS rings via CallKit + a VoIP push.
// Only turn ON once native LiveKit media carries the call audio — a CallKit call reserves the mic, so the
// WebView's WebRTC can't capture it (mic dead). Set CALLKIT_ENABLED=1 in the server .env to enable.
const CALLKIT_ENABLED = process.env.CALLKIT_ENABLED === '1';
module.exports = {
PORT: process.env.PORT || 8090,
HTTPS_PORT: process.env.HTTPS_PORT || 8443,
LIVEKIT_URL,
LIVEKIT_API_KEY,
LIVEKIT_API_SECRET,
LIVEKIT_ENABLED,
SMTP_HOST,
SMTP_PORT,
SMTP_SECURE,
SMTP_USER,
SMTP_PASS,
SMTP_FROM,
SMTP_ENABLED,
PUBLIC_BASE_URL,
GIPHY_API_KEY,
CALLKIT_ENABLED,
PUBLIC_DIR,
REC_DIR,
TRANS_DIR,
UPLOADS_DIR,
DOWNLOADS_DIR,
// Access-token / web-cookie lifetime. Long by design + SLID FORWARD on every /api/me (app load / focus /
// heartbeat), so an actively-used session never lapses — you only get logged out by choosing to log out.
// (Was 24h, which logged people out overnight.)
SESSION_TTL: 1000 * 60 * 60 * 24 * 90, // 90d
REFRESH_TTL: 1000 * 60 * 60 * 24 * 90, // 90d refresh-token lifetime (native clients)
};