import { ProviderId } from "../../../types/guid"; import { ProviderKey } from "../../../types/key"; import { EncryptService } from "../../abstractions/encrypt.service"; import { EncString, EncryptedString } from "../../models/domain/enc-string"; import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key"; import { CRYPTO_DISK, DeriveDefinition, UserKeyDefinition } from "../../state"; import { CryptoService } from "../crypto.service"; export const USER_ENCRYPTED_PROVIDER_KEYS = UserKeyDefinition.record( CRYPTO_DISK, "providerKeys", { deserializer: (obj) => obj, clearOn: ["logout"], }, ); export const USER_PROVIDER_KEYS = DeriveDefinition.from< Record, Record, { encryptService: EncryptService; cryptoService: CryptoService } // TODO: This should depend on an active user private key observable directly >(USER_ENCRYPTED_PROVIDER_KEYS, { deserializer: (obj) => { const result: Record = {}; for (const providerId of Object.keys(obj ?? {}) as ProviderId[]) { result[providerId] = SymmetricCryptoKey.fromJSON(obj[providerId]) as ProviderKey; } return result; }, derive: async (from, { encryptService, cryptoService }) => { const result: Record = {}; for (const providerId of Object.keys(from ?? {}) as ProviderId[]) { if (result[providerId] != null) { continue; } const encrypted = new EncString(from[providerId]); const privateKey = await cryptoService.getPrivateKey(); const decrypted = await encryptService.rsaDecrypt(encrypted, privateKey); const providerKey = new SymmetricCryptoKey(decrypted) as ProviderKey; result[providerId] = providerKey; } return result; }, });