mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 01:03:35 +00:00
* Use typescript-strict-plugin to iteratively turn on strict * Add strict testing to pipeline Can be executed locally through either `npm run test:types` for full type checking including spec files, or `npx tsc-strict` for only tsconfig.json included files. * turn on strict for scripts directory * Use plugin for all tsconfigs in monorepo vscode is capable of executing tsc with plugins, but uses the most relevant tsconfig to do so. If the plugin is not a part of that config, it is skipped and developers get no feedback of strict compile time issues. These updates remedy that at the cost of slightly more complex removal of the plugin when the time comes. * remove plugin from configs that extend one that already has it * Update workspace settings to honor strict plugin * Apply strict-plugin to native message test runner * Update vscode workspace to use root tsc version * `./node_modules/.bin/update-strict-comments` 🤖 This is a one-time operation. All future files should adhere to strict type checking. * Add fixme to `ts-strict-ignore` comments * `update-strict-comments` 🤖 repeated for new merge files
112 lines
4.3 KiB
TypeScript
112 lines
4.3 KiB
TypeScript
// FIXME: Update this file to be type safe and remove this and next line
|
|
// @ts-strict-ignore
|
|
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 { Classifier } from "./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: 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
|
|
// 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: Classifier<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: Classifier<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: Classifier<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>,
|
|
);
|
|
}
|
|
}
|