1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-19 09:43:23 +00:00

[PM-9613] port forwarders to integrations (#10075)

* introduced forwarder integrations
* simply contexts
* report error and message when both are present in an RPC response
This commit is contained in:
✨ Audrey ✨
2024-07-30 08:40:52 -04:00
committed by GitHub
parent 8f437dc773
commit 8c78959aaf
70 changed files with 2392 additions and 2415 deletions

View File

@@ -0,0 +1,37 @@
import { Jsonify } from "type-fest";
/** Classifies an object's JSON-serializable data by property into
* 3 categories:
* * Disclosed data MAY be stored in plaintext.
* * Excluded data MUST NOT be saved.
* * The remaining data is secret and MUST be stored using encryption.
*
* This type should not be used to classify functions.
* Data that cannot be serialized by JSON.stringify() should
* be excluded.
*/
export interface Classifier<Plaintext, Disclosed, Secret> {
/** Partitions `secret` into its disclosed properties and secret properties.
* @param value The object to partition
* @returns an object that classifies secrets.
* The `disclosed` member is new and contains disclosed properties.
* The `secret` member is a copy of the secret parameter, including its
* prototype, with all disclosed and excluded properties deleted.
*/
classify(value: Plaintext): { disclosed: Jsonify<Disclosed>; secret: Jsonify<Secret> };
/** Merges the properties of `secret` and `disclosed`. When `secret` and
* `disclosed` contain the same property, the `secret` property overrides
* the `disclosed` property.
* @param disclosed an object whose disclosed properties are merged into
* the output. Unknown properties are ignored.
* @param secret an objects whose properties are merged into the output.
* Excluded properties are ignored. Unknown properties are retained.
* @returns a new object containing the merged data.
*
* @remarks Declassified data is always jsonified--the purpose of classifying it is
* to Jsonify it,
* which causes type conversions.
*/
declassify(disclosed: Jsonify<Disclosed>, secret: Jsonify<Secret>): Jsonify<Plaintext>;
}

View File

@@ -1,5 +1,7 @@
import { Jsonify } from "type-fest";
import { Classifier } from "./classifier";
/** Classifies an object's JSON-serializable data by property into
* 3 categories:
* * Disclosed data MAY be stored in plaintext.
@@ -10,7 +12,9 @@ import { Jsonify } from "type-fest";
* Data that cannot be serialized by JSON.stringify() should
* be excluded.
*/
export class SecretClassifier<Plaintext extends object, Disclosed, Secret> {
export class SecretClassifier<Plaintext extends object, Disclosed, Secret>
implements Classifier<Plaintext, Disclosed, Secret>
{
private constructor(
disclosed: readonly (keyof Jsonify<Disclosed> & keyof Jsonify<Plaintext>)[],
excluded: readonly (keyof Plaintext)[],

View File

@@ -1,15 +1,19 @@
import { mock } from "jest-mock-extended";
import { Jsonify } from "type-fest";
import { GENERATOR_DISK, UserKeyDefinitionOptions } from "../../platform/state";
import { SecretClassifier } from "./secret-classifier";
import { Classifier } from "./classifier";
import { SecretKeyDefinition } from "./secret-key-definition";
describe("SecretKeyDefinition", () => {
const classifier = SecretClassifier.allSecret<{ foo: boolean }>();
type TestData = { foo: boolean };
const classifier = mock<Classifier<any, Record<string, never>, TestData>>();
const options: UserKeyDefinitionOptions<any> = { deserializer: (v: any) => v, clearOn: [] };
it("toEncryptedStateKey returns a key", () => {
const expectedOptions: UserKeyDefinitionOptions<any> = {
deserializer: (v: any) => v,
const expectedOptions: UserKeyDefinitionOptions<TestData> = {
deserializer: (v: Jsonify<TestData>) => v,
cleanupDelayMs: 100,
clearOn: ["logout", "lock"],
};

View File

@@ -2,7 +2,7 @@ import { UserKeyDefinitionOptions, UserKeyDefinition } from "../../platform/stat
// eslint-disable-next-line -- `StateDefinition` used as an argument
import { StateDefinition } from "../../platform/state/state-definition";
import { ClassifiedFormat } from "./classified-format";
import { SecretClassifier } from "./secret-classifier";
import { Classifier } from "./classifier";
/** Encryption and storage settings for data stored by a `SecretState`.
*/
@@ -10,7 +10,7 @@ export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Sec
private constructor(
readonly stateDefinition: StateDefinition,
readonly key: string,
readonly classifier: SecretClassifier<Inner, Disclosed, Secret>,
readonly classifier: Classifier<Inner, Disclosed, Secret>,
readonly options: UserKeyDefinitionOptions<Inner>,
// type erasure is necessary here because typescript doesn't support
// higher kinded types that generalize over collections. The invariants
@@ -46,7 +46,7 @@ export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Sec
static value<Value extends object, Disclosed, Secret>(
stateDefinition: StateDefinition,
key: string,
classifier: SecretClassifier<Value, Disclosed, Secret>,
classifier: Classifier<Value, Disclosed, Secret>,
options: UserKeyDefinitionOptions<Value>,
) {
return new SecretKeyDefinition<Value, void, Value, Disclosed, Secret>(
@@ -70,7 +70,7 @@ export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Sec
static array<Item extends object, Disclosed, Secret>(
stateDefinition: StateDefinition,
key: string,
classifier: SecretClassifier<Item, Disclosed, Secret>,
classifier: Classifier<Item, Disclosed, Secret>,
options: UserKeyDefinitionOptions<Item>,
) {
return new SecretKeyDefinition<Item[], number, Item, Disclosed, Secret>(
@@ -94,7 +94,7 @@ export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Sec
static record<Item extends object, Disclosed, Secret, Id extends string | number>(
stateDefinition: StateDefinition,
key: string,
classifier: SecretClassifier<Item, Disclosed, Secret>,
classifier: Classifier<Item, Disclosed, Secret>,
options: UserKeyDefinitionOptions<Item>,
) {
return new SecretKeyDefinition<Record<Id, Item>, Id, Item, Disclosed, Secret>(