From 0862aa64cbfba8ff6b6fcaa6f09769db7c9e11cd Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Tue, 11 Feb 2025 17:16:42 +0100 Subject: [PATCH] Add vault status check before generating new credential (#541) --- browser-extensions/chrome/background.ts | 6 ++- .../src/background/VaultMessageHandler.ts | 37 +++++++++++++++++++ .../chrome/src/contentScript/Popup.ts | 3 ++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/browser-extensions/chrome/background.ts b/browser-extensions/chrome/background.ts index a959cec2d..6e70fc729 100644 --- a/browser-extensions/chrome/background.ts +++ b/browser-extensions/chrome/background.ts @@ -1,6 +1,6 @@ import { VaultState, initialVaultState } from './src/background/VaultState'; import { setupContextMenus, handleContextMenuClick } from './src/background/ContextMenu'; -import { handleClearVault, handleCreateIdentity, handleGetCredentials, handleGetDefaultEmailDomain, handleGetDerivedKey, handleGetVault, handleStoreVault } from './src/background/VaultMessageHandler'; +import { handleClearVault, handleCreateIdentity, handleGetCredentials, handleGetDefaultEmailDomain, handleGetDerivedKey, handleGetVault, handleStoreVault, handleSyncVault } from './src/background/VaultMessageHandler'; import { handleOpenPopup, handlePopupWithCredential } from './src/background/PopupMessageHandler'; let vaultState: VaultState = { ...initialVaultState }; @@ -17,6 +17,10 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { handleStoreVault(message, vaultState, sendResponse); break; + case 'SYNC_VAULT': + handleSyncVault(vaultState, sendResponse); + break; + case 'GET_VAULT': handleGetVault(vaultState, sendResponse); break; diff --git a/browser-extensions/chrome/src/background/VaultMessageHandler.ts b/browser-extensions/chrome/src/background/VaultMessageHandler.ts index e13ed8b4e..f5d3aaff3 100644 --- a/browser-extensions/chrome/src/background/VaultMessageHandler.ts +++ b/browser-extensions/chrome/src/background/VaultMessageHandler.ts @@ -6,6 +6,7 @@ import { WebApiService } from '../shared/WebApiService'; import { Vault } from '../shared/types/webapi/Vault'; import { Credential } from '../shared/types/Credential'; import { VaultResponse } from '../shared/types/webapi/VaultResponse'; +import { StatusResponse } from '../shared/types/webapi/StatusResponse'; /** * Store the vault in browser storage. @@ -37,6 +38,42 @@ export async function handleStoreVault( } } +/** + * Sync the vault with the server to check if a newer vault is available. If so, the vault will be updated. + */ +export async function handleSyncVault( + vaultState: VaultState, + sendResponse: (response: any) => void +) : Promise { + const webApi = new WebApiService(() => {}); + await webApi.initializeBaseUrl(); + const response = await webApi.get('Auth/status') as StatusResponse; + + if (!response.supported) { + sendResponse({ success: false, error: 'Browser extension is not supported. Please update to the latest version.' }); + return; + } + + const result = await chrome.storage.session.get([ + 'vaultRevisionNumber' + ]); + + if (response.vaultRevision > result.vaultRevisionNumber) { + // Retrieve the latest vault from the server. + const vaultResponse = await webApi.get('Vault') as VaultResponse; + + // Store encrypted vault in chrome.storage.session + await chrome.storage.session.set({ + encryptedVault: vaultResponse.vault.blob, + publicEmailDomains: vaultResponse.vault.publicEmailDomainList, + privateEmailDomains: vaultResponse.vault.privateEmailDomainList, + vaultRevisionNumber: vaultResponse.vault.currentRevisionNumber + }); + } + + sendResponse({ success: true }); +} + /** * Get the vault from browser storage. */ diff --git a/browser-extensions/chrome/src/contentScript/Popup.ts b/browser-extensions/chrome/src/contentScript/Popup.ts index c4d32d901..bb3c038db 100644 --- a/browser-extensions/chrome/src/contentScript/Popup.ts +++ b/browser-extensions/chrome/src/contentScript/Popup.ts @@ -189,6 +189,9 @@ export function createAutofillPopup(input: HTMLInputElement, credentials: Creden const loadingPopup = createLoadingPopup(input, 'Creating new identity...'); try { + // Sync with api to ensure we have the latest vault. + await chrome.runtime.sendMessage({ type: 'SYNC_VAULT' }); + // Retrieve default email domain from background const response = await new Promise<{ domain: string }>((resolve) => { chrome.runtime.sendMessage({ type: 'GET_DEFAULT_EMAIL_DOMAIN' }, resolve);