diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 3a8c7f14bc0..e8834b3ffdb 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -5403,5 +5403,9 @@ }, "noPermissionsViewPage": { "message": "You do not have permissions to view this page. Try logging in with a different account." + }, + "wasmNotSupported": { + "message": "WebAssembly is not supported on your browser or is not enabled. WebAssembly is required to use the Bitwarden app.", + "description": "'WebAssembly' is a technical term and should not be translated." } } diff --git a/apps/browser/src/platform/services/sdk/browser-sdk-load.service.ts b/apps/browser/src/platform/services/sdk/browser-sdk-load.service.ts index 409ff0dea06..3ad6dc2583d 100644 --- a/apps/browser/src/platform/services/sdk/browser-sdk-load.service.ts +++ b/apps/browser/src/platform/services/sdk/browser-sdk-load.service.ts @@ -35,9 +35,9 @@ if (BrowserApi.isManifestVersion(3)) { console.info("WebAssembly is supported in this environment"); loadingPromise = import("./wasm"); } else { - // eslint-disable-next-line no-console - console.info("WebAssembly is not supported in this environment"); - loadingPromise = import("./fallback"); + loadingPromise = new Promise((_, reject) => { + reject(new Error("WebAssembly is not supported in this environment")); + }); } } @@ -51,9 +51,7 @@ async function importModule(): Promise { console.info("WebAssembly is supported in this environment"); await import("./wasm"); } else { - // eslint-disable-next-line no-console - console.info("WebAssembly is not supported in this environment"); - await import("./fallback"); + throw new Error("WebAssembly is not supported in this environment"); } // the wasm and fallback imports mutate globalThis to add the initSdk function diff --git a/apps/browser/src/platform/services/sdk/fallback.ts b/apps/browser/src/platform/services/sdk/fallback.ts deleted file mode 100644 index cee3598feda..00000000000 --- a/apps/browser/src/platform/services/sdk/fallback.ts +++ /dev/null @@ -1,8 +0,0 @@ -import * as sdk from "@bitwarden/sdk-internal"; -import * as wasm from "@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm.js"; - -import { GlobalWithWasmInit } from "./browser-sdk-load.service"; - -(globalThis as GlobalWithWasmInit).initSdk = () => { - (sdk as any).init(wasm); -}; diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts index b6d3615af94..6a26476de43 100644 --- a/apps/browser/src/popup/app.component.ts +++ b/apps/browser/src/popup/app.component.ts @@ -11,7 +11,17 @@ import { } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { NavigationEnd, Router, RouterOutlet } from "@angular/router"; -import { Subject, takeUntil, firstValueFrom, concatMap, filter, tap, map } from "rxjs"; +import { + Subject, + takeUntil, + firstValueFrom, + concatMap, + filter, + tap, + catchError, + of, + map, +} from "rxjs"; import { DeviceTrustToastService } from "@bitwarden/angular/auth/services/device-trust-toast.service.abstraction"; import { DocumentLangSetter } from "@bitwarden/angular/platform/i18n"; @@ -23,6 +33,7 @@ import { AnimationControlService } from "@bitwarden/common/platform/abstractions import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { MessageListener } from "@bitwarden/common/platform/messaging"; import { UserId } from "@bitwarden/common/types/guid"; @@ -48,23 +59,45 @@ import { DesktopSyncVerificationDialogComponent } from "./components/desktop-syn styles: [], animations: [routerTransition], template: ` -
- -
- + @if (showSdkWarning | async) { +
+ + {{ "wasmNotSupported" | i18n }} + + {{ "learnMore" | i18n }} + + +
+ } @else { +
+ +
+ + } `, standalone: false, }) export class AppComponent implements OnInit, OnDestroy { private compactModeService = inject(PopupCompactModeService); + private sdkService = inject(SdkService); private lastActivity: Date; private activeUserId: UserId; - private recordActivitySubject = new Subject(); private routerAnimations = false; private destroy$ = new Subject(); + // Show a warning if the SDK is not available. + protected showSdkWarning = this.sdkService.client$.pipe( + map(() => false), + catchError(() => of(true)), + ); + constructor( private authService: AuthService, private i18nService: I18nService, diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index 8bea41da4d6..b400cb5eec8 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -20,6 +20,8 @@ import { ButtonModule, FormFieldModule, ToastModule, + CalloutModule, + LinkModule, } from "@bitwarden/components"; import { AccountComponent } from "../auth/popup/account-switching/account.component"; @@ -87,6 +89,8 @@ import "../platform/popup/locales"; CurrentAccountComponent, FormFieldModule, ExtensionAnonLayoutWrapperComponent, + CalloutModule, + LinkModule, ], declarations: [ AppComponent,