mirror of
https://github.com/bitwarden/browser
synced 2026-02-15 07:54:55 +00:00
even more cleanup!
This commit is contained in:
@@ -248,7 +248,7 @@ import { EventCollectionService } from "@bitwarden/common/services/event/event-c
|
||||
import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service";
|
||||
import { SearchService } from "@bitwarden/common/services/search.service";
|
||||
import { AchievementService } from "@bitwarden/common/tools/achievements/achievement.service.abstraction";
|
||||
import { DefaultAchievementService } from "@bitwarden/common/tools/achievements/next-achievement.service";
|
||||
import { DefaultAchievementService } from "@bitwarden/common/tools/achievements/default-achievement.service";
|
||||
import { DefaultUserEventCollector } from "@bitwarden/common/tools/log/default-user-event-collector";
|
||||
import { UserEventCollector } from "@bitwarden/common/tools/log/user-event-collector";
|
||||
import {
|
||||
|
||||
@@ -16,8 +16,6 @@ export type ServiceFormat = EcsFormat & {
|
||||
/** a unique identifier(s) for this client installation */
|
||||
name: string;
|
||||
};
|
||||
/** The environment to which the client was connected */
|
||||
environment: "production" | "testing" | "development" | "local";
|
||||
|
||||
/** the unique identifier(s) for this client installation */
|
||||
version: string;
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// eslint-disable-next-line -- `StateDefinition` used as a type
|
||||
import { StateDefinition } from "../../platform/state/state-definition";
|
||||
import { Classifier } from "../state/classifier";
|
||||
|
||||
import { EcsFormat } from "./ecs-format";
|
||||
|
||||
export type LogKey<LogFormat extends EcsFormat, N extends number = 100> = {
|
||||
target: "log";
|
||||
format: "classified_circular_buffer";
|
||||
size: N;
|
||||
key: string;
|
||||
state: StateDefinition;
|
||||
cleanupDelayMs?: number;
|
||||
classifier: Classifier<LogFormat, unknown, unknown>;
|
||||
|
||||
/** For encrypted outputs, determines how much padding is applied to
|
||||
* encoded inputs. When this isn't specified, each frame is 32 bytes
|
||||
* long.
|
||||
*/
|
||||
frame?: number;
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
import { LogService } from "../../platform/abstractions/log.service";
|
||||
import { StateProvider } from "../../platform/state";
|
||||
import { LegacyEncryptorProvider } from "../cryptography/legacy-encryptor-provider";
|
||||
|
||||
export abstract class LogSubjectDependencyProvider {
|
||||
/** Provides objects that encrypt and decrypt user and organization data */
|
||||
abstract encryptor: LegacyEncryptorProvider;
|
||||
|
||||
/** Provides local object persistence */
|
||||
abstract state: StateProvider;
|
||||
|
||||
/** `LogSubject` uses the log service instead of semantic logging
|
||||
* to avoid creating a loop where it logs its own actions.
|
||||
*/
|
||||
abstract log: LogService;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BehaviorSubject, SubjectLike, from, map, zip } from "rxjs";
|
||||
import { BehaviorSubject, SubjectLike, from, map, of, zip } from "rxjs";
|
||||
import { Primitive } from "type-fest";
|
||||
|
||||
import { Account } from "../../auth/abstractions/account.service";
|
||||
@@ -22,40 +22,41 @@ export class UserEventMonitor {
|
||||
constructor(
|
||||
idService: AppIdService,
|
||||
utilService: PlatformUtilsService,
|
||||
account: Account,
|
||||
private account: Account,
|
||||
private now: () => number,
|
||||
private events$: SubjectLike<UserActionEvent>,
|
||||
private log: SemanticLogger = disabledSemanticLoggerProvider({}),
|
||||
) {
|
||||
zip(from(idService.getAppId()), from(utilService.getApplicationVersion()))
|
||||
.pipe(
|
||||
map(
|
||||
([appId, version]) =>
|
||||
({
|
||||
event: {
|
||||
kind: "event",
|
||||
category: "session",
|
||||
},
|
||||
service: {
|
||||
name: utilService.getDeviceString(),
|
||||
type: "client",
|
||||
node: {
|
||||
name: appId,
|
||||
},
|
||||
environment: "local",
|
||||
version,
|
||||
},
|
||||
user: {
|
||||
// `account` verified not-null via `filter`
|
||||
id: account!.id,
|
||||
email: (account!.emailVerified && account!.email) || undefined,
|
||||
},
|
||||
}) satisfies BaselineType,
|
||||
),
|
||||
)
|
||||
zip(
|
||||
from(idService.getAppId()),
|
||||
from(utilService.getApplicationVersion()),
|
||||
of(utilService.getDeviceString()),
|
||||
)
|
||||
.pipe(map(([appId, version, device]) => this.template(appId, device, version)))
|
||||
.subscribe((next) => this.baseline$.next(next));
|
||||
}
|
||||
|
||||
template(appId: string, device: string, version: string): BaselineType {
|
||||
return {
|
||||
event: {
|
||||
kind: "event",
|
||||
category: "session",
|
||||
},
|
||||
service: {
|
||||
name: device,
|
||||
type: "client",
|
||||
node: {
|
||||
name: appId,
|
||||
},
|
||||
version,
|
||||
},
|
||||
user: {
|
||||
id: this.account.id,
|
||||
email: (this.account.emailVerified && this.account.email) || undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private readonly baseline$ = new BehaviorSubject<BaselineType | null>(null);
|
||||
|
||||
creation(event: EventInfo) {
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/** A simple ring buffer; not in any way threadsafe */
|
||||
export class RingBuffer<T> {
|
||||
constructor(private capacity: number) {
|
||||
this.buffer = new Array(capacity).fill(null);
|
||||
}
|
||||
|
||||
private buffer: Array<T>;
|
||||
private head: number = 0;
|
||||
private tail: number = 0;
|
||||
private _length: number = 0;
|
||||
|
||||
/** The number of entries presently stored by the ring buffer */
|
||||
get length() {
|
||||
return this._length;
|
||||
}
|
||||
|
||||
/** `true` when the buffer is full. */
|
||||
get full() {
|
||||
return this.length === this.capacity;
|
||||
}
|
||||
|
||||
/** `true` when the buffer is empty */
|
||||
get empty() {
|
||||
return !this.length;
|
||||
}
|
||||
|
||||
/** Adds an item to the head of the buffer
|
||||
* @param value the item to add
|
||||
* @returns `true` if the item was added, otherwise `false`.
|
||||
*/
|
||||
enqueue(value: T) {
|
||||
if (this.full) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.buffer[this.head] = value;
|
||||
this.head = (this.head + 1) % this.capacity;
|
||||
this._length++;
|
||||
}
|
||||
|
||||
/** Removes the item at the tail of the buffer
|
||||
* @returns the tail item if the buffer contains any entries,
|
||||
* otherwise `undefined`.
|
||||
*/
|
||||
dequeue(): T | undefined {
|
||||
if (this.empty) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const value = this.buffer[this.tail];
|
||||
this.tail = (this.tail + 1) % this.capacity;
|
||||
this._length--;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { StateProvider, UserKeyDefinition } from "../../platform/state";
|
||||
import { UserId } from "../../types/guid";
|
||||
|
||||
/** Utility for spooling data to and from append-only storage. */
|
||||
export class Spooler<T> {
|
||||
/** Instantiates a spooler
|
||||
* @param state loads and stores the spool
|
||||
* @param location where spooled records are stored
|
||||
* @param userId user performing the spooling
|
||||
*/
|
||||
constructor(
|
||||
private state: StateProvider,
|
||||
private location: UserKeyDefinition<T[]>,
|
||||
private userId: UserId,
|
||||
) {}
|
||||
|
||||
private buffer = new Array<T>();
|
||||
|
||||
/** Append a value to append-only storage */
|
||||
async spool(value: T) {
|
||||
// TODO: encrypt spooled records? Or should that be done by the calling code?
|
||||
// either way, the value pushed to `this.buffer` should be ready-to-spool.
|
||||
this.buffer.push(value);
|
||||
|
||||
await this.state.setUserState(this.location, this.buffer, this.userId);
|
||||
}
|
||||
|
||||
/** Read all values from append-only storage */
|
||||
async read(): Promise<T[]> {
|
||||
// TODO: decrypt spooled records? Or should that be done by the calling code?
|
||||
return await firstValueFrom(this.state.getUserState$(this.location, this.userId));
|
||||
}
|
||||
|
||||
/** Read all values from append-only storage */
|
||||
async unspool(): Promise<T[]> {
|
||||
const results = await this.read();
|
||||
await this.clear();
|
||||
return results;
|
||||
}
|
||||
|
||||
/** Erase append-only storage */
|
||||
async clear() {
|
||||
await this.state.setUserState(this.location, null, this.userId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user