Skip to content

Commit

Permalink
Merge main into branch
Browse files Browse the repository at this point in the history
  • Loading branch information
coltonhurst committed Apr 2, 2024
2 parents 317a125 + 9956f02 commit b428d1b
Show file tree
Hide file tree
Showing 85 changed files with 2,178 additions and 843 deletions.
1 change: 1 addition & 0 deletions .checkmarx/config.yml
Expand Up @@ -7,5 +7,6 @@ checkmarx:
scan:
configs:
sast:
presetName: "BW ASA Premium"
# Exclude spec files, and test specific files
filter: "!*.spec.ts,!**/spec/**,!apps/desktop/native-messaging-test-runner/**"
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -61,6 +61,7 @@ apps/web/src/app/billing @bitwarden/team-billing-dev
libs/angular/src/billing @bitwarden/team-billing-dev
libs/common/src/billing @bitwarden/team-billing-dev
libs/billing @bitwarden/team-billing-dev
bitwarden_license/bit-web/src/app/billing @bitwarden/team-billing-dev

## Platform team files ##
apps/browser/src/platform @bitwarden/team-platform-dev
Expand Down
Expand Up @@ -24,6 +24,7 @@ import {
} from "../../../platform/background/service-factories/state-service.factory";

import { AccountServiceInitOptions, accountServiceFactory } from "./account-service.factory";
import { TokenServiceInitOptions, tokenServiceFactory } from "./token-service.factory";

type AuthServiceFactoryOptions = FactoryOptions;

Expand All @@ -32,7 +33,8 @@ export type AuthServiceInitOptions = AuthServiceFactoryOptions &
MessagingServiceInitOptions &
CryptoServiceInitOptions &
ApiServiceInitOptions &
StateServiceInitOptions;
StateServiceInitOptions &
TokenServiceInitOptions;

export function authServiceFactory(
cache: { authService?: AbstractAuthService } & CachedServices,
Expand All @@ -49,6 +51,7 @@ export function authServiceFactory(
await cryptoServiceFactory(cache, opts),
await apiServiceFactory(cache, opts),
await stateServiceFactory(cache, opts),
await tokenServiceFactory(cache, opts),
),
);
}
Expand Up @@ -39,9 +39,13 @@ import {
platformUtilsServiceFactory,
} from "../../../platform/background/service-factories/platform-utils-service.factory";
import {
StateServiceInitOptions,
stateServiceFactory,
} from "../../../platform/background/service-factories/state-service.factory";
StateProviderInitOptions,
stateProviderFactory,
} from "../../../platform/background/service-factories/state-provider.factory";
import {
SecureStorageServiceInitOptions,
secureStorageServiceFactory,
} from "../../../platform/background/service-factories/storage-service.factory";

