From a2ccee984b6f122c498d8d9e9d258c78e82bbef4 Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Thu, 27 Feb 2025 16:39:33 +0100 Subject: [PATCH] Simplify main logout flow to use page redirect (#622) --- browser-extensions/chrome/src/app/App.tsx | 4 ++- .../src/app/components/Layout/UserMenu.tsx | 5 +-- .../chrome/src/app/context/DbContext.tsx | 1 + .../chrome/src/app/pages/Logout.tsx | 31 +++++++++++++++++++ .../chrome/src/shared/WebApiService.ts | 4 +-- 5 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 browser-extensions/chrome/src/app/pages/Logout.tsx diff --git a/browser-extensions/chrome/src/app/App.tsx b/browser-extensions/chrome/src/app/App.tsx index ca682ab0f..3fa389cf2 100644 --- a/browser-extensions/chrome/src/app/App.tsx +++ b/browser-extensions/chrome/src/app/App.tsx @@ -9,12 +9,13 @@ import CredentialsList from './pages/CredentialsList'; import EmailsList from './pages/EmailsList'; import LoadingSpinner from './components/LoadingSpinner'; import Home from './pages/Home'; -import './style.css'; import CredentialDetails from './pages/CredentialDetails'; import EmailDetails from './pages/EmailDetails'; import Settings from './pages/Settings'; import GlobalStateChangeHandler from './components/GlobalStateChangeHandler'; import { useLoading } from './context/LoadingContext'; +import Logout from './pages/Logout'; +import './style.css'; /** * Route configuration. @@ -44,6 +45,7 @@ const App: React.FC = () => { { path: '/emails', element: , showBackButton: false }, { path: '/emails/:id', element: , showBackButton: true, title: 'Email details' }, { path: '/settings', element: , showBackButton: false }, + { path: '/logout', element: , showBackButton: false }, ]; useEffect(() => { diff --git a/browser-extensions/chrome/src/app/components/Layout/UserMenu.tsx b/browser-extensions/chrome/src/app/components/Layout/UserMenu.tsx index d14752c62..f171ba087 100644 --- a/browser-extensions/chrome/src/app/components/Layout/UserMenu.tsx +++ b/browser-extensions/chrome/src/app/components/Layout/UserMenu.tsx @@ -47,10 +47,7 @@ export const UserMenu: React.FC = () => { */ const onLogout = async () : Promise => { showLoading(); - await authContext.logout(); - navigate('/', { replace: true }); - // Delay for 100ms for improved UX - await new Promise(resolve => setTimeout(resolve, 100)); + navigate('/logout', { replace: true }); hideLoading(); }; diff --git a/browser-extensions/chrome/src/app/context/DbContext.tsx b/browser-extensions/chrome/src/app/context/DbContext.tsx index 81170725d..72a8f6a83 100644 --- a/browser-extensions/chrome/src/app/context/DbContext.tsx +++ b/browser-extensions/chrome/src/app/context/DbContext.tsx @@ -2,6 +2,7 @@ import React, { createContext, useContext, useState, useEffect, useCallback, use import SqliteClient from '../../shared/SqliteClient'; import { VaultResponse } from '../../shared/types/webapi/VaultResponse'; import EncryptionUtility from '../../shared/EncryptionUtility'; + type DbContextType = { sqliteClient: SqliteClient | null; dbInitialized: boolean; diff --git a/browser-extensions/chrome/src/app/pages/Logout.tsx b/browser-extensions/chrome/src/app/pages/Logout.tsx new file mode 100644 index 000000000..577becb09 --- /dev/null +++ b/browser-extensions/chrome/src/app/pages/Logout.tsx @@ -0,0 +1,31 @@ +import React, { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useAuth } from '../context/AuthContext'; + +/** + * Logout page. + */ +const Logout: React.FC = () => { + const authContext = useAuth(); + const navigate = useNavigate(); + + /** + * Logout and navigate to home page. + */ + useEffect(() => { + /** + * Perform logout via async method to ensure logout is completed before navigating to home page. + */ + const performLogout = async () : Promise => { + await authContext.logout(); + navigate('/'); + }; + + performLogout(); + }, [authContext, navigate]); + + // Return null since this is just a functional component that handles logout. + return null; +}; + +export default Logout; diff --git a/browser-extensions/chrome/src/shared/WebApiService.ts b/browser-extensions/chrome/src/shared/WebApiService.ts index c0af80d88..367eb0f91 100644 --- a/browser-extensions/chrome/src/shared/WebApiService.ts +++ b/browser-extensions/chrome/src/shared/WebApiService.ts @@ -308,7 +308,7 @@ export class WebApiService { /** * When the reader has finished loading, convert the result to a Base64 string. */ - reader.onloadend = () : void => { + reader.onloadend = (): void => { const result = reader.result; if (typeof result === 'string') { resolve(result.split(',')[1]); // Remove the data URL prefix @@ -320,7 +320,7 @@ export class WebApiService { /** * If the reader encounters an error, reject the promise with a proper Error object. */ - reader.onerror = () : void => { + reader.onerror = (): void => { reject(new Error('Failed to read blob as Data URL')); }; reader.readAsDataURL(blob);