From 3ff5ee4b6c34a4c45961b5e4180fba33f85dbe77 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Fri, 27 Feb 2026 14:15:40 +0100 Subject: [PATCH] chore: update CHANGELOG.md to include session synchronization across tabs feature, enhancing user experience, and update @ciphera-net/ui dependency to version 0.0.72 in package.json and package-lock.json --- CHANGELOG.md | 1 + lib/auth/context.tsx | 33 ++++++++++++++++++++++----------- package-lock.json | 8 ++++---- package.json | 2 +- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4adb0f..b5f0971 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### Added - **App Switcher in User Menu.** Click your profile in the top right and you'll now see a "Ciphera Apps" section. Expand it to quickly jump between Pulse, Drop (file sharing), and your Ciphera Account settings. This makes it easier to discover and navigate between Ciphera products without signing in again. +- **Session synchronization across tabs.** When you sign out in one browser tab, you're now automatically signed out in all other tabs of the same app. This prevents situations where you might still appear signed in on another tab after logging out. The same applies to signing in — when you sign in on one tab, other tabs will update to reflect your authenticated state. - **Faster billing page loading.** Your subscription details now load much quicker when you visit the billing page. Previously, several requests to our payment provider were made one after another, which could add 1-2 seconds to the page load. Now these happen simultaneously, cutting the wait time significantly. If any request takes too long, we gracefully continue so you always see your billing information without frustrating delays. - **Faster funnel analysis for multi-step conversions.** We've significantly improved how conversion funnels are calculated. Instead of scanning your data multiple times for each step in a funnel, we now do it in a single efficient pass. This means complex funnels with multiple steps load almost instantly instead of taking seconds—or even timing out. We've also added a reasonable limit of 5 steps per funnel to ensure optimal performance. - **More reliable database connections under heavy load.** We've optimized how Pulse manages its database connections to handle much higher traffic without issues. By increasing the connection pool size and improving how connections are reused, your dashboard stays responsive even when thousands of users are viewing analytics simultaneously. We also added better monitoring so we can detect and address connection issues before they affect you. diff --git a/lib/auth/context.tsx b/lib/auth/context.tsx index a8b5810..bbef444 100644 --- a/lib/auth/context.tsx +++ b/lib/auth/context.tsx @@ -3,7 +3,7 @@ import React, { createContext, useContext, useEffect, useState, useCallback } from 'react' import { useRouter, usePathname } from 'next/navigation' import apiRequest from '@/lib/api/client' -import { LoadingOverlay } from '@ciphera-net/ui' +import { LoadingOverlay, useSessionSync } from '@ciphera-net/ui' import { logoutAction, getSessionAction, setSessionAction } from '@/app/actions/auth' import { getUserOrganizations, switchContext } from '@/lib/api/organization' import { logger } from '@/lib/utils/logger' @@ -74,10 +74,12 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { setIsLoggingOut(true) await logoutAction() localStorage.removeItem('user') - // * Clear legacy tokens if they exist - localStorage.removeItem('token') - localStorage.removeItem('refreshToken') - + // * Broadcast logout to other tabs (BroadcastChannel will handle if available) + if (typeof window !== 'undefined' && 'BroadcastChannel' in window) { + const channel = new BroadcastChannel('ciphera_session') + channel.postMessage({ type: 'LOGOUT' }) + channel.close() + } setTimeout(() => { window.location.href = '/' }, 500) @@ -142,17 +144,26 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { setUser(null) } - // * Clear legacy tokens if they exist (migration) - if (localStorage.getItem('token')) { - localStorage.removeItem('token') - localStorage.removeItem('refreshToken') - } - setLoading(false) } init() }, []) + // * Sync session across browser tabs using BroadcastChannel + useSessionSync({ + onLogout: () => { + localStorage.removeItem('user') + window.location.href = '/' + }, + onLogin: (userData) => { + setUser(userData as User) + router.refresh() + }, + onRefresh: () => { + refresh() + }, + }) + // * Organization Wall & Auto-Switch useEffect(() => { const checkOrg = async () => { diff --git a/package-lock.json b/package-lock.json index 61eddb9..183acbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "pulse-frontend", "version": "0.11.1-alpha", "dependencies": { - "@ciphera-net/ui": "^0.0.71", + "@ciphera-net/ui": "^0.0.72", "@ducanh2912/next-pwa": "^10.2.9", "@radix-ui/react-icons": "^1.3.0", "@simplewebauthn/browser": "^13.2.2", @@ -1543,9 +1543,9 @@ } }, "node_modules/@ciphera-net/ui": { - "version": "0.0.71", - "resolved": "https://npm.pkg.github.com/download/@ciphera-net/ui/0.0.71/6ec24ff340c036efb82e0417c72ec0652cc14d83", - "integrity": "sha512-kfvCXb27BKAy1wQC9epecnDU7lS/SQ7eMVG7OeTZlWmy0ZwOE09E2Q6XTk164xLdSfXRkofxAluVwsuMEY4gFg==", + "version": "0.0.72", + "resolved": "https://npm.pkg.github.com/download/@ciphera-net/ui/0.0.72/564070c6fadd0c1167f810df0b2fdf8b07718280", + "integrity": "sha512-bgDON7ZNY6ad0PWMY8ls+IGgP8dRY3c6LyQmWenp/1aTrbMPAU/jhpWXIOKsEU4ORzLKd0RbiJnHIG6SLqNiCA==", "dependencies": { "@radix-ui/react-icons": "^1.3.0", "clsx": "^2.1.0", diff --git a/package.json b/package.json index cd33eca..d9259d5 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@ciphera-net/ui": "^0.0.71", + "@ciphera-net/ui": "^0.0.72", "@ducanh2912/next-pwa": "^10.2.9", "@radix-ui/react-icons": "^1.3.0", "@simplewebauthn/browser": "^13.2.2",