mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 01:33:33 +00:00
move state provider extensions to tools folder (#9436)
This commit is contained in:
109
libs/common/src/tools/state/secret-key-definition.ts
Normal file
109
libs/common/src/tools/state/secret-key-definition.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import { UserKeyDefinitionOptions, UserKeyDefinition } from "../../platform/state";
|
||||
// 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";
|
||||
|
||||
/** Encryption and storage settings for data stored by a `SecretState`.
|
||||
*/
|
||||
export class SecretKeyDefinition<Outer, Id, Inner extends object, Disclosed, Secret> {
|
||||
private constructor(
|
||||
readonly stateDefinition: StateDefinition,
|
||||
readonly key: string,
|
||||
readonly classifier: SecretClassifier<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
|
||||
// needed to make this typesafe are maintained by the static factories.
|
||||
readonly deconstruct: (value: any) => [Id, any][],
|
||||
readonly reconstruct: ([inners, ids]: (readonly [Id, any])[]) => Outer,
|
||||
) {}
|
||||
|
||||
/** Converts the secret key to the `KeyDefinition` used for secret storage. */
|
||||
toEncryptedStateKey() {
|
||||
const secretKey = new UserKeyDefinition<ClassifiedFormat<Id, Disclosed>[]>(
|
||||
this.stateDefinition,
|
||||
this.key,
|
||||
{
|
||||
cleanupDelayMs: this.options.cleanupDelayMs,
|
||||
deserializer: (jsonValue) => jsonValue as ClassifiedFormat<Id, Disclosed>[],
|
||||
// Clear encrypted state on logout
|
||||
clearOn: this.options.clearOn,
|
||||
},
|
||||
);
|
||||
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a secret state for a single value
|
||||
* @param stateDefinition The domain of the secret's durable state.
|
||||
* @param key Domain key that identifies the stored value. This key must not be reused
|
||||
* in any capacity.
|
||||
* @param classifier Partitions the value into encrypted, discarded, and public data.
|
||||
* @param options Configures the operation of the secret state.
|
||||
*/
|
||||
static value<Value extends object, Disclosed, Secret>(
|
||||
stateDefinition: StateDefinition,
|
||||
key: string,
|
||||
classifier: SecretClassifier<Value, Disclosed, Secret>,
|
||||
options: UserKeyDefinitionOptions<Value>,
|
||||
) {
|
||||
return new SecretKeyDefinition<Value, void, Value, Disclosed, Secret>(
|
||||
stateDefinition,
|
||||
key,
|
||||
classifier,
|
||||
options,
|
||||
(value) => [[null, value]],
|
||||
([[, inner]]) => inner,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a secret state for an array of values. Each item is encrypted separately.
|
||||
* @param stateDefinition The domain of the secret's durable state.
|
||||
* @param key Domain key that identifies the stored items. This key must not be reused
|
||||
* in any capacity.
|
||||
* @param classifier Partitions each item into encrypted, discarded, and public data.
|
||||
* @param options Configures the operation of the secret state.
|
||||
*/
|
||||
static array<Item extends object, Disclosed, Secret>(
|
||||
stateDefinition: StateDefinition,
|
||||
key: string,
|
||||
classifier: SecretClassifier<Item, Disclosed, Secret>,
|
||||
options: UserKeyDefinitionOptions<Item>,
|
||||
) {
|
||||
return new SecretKeyDefinition<Item[], number, Item, Disclosed, Secret>(
|
||||
stateDefinition,
|
||||
key,
|
||||
classifier,
|
||||
options,
|
||||
(value) => value.map((v: any, id: number) => [id, v]),
|
||||
(values) => values.map(([, v]) => v),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a secret state for a record. Each property is encrypted separately.
|
||||
* @param stateDefinition The domain of the secret's durable state.
|
||||
* @param key Domain key that identifies the stored properties. This key must not be reused
|
||||
* in any capacity.
|
||||
* @param classifier Partitions each property into encrypted, discarded, and public data.
|
||||
* @param options Configures the operation of the secret state.
|
||||
*/
|
||||
static record<Item extends object, Disclosed, Secret, Id extends string | number>(
|
||||
stateDefinition: StateDefinition,
|
||||
key: string,
|
||||
classifier: SecretClassifier<Item, Disclosed, Secret>,
|
||||
options: UserKeyDefinitionOptions<Item>,
|
||||
) {
|
||||
return new SecretKeyDefinition<Record<Id, Item>, Id, Item, Disclosed, Secret>(
|
||||
stateDefinition,
|
||||
key,
|
||||
classifier,
|
||||
options,
|
||||
(value) => Object.entries(value) as [Id, Item][],
|
||||
(values) => Object.fromEntries(values) as Record<Id, Item>,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user