mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 09:43:23 +00:00
* 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 * Remove `updateMock` * Call Super in Web Implementation * Use Better Type to Avoid Casting * Better Error Docs * Move StorageKey Creation to Function * Throw Aggregated Error for Failures
77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
import { PossibleLocation, StorageServiceProvider } from "../services/storage-service.provider";
|
|
|
|
import { GlobalState } from "./global-state";
|
|
import { GlobalStateProvider } from "./global-state.provider";
|
|
import { KeyDefinition } from "./key-definition";
|
|
import { CLEAR_EVENT_DISK } from "./state-definitions";
|
|
import { ClearEvent, UserKeyDefinition } from "./user-key-definition";
|
|
|
|
export type StateEventInfo = {
|
|
state: string;
|
|
key: string;
|
|
location: PossibleLocation;
|
|
};
|
|
|
|
export const STATE_LOCK_EVENT = KeyDefinition.array<StateEventInfo>(CLEAR_EVENT_DISK, "lock", {
|
|
deserializer: (e) => e,
|
|
});
|
|
|
|
export const STATE_LOGOUT_EVENT = KeyDefinition.array<StateEventInfo>(CLEAR_EVENT_DISK, "logout", {
|
|
deserializer: (e) => e,
|
|
});
|
|
|
|
export class StateEventRegistrarService {
|
|
private readonly stateEventStateMap: { [Prop in ClearEvent]: GlobalState<StateEventInfo[]> };
|
|
|
|
constructor(
|
|
globalStateProvider: GlobalStateProvider,
|
|
private storageServiceProvider: StorageServiceProvider,
|
|
) {
|
|
this.stateEventStateMap = {
|
|
lock: globalStateProvider.get(STATE_LOCK_EVENT),
|
|
logout: globalStateProvider.get(STATE_LOGOUT_EVENT),
|
|
};
|
|
}
|
|
|
|
async registerEvents(keyDefinition: UserKeyDefinition<unknown>) {
|
|
for (const clearEvent of keyDefinition.clearOn) {
|
|
const eventState = this.stateEventStateMap[clearEvent];
|
|
// Determine the storage location for this
|
|
const [storageLocation] = this.storageServiceProvider.get(
|
|
keyDefinition.stateDefinition.defaultStorageLocation,
|
|
keyDefinition.stateDefinition.storageLocationOverrides,
|
|
);
|
|
|
|
const newEvent: StateEventInfo = {
|
|
state: keyDefinition.stateDefinition.name,
|
|
key: keyDefinition.key,
|
|
location: storageLocation,
|
|
};
|
|
|
|
// Only update the event state if the existing list doesn't have a matching entry
|
|
await eventState.update(
|
|
(existingTickets) => {
|
|
existingTickets ??= [];
|
|
existingTickets.push(newEvent);
|
|
return existingTickets;
|
|
},
|
|
{
|
|
shouldUpdate: (currentTickets) => {
|
|
return (
|
|
// If the current tickets are null, then it will for sure be added
|
|
currentTickets == null ||
|
|
// If an existing match couldn't be found, we also need to add one
|
|
currentTickets.findIndex(
|
|
(e) =>
|
|
e.state === newEvent.state &&
|
|
e.key === newEvent.key &&
|
|
e.location === newEvent.location,
|
|
) === -1
|
|
);
|
|
},
|
|
},
|
|
);
|
|
}
|
|
}
|
|
}
|