1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-13 15:03:26 +00:00

Merge branch 'main' into ps/extension-refresh

This commit is contained in:
Victoria League
2024-09-30 16:48:32 -04:00
committed by GitHub
80 changed files with 1120 additions and 485 deletions

View File

@@ -29,14 +29,13 @@ 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 { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service";
import { KeySuffixOptions } from "@bitwarden/common/platform/enums";
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
import { UserId } from "@bitwarden/common/types/guid";
import { UserKey } from "@bitwarden/common/types/key";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { DialogService, ToastService } from "@bitwarden/components";
import { BiometricStateService, BiometricsService } from "@bitwarden/key-management";
@Directive()
export class LockComponent implements OnInit, OnDestroy {

View File

@@ -151,10 +151,6 @@ import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwar
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
import { ValidationService as ValidationServiceAbstraction } from "@bitwarden/common/platform/abstractions/validation.service";
import {
BiometricStateService,
DefaultBiometricStateService,
} from "@bitwarden/common/platform/biometrics/biometric-state.service";
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging";
// eslint-disable-next-line no-restricted-imports -- Used for dependency injection
@@ -263,6 +259,7 @@ import {
ImportService,
ImportServiceAbstraction,
} from "@bitwarden/importer/core";
import { BiometricStateService, DefaultBiometricStateService } from "@bitwarden/key-management";
import { PasswordRepromptService } from "@bitwarden/vault";
import {
VaultExportService,

View File

@@ -308,9 +308,7 @@ export class AddEditComponent implements OnInit, OnDestroy {
this.folders$ = this.folderService.folderViews$;
if (this.editMode && this.previousCipherId !== this.cipherId) {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.eventCollectionService.collect(EventType.Cipher_ClientViewed, this.cipherId);
void this.eventCollectionService.collectMany(EventType.Cipher_ClientViewed, [this.cipher]);
}
this.previousCipherId = this.cipherId;
this.reprompt = this.cipher.reprompt !== CipherRepromptType.None;
@@ -551,12 +549,9 @@ export class AddEditComponent implements OnInit, OnDestroy {
if (this.editMode && this.showPassword) {
document.getElementById("loginPassword")?.focus();
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.eventCollectionService.collect(
EventType.Cipher_ClientToggledPasswordVisible,
this.cipherId,
);
void this.eventCollectionService.collectMany(EventType.Cipher_ClientToggledPasswordVisible, [
this.cipher,
]);
}
}
@@ -566,23 +561,18 @@ export class AddEditComponent implements OnInit, OnDestroy {
if (this.editMode && this.showTotpSeed) {
document.getElementById("loginTotp")?.focus();
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.eventCollectionService.collect(
EventType.Cipher_ClientToggledTOTPSeedVisible,
this.cipherId,
);
void this.eventCollectionService.collectMany(EventType.Cipher_ClientToggledTOTPSeedVisible, [
this.cipher,
]);
}
}
async toggleCardNumber() {
this.showCardNumber = !this.showCardNumber;
if (this.showCardNumber) {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.eventCollectionService.collect(
void this.eventCollectionService.collectMany(
EventType.Cipher_ClientToggledCardNumberVisible,
this.cipherId,
[this.cipher],
);
}
}
@@ -591,12 +581,9 @@ export class AddEditComponent implements OnInit, OnDestroy {
this.showCardCode = !this.showCardCode;
document.getElementById("cardCode").focus();
if (this.editMode && this.showCardCode) {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.eventCollectionService.collect(
EventType.Cipher_ClientToggledCardCodeVisible,
this.cipherId,
);
void this.eventCollectionService.collectMany(EventType.Cipher_ClientToggledCardCodeVisible, [
this.cipher,
]);
}
}
@@ -742,17 +729,17 @@ export class AddEditComponent implements OnInit, OnDestroy {
);
if (typeI18nKey === "password") {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.eventCollectionService.collect(EventType.Cipher_ClientCopiedPassword, this.cipherId);
void this.eventCollectionService.collectMany(EventType.Cipher_ClientCopiedPassword, [
this.cipher,
]);
} else if (typeI18nKey === "securityCode") {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.eventCollectionService.collect(EventType.Cipher_ClientCopiedCardCode, this.cipherId);
void this.eventCollectionService.collectMany(EventType.Cipher_ClientCopiedCardCode, [
this.cipher,
]);
} else if (aType === "H_Field") {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.eventCollectionService.collect(EventType.Cipher_ClientCopiedHiddenField, this.cipherId);
void this.eventCollectionService.collectMany(EventType.Cipher_ClientCopiedHiddenField, [
this.cipher,
]);
}
return true;

View File

@@ -82,10 +82,10 @@ export function isCardExpired(cipherCard: CardView): boolean {
const parsedYear = parseInt(normalizedYear, 10);
// First day of the next month minus one, to get last day of the card month
const cardExpiry = new Date(parsedYear, parsedMonth + 1, 0);
// First day of the next month
const cardExpiry = new Date(parsedYear, parsedMonth + 1, 1);
return cardExpiry < now;
return cardExpiry <= now;
}
}

View File

@@ -1,5 +1,7 @@
import { firstValueFrom, map, Subscription, timeout } from "rxjs";
import { BiometricStateService } from "@bitwarden/key-management";
import { PinServiceAbstraction } from "../../../../auth/src/common/abstractions";
import { VaultTimeoutSettingsService } from "../../abstractions/vault-timeout/vault-timeout-settings.service";
import { AccountService } from "../../auth/abstractions/account.service";
@@ -11,7 +13,6 @@ import { UserId } from "../../types/guid";
import { MessagingService } from "../abstractions/messaging.service";
import { PlatformUtilsService } from "../abstractions/platform-utils.service";
import { SystemService as SystemServiceAbstraction } from "../abstractions/system.service";
import { BiometricStateService } from "../biometrics/biometric-state.service";
import { Utils } from "../misc/utils";
import { ScheduledTaskNames } from "../scheduling/scheduled-task-name.enum";
import { TaskSchedulerService } from "../scheduling/task-scheduler.service";

View File

@@ -8,6 +8,7 @@ import {
} from "@bitwarden/auth/common";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { UserId } from "@bitwarden/common/types/guid";
import { BiometricStateService } from "@bitwarden/key-management";
import { FakeAccountService, mockAccountServiceWith, FakeStateProvider } from "../../../spec";
import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "../../abstractions/vault-timeout/vault-timeout-settings.service";
@@ -17,7 +18,6 @@ import { TokenService } from "../../auth/abstractions/token.service";
import { VaultTimeoutAction } from "../../enums/vault-timeout-action.enum";
import { CryptoService } from "../../platform/abstractions/crypto.service";
import { LogService } from "../../platform/abstractions/log.service";
import { BiometricStateService } from "../../platform/biometrics/biometric-state.service";
import {
VAULT_TIMEOUT,
VAULT_TIMEOUT_ACTION,

View File

@@ -17,6 +17,7 @@ import {
PinServiceAbstraction,
UserDecryptionOptionsServiceAbstraction,
} from "@bitwarden/auth/common";
import { BiometricStateService } from "@bitwarden/key-management";
import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "../../abstractions/vault-timeout/vault-timeout-settings.service";
import { PolicyService } from "../../admin-console/abstractions/policy/policy.service.abstraction";
@@ -27,7 +28,6 @@ import { TokenService } from "../../auth/abstractions/token.service";
import { VaultTimeoutAction } from "../../enums/vault-timeout-action.enum";
import { CryptoService } from "../../platform/abstractions/crypto.service";
import { LogService } from "../../platform/abstractions/log.service";
import { BiometricStateService } from "../../platform/biometrics/biometric-state.service";
import { StateProvider } from "../../platform/state";
import { UserId } from "../../types/guid";
import { VaultTimeout, VaultTimeoutStringType } from "../../types/vault-timeout.type";

View File

@@ -0,0 +1,3 @@
# Key management
This lib represents the public API of the Key management team at Bitwarden. Modules are imported using `@bitwarden/key-management`.

View File

@@ -0,0 +1,20 @@
const { pathsToModuleNameMapper } = require("ts-jest");
const { compilerOptions } = require("../shared/tsconfig.libs");
const sharedConfig = require("../../libs/shared/jest.config.angular");
/** @type {import('jest').Config} */
module.exports = {
...sharedConfig,
displayName: "libs/key management tests",
preset: "jest-preset-angular",
setupFilesAfterEnv: ["<rootDir>/test.setup.ts"],
moduleNameMapper: pathsToModuleNameMapper(
// lets us use @bitwarden/common/spec in tests
{ "@bitwarden/common/spec": ["../common/spec"], ...(compilerOptions?.paths ?? {}) },
{
prefix: "<rootDir>/",
},
),
};

View File

@@ -0,0 +1,25 @@
{
"name": "@bitwarden/key-management",
"version": "0.0.0",
"description": "Common code used across Bitwarden JavaScript projects.",
"keywords": [
"bitwarden"
],
"author": "Bitwarden Inc.",
"homepage": "https://bitwarden.com",
"repository": {
"type": "git",
"url": "https://github.com/bitwarden/clients"
},
"license": "GPL-3.0",
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && tsc",
"build:watch": "npm run clean && tsc -watch"
},
"dependencies": {
"@bitwarden/angular": "file:../angular",
"@bitwarden/common": "file:../common",
"@bitwarden/components": "file:../components"
}
}

View File

@@ -1,11 +1,15 @@
import { firstValueFrom } from "rxjs";
import { makeEncString, trackEmissions } from "../../../spec";
import { FakeAccountService, mockAccountServiceWith } from "../../../spec/fake-account-service";
import { FakeGlobalState, FakeSingleUserState } from "../../../spec/fake-state";
import { FakeStateProvider } from "../../../spec/fake-state-provider";
import { UserId } from "../../types/guid";
import { EncryptedString } from "../models/domain/enc-string";
import { EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string";
import { UserId } from "@bitwarden/common/types/guid";
import { makeEncString, trackEmissions } from "../../../common/spec";
import {
FakeAccountService,
mockAccountServiceWith,
} from "../../../common/spec/fake-account-service";
import { FakeGlobalState, FakeSingleUserState } from "../../../common/spec/fake-state";
import { FakeStateProvider } from "../../../common/spec/fake-state-provider";
import { BiometricStateService, DefaultBiometricStateService } from "./biometric-state.service";
import {

View File

@@ -1,8 +1,8 @@
import { Observable, firstValueFrom, map, combineLatest } from "rxjs";
import { UserId } from "../../types/guid";
import { EncryptedString, EncString } from "../models/domain/enc-string";
import { ActiveUserState, GlobalState, StateProvider } from "../state";
import { EncryptedString, EncString } from "../../../common/src/platform/models/domain/enc-string";
import { ActiveUserState, GlobalState, StateProvider } from "../../../common/src/platform/state";
import { UserId } from "../../../common/src/types/guid";
import {
BIOMETRIC_UNLOCK_ENABLED,

View File

@@ -1,5 +1,5 @@
import { EncryptedString } from "../models/domain/enc-string";
import { KeyDefinition, UserKeyDefinition } from "../state";
import { EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string";
import { KeyDefinition, UserKeyDefinition } from "@bitwarden/common/platform/state";
import {
BIOMETRIC_UNLOCK_ENABLED,

View File

@@ -1,6 +1,10 @@
import { UserId } from "../../types/guid";
import { EncryptedString } from "../models/domain/enc-string";
import { KeyDefinition, BIOMETRIC_SETTINGS_DISK, UserKeyDefinition } from "../state";
import { EncryptedString } from "../../../common/src/platform/models/domain/enc-string";
import {
KeyDefinition,
BIOMETRIC_SETTINGS_DISK,
UserKeyDefinition,
} from "../../../common/src/platform/state";
import { UserId } from "../../../common/src/types/guid";
/**
* Indicates whether the user elected to store a biometric key to unlock their vault.
@@ -9,7 +13,7 @@ export const BIOMETRIC_UNLOCK_ENABLED = new UserKeyDefinition<boolean>(
BIOMETRIC_SETTINGS_DISK,
"biometricUnlockEnabled",
{
deserializer: (obj) => obj,
deserializer: (obj: any) => obj,
clearOn: [],
},
);
@@ -23,7 +27,7 @@ export const REQUIRE_PASSWORD_ON_START = new UserKeyDefinition<boolean>(
BIOMETRIC_SETTINGS_DISK,
"requirePasswordOnStart",
{
deserializer: (value) => value,
deserializer: (value: any) => value,
clearOn: [],
},
);

View File

@@ -0,0 +1,6 @@
export {
BiometricStateService,
DefaultBiometricStateService,
} from "./biometrics/biometric-state.service";
export { BiometricsService } from "./biometrics/biometric.service";
export * from "./biometrics/biometric.state";

View File

@@ -0,0 +1,28 @@
import { webcrypto } from "crypto";
import "jest-preset-angular/setup-jest";
Object.defineProperty(window, "CSS", { value: null });
Object.defineProperty(window, "getComputedStyle", {
value: () => {
return {
display: "none",
appearance: ["-webkit-appearance"],
};
},
});
Object.defineProperty(document, "doctype", {
value: "<!DOCTYPE html>",
});
Object.defineProperty(document.body.style, "transform", {
value: () => {
return {
enumerable: true,
configurable: true,
};
},
});
Object.defineProperty(window, "crypto", {
value: webcrypto,
});

View File

@@ -0,0 +1,5 @@
{
"extends": "../shared/tsconfig.libs",
"include": ["src", "spec"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"files": ["./test.setup.ts"]
}

View File

@@ -19,6 +19,7 @@
"@bitwarden/vault-export-ui": ["../tools/export/vault-export/vault-export-ui/src"],
"@bitwarden/importer/core": ["../importer/src"],
"@bitwarden/importer/ui": ["../importer/src/components"],
"@bitwarden/key-management": ["../key-management/src"],
"@bitwarden/platform": ["../platform/src"],
"@bitwarden/send-ui": ["../tools/send/send-ui/src"],
"@bitwarden/node/*": ["../node/src/*"],

View File

@@ -1,6 +1,6 @@
<h2 class="tw-sr-only" id="attachments">{{ "attachments" | i18n }}</h2>
<ul *ngIf="cipher?.attachments" aria-labelledby="attachments" class="tw-list-none">
<ul *ngIf="cipher?.attachments" aria-labelledby="attachments" class="tw-list-none tw-pl-0">
<li *ngFor="let attachment of cipher.attachments">
<bit-item>
<bit-item-content>