import {
UserDecryptionOptionsServiceInitOptions,
Expand All @@ -55,11 +59,12 @@ export type DeviceTrustCryptoServiceInitOptions = DeviceTrustCryptoServiceFactor
CryptoFunctionServiceInitOptions &
CryptoServiceInitOptions &
EncryptServiceInitOptions &
StateServiceInitOptions &
AppIdServiceInitOptions &
DevicesApiServiceInitOptions &
I18nServiceInitOptions &
PlatformUtilsServiceInitOptions &
StateProviderInitOptions &
SecureStorageServiceInitOptions &
UserDecryptionOptionsServiceInitOptions;

export function deviceTrustCryptoServiceFactory(
Expand All @@ -76,11 +81,12 @@ export function deviceTrustCryptoServiceFactory(
await cryptoFunctionServiceFactory(cache, opts),
await cryptoServiceFactory(cache, opts),
await encryptServiceFactory(cache, opts),
await stateServiceFactory(cache, opts),
await appIdServiceFactory(cache, opts),
await devicesApiServiceFactory(cache, opts),
await i18nServiceFactory(cache, opts),
await platformUtilsServiceFactory(cache, opts),
await stateProviderFactory(cache, opts),
await secureStorageServiceFactory(cache, opts),
await userDecryptionOptionsServiceFactory(cache, opts),
),
);
Expand Down
3 changes: 3 additions & 0 deletions apps/browser/src/auth/popup/lock.component.ts
Expand Up @@ -9,6 +9,7 @@ import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaul
import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout.service";
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
Expand Down Expand Up @@ -62,6 +63,7 @@ export class LockComponent extends BaseLockComponent {
pinCryptoService: PinCryptoServiceAbstraction,
private routerService: BrowserRouterService,
biometricStateService: BiometricStateService,
accountService: AccountService,
) {
super(
router,
Expand All @@ -84,6 +86,7 @@ export class LockComponent extends BaseLockComponent {
userVerificationService,
pinCryptoService,
biometricStateService,
accountService,
);
this.successRoute = "/tabs/current";
this.isInitialLockScreen = (window as any).previousPopupUrl == null;
Expand Down
Expand Up @@ -9,6 +9,7 @@ import {
LoginEmailServiceAbstraction,
} from "@bitwarden/auth/common";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AnonymousHubService } from "@bitwarden/common/auth/abstractions/anonymous-hub.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
Expand Down Expand Up @@ -49,6 +50,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent {
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
authRequestService: AuthRequestServiceAbstraction,
loginStrategyService: LoginStrategyServiceAbstraction,
accountService: AccountService,
private location: Location,
) {
super(
Expand All @@ -70,6 +72,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent {
deviceTrustCryptoService,
authRequestService,
loginStrategyService,
accountService,
);
super.onSuccessfulLogin = async () => {
await syncService.fullSync(true);
Expand Down
31 changes: 20 additions & 11 deletions apps/browser/src/background/main.background.ts
Expand Up @@ -207,6 +207,7 @@ import { BrowserStateService as StateServiceAbstraction } from "../platform/serv
import { BrowserCryptoService } from "../platform/services/browser-crypto.service";
import { BrowserEnvironmentService } from "../platform/services/browser-environment.service";
import BrowserLocalStorageService from "../platform/services/browser-local-storage.service";
import BrowserMemoryStorageService from "../platform/services/browser-memory-storage.service";
import BrowserMessagingPrivateModeBackgroundService from "../platform/services/browser-messaging-private-mode-background.service";
import BrowserMessagingService from "../platform/services/browser-messaging.service";
import { BrowserStateService } from "../platform/services/browser-state.service";
Expand All @@ -230,7 +231,7 @@ import RuntimeBackground from "./runtime.background";

export default class MainBackground {
messagingService: MessagingServiceAbstraction;
storageService: AbstractStorageService;
storageService: AbstractStorageService & ObservableStorageService;
secureStorageService: AbstractStorageService;
memoryStorageService: AbstractMemoryStorageService;
memoryStorageForStateProviders: AbstractMemoryStorageService & ObservableStorageService;
Expand Down Expand Up @@ -365,22 +366,28 @@ export default class MainBackground {
this.cryptoFunctionService = new WebCryptoFunctionService(self);
this.keyGenerationService = new KeyGenerationService(this.cryptoFunctionService);
this.storageService = new BrowserLocalStorageService();

const mv3MemoryStorageCreator = (partitionName: string) => {
// TODO: Consider using multithreaded encrypt service in popup only context
return new LocalBackedSessionStorageService(
new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, false),
this.keyGenerationService,
new BrowserLocalStorageService(),
new BrowserMemoryStorageService(),
partitionName,
);
};

this.secureStorageService = this.storageService; // secure storage is not supported in browsers, so we use local storage and warn users when it is used
this.memoryStorageService = BrowserApi.isManifestVersion(3)
? new LocalBackedSessionStorageService(
new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, false),
this.keyGenerationService,
)
? mv3MemoryStorageCreator("stateService")
: new MemoryStorageService();
this.memoryStorageForStateProviders = BrowserApi.isManifestVersion(3)
? new LocalBackedSessionStorageService(
new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, false),
this.keyGenerationService,
)
? mv3MemoryStorageCreator("stateProviders")
: new BackgroundMemoryStorageService();

const storageServiceProvider = new StorageServiceProvider(
this.storageService as BrowserLocalStorageService,
this.storageService,
this.memoryStorageForStateProviders,
);

Expand Down Expand Up @@ -556,11 +563,12 @@ export default class MainBackground {
this.cryptoFunctionService,
this.cryptoService,
this.encryptService,
this.stateService,
this.appIdService,
this.devicesApiService,
this.i18nService,
this.platformUtilsService,
this.stateProvider,
this.secureStorageService,
this.userDecryptionOptionsService,
);

Expand All @@ -579,6 +587,7 @@ export default class MainBackground {
this.cryptoService,
this.apiService,
this.stateService,
this.tokenService,
);

this.billingAccountProfileStateService = new DefaultBillingAccountProfileStateService(
Expand Down
65 changes: 29 additions & 36 deletions apps/browser/src/platform/background.ts
@@ -1,42 +1,35 @@
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";

import MainBackground from "../background/main.background";

import { onAlarmListener } from "./alarms/on-alarm-listener";
import { registerAlarms } from "./alarms/register-alarms";
import { BrowserApi } from "./browser/browser-api";
import {
contextMenusClickedListener,
onCommandListener,
onInstallListener,
runtimeMessageListener,
windowsOnFocusChangedListener,
tabsOnActivatedListener,
tabsOnReplacedListener,
tabsOnUpdatedListener,
} from "./listeners";

if (BrowserApi.isManifestVersion(3)) {
chrome.commands.onCommand.addListener(onCommandListener);
chrome.runtime.onInstalled.addListener(onInstallListener);
chrome.alarms.onAlarm.addListener(onAlarmListener);
registerAlarms();
chrome.windows.onFocusChanged.addListener(windowsOnFocusChangedListener);
chrome.tabs.onActivated.addListener(tabsOnActivatedListener);
chrome.tabs.onReplaced.addListener(tabsOnReplacedListener);
chrome.tabs.onUpdated.addListener(tabsOnUpdatedListener);
chrome.contextMenus.onClicked.addListener(contextMenusClickedListener);
BrowserApi.messageListener(
"runtime.background",
(message: { command: string }, sender, sendResponse) => {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
runtimeMessageListener(message, sender);
},
);
} else {
const bitwardenMain = ((self as any).bitwardenMain = new MainBackground());
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
bitwardenMain.bootstrap().then(() => {
const logService = new ConsoleLogService(false);
const bitwardenMain = ((self as any).bitwardenMain = new MainBackground());
bitwardenMain
.bootstrap()
.then(() => {
// Finished bootstrapping
});
if (BrowserApi.isManifestVersion(3)) {
startHeartbeat().catch((error) => logService.error(error));
}
})
.catch((error) => logService.error(error));

/**
* Tracks when a service worker was last alive and extends the service worker
* lifetime by writing the current time to extension storage every 20 seconds.
*/
async function runHeartbeat() {
await chrome.storage.local.set({ "last-heartbeat": new Date().getTime() });
}

/**
* Starts the heartbeat interval which keeps the service worker alive.
*/
async function startHeartbeat() {
// Run the heartbeat once at service worker startup, then again every 20 seconds.
runHeartbeat()
.then(() => setInterval(runHeartbeat, 20 * 1000))
.catch((error) => logService.error(error));
}
Expand Up @@ -7,6 +7,7 @@ import { MemoryStorageService } from "@bitwarden/common/platform/services/memory

import { BrowserApi } from "../../browser/browser-api";
import BrowserLocalStorageService from "../../services/browser-local-storage.service";
import BrowserMemoryStorageService from "../../services/browser-memory-storage.service";
import { LocalBackedSessionStorageService } from "../../services/local-backed-session-storage.service";
import { BackgroundMemoryStorageService } from "../../storage/background-memory-storage.service";

Expand All @@ -17,13 +18,14 @@ import {
keyGenerationServiceFactory,
} from "./key-generation-service.factory";

type StorageServiceFactoryOptions = FactoryOptions;

export type DiskStorageServiceInitOptions = StorageServiceFactoryOptions;
export type SecureStorageServiceInitOptions = StorageServiceFactoryOptions;
export type MemoryStorageServiceInitOptions = StorageServiceFactoryOptions &
export type DiskStorageServiceInitOptions = FactoryOptions;
export type SecureStorageServiceInitOptions = FactoryOptions;
export type SessionStorageServiceInitOptions = FactoryOptions;
export type MemoryStorageServiceInitOptions = FactoryOptions &
EncryptServiceInitOptions &
KeyGenerationServiceInitOptions;
KeyGenerationServiceInitOptions &
DiskStorageServiceInitOptions &
SessionStorageServiceInitOptions;

export function diskStorageServiceFactory(
cache: { diskStorageService?: AbstractStorageService } & CachedServices,
Expand All @@ -47,6 +49,13 @@ export function secureStorageServiceFactory(
return factory(cache, "secureStorageService", opts, () => new BrowserLocalStorageService());
}

export function sessionStorageServiceFactory(
cache: { sessionStorageService?: AbstractStorageService } & CachedServices,
opts: SessionStorageServiceInitOptions,
): Promise<AbstractStorageService> {
return factory(cache, "sessionStorageService", opts, () => new BrowserMemoryStorageService());
}

export function memoryStorageServiceFactory(
cache: { memoryStorageService?: AbstractMemoryStorageService } & CachedServices,
opts: MemoryStorageServiceInitOptions,
Expand All @@ -56,6 +65,9 @@ export function memoryStorageServiceFactory(
return new LocalBackedSessionStorageService(
await encryptServiceFactory(cache, opts),
await keyGenerationServiceFactory(cache, opts),
await diskStorageServiceFactory(cache, opts),
await sessionStorageServiceFactory(cache, opts),
"serviceFactories",
);
}
return new MemoryStorageService();
Expand Down
Expand Up @@ -3,22 +3,9 @@ import { StorageOptions } from "@bitwarden/common/platform/models/domain/storage

import { Account } from "../../../models/account";
import { BrowserComponentState } from "../../../models/browserComponentState";
import { BrowserGroupingsComponentState } from "../../../models/browserGroupingsComponentState";
import { BrowserSendComponentState } from "../../../models/browserSendComponentState";

export abstract class BrowserStateService extends BaseStateServiceAbstraction<Account> {
getBrowserGroupingComponentState: (
options?: StorageOptions,
) => Promise<BrowserGroupingsComponentState>;
setBrowserGroupingComponentState: (
value: BrowserGroupingsComponentState,
options?: StorageOptions,
) => Promise<void>;
getBrowserVaultItemsComponentState: (options?: StorageOptions) => Promise<BrowserComponentState>;
setBrowserVaultItemsComponentState: (
value: BrowserComponentState,
options?: StorageOptions,
) => Promise<void>;
getBrowserSendComponentState: (options?: StorageOptions) => Promise<BrowserSendComponentState>;
setBrowserSendComponentState: (
value: BrowserSendComponentState,
Expand Down
22 changes: 0 additions & 22 deletions apps/browser/src/platform/services/browser-state.service.spec.ts
Expand Up @@ -18,7 +18,6 @@ import { UserId } from "@bitwarden/common/types/guid";

import { Account } from "../../models/account";
import { BrowserComponentState } from "../../models/browserComponentState";
import { BrowserGroupingsComponentState } from "../../models/browserGroupingsComponentState";
import { BrowserSendComponentState } from "../../models/browserSendComponentState";

import { BrowserStateService } from "./browser-state.service";
Expand Down Expand Up @@ -86,27 +85,6 @@ describe("Browser State Service", () => {
);
});

describe("getBrowserGroupingComponentState", () => {
it("should return a BrowserGroupingsComponentState", async () => {
state.accounts[userId].groupings = new BrowserGroupingsComponentState();

const actual = await sut.getBrowserGroupingComponentState();
expect(actual).toBeInstanceOf(BrowserGroupingsComponentState);
});
});

describe("getBrowserVaultItemsComponentState", () => {
it("should return a BrowserComponentState", async () => {
const componentState = new BrowserComponentState();
componentState.scrollY = 0;
componentState.searchText = "test";
state.accounts[userId].ciphers = componentState;

const actual = await sut.getBrowserVaultItemsComponentState();
expect(actual).toStrictEqual(componentState);
});
});

describe("getBrowserSendComponentState", () => {
it("should return a BrowserSendComponentState", async () => {
const sendState = new BrowserSendComponentState();
Expand Down

0 comments on commit b428d1b

Please sign in to comment.