Merge branch 'main' into SM-1192-SecretsNames

This commit is contained in:
cd-bitwarden 2024-04-25 12:48:48 -04:00 committed by GitHub
commit ed6a8fda9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
57 changed files with 405 additions and 363 deletions

View File

@ -1,5 +1,5 @@
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation";
import {
DevicesApiServiceInitOptions,
@ -52,9 +52,9 @@ import {
userDecryptionOptionsServiceFactory,
} from "./user-decryption-options-service.factory";
type DeviceTrustCryptoServiceFactoryOptions = FactoryOptions;
type DeviceTrustServiceFactoryOptions = FactoryOptions;
export type DeviceTrustCryptoServiceInitOptions = DeviceTrustCryptoServiceFactoryOptions &
export type DeviceTrustServiceInitOptions = DeviceTrustServiceFactoryOptions &
KeyGenerationServiceInitOptions &
CryptoFunctionServiceInitOptions &
CryptoServiceInitOptions &
@ -67,16 +67,16 @@ export type DeviceTrustCryptoServiceInitOptions = DeviceTrustCryptoServiceFactor
SecureStorageServiceInitOptions &
UserDecryptionOptionsServiceInitOptions;
export function deviceTrustCryptoServiceFactory(
cache: { deviceTrustCryptoService?: DeviceTrustCryptoServiceAbstraction } & CachedServices,
opts: DeviceTrustCryptoServiceInitOptions,
): Promise<DeviceTrustCryptoServiceAbstraction> {
export function deviceTrustServiceFactory(
cache: { deviceTrustService?: DeviceTrustServiceAbstraction } & CachedServices,
opts: DeviceTrustServiceInitOptions,
): Promise<DeviceTrustServiceAbstraction> {
return factory(
cache,
"deviceTrustCryptoService",
"deviceTrustService",
opts,
async () =>
new DeviceTrustCryptoService(
new DeviceTrustService(
await keyGenerationServiceFactory(cache, opts),
await cryptoFunctionServiceFactory(cache, opts),
await cryptoServiceFactory(cache, opts),

View File

@ -65,9 +65,9 @@ import {
AuthRequestServiceInitOptions,
} from "./auth-request-service.factory";
import {
deviceTrustCryptoServiceFactory,
DeviceTrustCryptoServiceInitOptions,
} from "./device-trust-crypto-service.factory";
deviceTrustServiceFactory,
DeviceTrustServiceInitOptions,
} from "./device-trust-service.factory";
import {
keyConnectorServiceFactory,
KeyConnectorServiceInitOptions,
@ -102,7 +102,7 @@ export type LoginStrategyServiceInitOptions = LoginStrategyServiceFactoryOptions
EncryptServiceInitOptions &
PolicyServiceInitOptions &
PasswordStrengthServiceInitOptions &
DeviceTrustCryptoServiceInitOptions &
DeviceTrustServiceInitOptions &
AuthRequestServiceInitOptions &
UserDecryptionOptionsServiceInitOptions &
GlobalStateProviderInitOptions &
@ -135,7 +135,7 @@ export function loginStrategyServiceFactory(
await encryptServiceFactory(cache, opts),
await passwordStrengthServiceFactory(cache, opts),
await policyServiceFactory(cache, opts),
await deviceTrustCryptoServiceFactory(cache, opts),
await deviceTrustServiceFactory(cache, opts),
await authRequestServiceFactory(cache, opts),
await internalUserDecryptionOptionServiceFactory(cache, opts),
await globalStateProviderFactory(cache, opts),

View File

@ -11,7 +11,7 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs
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 { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
@ -60,7 +60,7 @@ export class LockComponent extends BaseLockComponent {
passwordStrengthService: PasswordStrengthServiceAbstraction,
private authService: AuthService,
dialogService: DialogService,
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
deviceTrustService: DeviceTrustServiceAbstraction,
userVerificationService: UserVerificationService,
pinCryptoService: PinCryptoServiceAbstraction,
private routerService: BrowserRouterService,
@ -85,7 +85,7 @@ export class LockComponent extends BaseLockComponent {
policyService,
passwordStrengthService,
dialogService,
deviceTrustCryptoService,
deviceTrustService,
userVerificationService,
pinCryptoService,
biometricStateService,

View File

@ -12,7 +12,7 @@ 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";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
@ -47,7 +47,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent {
stateService: StateService,
loginEmailService: LoginEmailServiceAbstraction,
syncService: SyncService,
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
deviceTrustService: DeviceTrustServiceAbstraction,
authRequestService: AuthRequestServiceAbstraction,
loginStrategyService: LoginStrategyServiceAbstraction,
accountService: AccountService,
@ -69,7 +69,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent {
validationService,
stateService,
loginEmailService,
deviceTrustCryptoService,
deviceTrustService,
authRequestService,
loginStrategyService,
accountService,

View File

@ -30,7 +30,7 @@ import { ProviderService } from "@bitwarden/common/admin-console/services/provid
import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service";
import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service";
@ -45,7 +45,7 @@ import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/for
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
import { AvatarService } from "@bitwarden/common/auth/services/avatar.service";
import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation";
import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation";
import { DevicesServiceImplementation } from "@bitwarden/common/auth/services/devices/devices.service.implementation";
import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation";
import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service";
@ -318,7 +318,7 @@ export default class MainBackground {
configApiService: ConfigApiServiceAbstraction;
devicesApiService: DevicesApiServiceAbstraction;
devicesService: DevicesServiceAbstraction;
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction;
deviceTrustService: DeviceTrustServiceAbstraction;
authRequestService: AuthRequestServiceAbstraction;
accountService: AccountServiceAbstraction;
globalStateProvider: GlobalStateProvider;
@ -612,7 +612,7 @@ export default class MainBackground {
this.userDecryptionOptionsService = new UserDecryptionOptionsService(this.stateProvider);
this.devicesApiService = new DevicesApiServiceImplementation(this.apiService);
this.deviceTrustCryptoService = new DeviceTrustCryptoService(
this.deviceTrustService = new DeviceTrustService(
this.keyGenerationService,
this.cryptoFunctionService,
this.cryptoService,
@ -670,7 +670,7 @@ export default class MainBackground {
this.encryptService,
this.passwordStrengthService,
this.policyService,
this.deviceTrustCryptoService,
this.deviceTrustService,
this.authRequestService,
this.userDecryptionOptionsService,
this.globalStateProvider,

View File

@ -10,7 +10,7 @@ import { SystemService } from "@bitwarden/common/platform/abstractions/system.se
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { CipherType } from "@bitwarden/common/vault/enums";
import { MessageListener } from "../../../../libs/common/src/platform/messaging";
import { MessageListener, isExternalMessage } from "../../../../libs/common/src/platform/messaging";
import {
closeUnlockPopout,
openSsoAuthResultPopout,
@ -266,7 +266,9 @@ export default class RuntimeBackground {
break;
}
case "reloadPopup":
this.messagingService.send("reloadPopup");
if (isExternalMessage(msg)) {
this.messagingService.send("reloadPopup");
}
break;
case "emailVerificationRequired":
this.messagingService.send("showDialog", {

View File

@ -92,9 +92,16 @@ export class LocalBackedSessionStorageService
// This is for observation purposes only. At some point, we don't want to write to local session storage if the value is the same.
if (this.platformUtilsService.isDev()) {
const existingValue = this.cache[key] as T;
if (this.compareValues<T>(existingValue, obj)) {
this.logService.warning(`Possible unnecessary write to local session storage. Key: ${key}`);
this.logService.warning(obj as any);
try {
if (this.compareValues<T>(existingValue, obj)) {
this.logService.warning(
`Possible unnecessary write to local session storage. Key: ${key}`,
);
this.logService.warning(obj as any);
}
} catch (err) {
this.logService.warning(`Error while comparing values for key: ${key}`);
this.logService.warning(err);
}
}

View File

@ -28,7 +28,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
@ -250,8 +250,8 @@ const safeProviders: SafeProvider[] = [
deps: [],
}),
safeProvider({
provide: DeviceTrustCryptoServiceAbstraction,
useFactory: getBgService<DeviceTrustCryptoServiceAbstraction>("deviceTrustCryptoService"),
provide: DeviceTrustServiceAbstraction,
useFactory: getBgService<DeviceTrustServiceAbstraction>("deviceTrustService"),
deps: [],
}),
safeProvider({

View File

@ -28,13 +28,13 @@ import { ProviderApiService } from "@bitwarden/common/admin-console/services/pro
import { ProviderService } from "@bitwarden/common/admin-console/services/provider.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
import { AvatarService } from "@bitwarden/common/auth/services/avatar.service";
import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation";
import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation";
import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation";
import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service";
import { MasterPasswordService } from "@bitwarden/common/auth/services/master-password/master-password.service";
@ -77,6 +77,7 @@ import { MigrationBuilderService } from "@bitwarden/common/platform/services/mig
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
import { StateService } from "@bitwarden/common/platform/services/state.service";
import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider";
import { UserKeyInitService } from "@bitwarden/common/platform/services/user-key-init.service";
import {
ActiveUserStateProvider,
DerivedStateProvider,
@ -217,7 +218,7 @@ export class Main {
syncNotifierService: SyncNotifierService;
sendApiService: SendApiService;
devicesApiService: DevicesApiServiceAbstraction;
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction;
deviceTrustService: DeviceTrustServiceAbstraction;
authRequestService: AuthRequestService;
configApiService: ConfigApiServiceAbstraction;
configService: ConfigService;
@ -233,6 +234,7 @@ export class Main {
biometricStateService: BiometricStateService;
billingAccountProfileStateService: BillingAccountProfileStateService;
providerApiService: ProviderApiServiceAbstraction;
userKeyInitService: UserKeyInitService;
constructor() {
let p = null;
@ -460,7 +462,7 @@ export class Main {
this.userDecryptionOptionsService = new UserDecryptionOptionsService(this.stateProvider);
this.devicesApiService = new DevicesApiServiceImplementation(this.apiService);
this.deviceTrustCryptoService = new DeviceTrustCryptoService(
this.deviceTrustService = new DeviceTrustService(
this.keyGenerationService,
this.cryptoFunctionService,
this.cryptoService,
@ -505,7 +507,7 @@ export class Main {
this.encryptService,
this.passwordStrengthService,
this.policyService,
this.deviceTrustCryptoService,
this.deviceTrustService,
this.authRequestService,
this.userDecryptionOptionsService,
this.globalStateProvider,
@ -692,6 +694,12 @@ export class Main {
);
this.providerApiService = new ProviderApiService(this.apiService);
this.userKeyInitService = new UserKeyInitService(
this.accountService,
this.cryptoService,
this.logService,
);
}
async run() {
@ -735,6 +743,7 @@ export class Main {
this.containerService.attachToGlobal(global);
await this.i18nService.init();
this.twoFactorService.init();
this.userKeyInitService.listenForActiveUserChangesToSetUserKey();
}
}

View File

@ -13,7 +13,7 @@ import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeou
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 { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service";
@ -145,8 +145,8 @@ describe("LockComponent", () => {
useValue: mock<DialogService>(),
},
{
provide: DeviceTrustCryptoServiceAbstraction,
useValue: mock<DeviceTrustCryptoServiceAbstraction>(),
provide: DeviceTrustServiceAbstraction,
useValue: mock<DeviceTrustServiceAbstraction>(),
},
{
provide: UserVerificationService,

View File

@ -10,7 +10,7 @@ import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeou
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 { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { DeviceType } from "@bitwarden/common/enums";
@ -58,7 +58,7 @@ export class LockComponent extends BaseLockComponent {
passwordStrengthService: PasswordStrengthServiceAbstraction,
logService: LogService,
dialogService: DialogService,
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
deviceTrustService: DeviceTrustServiceAbstraction,
userVerificationService: UserVerificationService,
pinCryptoService: PinCryptoServiceAbstraction,
biometricStateService: BiometricStateService,
@ -82,7 +82,7 @@ export class LockComponent extends BaseLockComponent {
policyService,
passwordStrengthService,
dialogService,
deviceTrustCryptoService,
deviceTrustService,
userVerificationService,
pinCryptoService,
biometricStateService,

View File

@ -13,7 +13,7 @@ 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";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
@ -55,7 +55,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent {
syncService: SyncService,
stateService: StateService,
loginEmailService: LoginEmailServiceAbstraction,
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
deviceTrustService: DeviceTrustServiceAbstraction,
authRequestService: AuthRequestServiceAbstraction,
loginStrategyService: LoginStrategyServiceAbstraction,
accountService: AccountService,
@ -77,7 +77,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent {
validationService,
stateService,
loginEmailService,
deviceTrustCryptoService,
deviceTrustService,
authRequestService,
loginStrategyService,
accountService,

View File

@ -37,7 +37,7 @@ import {
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request";
import { OrganizationBillingServiceAbstraction as OrganizationBillingService } from "@bitwarden/common/billing/abstractions/organization-billing.service";
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction";
import { ProductType } from "@bitwarden/common/enums";
import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
@ -121,7 +121,7 @@ export class PeopleComponent extends BasePeopleComponent<OrganizationUserView> {
private groupService: GroupService,
private collectionService: CollectionService,
organizationManagementPreferencesService: OrganizationManagementPreferencesService,
private organizationBillingService: OrganizationBillingService,
private billingApiService: BillingApiServiceAbstraction,
) {
super(
apiService,
@ -190,10 +190,11 @@ export class PeopleComponent extends BasePeopleComponent<OrganizationUserView> {
.find((p) => p.organizationId === this.organization.id);
this.orgResetPasswordPolicyEnabled = resetPasswordPolicy?.enabled;
this.orgIsOnSecretsManagerStandalone =
await this.organizationBillingService.isOnSecretsManagerStandalone(
this.organization.id,
);
const billingMetadata = await this.billingApiService.getOrganizationBillingMetadata(
this.organization.id,
);
this.orgIsOnSecretsManagerStandalone = billingMetadata.isOnSecretsManagerStandalone;
await this.load();

View File

@ -1,7 +1,7 @@
import { mock, MockProxy } from "jest-mock-extended";
import { BehaviorSubject } from "rxjs";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
@ -42,7 +42,7 @@ describe("KeyRotationService", () => {
let mockSendService: MockProxy<SendService>;
let mockEmergencyAccessService: MockProxy<EmergencyAccessService>;
let mockResetPasswordService: MockProxy<OrganizationUserResetPasswordService>;
let mockDeviceTrustCryptoService: MockProxy<DeviceTrustCryptoServiceAbstraction>;
let mockDeviceTrustService: MockProxy<DeviceTrustServiceAbstraction>;
let mockCryptoService: MockProxy<CryptoService>;
let mockEncryptService: MockProxy<EncryptService>;
let mockStateService: MockProxy<StateService>;
@ -60,7 +60,7 @@ describe("KeyRotationService", () => {
mockSendService = mock<SendService>();
mockEmergencyAccessService = mock<EmergencyAccessService>();
mockResetPasswordService = mock<OrganizationUserResetPasswordService>();
mockDeviceTrustCryptoService = mock<DeviceTrustCryptoServiceAbstraction>();
mockDeviceTrustService = mock<DeviceTrustServiceAbstraction>();
mockCryptoService = mock<CryptoService>();
mockEncryptService = mock<EncryptService>();
mockStateService = mock<StateService>();
@ -74,7 +74,7 @@ describe("KeyRotationService", () => {
mockSendService,
mockEmergencyAccessService,
mockResetPasswordService,
mockDeviceTrustCryptoService,
mockDeviceTrustService,
mockCryptoService,
mockEncryptService,
mockStateService,

View File

@ -2,7 +2,7 @@ import { Injectable } from "@angular/core";
import { firstValueFrom } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
@ -33,7 +33,7 @@ export class UserKeyRotationService {
private sendService: SendService,
private emergencyAccessService: EmergencyAccessService,
private resetPasswordService: OrganizationUserResetPasswordService,
private deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
private deviceTrustService: DeviceTrustServiceAbstraction,
private cryptoService: CryptoService,
private encryptService: EncryptService,
private stateService: StateService,
@ -96,7 +96,7 @@ export class UserKeyRotationService {
}
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
await this.deviceTrustCryptoService.rotateDevicesTrust(
await this.deviceTrustService.rotateDevicesTrust(
activeAccount.id,
newUserKey,
masterPasswordHash,

View File

@ -23,7 +23,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
@ -93,7 +93,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
protected apiService: ApiService,
protected i18nService: I18nService,
protected validationService: ValidationService,
protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
protected deviceTrustService: DeviceTrustServiceAbstraction,
protected platformUtilsService: PlatformUtilsService,
protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
protected passwordResetEnrollmentService: PasswordResetEnrollmentServiceAbstraction,
@ -156,7 +156,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
}
private async setRememberDeviceDefaultValue() {
const rememberDeviceFromState = await this.deviceTrustCryptoService.getShouldTrustDevice(
const rememberDeviceFromState = await this.deviceTrustService.getShouldTrustDevice(
this.activeAccountId,
);
@ -169,9 +169,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
this.rememberDevice.valueChanges
.pipe(
switchMap((value) =>
defer(() =>
this.deviceTrustCryptoService.setShouldTrustDevice(this.activeAccountId, value),
),
defer(() => this.deviceTrustService.setShouldTrustDevice(this.activeAccountId, value)),
),
takeUntil(this.destroy$),
)
@ -288,7 +286,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
await this.passwordResetEnrollmentService.enroll(this.data.organizationId);
if (this.rememberDeviceForm.value.rememberDevice) {
await this.deviceTrustCryptoService.trustDevice(this.activeAccountId);
await this.deviceTrustService.trustDevice(this.activeAccountId);
}
} catch (error) {
this.validationService.showError(error);

View File

@ -11,7 +11,7 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs
import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
@ -74,7 +74,7 @@ export class LockComponent implements OnInit, OnDestroy {
protected policyService: InternalPolicyService,
protected passwordStrengthService: PasswordStrengthServiceAbstraction,
protected dialogService: DialogService,
protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
protected deviceTrustService: DeviceTrustServiceAbstraction,
protected userVerificationService: UserVerificationService,
protected pinCryptoService: PinCryptoServiceAbstraction,
protected biometricStateService: BiometricStateService,
@ -277,7 +277,7 @@ export class LockComponent implements OnInit, OnDestroy {
// Now that we have a decrypted user key in memory, we can check if we
// need to establish trust on the current device
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
await this.deviceTrustCryptoService.trustDeviceIfRequired(activeAccount.id);
await this.deviceTrustService.trustDeviceIfRequired(activeAccount.id);
await this.doContinue(evaluatePasswordAfterUnlock);
}

View File

@ -12,7 +12,7 @@ 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";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { AuthRequestType } from "@bitwarden/common/auth/enums/auth-request-type";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { AdminAuthRequestStorable } from "@bitwarden/common/auth/models/domain/admin-auth-req-storable";
@ -86,7 +86,7 @@ export class LoginViaAuthRequestComponent
private validationService: ValidationService,
private stateService: StateService,
private loginEmailService: LoginEmailServiceAbstraction,
private deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
private deviceTrustService: DeviceTrustServiceAbstraction,
private authRequestService: AuthRequestServiceAbstraction,
private loginStrategyService: LoginStrategyServiceAbstraction,
private accountService: AccountService,
@ -402,7 +402,7 @@ export class LoginViaAuthRequestComponent
// Now that we have a decrypted user key in memory, we can check if we
// need to establish trust on the current device
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
await this.deviceTrustCryptoService.trustDeviceIfRequired(activeAccount.id);
await this.deviceTrustService.trustDeviceIfRequired(activeAccount.id);
// TODO: don't forget to use auto enrollment service everywhere we trust device

View File

@ -8,7 +8,7 @@ import {
import { firstValueFrom } from "rxjs";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { ClientType } from "@bitwarden/common/enums";
@ -30,7 +30,7 @@ export function lockGuard(): CanActivateFn {
) => {
const authService = inject(AuthService);
const cryptoService = inject(CryptoService);
const deviceTrustCryptoService = inject(DeviceTrustCryptoServiceAbstraction);
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
const platformUtilService = inject(PlatformUtilsService);
const messagingService = inject(MessagingService);
const router = inject(Router);
@ -53,7 +53,7 @@ export function lockGuard(): CanActivateFn {
// User is authN and in locked state.
const tdeEnabled = await firstValueFrom(deviceTrustCryptoService.supportsDeviceTrust$);
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
// Create special exception which allows users to go from the login-initiated page to the lock page for the approve w/ MP flow
// The MP check is necessary to prevent direct manual navigation from other locked state pages for users who don't have a MP

View File

@ -3,7 +3,7 @@ import { CanActivateFn, Router } from "@angular/router";
import { firstValueFrom } from "rxjs";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
@ -31,7 +31,7 @@ export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActiv
return async (route) => {
const authService = inject(AuthService);
const cryptoService = inject(CryptoService);
const deviceTrustCryptoService = inject(DeviceTrustCryptoServiceAbstraction);
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
const router = inject(Router);
const authStatus = await authService.getAuthStatus();
@ -46,7 +46,7 @@ export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActiv
// If locked, TDE is enabled, and the user hasn't decrypted yet, then redirect to the
// login decryption options component.
const tdeEnabled = await firstValueFrom(deviceTrustCryptoService.supportsDeviceTrust$);
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$);
if (authStatus === AuthenticationStatus.Locked && tdeEnabled && !everHadUserKey) {
return router.createUrlTree([routes.notDecrypted], { queryParams: route.queryParams });

View File

@ -8,7 +8,7 @@ import {
import { firstValueFrom } from "rxjs";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
@ -22,11 +22,11 @@ export function tdeDecryptionRequiredGuard(): CanActivateFn {
return async (_: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
const authService = inject(AuthService);
const cryptoService = inject(CryptoService);
const deviceTrustCryptoService = inject(DeviceTrustCryptoServiceAbstraction);
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
const router = inject(Router);
const authStatus = await authService.getAuthStatus();
const tdeEnabled = await firstValueFrom(deviceTrustCryptoService.supportsDeviceTrust$);
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$);
if (authStatus !== AuthenticationStatus.Locked || !tdeEnabled || everHadUserKey) {
return router.createUrlTree(["/"]);

View File

@ -60,7 +60,7 @@ import {
import { AnonymousHubService as AnonymousHubServiceAbstraction } from "@bitwarden/common/auth/abstractions/anonymous-hub.service";
import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service";
import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service";
@ -82,7 +82,7 @@ import { AccountServiceImplementation } from "@bitwarden/common/auth/services/ac
import { AnonymousHubService } from "@bitwarden/common/auth/services/anonymous-hub.service";
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
import { AvatarService } from "@bitwarden/common/auth/services/avatar.service";
import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation";
import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation";
import { DevicesServiceImplementation } from "@bitwarden/common/auth/services/devices/devices.service.implementation";
import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation";
import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service";
@ -385,7 +385,7 @@ const safeProviders: SafeProvider[] = [
EncryptService,
PasswordStrengthServiceAbstraction,
PolicyServiceAbstraction,
DeviceTrustCryptoServiceAbstraction,
DeviceTrustServiceAbstraction,
AuthRequestServiceAbstraction,
InternalUserDecryptionOptionsServiceAbstraction,
GlobalStateProvider,
@ -949,8 +949,8 @@ const safeProviders: SafeProvider[] = [
deps: [DevicesApiServiceAbstraction],
}),
safeProvider({
provide: DeviceTrustCryptoServiceAbstraction,
useClass: DeviceTrustCryptoService,
provide: DeviceTrustServiceAbstraction,
useClass: DeviceTrustService,
deps: [
KeyGenerationServiceAbstraction,
CryptoFunctionServiceAbstraction,
@ -1058,7 +1058,6 @@ const safeProviders: SafeProvider[] = [
useClass: OrganizationBillingService,
deps: [
ApiServiceAbstraction,
BillingApiServiceAbstraction,
CryptoServiceAbstraction,
EncryptService,
I18nServiceAbstraction,

View File

@ -1,7 +1,7 @@
import { mock, MockProxy } from "jest-mock-extended";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
@ -42,7 +42,7 @@ describe("AuthRequestLoginStrategy", () => {
let stateService: MockProxy<StateService>;
let twoFactorService: MockProxy<TwoFactorService>;
let userDecryptionOptions: MockProxy<InternalUserDecryptionOptionsServiceAbstraction>;
let deviceTrustCryptoService: MockProxy<DeviceTrustCryptoServiceAbstraction>;
let deviceTrustService: MockProxy<DeviceTrustServiceAbstraction>;
let billingAccountProfileStateService: MockProxy<BillingAccountProfileStateService>;
const mockUserId = Utils.newGuid() as UserId;
@ -75,7 +75,7 @@ describe("AuthRequestLoginStrategy", () => {
stateService = mock<StateService>();
twoFactorService = mock<TwoFactorService>();
userDecryptionOptions = mock<InternalUserDecryptionOptionsServiceAbstraction>();
deviceTrustCryptoService = mock<DeviceTrustCryptoServiceAbstraction>();
deviceTrustService = mock<DeviceTrustServiceAbstraction>();
billingAccountProfileStateService = mock<BillingAccountProfileStateService>();
accountService = mockAccountServiceWith(mockUserId);
@ -99,7 +99,7 @@ describe("AuthRequestLoginStrategy", () => {
stateService,
twoFactorService,
userDecryptionOptions,
deviceTrustCryptoService,
deviceTrustService,
billingAccountProfileStateService,
);
@ -132,7 +132,7 @@ describe("AuthRequestLoginStrategy", () => {
);
expect(cryptoService.setMasterKeyEncryptedUserKey).toHaveBeenCalledWith(tokenResponse.key);
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
expect(deviceTrustCryptoService.trustDeviceIfRequired).toHaveBeenCalled();
expect(deviceTrustService.trustDeviceIfRequired).toHaveBeenCalled();
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
});
@ -160,6 +160,6 @@ describe("AuthRequestLoginStrategy", () => {
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
// trustDeviceIfRequired should be called
expect(deviceTrustCryptoService.trustDeviceIfRequired).not.toHaveBeenCalled();
expect(deviceTrustService.trustDeviceIfRequired).not.toHaveBeenCalled();
});
});

View File

@ -3,7 +3,6 @@ import { Jsonify } from "type-fest";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
@ -18,6 +17,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/src/auth/abstractions/device-trust.service.abstraction";
import { UserId } from "@bitwarden/common/types/guid";
import { InternalUserDecryptionOptionsServiceAbstraction } from "../abstractions/user-decryption-options.service.abstraction";
@ -61,7 +61,7 @@ export class AuthRequestLoginStrategy extends LoginStrategy {
stateService: StateService,
twoFactorService: TwoFactorService,
userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction,
private deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
private deviceTrustService: DeviceTrustServiceAbstraction,
billingAccountProfileStateService: BillingAccountProfileStateService,
) {
super(
@ -147,7 +147,7 @@ export class AuthRequestLoginStrategy extends LoginStrategy {
await this.trySetUserKeyWithMasterKey();
// Establish trust if required after setting user key
await this.deviceTrustCryptoService.trustDeviceIfRequired(userId);
await this.deviceTrustService.trustDeviceIfRequired(userId);
}
}

View File

@ -1,7 +1,7 @@
import { mock, MockProxy } from "jest-mock-extended";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
@ -50,7 +50,7 @@ describe("SsoLoginStrategy", () => {
let twoFactorService: MockProxy<TwoFactorService>;
let userDecryptionOptionsService: MockProxy<InternalUserDecryptionOptionsServiceAbstraction>;
let keyConnectorService: MockProxy<KeyConnectorService>;
let deviceTrustCryptoService: MockProxy<DeviceTrustCryptoServiceAbstraction>;
let deviceTrustService: MockProxy<DeviceTrustServiceAbstraction>;
let authRequestService: MockProxy<AuthRequestServiceAbstraction>;
let i18nService: MockProxy<I18nService>;
let billingAccountProfileStateService: MockProxy<BillingAccountProfileStateService>;
@ -82,7 +82,7 @@ describe("SsoLoginStrategy", () => {
twoFactorService = mock<TwoFactorService>();
userDecryptionOptionsService = mock<InternalUserDecryptionOptionsServiceAbstraction>();
keyConnectorService = mock<KeyConnectorService>();
deviceTrustCryptoService = mock<DeviceTrustCryptoServiceAbstraction>();
deviceTrustService = mock<DeviceTrustServiceAbstraction>();
authRequestService = mock<AuthRequestServiceAbstraction>();
i18nService = mock<I18nService>();
billingAccountProfileStateService = mock<BillingAccountProfileStateService>();
@ -106,7 +106,7 @@ describe("SsoLoginStrategy", () => {
twoFactorService,
userDecryptionOptionsService,
keyConnectorService,
deviceTrustCryptoService,
deviceTrustService,
authRequestService,
i18nService,
billingAccountProfileStateService,
@ -209,8 +209,8 @@ describe("SsoLoginStrategy", () => {
);
apiService.postIdentityToken.mockResolvedValue(idTokenResponse);
deviceTrustCryptoService.getDeviceKey.mockResolvedValue(mockDeviceKey);
deviceTrustCryptoService.decryptUserKeyWithDeviceKey.mockResolvedValue(mockUserKey);
deviceTrustService.getDeviceKey.mockResolvedValue(mockDeviceKey);
deviceTrustService.decryptUserKeyWithDeviceKey.mockResolvedValue(mockUserKey);
const cryptoSvcSetUserKeySpy = jest.spyOn(cryptoService, "setUserKey");
@ -218,8 +218,8 @@ describe("SsoLoginStrategy", () => {
await ssoLoginStrategy.logIn(credentials);
// Assert
expect(deviceTrustCryptoService.getDeviceKey).toHaveBeenCalledTimes(1);
expect(deviceTrustCryptoService.decryptUserKeyWithDeviceKey).toHaveBeenCalledTimes(1);
expect(deviceTrustService.getDeviceKey).toHaveBeenCalledTimes(1);
expect(deviceTrustService.decryptUserKeyWithDeviceKey).toHaveBeenCalledTimes(1);
expect(cryptoSvcSetUserKeySpy).toHaveBeenCalledTimes(1);
expect(cryptoSvcSetUserKeySpy).toHaveBeenCalledWith(mockUserKey);
});
@ -232,8 +232,8 @@ describe("SsoLoginStrategy", () => {
);
apiService.postIdentityToken.mockResolvedValue(idTokenResponse);
// Set deviceKey to be null
deviceTrustCryptoService.getDeviceKey.mockResolvedValue(null);
deviceTrustCryptoService.decryptUserKeyWithDeviceKey.mockResolvedValue(mockUserKey);
deviceTrustService.getDeviceKey.mockResolvedValue(null);
deviceTrustService.decryptUserKeyWithDeviceKey.mockResolvedValue(mockUserKey);
// Act
await ssoLoginStrategy.logIn(credentials);
@ -254,7 +254,7 @@ describe("SsoLoginStrategy", () => {
// Arrange
const idTokenResponse = mockIdTokenResponseWithModifiedTrustedDeviceOption(valueName, null);
apiService.postIdentityToken.mockResolvedValue(idTokenResponse);
deviceTrustCryptoService.getDeviceKey.mockResolvedValue(mockDeviceKey);
deviceTrustService.getDeviceKey.mockResolvedValue(mockDeviceKey);
// Act
await ssoLoginStrategy.logIn(credentials);
@ -271,9 +271,9 @@ describe("SsoLoginStrategy", () => {
userDecryptionOptsServerResponseWithTdeOption,
);
apiService.postIdentityToken.mockResolvedValue(idTokenResponse);
deviceTrustCryptoService.getDeviceKey.mockResolvedValue(mockDeviceKey);
deviceTrustService.getDeviceKey.mockResolvedValue(mockDeviceKey);
// Set userKey to be null
deviceTrustCryptoService.decryptUserKeyWithDeviceKey.mockResolvedValue(null);
deviceTrustService.decryptUserKeyWithDeviceKey.mockResolvedValue(null);
// Act
await ssoLoginStrategy.logIn(credentials);
@ -321,7 +321,7 @@ describe("SsoLoginStrategy", () => {
await ssoLoginStrategy.logIn(credentials);
expect(authRequestService.setKeysAfterDecryptingSharedMasterKeyAndHash).toHaveBeenCalled();
expect(deviceTrustCryptoService.decryptUserKeyWithDeviceKey).not.toHaveBeenCalled();
expect(deviceTrustService.decryptUserKeyWithDeviceKey).not.toHaveBeenCalled();
});
it("sets the user key from approved admin request if exists", async () => {
@ -338,7 +338,7 @@ describe("SsoLoginStrategy", () => {
await ssoLoginStrategy.logIn(credentials);
expect(authRequestService.setUserKeyAfterDecryptingSharedUserKey).toHaveBeenCalled();
expect(deviceTrustCryptoService.decryptUserKeyWithDeviceKey).not.toHaveBeenCalled();
expect(deviceTrustService.decryptUserKeyWithDeviceKey).not.toHaveBeenCalled();
});
it("attempts to establish a trusted device if successful", async () => {
@ -355,7 +355,7 @@ describe("SsoLoginStrategy", () => {
await ssoLoginStrategy.logIn(credentials);
expect(authRequestService.setUserKeyAfterDecryptingSharedUserKey).toHaveBeenCalled();
expect(deviceTrustCryptoService.trustDeviceIfRequired).toHaveBeenCalled();
expect(deviceTrustService.trustDeviceIfRequired).toHaveBeenCalled();
});
it("clears the admin auth request if server returns a 404, meaning it was deleted", async () => {
@ -369,7 +369,7 @@ describe("SsoLoginStrategy", () => {
authRequestService.setKeysAfterDecryptingSharedMasterKeyAndHash,
).not.toHaveBeenCalled();
expect(authRequestService.setUserKeyAfterDecryptingSharedUserKey).not.toHaveBeenCalled();
expect(deviceTrustCryptoService.trustDeviceIfRequired).not.toHaveBeenCalled();
expect(deviceTrustService.trustDeviceIfRequired).not.toHaveBeenCalled();
});
it("attempts to login with a trusted device if admin auth request isn't successful", async () => {
@ -382,11 +382,11 @@ describe("SsoLoginStrategy", () => {
};
apiService.getAuthRequest.mockResolvedValue(adminAuthResponse as AuthRequestResponse);
cryptoService.hasUserKey.mockResolvedValue(false);
deviceTrustCryptoService.getDeviceKey.mockResolvedValue("DEVICE_KEY" as any);
deviceTrustService.getDeviceKey.mockResolvedValue("DEVICE_KEY" as any);
await ssoLoginStrategy.logIn(credentials);
expect(deviceTrustCryptoService.decryptUserKeyWithDeviceKey).toHaveBeenCalled();
expect(deviceTrustService.decryptUserKeyWithDeviceKey).toHaveBeenCalled();
});
});
});

View File

@ -3,7 +3,6 @@ import { Jsonify } from "type-fest";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
@ -22,6 +21,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/src/auth/abstractions/device-trust.service.abstraction";
import { UserId } from "@bitwarden/common/types/guid";
import {
@ -94,7 +94,7 @@ export class SsoLoginStrategy extends LoginStrategy {
twoFactorService: TwoFactorService,
userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction,
private keyConnectorService: KeyConnectorService,
private deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
private deviceTrustService: DeviceTrustServiceAbstraction,
private authRequestService: AuthRequestServiceAbstraction,
private i18nService: I18nService,
billingAccountProfileStateService: BillingAccountProfileStateService,
@ -298,7 +298,7 @@ export class SsoLoginStrategy extends LoginStrategy {
if (await this.cryptoService.hasUserKey()) {
// Now that we have a decrypted user key in memory, we can check if we
// need to establish trust on the current device
await this.deviceTrustCryptoService.trustDeviceIfRequired(userId);
await this.deviceTrustService.trustDeviceIfRequired(userId);
// if we successfully decrypted the user key, we can delete the admin auth request out of state
// TODO: eventually we post and clean up DB as well once consumed on client
@ -314,7 +314,7 @@ export class SsoLoginStrategy extends LoginStrategy {
const userId = (await this.stateService.getUserId()) as UserId;
const deviceKey = await this.deviceTrustCryptoService.getDeviceKey(userId);
const deviceKey = await this.deviceTrustService.getDeviceKey(userId);
const encDevicePrivateKey = trustedDeviceOption?.encryptedPrivateKey;
const encUserKey = trustedDeviceOption?.encryptedUserKey;
@ -322,7 +322,7 @@ export class SsoLoginStrategy extends LoginStrategy {
return;
}
const userKey = await this.deviceTrustCryptoService.decryptUserKeyWithDeviceKey(
const userKey = await this.deviceTrustService.decryptUserKeyWithDeviceKey(
userId,
encDevicePrivateKey,
encUserKey,

View File

@ -2,7 +2,7 @@ import { MockProxy, mock } from "jest-mock-extended";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
@ -62,7 +62,7 @@ describe("LoginStrategyService", () => {
let encryptService: MockProxy<EncryptService>;
let passwordStrengthService: MockProxy<PasswordStrengthServiceAbstraction>;
let policyService: MockProxy<PolicyService>;
let deviceTrustCryptoService: MockProxy<DeviceTrustCryptoServiceAbstraction>;
let deviceTrustService: MockProxy<DeviceTrustServiceAbstraction>;
let authRequestService: MockProxy<AuthRequestServiceAbstraction>;
let userDecryptionOptionsService: MockProxy<InternalUserDecryptionOptionsServiceAbstraction>;
let billingAccountProfileStateService: MockProxy<BillingAccountProfileStateService>;
@ -90,7 +90,7 @@ describe("LoginStrategyService", () => {
encryptService = mock<EncryptService>();
passwordStrengthService = mock<PasswordStrengthServiceAbstraction>();
policyService = mock<PolicyService>();
deviceTrustCryptoService = mock<DeviceTrustCryptoServiceAbstraction>();
deviceTrustService = mock<DeviceTrustServiceAbstraction>();
authRequestService = mock<AuthRequestServiceAbstraction>();
userDecryptionOptionsService = mock<UserDecryptionOptionsService>();
billingAccountProfileStateService = mock<BillingAccountProfileStateService>();
@ -114,7 +114,7 @@ describe("LoginStrategyService", () => {
encryptService,
passwordStrengthService,
policyService,
deviceTrustCryptoService,
deviceTrustService,
authRequestService,
userDecryptionOptionsService,
stateProvider,

View File

@ -10,7 +10,6 @@ import {
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
@ -36,6 +35,7 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv
import { KdfType } from "@bitwarden/common/platform/enums";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { GlobalState, GlobalStateProvider } from "@bitwarden/common/platform/state";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/src/auth/abstractions/device-trust.service.abstraction";
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
import { MasterKey } from "@bitwarden/common/types/key";
@ -100,7 +100,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
protected encryptService: EncryptService,
protected passwordStrengthService: PasswordStrengthServiceAbstraction,
protected policyService: PolicyService,
protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
protected deviceTrustService: DeviceTrustServiceAbstraction,
protected authRequestService: AuthRequestServiceAbstraction,
protected userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction,
protected stateProvider: GlobalStateProvider,
@ -371,7 +371,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
this.twoFactorService,
this.userDecryptionOptionsService,
this.keyConnectorService,
this.deviceTrustCryptoService,
this.deviceTrustService,
this.authRequestService,
this.i18nService,
this.billingAccountProfileStateService,
@ -410,7 +410,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
this.stateService,
this.twoFactorService,
this.userDecryptionOptionsService,
this.deviceTrustCryptoService,
this.deviceTrustService,
this.billingAccountProfileStateService,
);
case AuthenticationType.WebAuthn:

View File

@ -3,9 +3,10 @@ import { Observable } from "rxjs";
import { EncString } from "../../platform/models/domain/enc-string";
import { UserId } from "../../types/guid";
import { DeviceKey, UserKey } from "../../types/key";
import { DeviceResponse } from "../abstractions/devices/responses/device.response";
export abstract class DeviceTrustCryptoServiceAbstraction {
import { DeviceResponse } from "./devices/responses/device.response";
export abstract class DeviceTrustServiceAbstraction {
supportsDeviceTrust$: Observable<boolean>;
/**
* @description Retrieves the users choice to trust the device which can only happen after decryption

View File

@ -17,7 +17,7 @@ import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypt
import { DEVICE_TRUST_DISK_LOCAL, StateProvider, UserKeyDefinition } from "../../platform/state";
import { UserId } from "../../types/guid";
import { UserKey, DeviceKey } from "../../types/key";
import { DeviceTrustCryptoServiceAbstraction } from "../abstractions/device-trust-crypto.service.abstraction";
import { DeviceTrustServiceAbstraction } from "../abstractions/device-trust.service.abstraction";
import { DeviceResponse } from "../abstractions/devices/responses/device.response";
import { DevicesApiServiceAbstraction } from "../abstractions/devices-api.service.abstraction";
import { SecretVerificationRequest } from "../models/request/secret-verification.request";
@ -42,7 +42,7 @@ export const SHOULD_TRUST_DEVICE = new UserKeyDefinition<boolean>(
},
);
export class DeviceTrustCryptoService implements DeviceTrustCryptoServiceAbstraction {
export class DeviceTrustService implements DeviceTrustServiceAbstraction {
private readonly platformSupportsSecureStorage =
this.platformUtilsService.supportsSecureStorage();
private readonly deviceKeySecureStorageKey: string = "_deviceKey";

View File

@ -33,11 +33,11 @@ import { ProtectedDeviceResponse } from "../models/response/protected-device.res
import {
SHOULD_TRUST_DEVICE,
DEVICE_KEY,
DeviceTrustCryptoService,
} from "./device-trust-crypto.service.implementation";
DeviceTrustService,
} from "./device-trust.service.implementation";
describe("deviceTrustCryptoService", () => {
let deviceTrustCryptoService: DeviceTrustCryptoService;
describe("deviceTrustService", () => {
let deviceTrustService: DeviceTrustService;
const keyGenerationService = mock<KeyGenerationService>();
const cryptoFunctionService = mock<CryptoFunctionService>();
@ -70,11 +70,11 @@ describe("deviceTrustCryptoService", () => {
jest.clearAllMocks();
const supportsSecureStorage = false; // default to false; tests will override as needed
// By default all the tests will have a mocked active user in state provider.
deviceTrustCryptoService = createDeviceTrustCryptoService(mockUserId, supportsSecureStorage);
deviceTrustService = createDeviceTrustService(mockUserId, supportsSecureStorage);
});
it("instantiates", () => {
expect(deviceTrustCryptoService).not.toBeFalsy();
expect(deviceTrustService).not.toBeFalsy();
});
describe("User Trust Device Choice For Decryption", () => {
@ -84,7 +84,7 @@ describe("deviceTrustCryptoService", () => {
await stateProvider.setUserState(SHOULD_TRUST_DEVICE, newValue, mockUserId);
const result = await deviceTrustCryptoService.getShouldTrustDevice(mockUserId);
const result = await deviceTrustService.getShouldTrustDevice(mockUserId);
expect(result).toEqual(newValue);
});
@ -95,9 +95,9 @@ describe("deviceTrustCryptoService", () => {
await stateProvider.setUserState(SHOULD_TRUST_DEVICE, false, mockUserId);
const newValue = true;
await deviceTrustCryptoService.setShouldTrustDevice(mockUserId, newValue);
await deviceTrustService.setShouldTrustDevice(mockUserId, newValue);
const result = await deviceTrustCryptoService.getShouldTrustDevice(mockUserId);
const result = await deviceTrustService.getShouldTrustDevice(mockUserId);
expect(result).toEqual(newValue);
});
});
@ -105,25 +105,25 @@ describe("deviceTrustCryptoService", () => {
describe("trustDeviceIfRequired", () => {
it("should trust device and reset when getShouldTrustDevice returns true", async () => {
jest.spyOn(deviceTrustCryptoService, "getShouldTrustDevice").mockResolvedValue(true);
jest.spyOn(deviceTrustCryptoService, "trustDevice").mockResolvedValue({} as DeviceResponse);
jest.spyOn(deviceTrustCryptoService, "setShouldTrustDevice").mockResolvedValue();
jest.spyOn(deviceTrustService, "getShouldTrustDevice").mockResolvedValue(true);
jest.spyOn(deviceTrustService, "trustDevice").mockResolvedValue({} as DeviceResponse);
jest.spyOn(deviceTrustService, "setShouldTrustDevice").mockResolvedValue();
await deviceTrustCryptoService.trustDeviceIfRequired(mockUserId);
await deviceTrustService.trustDeviceIfRequired(mockUserId);
expect(deviceTrustCryptoService.getShouldTrustDevice).toHaveBeenCalledTimes(1);
expect(deviceTrustCryptoService.trustDevice).toHaveBeenCalledTimes(1);
expect(deviceTrustCryptoService.setShouldTrustDevice).toHaveBeenCalledWith(mockUserId, false);
expect(deviceTrustService.getShouldTrustDevice).toHaveBeenCalledTimes(1);
expect(deviceTrustService.trustDevice).toHaveBeenCalledTimes(1);
expect(deviceTrustService.setShouldTrustDevice).toHaveBeenCalledWith(mockUserId, false);
});
it("should not trust device nor reset when getShouldTrustDevice returns false", async () => {
const getShouldTrustDeviceSpy = jest
.spyOn(deviceTrustCryptoService, "getShouldTrustDevice")
.spyOn(deviceTrustService, "getShouldTrustDevice")
.mockResolvedValue(false);
const trustDeviceSpy = jest.spyOn(deviceTrustCryptoService, "trustDevice");
const setShouldTrustDeviceSpy = jest.spyOn(deviceTrustCryptoService, "setShouldTrustDevice");
const trustDeviceSpy = jest.spyOn(deviceTrustService, "trustDevice");
const setShouldTrustDeviceSpy = jest.spyOn(deviceTrustService, "setShouldTrustDevice");
await deviceTrustCryptoService.trustDeviceIfRequired(mockUserId);
await deviceTrustService.trustDeviceIfRequired(mockUserId);
expect(getShouldTrustDeviceSpy).toHaveBeenCalledTimes(1);
expect(trustDeviceSpy).not.toHaveBeenCalled();
@ -151,7 +151,7 @@ describe("deviceTrustCryptoService", () => {
it("returns null when there is not an existing device key", async () => {
await stateProvider.setUserState(DEVICE_KEY, null, mockUserId);
const deviceKey = await deviceTrustCryptoService.getDeviceKey(mockUserId);
const deviceKey = await deviceTrustService.getDeviceKey(mockUserId);
expect(deviceKey).toBeNull();
expect(secureStorageService.get).not.toHaveBeenCalled();
@ -160,7 +160,7 @@ describe("deviceTrustCryptoService", () => {
it("returns the device key when there is an existing device key", async () => {
await stateProvider.setUserState(DEVICE_KEY, existingDeviceKey, mockUserId);
const deviceKey = await deviceTrustCryptoService.getDeviceKey(mockUserId);
const deviceKey = await deviceTrustService.getDeviceKey(mockUserId);
expect(deviceKey).not.toBeNull();
expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey);
@ -172,17 +172,14 @@ describe("deviceTrustCryptoService", () => {
describe("Secure Storage supported", () => {
beforeEach(() => {
const supportsSecureStorage = true;
deviceTrustCryptoService = createDeviceTrustCryptoService(
mockUserId,
supportsSecureStorage,
);
deviceTrustService = createDeviceTrustService(mockUserId, supportsSecureStorage);
});
it("returns null when there is not an existing device key for the passed in user id", async () => {
secureStorageService.get.mockResolvedValue(null);
// Act
const deviceKey = await deviceTrustCryptoService.getDeviceKey(mockUserId);
const deviceKey = await deviceTrustService.getDeviceKey(mockUserId);
// Assert
expect(deviceKey).toBeNull();
@ -193,7 +190,7 @@ describe("deviceTrustCryptoService", () => {
secureStorageService.get.mockResolvedValue(existingDeviceKeyB64);
// Act
const deviceKey = await deviceTrustCryptoService.getDeviceKey(mockUserId);
const deviceKey = await deviceTrustService.getDeviceKey(mockUserId);
// Assert
expect(deviceKey).not.toBeNull();
@ -203,7 +200,7 @@ describe("deviceTrustCryptoService", () => {
});
it("throws an error when no user id is passed in", async () => {
await expect(deviceTrustCryptoService.getDeviceKey(null)).rejects.toThrow(
await expect(deviceTrustService.getDeviceKey(null)).rejects.toThrow(
"UserId is required. Cannot get device key.",
);
});
@ -220,7 +217,7 @@ describe("deviceTrustCryptoService", () => {
// TypeScript will allow calling private methods if the object is of type 'any'
// This is a hacky workaround, but it allows for cleaner tests
await (deviceTrustCryptoService as any).setDeviceKey(mockUserId, newDeviceKey);
await (deviceTrustService as any).setDeviceKey(mockUserId, newDeviceKey);
expect(stateProvider.mock.setUserState).toHaveBeenLastCalledWith(
DEVICE_KEY,
@ -232,10 +229,7 @@ describe("deviceTrustCryptoService", () => {
describe("Secure Storage supported", () => {
beforeEach(() => {
const supportsSecureStorage = true;
deviceTrustCryptoService = createDeviceTrustCryptoService(
mockUserId,
supportsSecureStorage,
);
deviceTrustService = createDeviceTrustService(mockUserId, supportsSecureStorage);
});
it("successfully sets the device key in secure storage", async () => {
@ -251,7 +245,7 @@ describe("deviceTrustCryptoService", () => {
// Act
// TypeScript will allow calling private methods if the object is of type 'any'
// This is a hacky workaround, but it allows for cleaner tests
await (deviceTrustCryptoService as any).setDeviceKey(mockUserId, newDeviceKey);
await (deviceTrustService as any).setDeviceKey(mockUserId, newDeviceKey);
// Assert
expect(stateProvider.mock.setUserState).not.toHaveBeenCalledTimes(2);
@ -268,9 +262,9 @@ describe("deviceTrustCryptoService", () => {
new Uint8Array(deviceKeyBytesLength) as CsprngArray,
) as DeviceKey;
await expect(
(deviceTrustCryptoService as any).setDeviceKey(null, newDeviceKey),
).rejects.toThrow("UserId is required. Cannot set device key.");
await expect((deviceTrustService as any).setDeviceKey(null, newDeviceKey)).rejects.toThrow(
"UserId is required. Cannot set device key.",
);
});
});
@ -285,7 +279,7 @@ describe("deviceTrustCryptoService", () => {
// TypeScript will allow calling private methods if the object is of type 'any'
// This is a hacky workaround, but it allows for cleaner tests
const deviceKey = await (deviceTrustCryptoService as any).makeDeviceKey();
const deviceKey = await (deviceTrustService as any).makeDeviceKey();
expect(keyGenSvcGenerateKeySpy).toHaveBeenCalledTimes(1);
expect(keyGenSvcGenerateKeySpy).toHaveBeenCalledWith(deviceKeyBytesLength * 8);
@ -362,7 +356,7 @@ describe("deviceTrustCryptoService", () => {
// TypeScript will allow calling private methods if the object is of type 'any'
makeDeviceKeySpy = jest
.spyOn(deviceTrustCryptoService as any, "makeDeviceKey")
.spyOn(deviceTrustService as any, "makeDeviceKey")
.mockResolvedValue(mockDeviceKey);
rsaGenerateKeyPairSpy = jest
@ -398,7 +392,7 @@ describe("deviceTrustCryptoService", () => {
});
it("calls the required methods with the correct arguments and returns a DeviceResponse", async () => {
const response = await deviceTrustCryptoService.trustDevice(mockUserId);
const response = await deviceTrustService.trustDevice(mockUserId);
expect(makeDeviceKeySpy).toHaveBeenCalledTimes(1);
expect(rsaGenerateKeyPairSpy).toHaveBeenCalledTimes(1);
@ -429,7 +423,7 @@ describe("deviceTrustCryptoService", () => {
// setup the spy to return null
cryptoSvcGetUserKeySpy.mockResolvedValue(null);
// check if the expected error is thrown
await expect(deviceTrustCryptoService.trustDevice(mockUserId)).rejects.toThrow(
await expect(deviceTrustService.trustDevice(mockUserId)).rejects.toThrow(
"User symmetric key not found",
);
@ -439,7 +433,7 @@ describe("deviceTrustCryptoService", () => {
// setup the spy to return undefined
cryptoSvcGetUserKeySpy.mockResolvedValue(undefined);
// check if the expected error is thrown
await expect(deviceTrustCryptoService.trustDevice(mockUserId)).rejects.toThrow(
await expect(deviceTrustService.trustDevice(mockUserId)).rejects.toThrow(
"User symmetric key not found",
);
});
@ -479,9 +473,7 @@ describe("deviceTrustCryptoService", () => {
it(`throws an error if ${method} fails`, async () => {
const methodSpy = spy();
methodSpy.mockRejectedValue(new Error(errorText));
await expect(deviceTrustCryptoService.trustDevice(mockUserId)).rejects.toThrow(
errorText,
);
await expect(deviceTrustService.trustDevice(mockUserId)).rejects.toThrow(errorText);
});
test.each([null, undefined])(
@ -489,14 +481,14 @@ describe("deviceTrustCryptoService", () => {
async (invalidValue) => {
const methodSpy = spy();
methodSpy.mockResolvedValue(invalidValue);
await expect(deviceTrustCryptoService.trustDevice(mockUserId)).rejects.toThrow();
await expect(deviceTrustService.trustDevice(mockUserId)).rejects.toThrow();
},
);
},
);
it("throws an error when a null user id is passed in", async () => {
await expect(deviceTrustCryptoService.trustDevice(null)).rejects.toThrow(
await expect(deviceTrustService.trustDevice(null)).rejects.toThrow(
"UserId is required. Cannot trust device.",
);
});
@ -530,7 +522,7 @@ describe("deviceTrustCryptoService", () => {
it("throws an error when a null user id is passed in", async () => {
await expect(
deviceTrustCryptoService.decryptUserKeyWithDeviceKey(
deviceTrustService.decryptUserKeyWithDeviceKey(
null,
mockEncryptedDevicePrivateKey,
mockEncryptedUserKey,
@ -540,7 +532,7 @@ describe("deviceTrustCryptoService", () => {
});
it("returns null when device key isn't provided", async () => {
const result = await deviceTrustCryptoService.decryptUserKeyWithDeviceKey(
const result = await deviceTrustService.decryptUserKeyWithDeviceKey(
mockUserId,
mockEncryptedDevicePrivateKey,
mockEncryptedUserKey,
@ -558,7 +550,7 @@ describe("deviceTrustCryptoService", () => {
.spyOn(cryptoService, "rsaDecrypt")
.mockResolvedValue(new Uint8Array(userKeyBytesLength));
const result = await deviceTrustCryptoService.decryptUserKeyWithDeviceKey(
const result = await deviceTrustService.decryptUserKeyWithDeviceKey(
mockUserId,
mockEncryptedDevicePrivateKey,
mockEncryptedUserKey,
@ -574,9 +566,9 @@ describe("deviceTrustCryptoService", () => {
const decryptToBytesSpy = jest
.spyOn(encryptService, "decryptToBytes")
.mockRejectedValue(new Error("Decryption error"));
const setDeviceKeySpy = jest.spyOn(deviceTrustCryptoService as any, "setDeviceKey");
const setDeviceKeySpy = jest.spyOn(deviceTrustService as any, "setDeviceKey");
const result = await deviceTrustCryptoService.decryptUserKeyWithDeviceKey(
const result = await deviceTrustService.decryptUserKeyWithDeviceKey(
mockUserId,
mockEncryptedDevicePrivateKey,
mockEncryptedUserKey,
@ -606,7 +598,7 @@ describe("deviceTrustCryptoService", () => {
it("throws an error when a null user id is passed in", async () => {
await expect(
deviceTrustCryptoService.rotateDevicesTrust(null, fakeNewUserKey, ""),
deviceTrustService.rotateDevicesTrust(null, fakeNewUserKey, ""),
).rejects.toThrow("UserId is required. Cannot rotate device's trust.");
});
@ -615,7 +607,7 @@ describe("deviceTrustCryptoService", () => {
stateProvider.activeUser.getFake(DEVICE_KEY);
deviceKeyState.nextState(null);
await deviceTrustCryptoService.rotateDevicesTrust(mockUserId, fakeNewUserKey, "");
await deviceTrustService.rotateDevicesTrust(mockUserId, fakeNewUserKey, "");
expect(devicesApiService.updateTrust).not.toHaveBeenCalled();
});
@ -691,7 +683,7 @@ describe("deviceTrustCryptoService", () => {
);
});
await deviceTrustCryptoService.rotateDevicesTrust(
await deviceTrustService.rotateDevicesTrust(
mockUserId,
fakeNewUserKey,
"my_password_hash",
@ -713,10 +705,7 @@ describe("deviceTrustCryptoService", () => {
});
// Helpers
function createDeviceTrustCryptoService(
mockUserId: UserId | null,
supportsSecureStorage: boolean,
) {
function createDeviceTrustService(mockUserId: UserId | null, supportsSecureStorage: boolean) {
accountService = mockAccountServiceWith(mockUserId);
stateProvider = new FakeStateProvider(accountService);
@ -725,7 +714,7 @@ describe("deviceTrustCryptoService", () => {
decryptionOptions.next({} as any);
userDecryptionOptionsService.userDecryptionOptions$ = decryptionOptions;
return new DeviceTrustCryptoService(
return new DeviceTrustService(
keyGenerationService,
cryptoFunctionService,
cryptoService,

View File

@ -1,4 +1,5 @@
import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request";
import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response";
import { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response";
import { OrganizationSubscriptionResponse } from "../../billing/models/response/organization-subscription.response";
import { PlanResponse } from "../../billing/models/response/plan.response";
@ -12,13 +13,15 @@ export abstract class BillingApiServiceAbstraction {
organizationId: string,
request: SubscriptionCancellationRequest,
) => Promise<void>;
cancelPremiumUserSubscription: (request: SubscriptionCancellationRequest) => Promise<void>;
createClientOrganization: (
providerId: string,
request: CreateClientOrganizationRequest,
) => Promise<void>;
getBillingStatus: (id: string) => Promise<OrganizationBillingStatusResponse>;
getOrganizationBillingMetadata: (
organizationId: string,
) => Promise<OrganizationBillingMetadataResponse>;
getOrganizationSubscription: (
organizationId: string,
) => Promise<OrganizationSubscriptionResponse>;

View File

@ -41,8 +41,6 @@ export type SubscriptionInformation = {
};
export abstract class OrganizationBillingServiceAbstraction {
isOnSecretsManagerStandalone: (organizationId: string) => Promise<boolean>;
purchaseSubscription: (subscription: SubscriptionInformation) => Promise<OrganizationResponse>;
startFree: (subscription: SubscriptionInformation) => Promise<OrganizationResponse>;

View File

@ -0,0 +1,10 @@
import { BaseResponse } from "../../../models/response/base.response";
export class OrganizationBillingMetadataResponse extends BaseResponse {
isOnSecretsManagerStandalone: boolean;
constructor(response: any) {
super(response);
this.isOnSecretsManagerStandalone = this.getResponseProperty("IsOnSecretsManagerStandalone");
}
}

View File

@ -1,3 +1,5 @@
import { OrganizationBillingMetadataResponse } from "@bitwarden/common/billing/models/response/organization-billing-metadata.response";
import { ApiService } from "../../abstractions/api.service";
import { BillingApiServiceAbstraction } from "../../billing/abstractions/billilng-api.service.abstraction";
import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request";
@ -53,6 +55,20 @@ export class BillingApiService implements BillingApiServiceAbstraction {
return new OrganizationBillingStatusResponse(r);
}
async getOrganizationBillingMetadata(
organizationId: string,
): Promise<OrganizationBillingMetadataResponse> {
const r = await this.apiService.send(
"GET",
"/organizations/" + organizationId + "/billing/metadata",
null,
true,
true,
);
return new OrganizationBillingMetadataResponse(r);
}
async getOrganizationSubscription(
organizationId: string,
): Promise<OrganizationSubscriptionResponse> {

View File

@ -9,7 +9,6 @@ import { I18nService } from "../../platform/abstractions/i18n.service";
import { EncString } from "../../platform/models/domain/enc-string";
import { OrgKey } from "../../types/key";
import { SyncService } from "../../vault/abstractions/sync/sync.service.abstraction";
import { BillingApiServiceAbstraction as BillingApiService } from "../abstractions/billilng-api.service.abstraction";
import {
OrganizationBillingServiceAbstraction,
OrganizationInformation,
@ -29,7 +28,6 @@ interface OrganizationKeys {
export class OrganizationBillingService implements OrganizationBillingServiceAbstraction {
constructor(
private apiService: ApiService,
private billingApiService: BillingApiService,
private cryptoService: CryptoService,
private encryptService: EncryptService,
private i18nService: I18nService,
@ -37,19 +35,6 @@ export class OrganizationBillingService implements OrganizationBillingServiceAbs
private syncService: SyncService,
) {}
async isOnSecretsManagerStandalone(organizationId: string): Promise<boolean> {
const response = await this.billingApiService.getOrganizationSubscription(organizationId);
if (response.customerDiscount?.id === "sm-standalone") {
const productIds = response.subscription.items.map((item) => item.productId);
return (
response.customerDiscount?.appliesTo.filter((appliesToProductId) =>
productIds.includes(appliesToProductId),
).length > 0
);
}
return false;
}
async purchaseSubscription(subscription: SubscriptionInformation): Promise<OrganizationResponse> {
const request = new OrganizationCreateRequest();

View File

@ -2,6 +2,8 @@ import { EncString } from "../../platform/models/domain/enc-string";
import { Card as CardDomain } from "../../vault/models/domain/card";
import { CardView } from "../../vault/models/view/card.view";
import { safeGetString } from "./utils";
export class CardExport {
static template(): CardExport {
const req = new CardExport();
@ -46,20 +48,11 @@ export class CardExport {
return;
}
if (o instanceof CardView) {
this.cardholderName = o.cardholderName;
this.brand = o.brand;
this.number = o.number;
this.expMonth = o.expMonth;
this.expYear = o.expYear;
this.code = o.code;
} else {
this.cardholderName = o.cardholderName?.encryptedString;
this.brand = o.brand?.encryptedString;
this.number = o.number?.encryptedString;
this.expMonth = o.expMonth?.encryptedString;
this.expYear = o.expYear?.encryptedString;
this.code = o.code?.encryptedString;
}
this.cardholderName = safeGetString(o.cardholderName);
this.brand = safeGetString(o.brand);
this.number = safeGetString(o.number);
this.expMonth = safeGetString(o.expMonth);
this.expYear = safeGetString(o.expYear);
this.code = safeGetString(o.code);
}
}

View File

@ -10,6 +10,7 @@ import { IdentityExport } from "./identity.export";
import { LoginExport } from "./login.export";
import { PasswordHistoryExport } from "./password-history.export";
import { SecureNoteExport } from "./secure-note.export";
import { safeGetString } from "./utils";
export class CipherExport {
static template(): CipherExport {
@ -145,23 +146,16 @@ export class CipherExport {
this.type = o.type;
this.reprompt = o.reprompt;
if (o instanceof CipherView) {
this.name = o.name;
this.notes = o.notes;
} else {
this.name = o.name?.encryptedString;
this.notes = o.notes?.encryptedString;
this.name = safeGetString(o.name);
this.notes = safeGetString(o.notes);
if ("key" in o) {
this.key = o.key?.encryptedString;
}
this.favorite = o.favorite;
if (o.fields != null) {
if (o instanceof CipherView) {
this.fields = o.fields.map((f) => new FieldExport(f));
} else {
this.fields = o.fields.map((f) => new FieldExport(f));
}
this.fields = o.fields.map((f) => new FieldExport(f));
}
switch (o.type) {
@ -180,11 +174,7 @@ export class CipherExport {
}
if (o.passwordHistory != null) {
if (o instanceof CipherView) {
this.passwordHistory = o.passwordHistory.map((ph) => new PasswordHistoryExport(ph));
} else {
this.passwordHistory = o.passwordHistory.map((ph) => new PasswordHistoryExport(ph));
}
this.passwordHistory = o.passwordHistory.map((ph) => new PasswordHistoryExport(ph));
}
this.creationDate = o.creationDate;

View File

@ -2,6 +2,8 @@ import { EncString } from "../../platform/models/domain/enc-string";
import { Collection as CollectionDomain } from "../../vault/models/domain/collection";
import { CollectionView } from "../../vault/models/view/collection.view";
import { safeGetString } from "./utils";
export class CollectionExport {
static template(): CollectionExport {
const req = new CollectionExport();
@ -36,11 +38,7 @@ export class CollectionExport {
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
build(o: CollectionView | CollectionDomain) {
this.organizationId = o.organizationId;
if (o instanceof CollectionView) {
this.name = o.name;
} else {
this.name = o.name?.encryptedString;
}
this.name = safeGetString(o.name);
this.externalId = o.externalId;
}
}

View File

@ -2,6 +2,8 @@ import { EncString } from "../../platform/models/domain/enc-string";
import { Fido2Credential } from "../../vault/models/domain/fido2-credential";
import { Fido2CredentialView } from "../../vault/models/view/fido2-credential.view";
import { safeGetString } from "./utils";
/**
* Represents format of Fido2 Credentials in JSON exports.
*/
@ -99,33 +101,18 @@ export class Fido2CredentialExport {
return;
}
if (o instanceof Fido2CredentialView) {
this.credentialId = o.credentialId;
this.keyType = o.keyType;
this.keyAlgorithm = o.keyAlgorithm;
this.keyCurve = o.keyCurve;
this.keyValue = o.keyValue;
this.rpId = o.rpId;
this.userHandle = o.userHandle;
this.userName = o.userName;
this.counter = String(o.counter);
this.rpName = o.rpName;
this.userDisplayName = o.userDisplayName;
this.discoverable = String(o.discoverable);
} else {
this.credentialId = o.credentialId?.encryptedString;
this.keyType = o.keyType?.encryptedString;
this.keyAlgorithm = o.keyAlgorithm?.encryptedString;
this.keyCurve = o.keyCurve?.encryptedString;
this.keyValue = o.keyValue?.encryptedString;
this.rpId = o.rpId?.encryptedString;
this.userHandle = o.userHandle?.encryptedString;
this.userName = o.userName?.encryptedString;
this.counter = o.counter?.encryptedString;
this.rpName = o.rpName?.encryptedString;
this.userDisplayName = o.userDisplayName?.encryptedString;
this.discoverable = o.discoverable?.encryptedString;
}
this.credentialId = safeGetString(o.credentialId);
this.keyType = safeGetString(o.keyType);
this.keyAlgorithm = safeGetString(o.keyAlgorithm);
this.keyCurve = safeGetString(o.keyCurve);
this.keyValue = safeGetString(o.keyValue);
this.rpId = safeGetString(o.rpId);
this.userHandle = safeGetString(o.userHandle);
this.userName = safeGetString(o.userName);
this.counter = safeGetString(String(o.counter));
this.rpName = safeGetString(o.rpName);
this.userDisplayName = safeGetString(o.userDisplayName);
this.discoverable = safeGetString(String(o.discoverable));
this.creationDate = o.creationDate;
}
}

View File

@ -3,6 +3,8 @@ import { FieldType, LinkedIdType } from "../../vault/enums";
import { Field as FieldDomain } from "../../vault/models/domain/field";
import { FieldView } from "../../vault/models/view/field.view";
import { safeGetString } from "./utils";
export class FieldExport {
static template(): FieldExport {
const req = new FieldExport();
@ -38,13 +40,8 @@ export class FieldExport {
return;
}
if (o instanceof FieldView) {
this.name = o.name;
this.value = o.value;
} else {
this.name = o.name?.encryptedString;
this.value = o.value?.encryptedString;
}
this.name = safeGetString(o.name);
this.value = safeGetString(o.value);
this.type = o.type;
this.linkedId = o.linkedId;
}

View File

@ -2,6 +2,8 @@ import { EncString } from "../../platform/models/domain/enc-string";
import { Folder as FolderDomain } from "../../vault/models/domain/folder";
import { FolderView } from "../../vault/models/view/folder.view";
import { safeGetString } from "./utils";
export class FolderExport {
static template(): FolderExport {
const req = new FolderExport();
@ -23,10 +25,6 @@ export class FolderExport {
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
build(o: FolderView | FolderDomain) {
if (o instanceof FolderView) {
this.name = o.name;
} else {
this.name = o.name?.encryptedString;
}
this.name = safeGetString(o.name);
}
}

View File

@ -2,6 +2,8 @@ import { EncString } from "../../platform/models/domain/enc-string";
import { Identity as IdentityDomain } from "../../vault/models/domain/identity";
import { IdentityView } from "../../vault/models/view/identity.view";
import { safeGetString } from "./utils";
export class IdentityExport {
static template(): IdentityExport {
const req = new IdentityExport();
@ -94,44 +96,23 @@ export class IdentityExport {
return;
}
if (o instanceof IdentityView) {
this.title = o.title;
this.firstName = o.firstName;
this.middleName = o.middleName;
this.lastName = o.lastName;
this.address1 = o.address1;
this.address2 = o.address2;
this.address3 = o.address3;
this.city = o.city;
this.state = o.state;
this.postalCode = o.postalCode;
this.country = o.country;
this.company = o.company;
this.email = o.email;
this.phone = o.phone;
this.ssn = o.ssn;
this.username = o.username;
this.passportNumber = o.passportNumber;
this.licenseNumber = o.licenseNumber;
} else {
this.title = o.title?.encryptedString;
this.firstName = o.firstName?.encryptedString;
this.middleName = o.middleName?.encryptedString;
this.lastName = o.lastName?.encryptedString;
this.address1 = o.address1?.encryptedString;
this.address2 = o.address2?.encryptedString;
this.address3 = o.address3?.encryptedString;
this.city = o.city?.encryptedString;
this.state = o.state?.encryptedString;
this.postalCode = o.postalCode?.encryptedString;
this.country = o.country?.encryptedString;
this.company = o.company?.encryptedString;
this.email = o.email?.encryptedString;
this.phone = o.phone?.encryptedString;
this.ssn = o.ssn?.encryptedString;
this.username = o.username?.encryptedString;
this.passportNumber = o.passportNumber?.encryptedString;
this.licenseNumber = o.licenseNumber?.encryptedString;
}
this.title = safeGetString(o.title);
this.firstName = safeGetString(o.firstName);
this.middleName = safeGetString(o.middleName);
this.lastName = safeGetString(o.lastName);
this.address1 = safeGetString(o.address1);
this.address2 = safeGetString(o.address2);
this.address3 = safeGetString(o.address3);
this.city = safeGetString(o.city);
this.state = safeGetString(o.state);
this.postalCode = safeGetString(o.postalCode);
this.country = safeGetString(o.country);
this.company = safeGetString(o.company);
this.email = safeGetString(o.email);
this.phone = safeGetString(o.phone);
this.ssn = safeGetString(o.ssn);
this.username = safeGetString(o.username);
this.passportNumber = safeGetString(o.passportNumber);
this.licenseNumber = safeGetString(o.licenseNumber);
}
}

View File

@ -3,6 +3,8 @@ import { EncString } from "../../platform/models/domain/enc-string";
import { LoginUri as LoginUriDomain } from "../../vault/models/domain/login-uri";
import { LoginUriView } from "../../vault/models/view/login-uri.view";
import { safeGetString } from "./utils";
export class LoginUriExport {
static template(): LoginUriExport {
const req = new LoginUriExport();
@ -33,10 +35,8 @@ export class LoginUriExport {
return;
}
if (o instanceof LoginUriView) {
this.uri = o.uri;
} else {
this.uri = o.uri?.encryptedString;
this.uri = safeGetString(o.uri);
if ("uriChecksum" in o) {
this.uriChecksum = o.uriChecksum?.encryptedString;
}
this.match = o.match;

View File

@ -4,6 +4,7 @@ import { LoginView } from "../../vault/models/view/login.view";
import { Fido2CredentialExport } from "./fido2-credential.export";
import { LoginUriExport } from "./login-uri.export";
import { safeGetString } from "./utils";
export class LoginExport {
static template(): LoginExport {
@ -53,25 +54,15 @@ export class LoginExport {
}
if (o.uris != null) {
if (o instanceof LoginView) {
this.uris = o.uris.map((u) => new LoginUriExport(u));
} else {
this.uris = o.uris.map((u) => new LoginUriExport(u));
}
this.uris = o.uris.map((u) => new LoginUriExport(u));
}
if (o.fido2Credentials != null) {
this.fido2Credentials = o.fido2Credentials.map((key) => new Fido2CredentialExport(key));
}
if (o instanceof LoginView) {
this.username = o.username;
this.password = o.password;
this.totp = o.totp;
} else {
this.username = o.username?.encryptedString;
this.password = o.password?.encryptedString;
this.totp = o.totp?.encryptedString;
}
this.username = safeGetString(o.username);
this.password = safeGetString(o.password);
this.totp = safeGetString(o.totp);
}
}

View File

@ -2,6 +2,8 @@ import { EncString } from "../../platform/models/domain/enc-string";
import { Password } from "../../vault/models/domain/password";
import { PasswordHistoryView } from "../../vault/models/view/password-history.view";
import { safeGetString } from "./utils";
export class PasswordHistoryExport {
static template(): PasswordHistoryExport {
const req = new PasswordHistoryExport();
@ -30,11 +32,7 @@ export class PasswordHistoryExport {
return;
}
if (o instanceof PasswordHistoryView) {
this.password = o.password;
} else {
this.password = o.password?.encryptedString;
}
this.password = safeGetString(o.password);
this.lastUsedDate = o.lastUsedDate;
}
}

View File

@ -0,0 +1,12 @@
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
export function safeGetString(value: string | EncString) {
if (value == null) {
return null;
}
if (typeof value == "string") {
return value;
}
return value?.encryptedString;
}

View File

@ -49,7 +49,7 @@ import { AddKeyTypeToOrgKeysMigrator } from "./migrations/5-add-key-type-to-org-
import { KeyConnectorMigrator } from "./migrations/50-move-key-connector-to-state-provider";
import { RememberedEmailMigrator } from "./migrations/51-move-remembered-email-to-state-providers";
import { DeleteInstalledVersion } from "./migrations/52-delete-installed-version";
import { DeviceTrustCryptoServiceStateProviderMigrator } from "./migrations/53-migrate-device-trust-crypto-svc-to-state-providers";
import { DeviceTrustServiceStateProviderMigrator } from "./migrations/53-migrate-device-trust-svc-to-state-providers";
import { SendMigrator } from "./migrations/54-move-encrypted-sends";
import { MoveMasterKeyStateToProviderMigrator } from "./migrations/55-move-master-key-state-to-provider";
import { AuthRequestMigrator } from "./migrations/56-move-auth-requests";
@ -117,7 +117,7 @@ export function createMigrationBuilder() {
.with(KeyConnectorMigrator, 49, 50)
.with(RememberedEmailMigrator, 50, 51)
.with(DeleteInstalledVersion, 51, 52)
.with(DeviceTrustCryptoServiceStateProviderMigrator, 52, 53)
.with(DeviceTrustServiceStateProviderMigrator, 52, 53)
.with(SendMigrator, 53, 54)
.with(MoveMasterKeyStateToProviderMigrator, 54, 55)
.with(AuthRequestMigrator, 55, 56)

View File

@ -5,9 +5,9 @@ import { mockMigrationHelper } from "../migration-helper.spec";
import {
DEVICE_KEY,
DeviceTrustCryptoServiceStateProviderMigrator,
DeviceTrustServiceStateProviderMigrator,
SHOULD_TRUST_DEVICE,
} from "./53-migrate-device-trust-crypto-svc-to-state-providers";
} from "./53-migrate-device-trust-svc-to-state-providers";
// Represents data in state service pre-migration
function preMigrationJson() {
@ -79,14 +79,14 @@ function rollbackJSON() {
};
}
describe("DeviceTrustCryptoServiceStateProviderMigrator", () => {
describe("DeviceTrustServiceStateProviderMigrator", () => {
let helper: MockProxy<MigrationHelper>;
let sut: DeviceTrustCryptoServiceStateProviderMigrator;
let sut: DeviceTrustServiceStateProviderMigrator;
describe("migrate", () => {
beforeEach(() => {
helper = mockMigrationHelper(preMigrationJson(), 52);
sut = new DeviceTrustCryptoServiceStateProviderMigrator(52, 53);
sut = new DeviceTrustServiceStateProviderMigrator(52, 53);
});
// it should remove deviceKey and trustDeviceChoiceForDecryption from all accounts
@ -126,7 +126,7 @@ describe("DeviceTrustCryptoServiceStateProviderMigrator", () => {
describe("rollback", () => {
beforeEach(() => {
helper = mockMigrationHelper(rollbackJSON(), 53);
sut = new DeviceTrustCryptoServiceStateProviderMigrator(52, 53);
sut = new DeviceTrustServiceStateProviderMigrator(52, 53);
});
it("should null out newly migrated entries in state provider framework", async () => {

View File

@ -16,7 +16,7 @@ type ExpectedAccountType = {
};
export const DEVICE_KEY: KeyDefinitionLike = {
key: "deviceKey", // matches KeyDefinition.key in DeviceTrustCryptoService
key: "deviceKey", // matches KeyDefinition.key in DeviceTrustService
stateDefinition: {
name: "deviceTrust", // matches StateDefinition.name in StateDefinitions
},
@ -29,7 +29,7 @@ export const SHOULD_TRUST_DEVICE: KeyDefinitionLike = {
},
};
export class DeviceTrustCryptoServiceStateProviderMigrator extends Migrator<52, 53> {
export class DeviceTrustServiceStateProviderMigrator extends Migrator<52, 53> {
async migrate(helper: MigrationHelper): Promise<void> {
const accounts = await helper.getAccounts<ExpectedAccountType>();
async function migrateAccount(userId: string, account: ExpectedAccountType): Promise<void> {

View File

@ -4,7 +4,7 @@ import { IRREVERSIBLE, Migrator } from "../migrator";
type ExpectedAccountType = NonNullable<unknown>;
export const REFRESH_TOKEN_MIGRATED_TO_SECURE_STORAGE: KeyDefinitionLike = {
key: "refreshTokenMigratedToSecureStorage", // matches KeyDefinition.key in DeviceTrustCryptoService
key: "refreshTokenMigratedToSecureStorage", // matches KeyDefinition.key
stateDefinition: {
name: "token", // matches StateDefinition.name in StateDefinitions
},

View File

@ -0,0 +1,15 @@
import { CommonModule } from "@angular/common";
import { ChangeDetectionStrategy, Component } from "@angular/core";
@Component({
selector: "bit-card",
standalone: true,
imports: [CommonModule],
template: `<ng-content></ng-content>`,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class:
"tw-box-border tw-block tw-bg-background tw-text-main tw-border-solid tw-border-b tw-border-0 tw-border-b-secondary-300 tw-rounded-lg tw-py-4 tw-px-3",
},
})
export class CardComponent {}

View File

@ -0,0 +1,62 @@
import { Meta, StoryObj, componentWrapperDecorator, moduleMetadata } from "@storybook/angular";
import { SectionComponent } from "../section";
import { TypographyModule } from "../typography";
import { CardComponent } from "./card.component";
export default {
title: "Component Library/Card",
component: CardComponent,
decorators: [
moduleMetadata({
imports: [TypographyModule, SectionComponent],
}),
componentWrapperDecorator(
(story) => `<div class="tw-bg-background-alt tw-p-10 tw-text-main">${story}</div>`,
),
],
} as Meta;
type Story = StoryObj<CardComponent>;
/** Cards are presentational containers. */
export const Default: Story = {
render: (args) => ({
props: args,
template: /*html*/ `
<bit-card>
<p bitTypography="body1" class="!tw-mb-0">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex. </p>
</bit-card>
`,
}),
};
/** Cards are often paired with [Sections](/docs/component-library-section--docs). */
export const WithinSections: Story = {
render: (args) => ({
props: args,
template: /*html*/ `
<bit-section>
<h2 bitTypography="h5">Bar</h2>
<bit-card>
<p bitTypography="body1" class="!tw-mb-0">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex. </p>
</bit-card>
</bit-section>
<bit-section>
<h2 bitTypography="h5">Bar</h2>
<bit-card>
<p bitTypography="body1" class="!tw-mb-0">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex. </p>
</bit-card>
</bit-section>
<bit-section>
<h2 bitTypography="h5">Bar</h2>
<bit-card>
<p bitTypography="body1" class="!tw-mb-0">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex. </p>
</bit-card>
</bit-section>
`,
}),
};

View File

@ -0,0 +1 @@
export * from "./card.component";

View File

@ -7,6 +7,7 @@ export * from "./breadcrumbs";
export * from "./button";
export { ButtonType } from "./shared/button-like.abstraction";
export * from "./callout";
export * from "./card";
export * from "./checkbox";
export * from "./color-password";
export * from "./container";

View File

@ -6,7 +6,7 @@ import { Component } from "@angular/core";
standalone: true,
imports: [CommonModule],
template: `
<section class="tw-mb-12">
<section class="tw-mb-6 md:tw-mb-12">
<ng-content></ng-content>
</section>
`,

View File

@ -17,7 +17,7 @@ export default {
type Story = StoryObj<SectionComponent>;
/** Sections are simple containers that apply a bottom margin. They often contain a heading. */
/** Sections are simple containers that apply a responsive bottom margin. They often contain a heading. */
export const Default: Story = {
render: (args) => ({
props: args,