mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[PM-12024] Move Lock All To Happen in Background (#11047)
* Move Lock All To Happen in Background - Make it done serially - Have the promise only resolve once it's complete * Unlock Active Account Last * Add Tests * Update Comment
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { CommonModule, Location } from "@angular/common";
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { Subject, firstValueFrom, map, of, startWith, switchMap, takeUntil } from "rxjs";
|
||||
import { Subject, firstValueFrom, map, of, startWith, switchMap } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { LockService } from "@bitwarden/auth/common";
|
||||
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service";
|
||||
import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
@@ -70,6 +71,7 @@ export class AccountSwitcherComponent implements OnInit, OnDestroy {
|
||||
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
|
||||
private authService: AuthService,
|
||||
private configService: ConfigService,
|
||||
private lockService: LockService,
|
||||
) {}
|
||||
|
||||
get accountLimit() {
|
||||
@@ -131,26 +133,8 @@ export class AccountSwitcherComponent implements OnInit, OnDestroy {
|
||||
|
||||
async lockAll() {
|
||||
this.loading = true;
|
||||
this.availableAccounts$
|
||||
.pipe(
|
||||
map((accounts) =>
|
||||
accounts
|
||||
.filter((account) => account.id !== this.specialAddAccountId)
|
||||
.sort((a, b) => (a.isActive ? -1 : b.isActive ? 1 : 0)) // Log out of the active account first
|
||||
.map((account) => account.id),
|
||||
),
|
||||
switchMap(async (accountIds) => {
|
||||
if (accountIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Must lock active (first) account first, then order doesn't matter
|
||||
await this.vaultTimeoutService.lock(accountIds.shift());
|
||||
await Promise.all(accountIds.map((id) => this.vaultTimeoutService.lock(id)));
|
||||
}),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe(() => this.router.navigate(["lock"]));
|
||||
await this.lockService.lockAll();
|
||||
await this.router.navigate(["lock"]);
|
||||
}
|
||||
|
||||
async logOut(userId: UserId) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { filter, firstValueFrom } from "rxjs";
|
||||
|
||||
import { LockService } from "@bitwarden/auth/common";
|
||||
import {
|
||||
CommandDefinition,
|
||||
MessageListener,
|
||||
MessageSender,
|
||||
} from "@bitwarden/common/platform/messaging";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
|
||||
const LOCK_ALL_FINISHED = new CommandDefinition<{ requestId: string }>("lockAllFinished");
|
||||
const LOCK_ALL = new CommandDefinition<{ requestId: string }>("lockAll");
|
||||
|
||||
export class ForegroundLockService implements LockService {
|
||||
constructor(
|
||||
private readonly messageSender: MessageSender,
|
||||
private readonly messageListener: MessageListener,
|
||||
) {}
|
||||
|
||||
async lockAll(): Promise<void> {
|
||||
const requestId = Utils.newGuid();
|
||||
const finishMessage = firstValueFrom(
|
||||
this.messageListener
|
||||
.messages$(LOCK_ALL_FINISHED)
|
||||
.pipe(filter((m) => m.requestId === requestId)),
|
||||
);
|
||||
|
||||
this.messageSender.send(LOCK_ALL, { requestId });
|
||||
|
||||
await finishMessage;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
AuthRequestService,
|
||||
LoginEmailServiceAbstraction,
|
||||
LogoutReason,
|
||||
DefaultLockService,
|
||||
} from "@bitwarden/auth/common";
|
||||
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
||||
@@ -1065,6 +1066,9 @@ export default class MainBackground {
|
||||
this.scriptInjectorService,
|
||||
this.configService,
|
||||
);
|
||||
|
||||
const lockService = new DefaultLockService(this.accountService, this.vaultTimeoutService);
|
||||
|
||||
this.runtimeBackground = new RuntimeBackground(
|
||||
this,
|
||||
this.autofillService,
|
||||
@@ -1079,6 +1083,7 @@ export default class MainBackground {
|
||||
this.fido2Background,
|
||||
messageListener,
|
||||
this.accountService,
|
||||
lockService,
|
||||
);
|
||||
this.nativeMessagingBackground = new NativeMessagingBackground(
|
||||
this.cryptoService,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { firstValueFrom, map, mergeMap, of, switchMap } from "rxjs";
|
||||
|
||||
import { LockService } from "@bitwarden/auth/common";
|
||||
import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AutofillOverlayVisibility, ExtensionCommand } from "@bitwarden/common/autofill/constants";
|
||||
@@ -48,6 +49,7 @@ export default class RuntimeBackground {
|
||||
private fido2Background: Fido2Background,
|
||||
private messageListener: MessageListener,
|
||||
private accountService: AccountService,
|
||||
private readonly lockService: LockService,
|
||||
) {
|
||||
// onInstalled listener must be wired up before anything else, so we do it in the ctor
|
||||
chrome.runtime.onInstalled.addListener((details: any) => {
|
||||
@@ -245,6 +247,12 @@ export default class RuntimeBackground {
|
||||
case "lockVault":
|
||||
await this.main.vaultTimeoutService.lock(msg.userId);
|
||||
break;
|
||||
case "lockAll":
|
||||
{
|
||||
await this.lockService.lockAll();
|
||||
this.messagingService.send("lockAllFinished", { requestId: msg.requestId });
|
||||
}
|
||||
break;
|
||||
case "logout":
|
||||
await this.main.logout(msg.expired, msg.userId);
|
||||
break;
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from "@bitwarden/angular/services/injection-tokens";
|
||||
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
|
||||
import { AnonLayoutWrapperDataService } from "@bitwarden/auth/angular";
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { LockService, PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { EventCollectionService as EventCollectionServiceAbstraction } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service";
|
||||
import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout.service";
|
||||
@@ -91,6 +91,7 @@ import { TotpService } from "@bitwarden/common/vault/services/totp.service";
|
||||
import { DialogService, ToastService } from "@bitwarden/components";
|
||||
import { PasswordRepromptService } from "@bitwarden/vault";
|
||||
|
||||
import { ForegroundLockService } from "../../auth/popup/accounts/foreground-lock.service";
|
||||
import { ExtensionAnonLayoutWrapperDataService } from "../../auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper-data.service";
|
||||
import { AutofillService as AutofillServiceAbstraction } from "../../autofill/services/abstractions/autofill.service";
|
||||
import AutofillService from "../../autofill/services/autofill.service";
|
||||
@@ -560,6 +561,11 @@ const safeProviders: SafeProvider[] = [
|
||||
useClass: ExtensionAnonLayoutWrapperDataService,
|
||||
deps: [],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: LockService,
|
||||
useClass: ForegroundLockService,
|
||||
deps: [MessageSender, MessageListener],
|
||||
}),
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
Reference in New Issue
Block a user