mirror of
https://github.com/bitwarden/jslib
synced 2025-12-17 16:53:20 +00:00
Use separate data model
This commit is contained in:
@@ -1,14 +1,10 @@
|
|||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import {
|
import { EncryptedOrganizationKeyData } from "jslib-common/models/data/encryptedOrganizationKeyData";
|
||||||
BaseEncryptedOrganizationKey,
|
|
||||||
EncryptedOrganizationKey,
|
|
||||||
} from "jslib-common/models/domain/account/encryptedKey";
|
|
||||||
|
|
||||||
import { KdfType } from "../enums/kdfType";
|
import { KdfType } from "../enums/kdfType";
|
||||||
import { ThemeType } from "../enums/themeType";
|
import { ThemeType } from "../enums/themeType";
|
||||||
import { UriMatchType } from "../enums/uriMatchType";
|
import { UriMatchType } from "../enums/uriMatchType";
|
||||||
import { EncryptedOrganizationKeyStore } from "../interfaces/encryptedOrganizationKeyStore";
|
|
||||||
import { CipherData } from "../models/data/cipherData";
|
import { CipherData } from "../models/data/cipherData";
|
||||||
import { CollectionData } from "../models/data/collectionData";
|
import { CollectionData } from "../models/data/collectionData";
|
||||||
import { EventData } from "../models/data/eventData";
|
import { EventData } from "../models/data/eventData";
|
||||||
@@ -29,6 +25,7 @@ import { CipherView } from "../models/view/cipherView";
|
|||||||
import { CollectionView } from "../models/view/collectionView";
|
import { CollectionView } from "../models/view/collectionView";
|
||||||
import { FolderView } from "../models/view/folderView";
|
import { FolderView } from "../models/view/folderView";
|
||||||
import { SendView } from "../models/view/sendView";
|
import { SendView } from "../models/view/sendView";
|
||||||
|
|
||||||
export abstract class StateService<T extends Account = Account> {
|
export abstract class StateService<T extends Account = Account> {
|
||||||
accounts: BehaviorSubject<{ [userId: string]: T }>;
|
accounts: BehaviorSubject<{ [userId: string]: T }>;
|
||||||
activeAccount: BehaviorSubject<string>;
|
activeAccount: BehaviorSubject<string>;
|
||||||
@@ -191,9 +188,9 @@ export abstract class StateService<T extends Account = Account> {
|
|||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
getEncryptedOrganizationKeys: (
|
getEncryptedOrganizationKeys: (
|
||||||
options?: StorageOptions
|
options?: StorageOptions
|
||||||
) => Promise<{ [orgId: string]: BaseEncryptedOrganizationKey }>;
|
) => Promise<{ [orgId: string]: EncryptedOrganizationKeyData }>;
|
||||||
setEncryptedOrganizationKeys: (
|
setEncryptedOrganizationKeys: (
|
||||||
value: { [orgId: string]: BaseEncryptedOrganizationKey },
|
value: { [orgId: string]: EncryptedOrganizationKeyData },
|
||||||
options?: StorageOptions
|
options?: StorageOptions
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
getEncryptedPasswordGenerationHistory: (
|
getEncryptedPasswordGenerationHistory: (
|
||||||
|
|||||||
7
common/src/models/data/encryptedOrganizationKeyData.ts
Normal file
7
common/src/models/data/encryptedOrganizationKeyData.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export class EncryptedOrganizationKeyData {
|
||||||
|
constructor(public key: string, public providerId?: string) {}
|
||||||
|
|
||||||
|
static fromObj(obj: { key: string; providerId?: string }) {
|
||||||
|
return new EncryptedOrganizationKeyData(obj.key, obj.providerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { AuthenticationStatus } from "../../enums/authenticationStatus";
|
import { AuthenticationStatus } from "../../enums/authenticationStatus";
|
||||||
import { KdfType } from "../../enums/kdfType";
|
import { KdfType } from "../../enums/kdfType";
|
||||||
import { UriMatchType } from "../../enums/uriMatchType";
|
import { UriMatchType } from "../../enums/uriMatchType";
|
||||||
import { EncryptedOrganizationKeyStore } from "../../interfaces/encryptedOrganizationKeyStore";
|
|
||||||
import { CipherData } from "../data/cipherData";
|
import { CipherData } from "../data/cipherData";
|
||||||
import { CollectionData } from "../data/collectionData";
|
import { CollectionData } from "../data/collectionData";
|
||||||
|
import { EncryptedOrganizationKeyData } from "../data/encryptedOrganizationKeyData";
|
||||||
import { EventData } from "../data/eventData";
|
import { EventData } from "../data/eventData";
|
||||||
import { FolderData } from "../data/folderData";
|
import { FolderData } from "../data/folderData";
|
||||||
import { OrganizationData } from "../data/organizationData";
|
import { OrganizationData } from "../data/organizationData";
|
||||||
@@ -15,6 +15,7 @@ import { CollectionView } from "../view/collectionView";
|
|||||||
import { FolderView } from "../view/folderView";
|
import { FolderView } from "../view/folderView";
|
||||||
import { SendView } from "../view/sendView";
|
import { SendView } from "../view/sendView";
|
||||||
|
|
||||||
|
import { BaseEncryptedOrganizationKey } from "./account/encryptedKey";
|
||||||
import { EncString } from "./encString";
|
import { EncString } from "./encString";
|
||||||
import { EnvironmentUrls } from "./environmentUrls";
|
import { EnvironmentUrls } from "./environmentUrls";
|
||||||
import { GeneratedPasswordHistory } from "./generatedPasswordHistory";
|
import { GeneratedPasswordHistory } from "./generatedPasswordHistory";
|
||||||
@@ -67,10 +68,10 @@ export class AccountKeys {
|
|||||||
SymmetricCryptoKey
|
SymmetricCryptoKey
|
||||||
>();
|
>();
|
||||||
organizationKeys?: EncryptionPair<
|
organizationKeys?: EncryptionPair<
|
||||||
{ [orgId: string]: EncryptedOrganizationKeyStore },
|
{ [orgId: string]: EncryptedOrganizationKeyData },
|
||||||
Map<string, SymmetricCryptoKey>
|
Map<string, SymmetricCryptoKey>
|
||||||
> = new EncryptionPair<
|
> = new EncryptionPair<
|
||||||
{ [orgId: string]: EncryptedOrganizationKeyStore },
|
{ [orgId: string]: EncryptedOrganizationKeyData },
|
||||||
Map<string, SymmetricCryptoKey>
|
Map<string, SymmetricCryptoKey>
|
||||||
>();
|
>();
|
||||||
providerKeys?: EncryptionPair<any, Map<string, SymmetricCryptoKey>> = new EncryptionPair<
|
providerKeys?: EncryptionPair<any, Map<string, SymmetricCryptoKey>> = new EncryptionPair<
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
||||||
|
import { EncryptedOrganizationKeyData } from "jslib-common/models/data/encryptedOrganizationKeyData";
|
||||||
|
|
||||||
import { EncString } from "../encString";
|
import { EncString } from "../encString";
|
||||||
import { SymmetricCryptoKey } from "../symmetricCryptoKey";
|
import { SymmetricCryptoKey } from "../symmetricCryptoKey";
|
||||||
|
|
||||||
export abstract class BaseEncryptedOrganizationKey {
|
export abstract class BaseEncryptedOrganizationKey {
|
||||||
decrypt: (cryptoService: CryptoService) => Promise<SymmetricCryptoKey>;
|
decrypt: (cryptoService: CryptoService) => Promise<SymmetricCryptoKey>;
|
||||||
toJSON: () => string;
|
|
||||||
|
|
||||||
static fromObj(obj: { key: string; providerId?: string }) {
|
static fromData(data: EncryptedOrganizationKeyData) {
|
||||||
if (obj.providerId != null) {
|
if (data.providerId != null) {
|
||||||
return new ProviderEncryptedOrganizationKey(obj.key, obj.providerId);
|
return new ProviderEncryptedOrganizationKey(data.key, data.providerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EncryptedOrganizationKey(obj.key);
|
return new EncryptedOrganizationKey(data.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,8 +24,8 @@ export class EncryptedOrganizationKey implements BaseEncryptedOrganizationKey {
|
|||||||
return new SymmetricCryptoKey(decValue);
|
return new SymmetricCryptoKey(decValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toData() {
|
||||||
return JSON.stringify({ key: this.key });
|
return new EncryptedOrganizationKeyData(this.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,10 +38,7 @@ export class ProviderEncryptedOrganizationKey implements BaseEncryptedOrganizati
|
|||||||
return new SymmetricCryptoKey(decValue);
|
return new SymmetricCryptoKey(decValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toData() {
|
||||||
return JSON.stringify({
|
return new EncryptedOrganizationKeyData(this.key, this.providerId);
|
||||||
key: this.key,
|
|
||||||
providerId: this.providerId,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import * as bigInt from "big-integer";
|
import * as bigInt from "big-integer";
|
||||||
|
|
||||||
import { EncryptedOrganizationKeyStore } from "jslib-common/interfaces/encryptedOrganizationKeyStore";
|
import { EncryptedOrganizationKeyData } from "jslib-common/models/data/encryptedOrganizationKeyData";
|
||||||
import {
|
import { BaseEncryptedOrganizationKey } from "jslib-common/models/domain/account/encryptedKey";
|
||||||
BaseEncryptedOrganizationKey,
|
|
||||||
EncryptedOrganizationKey,
|
|
||||||
} from "jslib-common/models/domain/account/encryptedKey";
|
|
||||||
|
|
||||||
import { CryptoService as CryptoServiceAbstraction } from "../abstractions/crypto.service";
|
import { CryptoService as CryptoServiceAbstraction } from "../abstractions/crypto.service";
|
||||||
import { CryptoFunctionService } from "../abstractions/cryptoFunction.service";
|
import { CryptoFunctionService } from "../abstractions/cryptoFunction.service";
|
||||||
@@ -65,15 +62,15 @@ export class CryptoService implements CryptoServiceAbstraction {
|
|||||||
orgs: ProfileOrganizationResponse[],
|
orgs: ProfileOrganizationResponse[],
|
||||||
providerOrgs: ProfileProviderOrganizationResponse[]
|
providerOrgs: ProfileProviderOrganizationResponse[]
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const encOrgKeys: { [orgId: string]: BaseEncryptedOrganizationKey } = {};
|
const encOrgKeyData: { [orgId: string]: EncryptedOrganizationKeyData } = {};
|
||||||
|
|
||||||
const allOrgs = orgs.concat(providerOrgs);
|
const allOrgs = orgs.concat(providerOrgs);
|
||||||
allOrgs.forEach((org) => {
|
allOrgs.forEach((org) => {
|
||||||
encOrgKeys[org.id] = BaseEncryptedOrganizationKey.fromObj(org);
|
encOrgKeyData[org.id] = EncryptedOrganizationKeyData.fromObj(org);
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.stateService.setDecryptedOrganizationKeys(null);
|
await this.stateService.setDecryptedOrganizationKeys(null);
|
||||||
return await this.stateService.setEncryptedOrganizationKeys(encOrgKeys);
|
return await this.stateService.setEncryptedOrganizationKeys(encOrgKeyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setProviderKeys(providers: ProfileProviderResponse[]): Promise<void> {
|
async setProviderKeys(providers: ProfileProviderResponse[]): Promise<void> {
|
||||||
@@ -216,21 +213,22 @@ export class CryptoService implements CryptoServiceAbstraction {
|
|||||||
return decryptedOrganizationKeys;
|
return decryptedOrganizationKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
const encOrgKeys = await this.stateService.getEncryptedOrganizationKeys();
|
const encOrgKeyData = await this.stateService.getEncryptedOrganizationKeys();
|
||||||
if (encOrgKeys == null) {
|
if (encOrgKeyData == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let setKey = false;
|
let setKey = false;
|
||||||
|
|
||||||
for (const orgId in encOrgKeys) {
|
for (const orgId in encOrgKeyData) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
if (!encOrgKeys.hasOwnProperty(orgId) || result.has(orgId)) {
|
if (!encOrgKeyData.hasOwnProperty(orgId) || result.has(orgId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const decryptedKey = await encOrgKeys[orgId].decrypt(this);
|
const encOrgKey = BaseEncryptedOrganizationKey.fromData(encOrgKeyData[orgId]);
|
||||||
result.set(orgId, decryptedKey);
|
const decOrgKey = await encOrgKey.decrypt(this);
|
||||||
|
result.set(orgId, decOrgKey);
|
||||||
setKey = true;
|
setKey = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { EncryptedOrganizationKeyStore } from "jslib-common/interfaces/encryptedOrganizationKeyStore";
|
import { EncryptedOrganizationKeyData } from "jslib-common/models/data/encryptedOrganizationKeyData";
|
||||||
import {
|
|
||||||
BaseEncryptedOrganizationKey,
|
|
||||||
EncryptedOrganizationKey,
|
|
||||||
} from "jslib-common/models/domain/account/encryptedKey";
|
|
||||||
|
|
||||||
import { LogService } from "../abstractions/log.service";
|
import { LogService } from "../abstractions/log.service";
|
||||||
import { StateService as StateServiceAbstraction } from "../abstractions/state.service";
|
import { StateService as StateServiceAbstraction } from "../abstractions/state.service";
|
||||||
@@ -1221,32 +1217,20 @@ export class StateService<
|
|||||||
|
|
||||||
async getEncryptedOrganizationKeys(
|
async getEncryptedOrganizationKeys(
|
||||||
options?: StorageOptions
|
options?: StorageOptions
|
||||||
): Promise<{ [orgId: string]: BaseEncryptedOrganizationKey }> {
|
): Promise<{ [orgId: string]: EncryptedOrganizationKeyData }> {
|
||||||
const data = (
|
return (
|
||||||
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
||||||
)?.keys?.organizationKeys.encrypted;
|
)?.keys?.organizationKeys.encrypted;
|
||||||
|
|
||||||
const result: { [orgId: string]: BaseEncryptedOrganizationKey } = {};
|
|
||||||
for (const orgId in data) {
|
|
||||||
result[orgId] = BaseEncryptedOrganizationKey.fromObj(data[orgId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async setEncryptedOrganizationKeys(
|
async setEncryptedOrganizationKeys(
|
||||||
value: { [orgId: string]: EncryptedOrganizationKeyStore },
|
value: { [orgId: string]: EncryptedOrganizationKeyData },
|
||||||
options?: StorageOptions
|
options?: StorageOptions
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const data: { [orgId: string]: EncryptedOrganizationKey } = {};
|
|
||||||
for (const orgId in value) {
|
|
||||||
data[orgId] = value[orgId].toJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
const account = await this.getAccount(
|
const account = await this.getAccount(
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions())
|
this.reconcileOptions(options, await this.defaultOnDiskOptions())
|
||||||
);
|
);
|
||||||
account.keys.organizationKeys.encrypted = data;
|
account.keys.organizationKeys.encrypted = value;
|
||||||
await this.saveAccount(
|
await this.saveAccount(
|
||||||
account,
|
account,
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions())
|
this.reconcileOptions(options, await this.defaultOnDiskOptions())
|
||||||
|
|||||||
Reference in New Issue
Block a user