1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-14 23:45:37 +00:00

wip: first version of tracing

This commit is contained in:
Andreas Coroiu
2025-11-19 10:49:56 +01:00
parent ec5a54fa37
commit 73cc594102
3 changed files with 96 additions and 3 deletions

View File

@@ -3,15 +3,61 @@ import { firstValueFrom } from "rxjs";
// eslint-disable-next-line no-restricted-imports
import { KeyService } from "@bitwarden/key-management";
import { LogService } from "@bitwarden/logging";
import { isCryptoError } from "@bitwarden/sdk-internal";
import {
EventDefinition,
isCryptoError,
SpanDefinition,
TracingLevel,
} from "@bitwarden/sdk-internal";
import { UserId } from "@bitwarden/user-core";
import { SdkLoadService } from "../../../platform/abstractions/sdk/sdk-load.service";
import { HashPurpose } from "../../../platform/enums";
import { UserKey } from "../../../types/key";
import { MasterPasswordUnlockService } from "../abstractions/master-password-unlock.service";
import { InternalMasterPasswordServiceAbstraction } from "../abstractions/master-password.service.abstraction";
import { MasterPasswordUnlockData } from "../types/master-password.types";
const UnlockWithMasterPasswordSpan = SdkLoadService.WithSdk(
() =>
new SpanDefinition(
"unlockWithMasterPassword",
"DefaultMasterPasswordUnlockService",
TracingLevel.Info,
[],
),
);
const InputValidatedEvent = SdkLoadService.WithSdk(
() =>
new EventDefinition(
"inputValidated",
"DefaultMasterPasswordUnlockService",
TracingLevel.Debug,
[],
),
);
const UserKeyUnwrappedEvent = SdkLoadService.WithSdk(
() =>
new EventDefinition(
"userKeyUnwrapped",
"DefaultMasterPasswordUnlockService",
TracingLevel.Debug,
[],
),
);
const LegacyStateSetEvent = SdkLoadService.WithSdk(
() =>
new EventDefinition(
"legacyStateSet",
"DefaultMasterPasswordUnlockService",
TracingLevel.Debug,
[],
),
);
export class DefaultMasterPasswordUnlockService implements MasterPasswordUnlockService {
constructor(
private readonly masterPasswordService: InternalMasterPasswordServiceAbstraction,
@@ -20,7 +66,12 @@ export class DefaultMasterPasswordUnlockService implements MasterPasswordUnlockS
) {}
async unlockWithMasterPassword(masterPassword: string, userId: UserId): Promise<UserKey> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
using _span = (await UnlockWithMasterPasswordSpan).enter();
console.log("DefaultMasterPasswordUnlockService: unlockWithMasterPassword called");
this.validateInput(masterPassword, userId);
(await InputValidatedEvent).record();
const masterPasswordUnlockData = await firstValueFrom(
this.masterPasswordService.masterPasswordUnlockData$(userId),
@@ -34,8 +85,10 @@ export class DefaultMasterPasswordUnlockService implements MasterPasswordUnlockS
masterPassword,
masterPasswordUnlockData,
);
(await UserKeyUnwrappedEvent).record();
await this.setLegacyState(masterPassword, masterPasswordUnlockData, userId);
(await LegacyStateSetEvent).record();
return userKey;
}

View File

@@ -1,4 +1,4 @@
import { init_sdk } from "@bitwarden/sdk-internal";
import { init_sdk, LogLevel } from "@bitwarden/sdk-internal";
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- used in docs
import type { SdkService } from "./sdk.service";
@@ -33,6 +33,15 @@ export abstract class SdkLoadService {
SdkLoadService.markAsFailed = (error: unknown) => reject(new SdkLoadFailedError(error));
});
/**
* Helper to run a function after the SDK is ready.
* @param fn The function to run after the SDK is ready.
* @returns The result of the function.
*/
static readonly WithSdk = <T>(fn: () => T | Promise<T>): Promise<T> => {
return SdkLoadService.Ready.then(() => fn());
};
/**
* Load WASM and initalize SDK-JS integrations such as logging.
* This method should be called once at the start of the application.
@@ -41,7 +50,7 @@ export abstract class SdkLoadService {
async loadAndInit(): Promise<void> {
try {
await this.load();
init_sdk();
init_sdk(LogLevel.Debug);
SdkLoadService.markAsReady();
} catch (error) {
SdkLoadService.markAsFailed(error);

View File

@@ -23,7 +23,11 @@ import { KeyService, KdfConfigService, KdfConfig, KdfType } from "@bitwarden/key
import {
PasswordManagerClient,
ClientSettings,
EventDefinition,
DeviceType as SdkDeviceType,
SpanDefinition,
TokenProvider,
TracingLevel,
UnsignedSharedKey,
WrappedAccountCryptographicState,
} from "@bitwarden/sdk-internal";
@@ -49,6 +53,26 @@ import { StateProvider } from "../../state";
import { initializeState } from "./client-managed-state";
const InitializeClientSpan = SdkLoadService.WithSdk(
() => new SpanDefinition("initializeUserClient", "DefaultSdkService", TracingLevel.Info, []),
);
const UserCryptoInitializedEvent = SdkLoadService.WithSdk(
() => new EventDefinition("userCryptoInitialized", "DefaultSdkService", TracingLevel.Debug, []),
);
const OrgCryptoInitializedEvent = SdkLoadService.WithSdk(
() => new EventDefinition("orgCryptoInitialized", "DefaultSdkService", TracingLevel.Debug, []),
);
const ClientStateInitializedEvent = SdkLoadService.WithSdk(
() => new EventDefinition("clientStateInitialized", "DefaultSdkService", TracingLevel.Debug, []),
);
const FeatureFlagsLoadedEvent = SdkLoadService.WithSdk(
() => new EventDefinition("featureFlagsLoaded", "DefaultSdkService", TracingLevel.Debug, []),
);
// A symbol that represents an overridden client that is explicitly set to undefined,
// blocking the creation of an internal client for that user.
const UnsetClient = Symbol("UnsetClient");
@@ -279,6 +303,9 @@ export class DefaultSdkService implements SdkService {
accountCryptographicState: WrappedAccountCryptographicState,
orgKeys: Record<OrganizationId, EncString>,
) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
using _span = (await InitializeClientSpan).enter();
await client.crypto().initialize_user_crypto({
userId: asUuid(userId),
email: account.email,
@@ -295,6 +322,7 @@ export class DefaultSdkService implements SdkService {
},
accountCryptographicState: accountCryptographicState,
});
(await UserCryptoInitializedEvent).record();
// We initialize the org crypto even if the org_keys are
// null to make sure any existing org keys are cleared.
@@ -303,11 +331,14 @@ export class DefaultSdkService implements SdkService {
Object.entries(orgKeys).map(([k, v]) => [asUuid(k), v.toJSON() as UnsignedSharedKey]),
),
});
(await OrgCryptoInitializedEvent).record();
// Initialize the SDK managed database and the client managed repositories.
await initializeState(userId, client.platform().state(), this.stateProvider);
(await ClientStateInitializedEvent).record();
await this.loadFeatureFlags(client);
(await FeatureFlagsLoadedEvent).record();
}
private async loadFeatureFlags(client: PasswordManagerClient) {