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:
37
libs/common/src/tools/state/classifier.ts
Normal file
37
libs/common/src/tools/state/classifier.ts
Normal 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>;
|
||||
}
|
||||
@@ -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)[],
|
||||
|
||||
@@ -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"],
|
||||
};
|
||||
|
||||
@@ -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>(
|
||||
|
||||
Reference in New Issue
Block a user