From 7a40ca1b26d0b85836c0081c9d3d5cdca013ac97 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 4 Feb 2025 12:38:40 -0800 Subject: [PATCH] WIP: generate SPA checksum to validate web page --- .../platform/listeners/script-signature.ts | 5 +++ .../src/platform/listeners/update-badge.ts | 23 +++++++++++- apps/web/scripts/generateChecksums.js | 35 +++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 apps/browser/src/platform/listeners/script-signature.ts create mode 100644 apps/web/scripts/generateChecksums.js diff --git a/apps/browser/src/platform/listeners/script-signature.ts b/apps/browser/src/platform/listeners/script-signature.ts new file mode 100644 index 00000000000..5a6f2e45aec --- /dev/null +++ b/apps/browser/src/platform/listeners/script-signature.ts @@ -0,0 +1,5 @@ +import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; + +export class ScriptSignature { + constructor(private readonly cryptoFunctionService: CryptoFunctionService) {} +} diff --git a/apps/browser/src/platform/listeners/update-badge.ts b/apps/browser/src/platform/listeners/update-badge.ts index f67b96c847f..3d3d343819a 100644 --- a/apps/browser/src/platform/listeners/update-badge.ts +++ b/apps/browser/src/platform/listeners/update-badge.ts @@ -5,6 +5,7 @@ import { firstValueFrom } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { BadgeSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/badge-settings.service"; +import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -22,6 +23,7 @@ export class UpdateBadge { private authService: AuthService; private badgeSettingsService: BadgeSettingsServiceAbstraction; private cipherService: CipherService; + private environmentService: EnvironmentService; private badgeAction: typeof chrome.action | typeof chrome.browserAction; private sidebarAction: OperaSidebarAction | FirefoxSidebarAction; private win: Window & typeof globalThis; @@ -31,6 +33,7 @@ export class UpdateBadge { this.sidebarAction = BrowserApi.getSidebarAction(self); this.win = win; + this.environmentService = services.environmentService; this.badgeSettingsService = services.badgeSettingsService; this.authService = services.authService; this.cipherService = services.cipherService; @@ -38,9 +41,19 @@ export class UpdateBadge { async run(opts?: { tabId?: number; windowId?: number }): Promise { const authStatus = await this.authService.getAuthStatus(); + const environment = await firstValueFrom(this.environmentService.cloudWebVaultUrl$); await this.setBadgeBackgroundColor(); + const tab = await this.getTab(opts?.tabId, opts?.windowId); + await this.setAuthStatusBadge(authStatus, tab); + if (tab?.url?.startsWith(environment)) { + await this.setValidWebVaultBadge(authStatus, tab); + return; + } + } + + async setAuthStatusBadge(authStatus: AuthenticationStatus, tab: chrome.tabs.Tab) { switch (authStatus) { case AuthenticationStatus.LoggedOut: { await this.setLoggedOut(); @@ -51,13 +64,21 @@ export class UpdateBadge { break; } case AuthenticationStatus.Unlocked: { - const tab = await this.getTab(opts?.tabId, opts?.windowId); await this.setUnlocked({ tab, windowId: tab?.windowId }); break; } } } + async setValidWebVaultBadge(authStatus: AuthenticationStatus, tab: chrome.tabs.Tab) { + if (authStatus === AuthenticationStatus.Unlocked) { + await this.setUnlocked({ tab, windowId: tab?.windowId }); + } else { + await this.setBadgeIcon("_gray", tab.windowId); + await this.clearBadgeText(); + } + } + async setLoggedOut(): Promise { await this.setBadgeIcon("_gray"); await this.clearBadgeText(); diff --git a/apps/web/scripts/generateChecksums.js b/apps/web/scripts/generateChecksums.js new file mode 100644 index 00000000000..23264ba351c --- /dev/null +++ b/apps/web/scripts/generateChecksums.js @@ -0,0 +1,35 @@ +const fs = require("fs"); +const path = require("path"); +const crypto = require("crypto"); + +// Path to the built index.html file. The expectation is that this file contains