mirror of
https://github.com/bitwarden/browser
synced 2025-12-14 23:33:31 +00:00
[PM-6404] Fully Integrate clearOn Events (#8134)
* Add New KeyDefinitionOption * Add New Services * Add WebStorageServiceProvider Tests * Update Error Message * Add `UserKeyDefinition` * Fix Deserialization Helpers * Fix KeyDefinition * Add `UserKeyDefinition` * Fix Deserialization Helpers * Fix KeyDefinition * Move `ClearEvent` * Cleanup * Fix Imports * Integrate onClear Events * Remove Accidental Addition * Fix Test * Add VaultTimeoutService Tests * Only Register When Current State is Null * Address Feedback
This commit is contained in:
@@ -11,6 +11,7 @@ import { MessagingService } from "../../platform/abstractions/messaging.service"
|
||||
import { PlatformUtilsService } from "../../platform/abstractions/platform-utils.service";
|
||||
import { StateService } from "../../platform/abstractions/state.service";
|
||||
import { Account } from "../../platform/models/domain/account";
|
||||
import { StateEventRunnerService } from "../../platform/state";
|
||||
import { CipherService } from "../../vault/abstractions/cipher.service";
|
||||
import { CollectionService } from "../../vault/abstractions/collection.service";
|
||||
import { FolderService } from "../../vault/abstractions/folder/folder.service.abstraction";
|
||||
@@ -28,6 +29,7 @@ describe("VaultTimeoutService", () => {
|
||||
let stateService: MockProxy<StateService>;
|
||||
let authService: MockProxy<AuthService>;
|
||||
let vaultTimeoutSettingsService: MockProxy<VaultTimeoutSettingsService>;
|
||||
let stateEventRunnerService: MockProxy<StateEventRunnerService>;
|
||||
let lockedCallback: jest.Mock<Promise<void>, [userId: string]>;
|
||||
let loggedOutCallback: jest.Mock<Promise<void>, [expired: boolean, userId?: string]>;
|
||||
|
||||
@@ -48,6 +50,7 @@ describe("VaultTimeoutService", () => {
|
||||
stateService = mock();
|
||||
authService = mock();
|
||||
vaultTimeoutSettingsService = mock();
|
||||
stateEventRunnerService = mock();
|
||||
|
||||
lockedCallback = jest.fn();
|
||||
loggedOutCallback = jest.fn();
|
||||
@@ -73,6 +76,7 @@ describe("VaultTimeoutService", () => {
|
||||
stateService,
|
||||
authService,
|
||||
vaultTimeoutSettingsService,
|
||||
stateEventRunnerService,
|
||||
lockedCallback,
|
||||
loggedOutCallback,
|
||||
);
|
||||
@@ -103,7 +107,8 @@ describe("VaultTimeoutService", () => {
|
||||
return Promise.resolve(accounts[userId]?.authStatus);
|
||||
});
|
||||
stateService.getIsAuthenticated.mockImplementation((options) => {
|
||||
return Promise.resolve(accounts[options.userId]?.isAuthenticated);
|
||||
// Just like actual state service, if no userId is given fallback to active userId
|
||||
return Promise.resolve(accounts[options.userId ?? globalSetups?.userId]?.isAuthenticated);
|
||||
});
|
||||
|
||||
vaultTimeoutSettingsService.getVaultTimeout.mockImplementation((userId) => {
|
||||
@@ -337,4 +342,80 @@ describe("VaultTimeoutService", () => {
|
||||
expectNoAction("1");
|
||||
});
|
||||
});
|
||||
|
||||
describe("lock", () => {
|
||||
const setupLock = () => {
|
||||
setupAccounts(
|
||||
{
|
||||
user1: {
|
||||
authStatus: AuthenticationStatus.Unlocked,
|
||||
isAuthenticated: true,
|
||||
},
|
||||
user2: {
|
||||
authStatus: AuthenticationStatus.Unlocked,
|
||||
isAuthenticated: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
userId: "user1",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
it("should call state event runner with currently active user if no user passed into lock", async () => {
|
||||
setupLock();
|
||||
|
||||
await vaultTimeoutService.lock();
|
||||
|
||||
expect(stateEventRunnerService.handleEvent).toHaveBeenCalledWith("lock", "user1");
|
||||
});
|
||||
|
||||
it("should call messaging service locked message if no user passed into lock", async () => {
|
||||
setupLock();
|
||||
|
||||
await vaultTimeoutService.lock();
|
||||
|
||||
// Currently these pass `undefined` (or what they were given) as the userId back
|
||||
// but we could change this to give the user that was locked (active) to these methods
|
||||
// so they don't have to get it their own way, but that is a behavioral change that needs
|
||||
// to be tested.
|
||||
expect(messagingService.send).toHaveBeenCalledWith("locked", { userId: undefined });
|
||||
});
|
||||
|
||||
it("should call locked callback if no user passed into lock", async () => {
|
||||
setupLock();
|
||||
|
||||
await vaultTimeoutService.lock();
|
||||
|
||||
// Currently these pass `undefined` (or what they were given) as the userId back
|
||||
// but we could change this to give the user that was locked (active) to these methods
|
||||
// so they don't have to get it their own way, but that is a behavioral change that needs
|
||||
// to be tested.
|
||||
expect(lockedCallback).toHaveBeenCalledWith(undefined);
|
||||
});
|
||||
|
||||
it("should call state event runner with user passed into lock", async () => {
|
||||
setupLock();
|
||||
|
||||
await vaultTimeoutService.lock("user2");
|
||||
|
||||
expect(stateEventRunnerService.handleEvent).toHaveBeenCalledWith("lock", "user2");
|
||||
});
|
||||
|
||||
it("should call messaging service locked message with user passed into lock", async () => {
|
||||
setupLock();
|
||||
|
||||
await vaultTimeoutService.lock("user2");
|
||||
|
||||
expect(messagingService.send).toHaveBeenCalledWith("locked", { userId: "user2" });
|
||||
});
|
||||
|
||||
it("should call locked callback with user passed into lock", async () => {
|
||||
setupLock();
|
||||
|
||||
await vaultTimeoutService.lock("user2");
|
||||
|
||||
expect(lockedCallback).toHaveBeenCalledWith("user2");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,6 +11,8 @@ import { CryptoService } from "../../platform/abstractions/crypto.service";
|
||||
import { MessagingService } from "../../platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "../../platform/abstractions/platform-utils.service";
|
||||
import { StateService } from "../../platform/abstractions/state.service";
|
||||
import { StateEventRunnerService } from "../../platform/state";
|
||||
import { UserId } from "../../types/guid";
|
||||
import { CipherService } from "../../vault/abstractions/cipher.service";
|
||||
import { CollectionService } from "../../vault/abstractions/collection.service";
|
||||
import { FolderService } from "../../vault/abstractions/folder/folder.service.abstraction";
|
||||
@@ -29,6 +31,7 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
|
||||
private stateService: StateService,
|
||||
private authService: AuthService,
|
||||
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
|
||||
private stateEventRunnerService: StateEventRunnerService,
|
||||
private lockedCallback: (userId?: string) => Promise<void> = null,
|
||||
private loggedOutCallback: (expired: boolean, userId?: string) => Promise<void> = null,
|
||||
) {}
|
||||
@@ -81,7 +84,9 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
|
||||
await this.logOut(userId);
|
||||
}
|
||||
|
||||
if (userId == null || userId === (await this.stateService.getUserId())) {
|
||||
const currentUserId = await this.stateService.getUserId();
|
||||
|
||||
if (userId == null || userId === currentUserId) {
|
||||
this.searchService.clearIndex();
|
||||
await this.folderService.clearCache();
|
||||
await this.collectionService.clearActiveUserCache();
|
||||
@@ -98,6 +103,11 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
|
||||
|
||||
await this.cipherService.clearCache(userId);
|
||||
|
||||
await this.stateEventRunnerService.handleEvent("lock", (userId ?? currentUserId) as UserId);
|
||||
|
||||
// FIXME: We should send the userId of the user that was locked, in the case of this method being passed
|
||||
// undefined then it should give back the currentUserId. Better yet, this method shouldn't take
|
||||
// an undefined userId at all. All receivers need to be checked for how they handle getting undefined.
|
||||
this.messagingService.send("locked", { userId: userId });
|
||||
|
||||
if (this.lockedCallback != null) {
|
||||
|
||||
Reference in New Issue
Block a user