1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-21 16:18:28 +01:00

[STRICT TS] Migrate platform abstract services functions (#8527)

We currently use a callback syntax for abstract services. This syntax isn't completely strict compliant and will fail the strictPropertyInitialization check. We also currently don't get any compile time errors if we forget to implement a function.

To that end this PR updates all platform owned services to use the appropriate abstract keyword for non implemented functions. I also updated the fields to be actual functions and not properties.
This commit is contained in:
Oscar Hinton 2024-03-28 12:01:09 +01:00 committed by GitHub
parent d10c14791d
commit 2edc156dd6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 232 additions and 212 deletions

View File

@ -1,6 +1,6 @@
export abstract class BiometricsServiceAbstraction {
osSupportsBiometric: () => Promise<boolean>;
canAuthBiometric: ({
abstract osSupportsBiometric(): Promise<boolean>;
abstract canAuthBiometric({
service,
key,
userId,
@ -8,11 +8,11 @@ export abstract class BiometricsServiceAbstraction {
service: string;
key: string;
userId: string;
}) => Promise<boolean>;
authenticateBiometric: () => Promise<boolean>;
getBiometricKey: (service: string, key: string) => Promise<string | null>;
setBiometricKey: (service: string, key: string, value: string) => Promise<void>;
setEncryptionKeyHalf: ({
}): Promise<boolean>;
abstract authenticateBiometric(): Promise<boolean>;
abstract getBiometricKey(service: string, key: string): Promise<string | null>;
abstract setBiometricKey(service: string, key: string, value: string): Promise<void>;
abstract setEncryptionKeyHalf({
service,
key,
value,
@ -20,23 +20,23 @@ export abstract class BiometricsServiceAbstraction {
service: string;
key: string;
value: string;
}) => void;
deleteBiometricKey: (service: string, key: string) => Promise<void>;
}): void;
abstract deleteBiometricKey(service: string, key: string): Promise<void>;
}
export interface OsBiometricService {
osSupportsBiometric: () => Promise<boolean>;
authenticateBiometric: () => Promise<boolean>;
getBiometricKey: (
osSupportsBiometric(): Promise<boolean>;
authenticateBiometric(): Promise<boolean>;
getBiometricKey(
service: string,
key: string,
clientKeyHalfB64: string | undefined,
) => Promise<string | null>;
setBiometricKey: (
): Promise<string | null>;
setBiometricKey(
service: string,
key: string,
value: string,
clientKeyHalfB64: string | undefined,
) => Promise<void>;
deleteBiometricKey: (service: string, key: string) => Promise<void>;
): Promise<void>;
deleteBiometricKey(service: string, key: string): Promise<void>;
}

View File

@ -9,5 +9,5 @@ export interface FormGroupControls {
}
export abstract class FormValidationErrorsService {
getFormValidationErrors: (controls: FormGroupControls) => AllValidationErrors[];
abstract getFormValidationErrors(controls: FormGroupControls): AllValidationErrors[];
}

View File

@ -11,12 +11,12 @@ export abstract class AbstractThemingService {
* The effective theme based on the user configured choice and the current system theme if
* the configured choice is {@link ThemeType.System}.
*/
theme$: Observable<ThemeType>;
abstract theme$: Observable<ThemeType>;
/**
* Listens for effective theme changes and applies changes to the provided document.
* @param document The document that should have theme classes applied to it.
*
* @returns A subscription that can be unsubscribed from to cancel the application of theme classes.
*/
applyThemeChangesTo: (document: Document) => Subscription;
abstract applyThemeChangesTo(document: Document): Subscription;
}

View File

@ -1,8 +1,8 @@
import { Observable } from "rxjs";
export abstract class AppIdService {
appId$: Observable<string>;
anonymousAppId$: Observable<string>;
getAppId: () => Promise<string>;
getAnonymousAppId: () => Promise<string>;
abstract appId$: Observable<string>;
abstract anonymousAppId$: Observable<string>;
abstract getAppId(): Promise<string>;
abstract getAnonymousAppId(): Promise<string>;
}

View File

@ -9,13 +9,13 @@ export abstract class BroadcasterService {
/**
* @deprecated Use the observable from the appropriate service instead.
*/
send: (message: MessageBase, id?: string) => void;
abstract send(message: MessageBase, id?: string): void;
/**
* @deprecated Use the observable from the appropriate service instead.
*/
subscribe: (id: string, messageCallback: (message: MessageBase) => void) => void;
abstract subscribe(id: string, messageCallback: (message: MessageBase) => void): void;
/**
* @deprecated Use the observable from the appropriate service instead.
*/
unsubscribe: (id: string) => void;
abstract unsubscribe(id: string): void;
}

View File

@ -5,5 +5,5 @@ export abstract class ConfigApiServiceAbstraction {
/**
* Fetches the server configuration for the given user. If no user is provided, the configuration will not contain user-specific context.
*/
get: (userId: UserId | undefined) => Promise<ServerConfigResponse>;
abstract get(userId: UserId | undefined): Promise<ServerConfigResponse>;
}

View File

@ -3,85 +3,85 @@ import { DecryptParameters } from "../models/domain/decrypt-parameters";
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
export abstract class CryptoFunctionService {
pbkdf2: (
abstract pbkdf2(
password: string | Uint8Array,
salt: string | Uint8Array,
algorithm: "sha256" | "sha512",
iterations: number,
) => Promise<Uint8Array>;
argon2: (
): Promise<Uint8Array>;
abstract argon2(
password: string | Uint8Array,
salt: string | Uint8Array,
iterations: number,
memory: number,
parallelism: number,
) => Promise<Uint8Array>;
hkdf: (
): Promise<Uint8Array>;
abstract hkdf(
ikm: Uint8Array,
salt: string | Uint8Array,
info: string | Uint8Array,
outputByteSize: number,
algorithm: "sha256" | "sha512",
) => Promise<Uint8Array>;
hkdfExpand: (
): Promise<Uint8Array>;
abstract hkdfExpand(
prk: Uint8Array,
info: string | Uint8Array,
outputByteSize: number,
algorithm: "sha256" | "sha512",
) => Promise<Uint8Array>;
hash: (
): Promise<Uint8Array>;
abstract hash(
value: string | Uint8Array,
algorithm: "sha1" | "sha256" | "sha512" | "md5",
) => Promise<Uint8Array>;
hmac: (
): Promise<Uint8Array>;
abstract hmac(
value: Uint8Array,
key: Uint8Array,
algorithm: "sha1" | "sha256" | "sha512",
) => Promise<Uint8Array>;
compare: (a: Uint8Array, b: Uint8Array) => Promise<boolean>;
hmacFast: (
): Promise<Uint8Array>;
abstract compare(a: Uint8Array, b: Uint8Array): Promise<boolean>;
abstract hmacFast(
value: Uint8Array | string,
key: Uint8Array | string,
algorithm: "sha1" | "sha256" | "sha512",
) => Promise<Uint8Array | string>;
compareFast: (a: Uint8Array | string, b: Uint8Array | string) => Promise<boolean>;
aesEncrypt: (data: Uint8Array, iv: Uint8Array, key: Uint8Array) => Promise<Uint8Array>;
aesDecryptFastParameters: (
): Promise<Uint8Array | string>;
abstract compareFast(a: Uint8Array | string, b: Uint8Array | string): Promise<boolean>;
abstract aesEncrypt(data: Uint8Array, iv: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
abstract aesDecryptFastParameters(
data: string,
iv: string,
mac: string,
key: SymmetricCryptoKey,
) => DecryptParameters<Uint8Array | string>;
aesDecryptFast: (
): DecryptParameters<Uint8Array | string>;
abstract aesDecryptFast(
parameters: DecryptParameters<Uint8Array | string>,
mode: "cbc" | "ecb",
) => Promise<string>;
aesDecrypt: (
): Promise<string>;
abstract aesDecrypt(
data: Uint8Array,
iv: Uint8Array,
key: Uint8Array,
mode: "cbc" | "ecb",
) => Promise<Uint8Array>;
rsaEncrypt: (
): Promise<Uint8Array>;
abstract rsaEncrypt(
data: Uint8Array,
publicKey: Uint8Array,
algorithm: "sha1" | "sha256",
) => Promise<Uint8Array>;
rsaDecrypt: (
): Promise<Uint8Array>;
abstract rsaDecrypt(
data: Uint8Array,
privateKey: Uint8Array,
algorithm: "sha1" | "sha256",
) => Promise<Uint8Array>;
rsaExtractPublicKey: (privateKey: Uint8Array) => Promise<Uint8Array>;
rsaGenerateKeyPair: (length: 1024 | 2048 | 4096) => Promise<[Uint8Array, Uint8Array]>;
): Promise<Uint8Array>;
abstract rsaExtractPublicKey(privateKey: Uint8Array): Promise<Uint8Array>;
abstract rsaGenerateKeyPair(length: 1024 | 2048 | 4096): Promise<[Uint8Array, Uint8Array]>;
/**
* Generates a key of the given length suitable for use in AES encryption
*/
aesGenerateKey: (bitLength: 128 | 192 | 256 | 512) => Promise<CsprngArray>;
abstract aesGenerateKey(bitLength: 128 | 192 | 256 | 512): Promise<CsprngArray>;
/**
* Generates a random array of bytes of the given length. Uses a cryptographically secure random number generator.
*
* Do not use this for generating encryption keys. Use aesGenerateKey or rsaGenerateKeyPair instead.
*/
randomBytes: (length: number) => Promise<CsprngArray>;
abstract randomBytes(length: number): Promise<CsprngArray>;
}

View File

@ -12,7 +12,7 @@ import { EncString } from "../models/domain/enc-string";
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
export abstract class CryptoService {
activeUserKey$: Observable<UserKey>;
abstract activeUserKey$: Observable<UserKey>;
/**
* Sets the provided user key and stores
* any other necessary versions (such as auto, biometrics,
@ -22,105 +22,105 @@ export abstract class CryptoService {
* @param key The user key to set
* @param userId The desired user
*/
setUserKey: (key: UserKey, userId?: string) => Promise<void>;
abstract setUserKey(key: UserKey, userId?: string): Promise<void>;
/**
* Gets the user key from memory and sets it again,
* kicking off a refresh of any additional keys
* (such as auto, biometrics, or pin)
*/
refreshAdditionalKeys: () => Promise<void>;
abstract refreshAdditionalKeys(): Promise<void>;
/**
* Observable value that returns whether or not the currently active user has ever had auser key,
* i.e. has ever been unlocked/decrypted. This is key for differentiating between TDE locked and standard locked states.
*/
everHadUserKey$: Observable<boolean>;
abstract everHadUserKey$: Observable<boolean>;
/**
* Retrieves the user key
* @param userId The desired user
* @returns The user key
*/
getUserKey: (userId?: string) => Promise<UserKey>;
abstract getUserKey(userId?: string): Promise<UserKey>;
/**
* Checks if the user is using an old encryption scheme that used the master key
* for encryption of data instead of the user key.
*/
isLegacyUser: (masterKey?: MasterKey, userId?: string) => Promise<boolean>;
abstract isLegacyUser(masterKey?: MasterKey, userId?: string): Promise<boolean>;
/**
* Use for encryption/decryption of data in order to support legacy
* encryption models. It will return the user key if available,
* if not it will return the master key.
* @param userId The desired user
*/
getUserKeyWithLegacySupport: (userId?: string) => Promise<UserKey>;
abstract getUserKeyWithLegacySupport(userId?: string): Promise<UserKey>;
/**
* Retrieves the user key from storage
* @param keySuffix The desired version of the user's key to retrieve
* @param userId The desired user
* @returns The user key
*/
getUserKeyFromStorage: (keySuffix: KeySuffixOptions, userId?: string) => Promise<UserKey>;
abstract getUserKeyFromStorage(keySuffix: KeySuffixOptions, userId?: string): Promise<UserKey>;
/**
* Determines whether the user key is available for the given user.
* @param userId The desired user. If not provided, the active user will be used. If no active user exists, the method will return false.
* @returns True if the user key is available
*/
hasUserKey: (userId?: UserId) => Promise<boolean>;
abstract hasUserKey(userId?: UserId): Promise<boolean>;
/**
* Determines whether the user key is available for the given user in memory.
* @param userId The desired user. If not provided, the active user will be used. If no active user exists, the method will return false.
* @returns True if the user key is available
*/
hasUserKeyInMemory: (userId?: string) => Promise<boolean>;
abstract hasUserKeyInMemory(userId?: string): Promise<boolean>;
/**
* @param keySuffix The desired version of the user's key to check
* @param userId The desired user
* @returns True if the provided version of the user key is stored
*/
hasUserKeyStored: (keySuffix: KeySuffixOptions, userId?: string) => Promise<boolean>;
abstract hasUserKeyStored(keySuffix: KeySuffixOptions, userId?: string): Promise<boolean>;
/**
* Generates a new user key
* @param masterKey The user's master key
* @returns A new user key and the master key protected version of it
*/
makeUserKey: (key: MasterKey) => Promise<[UserKey, EncString]>;
abstract makeUserKey(key: MasterKey): Promise<[UserKey, EncString]>;
/**
* Clears the user key
* @param clearStoredKeys Clears all stored versions of the user keys as well,
* such as the biometrics key
* @param userId The desired user
*/
clearUserKey: (clearSecretStorage?: boolean, userId?: string) => Promise<void>;
abstract clearUserKey(clearSecretStorage?: boolean, userId?: string): Promise<void>;
/**
* Clears the user's stored version of the user key
* @param keySuffix The desired version of the key to clear
* @param userId The desired user
*/
clearStoredUserKey: (keySuffix: KeySuffixOptions, userId?: string) => Promise<void>;
abstract clearStoredUserKey(keySuffix: KeySuffixOptions, userId?: string): Promise<void>;
/**
* Stores the master key encrypted user key
* @param userKeyMasterKey The master key encrypted user key to set
* @param userId The desired user
*/
setMasterKeyEncryptedUserKey: (UserKeyMasterKey: string, userId?: string) => Promise<void>;
abstract setMasterKeyEncryptedUserKey(UserKeyMasterKey: string, userId?: string): Promise<void>;
/**
* Sets the user's master key
* @param key The user's master key to set
* @param userId The desired user
*/
setMasterKey: (key: MasterKey, userId?: string) => Promise<void>;
abstract setMasterKey(key: MasterKey, userId?: string): Promise<void>;
/**
* @param userId The desired user
* @returns The user's master key
*/
getMasterKey: (userId?: string) => Promise<MasterKey>;
abstract getMasterKey(userId?: string): Promise<MasterKey>;
/**
* @param password The user's master password that will be used to derive a master key if one isn't found
* @param userId The desired user
*/
getOrDeriveMasterKey: (password: string, userId?: string) => Promise<MasterKey>;
abstract getOrDeriveMasterKey(password: string, userId?: string): Promise<MasterKey>;
/**
* Generates a master key from the provided password
* @param password The user's master password
@ -129,17 +129,17 @@ export abstract class CryptoService {
* @param KdfConfig The user's key derivation function configuration
* @returns A master key derived from the provided password
*/
makeMasterKey: (
abstract makeMasterKey(
password: string,
email: string,
kdf: KdfType,
KdfConfig: KdfConfig,
) => Promise<MasterKey>;
): Promise<MasterKey>;
/**
* Clears the user's master key
* @param userId The desired user
*/
clearMasterKey: (userId?: string) => Promise<void>;
abstract clearMasterKey(userId?: string): Promise<void>;
/**
* Encrypts the existing (or provided) user key with the
* provided master key
@ -147,10 +147,10 @@ export abstract class CryptoService {
* @param userKey The user key
* @returns The user key and the master key protected version of it
*/
encryptUserKeyWithMasterKey: (
abstract encryptUserKeyWithMasterKey(
masterKey: MasterKey,
userKey?: UserKey,
) => Promise<[UserKey, EncString]>;
): Promise<[UserKey, EncString]>;
/**
* Decrypts the user key with the provided master key
* @param masterKey The user's master key
@ -158,11 +158,11 @@ export abstract class CryptoService {
* @param userId The desired user
* @returns The user key
*/
decryptUserKeyWithMasterKey: (
abstract decryptUserKeyWithMasterKey(
masterKey: MasterKey,
userKey?: EncString,
userId?: string,
) => Promise<UserKey>;
): Promise<UserKey>;
/**
* Creates a master password hash from the user's master password. Can
* be used for local authentication or for server authentication depending
@ -172,21 +172,25 @@ export abstract class CryptoService {
* @param hashPurpose The iterations to use for the hash
* @returns The user's master password hash
*/
hashMasterKey: (password: string, key: MasterKey, hashPurpose?: HashPurpose) => Promise<string>;
abstract hashMasterKey(
password: string,
key: MasterKey,
hashPurpose?: HashPurpose,
): Promise<string>;
/**
* Sets the user's master password hash
* @param keyHash The user's master password hash to set
*/
setMasterKeyHash: (keyHash: string) => Promise<void>;
abstract setMasterKeyHash(keyHash: string): Promise<void>;
/**
* @returns The user's master password hash
*/
getMasterKeyHash: () => Promise<string>;
abstract getMasterKeyHash(): Promise<string>;
/**
* Clears the user's stored master password hash
* @param userId The desired user
*/
clearMasterKeyHash: (userId?: string) => Promise<void>;
abstract clearMasterKeyHash(userId?: string): Promise<void>;
/**
* Compares the provided master password to the stored password hash and server password hash.
* Updates the stored hash if outdated.
@ -195,107 +199,109 @@ export abstract class CryptoService {
* @returns True if the provided master password matches either the stored
* key hash or the server key hash
*/
compareAndUpdateKeyHash: (masterPassword: string, masterKey: MasterKey) => Promise<boolean>;
abstract compareAndUpdateKeyHash(masterPassword: string, masterKey: MasterKey): Promise<boolean>;
/**
* Stores the encrypted organization keys and clears any decrypted
* organization keys currently in memory
* @param orgs The organizations to set keys for
* @param providerOrgs The provider organizations to set keys for
*/
setOrgKeys: (
abstract setOrgKeys(
orgs: ProfileOrganizationResponse[],
providerOrgs: ProfileProviderOrganizationResponse[],
) => Promise<void>;
activeUserOrgKeys$: Observable<Record<OrganizationId, OrgKey>>;
): Promise<void>;
abstract activeUserOrgKeys$: Observable<Record<OrganizationId, OrgKey>>;
/**
* Returns the organization's symmetric key
* @deprecated Use the observable activeUserOrgKeys$ and `map` to the desired orgKey instead
* @param orgId The desired organization
* @returns The organization's symmetric key
*/
getOrgKey: (orgId: string) => Promise<OrgKey>;
abstract getOrgKey(orgId: string): Promise<OrgKey>;
/**
* @deprecated Use the observable activeUserOrgKeys$ instead
* @returns A record of the organization Ids to their symmetric keys
*/
getOrgKeys: () => Promise<Record<string, SymmetricCryptoKey>>;
abstract getOrgKeys(): Promise<Record<string, SymmetricCryptoKey>>;
/**
* Uses the org key to derive a new symmetric key for encrypting data
* @param orgKey The organization's symmetric key
*/
makeDataEncKey: <T extends UserKey | OrgKey>(key: T) => Promise<[SymmetricCryptoKey, EncString]>;
abstract makeDataEncKey<T extends UserKey | OrgKey>(
key: T,
): Promise<[SymmetricCryptoKey, EncString]>;
/**
* Clears the user's stored organization keys
* @param memoryOnly Clear only the in-memory keys
* @param userId The desired user
*/
clearOrgKeys: (memoryOnly?: boolean, userId?: string) => Promise<void>;
abstract clearOrgKeys(memoryOnly?: boolean, userId?: string): Promise<void>;
/**
* Stores the encrypted provider keys and clears any decrypted
* provider keys currently in memory
* @param providers The providers to set keys for
*/
activeUserProviderKeys$: Observable<Record<ProviderId, ProviderKey>>;
setProviderKeys: (orgs: ProfileProviderResponse[]) => Promise<void>;
abstract activeUserProviderKeys$: Observable<Record<ProviderId, ProviderKey>>;
abstract setProviderKeys(orgs: ProfileProviderResponse[]): Promise<void>;
/**
* @param providerId The desired provider
* @returns The provider's symmetric key
*/
getProviderKey: (providerId: string) => Promise<ProviderKey>;
abstract getProviderKey(providerId: string): Promise<ProviderKey>;
/**
* @returns A record of the provider Ids to their symmetric keys
*/
getProviderKeys: () => Promise<Record<ProviderId, ProviderKey>>;
abstract getProviderKeys(): Promise<Record<ProviderId, ProviderKey>>;
/**
* @param memoryOnly Clear only the in-memory keys
* @param userId The desired user
*/
clearProviderKeys: (memoryOnly?: boolean, userId?: string) => Promise<void>;
abstract clearProviderKeys(memoryOnly?: boolean, userId?: string): Promise<void>;
/**
* Returns the public key from memory. If not available, extracts it
* from the private key and stores it in memory
* @returns The user's public key
*/
getPublicKey: () => Promise<Uint8Array>;
abstract getPublicKey(): Promise<Uint8Array>;
/**
* Creates a new organization key and encrypts it with the user's public key.
* This method can also return Provider keys for creating new Provider users.
* @returns The new encrypted org key and the decrypted key itself
*/
makeOrgKey: <T extends OrgKey | ProviderKey>() => Promise<[EncString, T]>;
abstract makeOrgKey<T extends OrgKey | ProviderKey>(): Promise<[EncString, T]>;
/**
* Sets the the user's encrypted private key in storage and
* clears the decrypted private key from memory
* Note: does not clear the private key if null is provided
* @param encPrivateKey An encrypted private key
*/
setPrivateKey: (encPrivateKey: string) => Promise<void>;
abstract setPrivateKey(encPrivateKey: string): Promise<void>;
/**
* Returns the private key from memory. If not available, decrypts it
* from storage and stores it in memory
* @returns The user's private key
*/
getPrivateKey: () => Promise<Uint8Array>;
abstract getPrivateKey(): Promise<Uint8Array>;
/**
* Generates a fingerprint phrase for the user based on their public key
* @param fingerprintMaterial Fingerprint material
* @param publicKey The user's public key
* @returns The user's fingerprint phrase
*/
getFingerprint: (fingerprintMaterial: string, publicKey?: Uint8Array) => Promise<string[]>;
abstract getFingerprint(fingerprintMaterial: string, publicKey?: Uint8Array): Promise<string[]>;
/**
* Generates a new keypair
* @param key A key to encrypt the private key with. If not provided,
* defaults to the user key
* @returns A new keypair: [publicKey in Base64, encrypted privateKey]
*/
makeKeyPair: (key?: SymmetricCryptoKey) => Promise<[string, EncString]>;
abstract makeKeyPair(key?: SymmetricCryptoKey): Promise<[string, EncString]>;
/**
* Clears the user's key pair
* @param memoryOnly Clear only the in-memory keys
* @param userId The desired user
*/
clearKeyPair: (memoryOnly?: boolean, userId?: string) => Promise<void[]>;
abstract clearKeyPair(memoryOnly?: boolean, userId?: string): Promise<void[]>;
/**
* @param pin The user's pin
* @param salt The user's salt
@ -303,14 +309,19 @@ export abstract class CryptoService {
* @param kdfConfig The user's kdf config
* @returns A key derived from the user's pin
*/
makePinKey: (pin: string, salt: string, kdf: KdfType, kdfConfig: KdfConfig) => Promise<PinKey>;
abstract makePinKey(
pin: string,
salt: string,
kdf: KdfType,
kdfConfig: KdfConfig,
): Promise<PinKey>;
/**
* Clears the user's pin keys from storage
* Note: This will remove the stored pin and as a result,
* disable pin protection for the user
* @param userId The desired user
*/
clearPinKeys: (userId?: string) => Promise<void>;
abstract clearPinKeys(userId?: string): Promise<void>;
/**
* Decrypts the user key with their pin
* @param pin The user's PIN
@ -321,13 +332,13 @@ export abstract class CryptoService {
* it will be retrieved from storage
* @returns The decrypted user key
*/
decryptUserKeyWithPin: (
abstract decryptUserKeyWithPin(
pin: string,
salt: string,
kdf: KdfType,
kdfConfig: KdfConfig,
protectedKeyCs?: EncString,
) => Promise<UserKey>;
): Promise<UserKey>;
/**
* Creates a new Pin key that encrypts the user key instead of the
* master key. Clears the old Pin key from state.
@ -340,55 +351,55 @@ export abstract class CryptoService {
* places depending on if Master Password on Restart was enabled)
* @returns The user key
*/
decryptAndMigrateOldPinKey: (
abstract decryptAndMigrateOldPinKey(
masterPasswordOnRestart: boolean,
pin: string,
email: string,
kdf: KdfType,
kdfConfig: KdfConfig,
oldPinKey: EncString,
) => Promise<UserKey>;
): Promise<UserKey>;
/**
* Replaces old master auto keys with new user auto keys
*/
migrateAutoKeyIfNeeded: (userId?: string) => Promise<void>;
abstract migrateAutoKeyIfNeeded(userId?: string): Promise<void>;
/**
* @param keyMaterial The key material to derive the send key from
* @returns A new send key
*/
makeSendKey: (keyMaterial: Uint8Array) => Promise<SymmetricCryptoKey>;
abstract makeSendKey(keyMaterial: Uint8Array): Promise<SymmetricCryptoKey>;
/**
* Clears all of the user's keys from storage
* @param userId The user's Id
*/
clearKeys: (userId?: string) => Promise<any>;
abstract clearKeys(userId?: string): Promise<any>;
/**
* RSA encrypts a value.
* @param data The data to encrypt
* @param publicKey The public key to use for encryption, if not provided, the user's public key will be used
* @returns The encrypted data
*/
rsaEncrypt: (data: Uint8Array, publicKey?: Uint8Array) => Promise<EncString>;
abstract rsaEncrypt(data: Uint8Array, publicKey?: Uint8Array): Promise<EncString>;
/**
* Decrypts a value using RSA.
* @param encValue The encrypted value to decrypt
* @param privateKeyValue The private key to use for decryption
* @returns The decrypted value
*/
rsaDecrypt: (encValue: string, privateKeyValue?: Uint8Array) => Promise<Uint8Array>;
randomNumber: (min: number, max: number) => Promise<number>;
abstract rsaDecrypt(encValue: string, privateKeyValue?: Uint8Array): Promise<Uint8Array>;
abstract randomNumber(min: number, max: number): Promise<number>;
/**
* Generates a new cipher key
* @returns A new cipher key
*/
makeCipherKey: () => Promise<CipherKey>;
abstract makeCipherKey(): Promise<CipherKey>;
/**
* Initialize all necessary crypto keys needed for a new account.
* Warning! This completely replaces any existing keys!
* @returns The user's newly created public key, private key, and encrypted private key
*/
initAccount: () => Promise<{
abstract initAccount(): Promise<{
userKey: UserKey;
publicKey: string;
privateKey: EncString;
@ -400,18 +411,18 @@ export abstract class CryptoService {
* @remarks
* Should always be called before updating a users KDF config.
*/
validateKdfConfig: (kdf: KdfType, kdfConfig: KdfConfig) => void;
abstract validateKdfConfig(kdf: KdfType, kdfConfig: KdfConfig): void;
/**
* @deprecated Left for migration purposes. Use decryptUserKeyWithPin instead.
*/
decryptMasterKeyWithPin: (
abstract decryptMasterKeyWithPin(
pin: string,
salt: string,
kdf: KdfType,
kdfConfig: KdfConfig,
protectedKeyCs?: EncString,
) => Promise<MasterKey>;
): Promise<MasterKey>;
/**
* Previously, the master key was used for any additional key like the biometrics or pin key.
* We have switched to using the user key for these purposes. This method is for clearing the state
@ -419,30 +430,36 @@ export abstract class CryptoService {
* @param keySuffix The desired type of key to clear
* @param userId The desired user
*/
clearDeprecatedKeys: (keySuffix: KeySuffixOptions, userId?: string) => Promise<void>;
abstract clearDeprecatedKeys(keySuffix: KeySuffixOptions, userId?: string): Promise<void>;
/**
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
* and then call encryptService.encrypt
*/
encrypt: (plainValue: string | Uint8Array, key?: SymmetricCryptoKey) => Promise<EncString>;
abstract encrypt(plainValue: string | Uint8Array, key?: SymmetricCryptoKey): Promise<EncString>;
/**
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
* and then call encryptService.encryptToBytes
*/
encryptToBytes: (plainValue: Uint8Array, key?: SymmetricCryptoKey) => Promise<EncArrayBuffer>;
abstract encryptToBytes(
plainValue: Uint8Array,
key?: SymmetricCryptoKey,
): Promise<EncArrayBuffer>;
/**
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
* and then call encryptService.decryptToBytes
*/
decryptToBytes: (encString: EncString, key?: SymmetricCryptoKey) => Promise<Uint8Array>;
abstract decryptToBytes(encString: EncString, key?: SymmetricCryptoKey): Promise<Uint8Array>;
/**
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
* and then call encryptService.decryptToUtf8
*/
decryptToUtf8: (encString: EncString, key?: SymmetricCryptoKey) => Promise<string>;
abstract decryptToUtf8(encString: EncString, key?: SymmetricCryptoKey): Promise<string>;
/**
* @deprecated July 25 2022: Get the key you need from CryptoService (getKeyForUserEncryption or getOrgKey)
* and then call encryptService.decryptToBytes
*/
decryptFromBytes: (encBuffer: EncArrayBuffer, key: SymmetricCryptoKey) => Promise<Uint8Array>;
abstract decryptFromBytes(
encBuffer: EncArrayBuffer,
key: SymmetricCryptoKey,
): Promise<Uint8Array>;
}

View File

@ -7,23 +7,26 @@ import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
export abstract class EncryptService {
abstract encrypt(plainValue: string | Uint8Array, key: SymmetricCryptoKey): Promise<EncString>;
abstract encryptToBytes: (
abstract encryptToBytes(
plainValue: Uint8Array,
key?: SymmetricCryptoKey,
) => Promise<EncArrayBuffer>;
abstract decryptToUtf8: (encString: EncString, key: SymmetricCryptoKey) => Promise<string>;
abstract decryptToBytes: (encThing: Encrypted, key: SymmetricCryptoKey) => Promise<Uint8Array>;
abstract rsaEncrypt: (data: Uint8Array, publicKey: Uint8Array) => Promise<EncString>;
abstract rsaDecrypt: (data: EncString, privateKey: Uint8Array) => Promise<Uint8Array>;
abstract resolveLegacyKey: (key: SymmetricCryptoKey, encThing: Encrypted) => SymmetricCryptoKey;
abstract decryptItems: <T extends InitializerMetadata>(
): Promise<EncArrayBuffer>;
abstract decryptToUtf8(encString: EncString, key: SymmetricCryptoKey): Promise<string>;
abstract decryptToBytes(encThing: Encrypted, key: SymmetricCryptoKey): Promise<Uint8Array>;
abstract rsaEncrypt(data: Uint8Array, publicKey: Uint8Array): Promise<EncString>;
abstract rsaDecrypt(data: EncString, privateKey: Uint8Array): Promise<Uint8Array>;
abstract resolveLegacyKey(key: SymmetricCryptoKey, encThing: Encrypted): SymmetricCryptoKey;
abstract decryptItems<T extends InitializerMetadata>(
items: Decryptable<T>[],
key: SymmetricCryptoKey,
) => Promise<T[]>;
): Promise<T[]>;
/**
* Generates a base64-encoded hash of the given value
* @param value The value to hash
* @param algorithm The hashing algorithm to use
*/
hash: (value: string | Uint8Array, algorithm: "sha1" | "sha256" | "sha512") => Promise<string>;
abstract hash(
value: string | Uint8Array,
algorithm: "sha1" | "sha256" | "sha512",
): Promise<string>;
}

View File

@ -1,5 +1,5 @@
import { FileDownloadRequest } from "./file-download.request";
export abstract class FileDownloadService {
download: (request: FileDownloadRequest) => void;
abstract download(request: FileDownloadRequest): void;
}

View File

@ -3,12 +3,12 @@ import { EncArrayBuffer } from "../../models/domain/enc-array-buffer";
import { EncString } from "../../models/domain/enc-string";
export abstract class FileUploadService {
upload: (
abstract upload(
uploadData: { url: string; fileUploadType: FileUploadType },
fileName: EncString,
encryptedFileData: EncArrayBuffer,
fileUploadMethods: FileUploadApiMethods,
) => Promise<void>;
): Promise<void>;
}
export type FileUploadApiMethods = {

View File

@ -3,8 +3,8 @@ import { Observable } from "rxjs";
import { TranslationService } from "./translation.service";
export abstract class I18nService extends TranslationService {
userSetLocale$: Observable<string | undefined>;
locale$: Observable<string>;
abstract userSetLocale$: Observable<string | undefined>;
abstract locale$: Observable<string>;
abstract setLocale(locale: string): Promise<void>;
abstract init(): Promise<void>;
}

View File

@ -11,7 +11,7 @@ export abstract class KeyGenerationService {
* 512 bits = 64 bytes
* @returns Generated key.
*/
createKey: (bitLength: 256 | 512) => Promise<SymmetricCryptoKey>;
abstract createKey(bitLength: 256 | 512): Promise<SymmetricCryptoKey>;
/**
* Generates key material from CSPRNG and derives a 64 byte key from it.
* Uses HKDF, see {@link https://datatracker.ietf.org/doc/html/rfc5869 RFC 5869}
@ -22,11 +22,11 @@ export abstract class KeyGenerationService {
* @param salt Optional. If not provided will be generated from CSPRNG.
* @returns An object containing the salt, key material, and derived key.
*/
createKeyWithPurpose: (
abstract createKeyWithPurpose(
bitLength: 128 | 192 | 256 | 512,
purpose: string,
salt?: string,
) => Promise<{ salt: string; material: CsprngArray; derivedKey: SymmetricCryptoKey }>;
): Promise<{ salt: string; material: CsprngArray; derivedKey: SymmetricCryptoKey }>;
/**
* Derives a 64 byte key from key material.
* @remark The key material should be generated from {@link createKey}, or {@link createKeyWithPurpose}.
@ -37,11 +37,11 @@ export abstract class KeyGenerationService {
* Different purposes results in different keys, even with the same material.
* @returns 64 byte derived key.
*/
deriveKeyFromMaterial: (
abstract deriveKeyFromMaterial(
material: CsprngArray,
salt: string,
purpose: string,
) => Promise<SymmetricCryptoKey>;
): Promise<SymmetricCryptoKey>;
/**
* Derives a 32 byte key from a password using a key derivation function.
* @param password Password to derive the key from.
@ -50,10 +50,10 @@ export abstract class KeyGenerationService {
* @param kdfConfig Configuration for the key derivation function.
* @returns 32 byte derived key.
*/
deriveKeyFromPassword: (
abstract deriveKeyFromPassword(
password: string | Uint8Array,
salt: string | Uint8Array,
kdf: KdfType,
kdfConfig: KdfConfig,
) => Promise<SymmetricCryptoKey>;
): Promise<SymmetricCryptoKey>;
}

View File

@ -1,9 +1,9 @@
import { LogLevelType } from "../enums/log-level-type.enum";
export abstract class LogService {
debug: (message: string) => void;
info: (message: string) => void;
warning: (message: string) => void;
error: (message: string) => void;
write: (level: LogLevelType, message: string) => void;
abstract debug(message: string): void;
abstract info(message: string): void;
abstract warning(message: string): void;
abstract error(message: string): void;
abstract write(level: LogLevelType, message: string): void;
}

View File

@ -1,3 +1,3 @@
export abstract class MessagingService {
send: (subscriber: string, arg?: any) => void;
abstract send(subscriber: string, arg?: any): void;
}

View File

@ -12,34 +12,34 @@ export type ClipboardOptions = {
};
export abstract class PlatformUtilsService {
getDevice: () => DeviceType;
getDeviceString: () => string;
getClientType: () => ClientType;
isFirefox: () => boolean;
isChrome: () => boolean;
isEdge: () => boolean;
isOpera: () => boolean;
isVivaldi: () => boolean;
isSafari: () => boolean;
isMacAppStore: () => boolean;
isViewOpen: () => Promise<boolean>;
launchUri: (uri: string, options?: any) => void;
getApplicationVersion: () => Promise<string>;
getApplicationVersionNumber: () => Promise<string>;
supportsWebAuthn: (win: Window) => boolean;
supportsDuo: () => boolean;
showToast: (
abstract getDevice(): DeviceType;
abstract getDeviceString(): string;
abstract getClientType(): ClientType;
abstract isFirefox(): boolean;
abstract isChrome(): boolean;
abstract isEdge(): boolean;
abstract isOpera(): boolean;
abstract isVivaldi(): boolean;
abstract isSafari(): boolean;
abstract isMacAppStore(): boolean;
abstract isViewOpen(): Promise<boolean>;
abstract launchUri(uri: string, options?: any): void;
abstract getApplicationVersion(): Promise<string>;
abstract getApplicationVersionNumber(): Promise<string>;
abstract supportsWebAuthn(win: Window): boolean;
abstract supportsDuo(): boolean;
abstract showToast(
type: "error" | "success" | "warning" | "info",
title: string,
text: string | string[],
options?: ToastOptions,
) => void;
isDev: () => boolean;
isSelfHost: () => boolean;
copyToClipboard: (text: string, options?: ClipboardOptions) => void | boolean;
readFromClipboard: () => Promise<string>;
supportsBiometric: () => Promise<boolean>;
authenticateBiometric: () => Promise<boolean>;
supportsSecureStorage: () => boolean;
getAutofillKeyboardShortcut: () => Promise<string>;
): void;
abstract isDev(): boolean;
abstract isSelfHost(): boolean;
abstract copyToClipboard(text: string, options?: ClipboardOptions): void | boolean;
abstract readFromClipboard(): Promise<string>;
abstract supportsBiometric(): Promise<boolean>;
abstract authenticateBiometric(): Promise<boolean>;
abstract supportsSecureStorage(): boolean;
abstract getAutofillKeyboardShortcut(): Promise<string>;
}

View File

@ -1,8 +1,8 @@
import { AuthService } from "../../auth/abstractions/auth.service";
export abstract class SystemService {
startProcessReload: (authService: AuthService) => Promise<void>;
cancelProcessReload: () => void;
clearClipboard: (clipboardValue: string, timeoutMs?: number) => Promise<void>;
clearPendingClipboard: () => Promise<any>;
abstract startProcessReload(authService: AuthService): Promise<void>;
abstract cancelProcessReload(): void;
abstract clearClipboard(clipboardValue: string, timeoutMs?: number): Promise<void>;
abstract clearPendingClipboard(): Promise<any>;
}

View File

@ -1,8 +1,8 @@
export abstract class TranslationService {
supportedTranslationLocales: string[];
translationLocale: string;
collator: Intl.Collator;
localeNames: Map<string, string>;
t: (id: string, p1?: string | number, p2?: string | number, p3?: string | number) => string;
translate: (id: string, p1?: string, p2?: string, p3?: string) => string;
abstract supportedTranslationLocales: string[];
abstract translationLocale: string;
abstract collator: Intl.Collator;
abstract localeNames: Map<string, string>;
abstract t(id: string, p1?: string | number, p2?: string | number, p3?: string | number): string;
abstract translate(id: string, p1?: string, p2?: string, p3?: string): string;
}

View File

@ -1,3 +1,3 @@
export abstract class ValidationService {
showError: (data: any) => string[];
abstract showError(data: any): string[];
}

View File

@ -18,42 +18,42 @@ export abstract class BiometricStateService {
/**
* `true` if the currently active user has elected to store a biometric key to unlock their vault.
*/
biometricUnlockEnabled$: Observable<boolean>; // used to be biometricUnlock
abstract biometricUnlockEnabled$: Observable<boolean>; // used to be biometricUnlock
/**
* If the user has elected to require a password on first unlock of an application instance, this key will store the
* encrypted client key half used to unlock the vault.
*
* Tracks the currently active user
*/
encryptedClientKeyHalf$: Observable<EncString | undefined>;
abstract encryptedClientKeyHalf$: Observable<EncString | undefined>;
/**
* whether or not a password is required on first unlock after opening the application
*
* tracks the currently active user
*/
requirePasswordOnStart$: Observable<boolean>;
abstract requirePasswordOnStart$: Observable<boolean>;
/**
* Indicates the user has been warned about the security implications of using biometrics and, depending on the OS,
*
* tracks the currently active user.
*/
dismissedRequirePasswordOnStartCallout$: Observable<boolean>;
abstract dismissedRequirePasswordOnStartCallout$: Observable<boolean>;
/**
* Whether the user has cancelled the biometric prompt.
*
* tracks the currently active user
*/
promptCancelled$: Observable<boolean>;
abstract promptCancelled$: Observable<boolean>;
/**
* Whether the user has elected to automatically prompt for biometrics.
*
* tracks the currently active user
*/
promptAutomatically$: Observable<boolean>;
abstract promptAutomatically$: Observable<boolean>;
/**
* Whether or not IPC fingerprint has been validated by the user this session.
*/
fingerprintValidated$: Observable<boolean>;
abstract fingerprintValidated$: Observable<boolean>;
/**
* Updates the require password on start state for the currently active user.

View File

@ -17,9 +17,9 @@ export abstract class DerivedStateProvider {
* well as some memory persistent information.
* @param dependencies The dependencies of the derive function
*/
get: <TFrom, TTo, TDeps extends DerivedStateDependencies>(
abstract get<TFrom, TTo, TDeps extends DerivedStateDependencies>(
parentState$: Observable<TFrom>,
deriveDefinition: DeriveDefinition<TFrom, TTo, TDeps>,
dependencies: TDeps,
) => DerivedState<TTo>;
): DerivedState<TTo>;
}

View File

@ -9,5 +9,5 @@ export abstract class GlobalStateProvider {
* Gets a {@link GlobalState} scoped to the given {@link KeyDefinition}
* @param keyDefinition - The {@link KeyDefinition} for which you want the state for.
*/
get: <T>(keyDefinition: KeyDefinition<T>) => GlobalState<T>;
abstract get<T>(keyDefinition: KeyDefinition<T>): GlobalState<T>;
}

View File

@ -19,7 +19,7 @@ import { ActiveUserStateProvider, SingleUserStateProvider } from "./user-state.p
*/
export abstract class StateProvider {
/** @see{@link ActiveUserStateProvider.activeUserId$} */
activeUserId$: Observable<UserId | undefined>;
abstract activeUserId$: Observable<UserId | undefined>;
/**
* Gets a state observable for a given key and userId.
@ -149,10 +149,10 @@ export abstract class StateProvider {
): SingleUserState<T>;
/** @see{@link GlobalStateProvider.get} */
getGlobal: <T>(keyDefinition: KeyDefinition<T>) => GlobalState<T>;
getDerived: <TFrom, TTo, TDeps extends DerivedStateDependencies>(
abstract getGlobal<T>(keyDefinition: KeyDefinition<T>): GlobalState<T>;
abstract getDerived<TFrom, TTo, TDeps extends DerivedStateDependencies>(
parentState$: Observable<TFrom>,
deriveDefinition: DeriveDefinition<TFrom, TTo, TDeps>,
dependencies: TDeps,
) => DerivedState<TTo>;
): DerivedState<TTo>;
}

View File

@ -39,7 +39,7 @@ export abstract class ActiveUserStateProvider {
/**
* Convenience re-emission of active user ID from {@link AccountService.activeAccount$}
*/
activeUserId$: Observable<UserId | undefined>;
abstract activeUserId$: Observable<UserId | undefined>;
/**
* Gets a {@link ActiveUserState} scoped to the given {@link KeyDefinition}, but updates when active user changes such

View File

@ -7,13 +7,13 @@ export abstract class ThemeStateService {
/**
* The users selected theme.
*/
selectedTheme$: Observable<ThemeType>;
abstract selectedTheme$: Observable<ThemeType>;
/**
* A method for updating the current users configured theme.
* @param theme The chosen user theme.
*/
setSelectedTheme: (theme: ThemeType) => Promise<void>;
abstract setSelectedTheme(theme: ThemeType): Promise<void>;
}
const THEME_SELECTION = new KeyDefinition<ThemeType>(THEMING_DISK, "selection", {