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:
49
libs/auth/src/common/services/accounts/lock.service.ts
Normal file
49
libs/auth/src/common/services/accounts/lock.service.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { combineLatest, firstValueFrom, map } from "rxjs";
|
||||
|
||||
import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
|
||||
export abstract class LockService {
|
||||
/**
|
||||
* Locks all accounts.
|
||||
*/
|
||||
abstract lockAll(): Promise<void>;
|
||||
}
|
||||
|
||||
export class DefaultLockService implements LockService {
|
||||
constructor(
|
||||
private readonly accountService: AccountService,
|
||||
private readonly vaultTimeoutService: VaultTimeoutService,
|
||||
) {}
|
||||
|
||||
async lockAll() {
|
||||
const accounts = await firstValueFrom(
|
||||
combineLatest([this.accountService.activeAccount$, this.accountService.accounts$]).pipe(
|
||||
map(([activeAccount, accounts]) => {
|
||||
const otherAccounts = Object.keys(accounts) as UserId[];
|
||||
|
||||
if (activeAccount == null) {
|
||||
return { activeAccount: null, otherAccounts: otherAccounts };
|
||||
}
|
||||
|
||||
return {
|
||||
activeAccount: activeAccount.id,
|
||||
otherAccounts: otherAccounts.filter((accountId) => accountId !== activeAccount.id),
|
||||
};
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
for (const otherAccount of accounts.otherAccounts) {
|
||||
await this.vaultTimeoutService.lock(otherAccount);
|
||||
}
|
||||
|
||||
// Do the active account last in case we ever try to route the user on lock
|
||||
// that way this whole operation will be complete before that routing
|
||||
// could take place.
|
||||
if (accounts.activeAccount != null) {
|
||||
await this.vaultTimeoutService.lock(accounts.activeAccount);
|
||||
}
|
||||
}
|
||||
}
|
||||
43
libs/auth/src/common/services/accounts/lock.services.spec.ts
Normal file
43
libs/auth/src/common/services/accounts/lock.services.spec.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { mock } from "jest-mock-extended";
|
||||
|
||||
import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout.service";
|
||||
import { mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { DefaultLockService } from "./lock.service";
|
||||
|
||||
describe("DefaultLockService", () => {
|
||||
const mockUser1 = "user1" as UserId;
|
||||
const mockUser2 = "user2" as UserId;
|
||||
const mockUser3 = "user3" as UserId;
|
||||
|
||||
const accountService = mockAccountServiceWith(mockUser1);
|
||||
const vaultTimeoutService = mock<VaultTimeoutService>();
|
||||
|
||||
const sut = new DefaultLockService(accountService, vaultTimeoutService);
|
||||
describe("lockAll", () => {
|
||||
it("locks the active account last", async () => {
|
||||
await accountService.addAccount(mockUser2, {
|
||||
name: "name2",
|
||||
email: "email2@example.com",
|
||||
emailVerified: false,
|
||||
});
|
||||
|
||||
await accountService.addAccount(mockUser3, {
|
||||
name: "name3",
|
||||
email: "email3@example.com",
|
||||
emailVerified: false,
|
||||
});
|
||||
|
||||
await sut.lockAll();
|
||||
|
||||
expect(vaultTimeoutService.lock).toHaveBeenCalledTimes(3);
|
||||
// Non-Active users should be called first
|
||||
expect(vaultTimeoutService.lock).toHaveBeenNthCalledWith(1, mockUser2);
|
||||
expect(vaultTimeoutService.lock).toHaveBeenNthCalledWith(2, mockUser3);
|
||||
|
||||
// Active user should be called last
|
||||
expect(vaultTimeoutService.lock).toHaveBeenNthCalledWith(3, mockUser1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,3 +4,4 @@ export * from "./login-strategies/login-strategy.service";
|
||||
export * from "./user-decryption-options/user-decryption-options.service";
|
||||
export * from "./auth-request/auth-request.service";
|
||||
export * from "./register-route.service";
|
||||
export * from "./accounts/lock.service";
|
||||
|
||||
Reference in New Issue
Block a user