Commit Graph

109 Commits

Author SHA1 Message Date
Sravan 15350c691b feat(chat): delivery ticks on the last message in the chat list (#3)
Conversations DTO now returns last_status (sent/delivered/read for DMs; sent for groups) for
my last message. The list row shows the matching tick (single/double, blue when read) and a
red 'Draft:' indicator when there's unsent text. Live 'sent' on send/receive; upgrades to
delivered/read on refresh. e2e 119.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:59:53 +05:30
Sravan a33ed27ffe feat(chat): per-chat drafts + fix emoji picker closing on tab switch
- Unsent text is saved per conversation (survives switching chats and reloads) and restored
  when you reopen the chat; cleared on send. (#1)
- Emoji picker: stopPropagation on tab/grid clicks so switching category no longer closes it
  (the re-render was detaching the clicked node -> outside-click handler fired). (#6)
build batch23.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:55:14 +05:30
Sravan 2b27889e07 fix(desktop): use Electron's native Notification (reliable click-to-open)
node-notifier/SnoreToast click callback never fired without the crashing wait mode. Switch the
chat toast to Electron's built-in Notification: shows avatar + message and its 'click' event
reliably raises the app + opens the chat. No SnoreToast, no external tools.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:16:35 +05:30
Sravan f8978ff796 fix(desktop): drop crashing SnoreToast reply path — clean click-to-open toast
The bundled SnoreToast crashes (0xC0000409) handling a text reply, and that crash triggered
a second (fallback) toast. Removed the direct-SnoreToast reply path entirely; the chat toast
now reliably shows avatar + message via node-notifier and opens the chat on click. Inline
text reply needs a different toast engine (deferred).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 08:58:26 +05:30
Sravan 0b58d33117 fix(desktop): drop -w — SnoreToast waits by default; -w made it fail (exit -1)
Testing showed SnoreToast blocks/waits for the toast interaction when given -pipeName; the
-w flag actually fails on this build (exit -1) which forced the reply-less fallback. Without
-w it waits, captures the typed reply, and writes it to our pipe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 08:43:40 +05:30
Sravan 0f5e5bf00a fix(desktop): spawn SnoreToast from app.asar.unpacked (was ENOENT inside asar)
snoreExe returned the app.asar path (fs.existsSync lies about asar paths), so spawn failed
with ENOENT and always fell back to the reply-less WindowsToaster. Map to app.asar.unpacked
unconditionally so the real SnoreToast binary (with -w) runs and captures the reply.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 00:28:43 +05:30
Sravan c0f7926210 fix(desktop): direct SnoreToast -w to capture reply + WindowsToaster fallback
Root cause: node-notifier's toaster whitelist has no -w, so SnoreToast never waits and the
reply is lost. Now drive SnoreToast directly with -w + our own pipe (correct args, no
-application which had broken the toast). If the binary is missing or fails to show, fall
back to node-notifier's WindowsToaster so a toast always appears. Logs code+raw for diagnosis.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 00:06:01 +05:30
Sravan 1abf6855d8 fix(desktop): drive SnoreToast directly with own named pipe + raw reply logging
node-notifier returned an empty result for text replies. Now spawn the bundled SnoreToast
with -tb -w -pipeName against our own pipe, read the raw UTF-16LE result, and parse the
reply (keeps spaces). Logs the raw pipe string to userData/toast-debug.log to pin the
exact reply field on real hardware.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:44:08 +05:30
Sravan 3f209bf619 feat(desktop): real Windows inline reply via SnoreToast -tb + sender/group avatar
- node-notifier's WindowsToaster forwards raw opts to SnoreToast, so inject -tb (reply box)
  + -p (image). Reuses its named-pipe + result parsing (exit 5 = TextEntered). No pwsh needed.
  Logs the raw toast result to userData/toast-debug.log to confirm the reply field on real HW.
- home.html: notifAvatarDataUrl draws the DM sender's pic / group's DP (else colored initials)
  to a round PNG and passes it as the toast image. Reply -> sendReplyTo; click -> open chat.
- dropped powertoast (ESM + needs pwsh 7, absent here). build batch22.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:26:24 +05:30
Sravan ffe04e6bff fix(desktop): asarUnpack node-notifier so SnoreToast can launch from the packaged app
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:03:48 +05:30
Sravan 21ae3e1aa5 feat(desktop): Phase D — inline-reply notifications (Windows toast reply box)
Reply to a chat straight from the OS notification, no app switch:
- node-notifier (bundles SnoreToast) renders a native Windows toast with a reply box —
  Electron's own Notification can't do Windows inline reply.
- main.js reply-notification handler resolves {text}|{open}|null; preload exposes replyNotify.
- home.html notify() routes chat toasts through it on desktop: a typed reply -> sendReplyTo()
  POSTs to /api/messages without opening the app; a click opens the chat. Web/PWA path unchanged.
- Works only in the installed app (needs the installer's AppUserModelID). desktop 0.1.2, build batch21.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 22:36:02 +05:30
Sravan 160a66f934 fix(landing): Windows logo on the Download button (signals it's the Windows app)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 22:27:31 +05:30
Sravan 9ff2ef5d48 feat(dashboard): "App installs" view + compact top-right Download button
- dashboard.html: admin "App installs" card — table of user · platform · version · OS ·
  first/last seen, from GET /api/v1/admin/installs (loadInstalls).
- index.html: replaced the long inline link with a compact white "Download app" button in
  the blue top header (top-right); hidden when already inside the desktop app.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 22:16:38 +05:30
Sravan 899770ed02 feat: Windows download link + self-served update feed + install tracking
Downloads/updates:
- config: DOWNLOADS_DIR (override to a mounted volume in prod).
- static.js: serves /downloads/* (installer, latest.yml, .blockmap) with range support for
  resumable + differential auto-updates; /download/windows redirects to the current .exe
  (stable link). Landing page gets a "Download the Windows desktop app" button (hidden in-app).

Install tracking (who installed the app):
- db app_installs + repos.appInstalls (upsert by install_id, fills in the user on sign-in).
- POST /api/v1/telemetry/install (records install + user once authenticated);
  GET /api/v1/admin/installs (admin: list installs with user/version/os/last-seen).
- desktop main.js: stable per-install id in userData, exposed via preload
  (bizConnectNative.installId/version/os); home.html reportInstall() posts it after login.
- e2e: +2 checks (telemetry recorded, admin sees it). 119/119. build batch20.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 21:28:53 +05:30
Sravan e5c94ebf6d fix: login submits on Enter (real <form>) + desktop notifications show "Biz Connect"
- home.html: login is now a real <form> with a submit button, so Enter (or click) both
  submit natively — replaces the ad-hoc keydown handler. (build batch19; header stays removed)
- desktop/main.js: app.setAppUserModelId('com.bizgaze.connect.desktop') so Windows resolves
  the installed shortcut and toasts read "Biz Connect" instead of "electron.app.BizConnect".
- desktop version → 0.1.1; installer rebuilt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 18:19:01 +05:30
Sravan e84e5eb241 feat(desktop): open the landing page (pre-login), not /home directly
The desktop app was hardcoded to /home, so it jumped straight to the login form and
skipped the 'before login' landing (no-login 'Share my screen' + sign-in). Now loads / —
same entry as the website; it redirects logged-in users to /home.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:55:49 +05:30
Sravan 07286899c5 chore(desktop): one-click installer (no scope/folder prompts)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:37:58 +05:30
Sravan c605304c67 chore(desktop): add author field (cleaner electron-builder output)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:21:54 +05:30
Sravan 1500d42cd2 feat(desktop): packaging + self-hosted auto-update (electron-builder/updater)
- package.json build config: NSIS installer, app icon, generic publish provider →
  https://remote.bizgaze.com/downloads/ (self-hosted update feed).
- main.js: electron-updater checks the feed on launch + every 6h, downloads in the
  background, installs on restart. Active only in packaged builds.
- build/icon.ico app icon; PACKAGING.md documents build/release/signing.
- Key design: web/UI changes reach installed apps instantly (they load the live server);
  only native shell changes need an auto-updated build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:03:18 +05:30
Sravan 2404538270 fix(ui): modern thin scrollbars app-wide (remove classic up/down arrows)
Only the chat LIST had styled scrollbars; the chat message area and every other scroll
region fell back to the OS scrollbar, which in the Electron/Windows shell shows classic
up/down stepper arrows. Added a global ::-webkit-scrollbar style (thin, rounded thumb,
scrollbar-button hidden) + scrollbar-width:thin to home.html, share.html, connect.html,
dashboard.html. (home build batch18)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:46:40 +05:30
Sravan 1ca0b836e1 feat(desktop): unread-chat count badge on the taskbar icon
Mirrors the rail's unread-chat count onto the Windows taskbar icon (overlay) and the
macOS/Linux dock badge. updateRailUnread() draws a small red count badge on a canvas
and hands it to the shell via bizConnectNative.setUnread(count, dataUrl); main sets it
with win.setOverlayIcon + app.setBadgeCount. Clears at 0, shows 99+ past 99. No-op in a
browser/mobile. (home.html build batch17)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:28:15 +05:30
Sravan 5a98ae4d34 feat(desktop): media/notification permissions + notification raises the app
- desktop/main.js: grant media (camera/mic), display-capture, notifications, clipboard,
  fullscreen, pointerLock for the app origin (Electron denies these by default, which
  silently broke meetings' camera/mic). Adds setPermissionRequestHandler +
  setPermissionCheckHandler on the app session.
- Clicking a notification now raises + focuses the window: preload exposes
  bizConnectNative.focusApp(), main handles 'focus-window' IPC, and the web notify()
  onclick calls it when running in the desktop shell. (home.html build batch16)
- CLIENTS.md: Phase D — inline-reply notifications (Windows Toast RemoteInput /
  Android RemoteInput / iOS UNTextInputNotificationAction) queued right after packaging.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:16:40 +05:30
Sravan 7a2ab3fc8d fix(agent): remote-control input now works (data channel + nut-js API)
Two latent bugs that broke input control on any setup:
- Data channel was created by the viewer (the answerer), so the agent's offer had
  no SCTP m-line and the channel never opened -> no input reached the agent. The
  agent (offerer) now creates the 'input' channel; the viewer receives it.
- inject.js used nut.screen.getResolution() which doesn't exist in this nut-js;
  switched to screen.width()/height() with per-session caching.

Verified end-to-end locally: screen streams + mouse injection moves the remote cursor.
Also commits desktop/ + mobile/ package-lock.json from client installs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 15:47:09 +05:30
Sravan 73b40a5d9f feat(mobile): Android prep — icons/splash assets, permissions, FCM setup
- resources/: 1024 icon.png + 2732 splash.png/splash-dark.png generated from the
  PWA icon + brand blue; wired @capacitor/assets (npm run assets) + splash-screen plugin.
- ANDROID_SETUP.md: end-to-end guide (SDK setup, cap add android, manifest permissions,
  Firebase/google-services.json + Gradle, run, Play AAB build) for package com.bizgaze.connect.
- android-permissions.xml: paste-ready POST_NOTIFICATIONS + camera/mic/WebRTC perms.
- mobile/README links the guide; setup adds `npm run assets`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 20:18:11 +05:30
Sravan 7ae0cacf74 feat(push): wire Capacitor native push into the web UI
home.html: in a Capacitor app shell, setupPush() now uses the native FCM/APNs path
instead of Web Push — requests permission, registers, POSTs the OS device token to
/api/v1/devices, deep-links on notification tap (selectChat), and unregisters the
token on logout. Web Notification prompts are suppressed on native. Fully inert in a
normal browser (Web Push unchanged). build batch15.

CLIENTS.md Phase B push items checked off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 19:56:59 +05:30
Sravan 4c75db2029 feat(push): native device-token registration + FCM/APNs senders
- /api/v1/devices (register) + /api/v1/devices/remove — auth-required, validates
  platform (ios|android), upserts by token; e2e covers register/validation/auth/remove.
- db device_tokens table + deviceTokens repo.
- push.js: FCM HTTP v1 (Android) and APNs token-based over HTTP/2 (iOS) folded into
  the single push.sendToUser path alongside Web Push; each transport independently
  config-gated and a silent no-op without creds. Dead tokens pruned on 404/410.
- docs: CLIENTS.md Phase B updated; DEPLOY.md env table adds FCM/APNs vars.

e2e 117/117.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:23:10 +05:30
Sravan 593a4677b6 feat(clients): scaffold mobile (Capacitor) + desktop (Electron) shells
Plan + decisions in CLIENTS.md (parallel mobile+desktop; desktop = technician
client + existing remote-control agent host; mobile = Capacitor wrap).

- desktop/: Electron technician client — loads the live Connect UI, native
  screen capture via setDisplayMediaRequestHandler, persisted session, external
  links to browser; electron-builder config for Win/Mac/Linux installers.
- mobile/: Capacitor project — server.url loads Connect UI, push/camera/status-bar
  plugins declared, www splash fallback; iOS/Android added via `cap add`.
- Reuses the existing /api/v1 + Bearer auth backend; no web-code changes.
- .gitignore: ignore generated mobile/android, mobile/ios platform dirs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 17:49:41 +05:30
Sravan f517c153c1 docs(deploy): add operational guardrails + env/verification checklist for IT
Single-instance requirement, ALLOW_LOCAL_LOGIN-off, server-side directory token,
no-store HTML, Node>=22.5/web-push, required env vars (SSO/VAPID/TURN), and the
window.__BUILD per-release verification step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 17:06:08 +05:30
Sravan 06f0b08a18 feat(chat): rich shared-media view, status selector, drag-drop upload + fixes
Chat / shared media:
- Media/Docs/Links: clean underline tabs (green active), audio & video now
  classified as Media and rendered as tiles (download + headphone/play +
  duration) instead of broken-image glyphs; image thumbnails -> lightbox
- Drag-and-drop a file/video/image onto a conversation to send it
- Fix: removed #chatPanel{position:relative} override that collapsed the
  conversation pane (messages spilled into a clipped right-edge strip)
- "Media, links & docs" row cleaned up (no folder/placeholder icon); media
  popup keeps the back arrow, drops the redundant close button

Presence / status:
- Single current-status row with an arrow that expands Available/Away/On leave
- On leave = circle with minus, In a call = solid red indicators
- Fix: selected-status tick now follows the chosen option

Icons: added headphones + play; bumped icons.js cache-bust to v4

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 17:01:15 +05:30
Sravan e9e5c7f406 fix(pwa): white icon tile for contrast + cache-bust icon URLs (v2)
Logo was dark-on-blue (low contrast); now centered on a white tile like the
header treatment. Icon URLs versioned (?v=2) so browsers/installs fetch the new
ones. Build marker -> pwa2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 15:02:11 +05:30
Sravan a427be9b6f fix(cache): send Cache-Control: no-store on all JSON/404 responses
Prevents a 404 (e.g. /manifest.json fetched before deploy) from being cached on
a device and persisting after the file exists — the cause of the manifest 404
on mobile but not desktop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 17:58:23 +05:30
Sravan b576ed372a feat(pwa): installable app (Add to Home Screen) for Android + iOS
- manifest.json (standalone display, theme color, maskable icons 192/512).
- generated square icons + apple-touch-icon (180) from the logo.
- apple-mobile-web-app + theme-color meta in home.html.
- sw.js gets a no-op fetch handler so it meets installability criteria (still
  no caching). static.js serves .json/.webmanifest with correct MIME.
- Installing as a PWA also unlocks Web Push on iOS (Apple requires Add to Home Screen).
Build marker -> pwa1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 17:13:01 +05:30
Sravan f4a23ae805 fix(cache): serve HTML with no-store so deploys reach browsers without a hard refresh
Browsers were serving a cached old home.html on normal reloads (only incognito/
hard-refresh got the new one). HTML now sends Cache-Control: no-store; versioned
assets keep ETag revalidation. Bumps build marker to push4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 16:30:17 +05:30
Sravan f7ddb2e7ae fix(push): wait for active SW before subscribe + log every step (subscribe was failing silently)
subscribePush() swallowed all errors, so if pushManager.subscribe() failed
(e.g. called before the service worker was active) nobody ever subscribed and
there was no trace. Now: await serviceWorker.ready before subscribing, and
console.log/warn each step so the real failure is visible. Server send path
verified independently (web-push builds valid VAPID requests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 13:57:03 +05:30
Sravan 5edb3fa241 fix(chat): dedup sent message in sendMessage too (WS echo can beat the POST response)
The server echoes the sender's own message over WS before returning the HTTP
response, so onChatMessage could append it before sendMessage's await resolved,
then sendMessage appended again -> double. Both append paths now dedup by id.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 13:39:42 +05:30
Sravan 88d7657364 chore: add build marker (window.__BUILD) to home.html for deploy verification
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 12:38:35 +05:30
Sravan 1272b81cee feat(push): Web Push notifications for backgrounded/closed/mobile tabs
Page-level Notifications can't fire when a tab is frozen/closed (and never on
mobile), which is why recipients on another tab/app got nothing. Adds a
notification-only service worker (sw.js, no caching) + Web Push:

- push.js: optional web-push wrapper (no-op unless web-push installed AND
  VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY set -> app unaffected if unconfigured).
- push_subscriptions table + R.pushSubs repo (upsert by endpoint, prune dead).
- /api/push/vapid|subscribe|unsubscribe; DM + group message routes also send a
  Web Push to recipients.
- Client registers /sw.js, subscribes when permission granted; hidden-tab popups
  are left to push to avoid double-notifying (pushActive flag); SW suppresses the
  OS popup when a tab is visible. Removes the old code that unregistered SWs.

Requires (prod, once): npm install + VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY/VAPID_SUBJECT env.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 21:58:49 +05:30
Sravan d50d4bde47 fix(icons): proper end-call (hang-up) glyph + cache-bust icons.js (v3)
- callEnd is now a rotated-handset hang-up icon (was a phone-off placeholder).
- All pages reference /icons.js?v=3 so browsers/proxies fetch the corrected
  file instead of a stale cached copy (fixes 'old end icon' + icons not
  appearing until a re-render when an old/404 icons.js was cached).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 18:47:24 +05:30
Sravan 1f4516d69b fix(chat): dedup own echoed message so sent messages don't show twice
Server echoes your own message back over WS (multi-tab/device sync) and
sendMessage already appended it optimistically; onChatMessage now skips the
append if the id is already in the thread.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 18:06:00 +05:30
Sravan fcd6a60baa fix(prod): add missing public/icons.js (was untracked -> 404 in prod)
icons.js was never committed (untracked, lost from disk), so every page
404'd /icons.js and stalled at Loading. Restored from commit e05a788 and
added 16 icons referenced by current code but absent in that snapshot
(bell, bold, italic, strikethrough, code, list, listOrdered, type, crown,
checkCheck, calendarX, calendarClock, fileText, record, callEnd, settings).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 17:41:44 +05:30
Sravan bda63b6f0a Merge origin/master (TURN/coturn + BizGaze-only login) into feature tree
Resolved conflicts in routes.js and share.html: kept the dev tree's superset
(ALLOW_LOCAL_LOGIN dev escape, avatar sync, richer login errors) which already
includes the incoming production BizGaze-only behavior; took the more descriptive
incoming comments. Restored 5 untracked modules (chat, calls, directory,
reminders, webhooks) that were missing from disk — required by routes/signaling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:27:59 +05:30
Sravan 27355cec76 BizGaze Connect: chat, meetings, recordings, mobile, directory + UI fixes
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:15:29 +05:30
Sravan 0a739ee2fd Merge branch 'hotfix/bizgaze-only-login' of Sravan/BizGaze_Remote into master 2026-06-16 09:21:35 +00:00
Sravan 54b74d5db1 feat(turn): self-hosted coturn support + time-limited creds + failure UX
- /api/ice: when TURN_SECRET is set, mint short-lived HMAC credentials
  (coturn use-auth-secret) so no permanent password is exposed and the relay
  can't be abused. Static TURN_USERNAME/CREDENTIAL still supported.
- share.html: connection watchdog + clear "couldn't connect on this network"
  message instead of a blank screen when no path can be established.
- deploy/coturn: ready-to-run turnserver.conf + docker-compose + README for
  hosting our own TURN on a VM we own (flat cost, no per-GB billing).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 14:36:05 +05:30
Sravan 6ac280f178 fix(webrtc): use TURN on desktop too (screen share blank/disconnect)
TURN relay candidates were applied only when IS_MOBILE, leaving desktop
clients STUN-only. Customers behind symmetric NAT / corporate firewalls /
VPNs then couldn't establish the peer connection -> connectionState 'failed'
-> "connection lost" -> blank screen right after granting permissions. This
hit only some users (those needing a relay).

Apply the /api/ice config (STUN + managed TURN) regardless of device, in both
the customer (share.html) and agent (connect.html) flows. Requires TURN_URLS /
TURN_USERNAME / TURN_CREDENTIAL to be set in the production environment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 13:15:06 +05:30
Sravan caba3b3a21 Merge branch 'hotfix/bizgaze-only-login' of Sravan/BizGaze_Remote into master 2026-06-16 05:24:28 +00:00
Sravan 5448cf0614 fix(auth): BizGaze-only login + admin sees all sessions
When BIZGAZE_LOGIN_URL is configured, verify credentials ONLY against BizGaze
(no local-password fallback) so stale in-app accounts can't shadow a BizGaze
login. Everyone is then provisioned into the same tenant, restoring the admin's
team-scoped "see all sessions" report.

- login: BizGaze-only when the IdP is configured; local path kept for dev/tests
- provisionFromBizgaze: keep role in sync with BizGaze (isAdmin) on every login;
  optional ADMIN_EMAILS allowlist as a lockout safety net
- block POST /api/users (add local agent) when BizGaze is the IdP — this is what
  previously split tenants
- scripts/migrate-bizgaze-only.js: one-time, dry-run-by-default cleanup that
  deletes pre-BizGaze local accounts (no sso_user_created audit entry)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:02:08 +05:30
Sravan d045847a59 added Username or password do not match" + lockout warning 2026-06-12 01:13:31 +05:30
Sravan ba8bfc3f46 feat: BizGaze Connect home, BizGaze login, modular backend, /api/v1
User-facing
- New post-login home (/home): chat rail + Share/Connect (embedded) + Meeting; login lives here when logged out
- Landing: "Log in with BizGaze" + no-login screen share
- Console replaced by a role-scoped Dashboard (/dashboard): admins see all team sessions, others see only their own; stats + CSV/PDF export
- Recordings saved as MP4 (H.264/AAC) with WebM fallback; old .webm still downloadable
- Fix: duplicate "Sign in" on the login card

Auth / integration
- BizGaze as identity provider: /api/login validates against BIZGAZE_LOGIN_URL (env-gated) and provisions a local user
- Phase 2 start: /api/v1 alias for all /api routes; Authorization: Bearer accepted across HTTP + WS; login returns a token (for native desktop/mobile clients)

Backend refactor (Phase 1, behavior-preserving)
- Split server.js into config/lib/session/presence/routes/static/signaling + repos (data-access) + bizgaze (service)
- All SQL behind repos.js, tenant-scoped (tenantId == team_id for now)
- e2e updated to current flow (21/21 pass before and after)

Docs: ARCHITECTURE.md (target architecture + phased plan), CLAUDE.md repo layout, .env.example BIZGAZE_LOGIN_URL

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 00:40:07 +05:30
Sravan f6ebaa7bfb Merge branch 'master' of https://code.bizgaze.com/Sravan/BizGaze_Remote 2026-06-10 17:34:35 +05:30