[PM-6797] Prevent account switching race condition on desktop & enable worker decryption (#9312)
* Prevent account switching race condition on desktop This enables us to allow background thread / multithread bulk decryption on desktop. * Disable account switcher component during switching
This commit is contained in:
parent
f03dabb6d6
commit
e977dacdcf
|
@ -210,7 +210,6 @@ import { AutofillService as AutofillServiceAbstraction } from "../autofill/servi
|
|||
import AutofillService from "../autofill/services/autofill.service";
|
||||
import { SafariApp } from "../browser/safariApp";
|
||||
import { BrowserApi } from "../platform/browser/browser-api";
|
||||
import { flagEnabled } from "../platform/flags";
|
||||
import { UpdateBadge } from "../platform/listeners/update-badge";
|
||||
/* eslint-disable no-restricted-imports */
|
||||
import { ChromeMessageSender } from "../platform/messaging/chrome-message.sender";
|
||||
|
@ -484,14 +483,13 @@ export default class MainBackground {
|
|||
storageServiceProvider,
|
||||
);
|
||||
|
||||
this.encryptService =
|
||||
flagEnabled("multithreadDecryption") && BrowserApi.isManifestVersion(2)
|
||||
? new MultithreadEncryptServiceImplementation(
|
||||
this.cryptoFunctionService,
|
||||
this.logService,
|
||||
true,
|
||||
)
|
||||
: new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, true);
|
||||
this.encryptService = BrowserApi.isManifestVersion(2)
|
||||
? new MultithreadEncryptServiceImplementation(
|
||||
this.cryptoFunctionService,
|
||||
this.logService,
|
||||
true,
|
||||
)
|
||||
: new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, true);
|
||||
|
||||
this.singleUserStateProvider = new DefaultSingleUserStateProvider(
|
||||
storageServiceProvider,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"devFlags": {},
|
||||
"flags": {
|
||||
"multithreadDecryption": false,
|
||||
"enableCipherKeyEncryption": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -422,12 +422,13 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
} else {
|
||||
this.messagingService.send("unlocked");
|
||||
this.loading = true;
|
||||
await this.syncService.fullSync(true);
|
||||
await this.syncService.fullSync(false);
|
||||
this.loading = false;
|
||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.router.navigate(["vault"]);
|
||||
}
|
||||
this.messagingService.send("finishSwitchAccount");
|
||||
break;
|
||||
}
|
||||
case "systemSuspended":
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
cdkOverlayOrigin
|
||||
#trigger="cdkOverlayOrigin"
|
||||
[hidden]="!view.showSwitcher"
|
||||
[disabled]="disabled"
|
||||
aria-haspopup="dialog"
|
||||
>
|
||||
<ng-container *ngIf="view.activeAccount; else noActiveAccount">
|
||||
|
|
|
@ -12,6 +12,7 @@ import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authenticatio
|
|||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { CommandDefinition, MessageListener } from "@bitwarden/common/platform/messaging";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
|
||||
type ActiveAccount = {
|
||||
|
@ -75,12 +76,14 @@ export class AccountSwitcherComponent {
|
|||
showSwitcher$: Observable<boolean>;
|
||||
|
||||
numberOfAccounts$: Observable<number>;
|
||||
disabled = false;
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
private authService: AuthService,
|
||||
private avatarService: AvatarService,
|
||||
private messagingService: MessagingService,
|
||||
private messageListener: MessageListener,
|
||||
private router: Router,
|
||||
private environmentService: EnvironmentService,
|
||||
private loginEmailService: LoginEmailServiceAbstraction,
|
||||
|
@ -159,7 +162,13 @@ export class AccountSwitcherComponent {
|
|||
async switch(userId: string) {
|
||||
this.close();
|
||||
|
||||
this.messagingService.send("switchAccount", { userId: userId });
|
||||
this.disabled = true;
|
||||
const accountSwitchFinishedPromise = firstValueFrom(
|
||||
this.messageListener.messages$(new CommandDefinition("finishSwitchAccount")),
|
||||
);
|
||||
this.messagingService.send("switchAccount", { userId });
|
||||
await accountSwitchFinishedPromise;
|
||||
this.disabled = false;
|
||||
}
|
||||
|
||||
async addAccount() {
|
||||
|
|
|
@ -154,7 +154,7 @@ import { StateFactory } from "@bitwarden/common/platform/factories/state-factory
|
|||
import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging";
|
||||
// eslint-disable-next-line no-restricted-imports -- Used for dependency injection
|
||||
import { SubjectMessageSender } from "@bitwarden/common/platform/messaging/internal";
|
||||
import { devFlagEnabled, flagEnabled } from "@bitwarden/common/platform/misc/flags";
|
||||
import { devFlagEnabled } from "@bitwarden/common/platform/misc/flags";
|
||||
import { Account } from "@bitwarden/common/platform/models/domain/account";
|
||||
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
||||
import { AppIdService } from "@bitwarden/common/platform/services/app-id.service";
|
||||
|
@ -162,7 +162,6 @@ import { ConfigApiService } from "@bitwarden/common/platform/services/config/con
|
|||
import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service";
|
||||
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/services/crypto.service";
|
||||
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
|
||||
import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/multithread-encrypt.service.implementation";
|
||||
import { DefaultBroadcasterService } from "@bitwarden/common/platform/services/default-broadcaster.service";
|
||||
import { DefaultEnvironmentService } from "@bitwarden/common/platform/services/default-environment.service";
|
||||
|
@ -822,7 +821,7 @@ const safeProviders: SafeProvider[] = [
|
|||
}),
|
||||
safeProvider({
|
||||
provide: EncryptService,
|
||||
useFactory: encryptServiceFactory,
|
||||
useClass: MultithreadEncryptServiceImplementation,
|
||||
deps: [CryptoFunctionServiceAbstraction, LogService, LOG_MAC_FAILURES],
|
||||
}),
|
||||
safeProvider({
|
||||
|
@ -1242,16 +1241,6 @@ const safeProviders: SafeProvider[] = [
|
|||
}),
|
||||
];
|
||||
|
||||
function encryptServiceFactory(
|
||||
cryptoFunctionservice: CryptoFunctionServiceAbstraction,
|
||||
logService: LogService,
|
||||
logMacFailures: boolean,
|
||||
): EncryptService {
|
||||
return flagEnabled("multithreadDecryption")
|
||||
? new MultithreadEncryptServiceImplementation(cryptoFunctionservice, logService, logMacFailures)
|
||||
: new EncryptServiceImplementation(cryptoFunctionservice, logService, logMacFailures);
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
// Do not register your dependency here! Add it to the typesafeProviders array using the helper function
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// required to avoid linting errors when there are no flags
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type SharedFlags = {
|
||||
multithreadDecryption: boolean;
|
||||
showPasswordless?: boolean;
|
||||
enableCipherKeyEncryption?: boolean;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue