This commit is contained in:
Bruno Windels 2023-03-31 17:42:38 +02:00
parent 25aac4b7c0
commit 8cf7a1b161
4 changed files with 81 additions and 13 deletions

View File

@ -777,13 +777,15 @@ export class Session {
txn.accountData.set(event);
}
}
changes.accountData = accountData.events;
if (this._secretStorage) {
changes.secretStorageChanges = await this._secretStorage.writeSync(accountData.events, txn, log);
}
}
return changes;
}
/** @internal */
afterSync({syncInfo, e2eeAccountChanges, accountData}) {
afterSync({syncInfo, e2eeAccountChanges, secretStorageChanges}) {
if (syncInfo) {
// sync transaction succeeded, modify object state now
this._syncInfo = syncInfo;
@ -791,8 +793,8 @@ export class Session {
if (this._e2eeAccount) {
this._e2eeAccount.afterSync(e2eeAccountChanges);
}
if (accountData && this._secretStorage) {
this._secretStorage.afterSync(accountData);
if (secretStorageChanges && this._secretStorage) {
this._secretStorage.afterSync(secretStorageChanges);
}
}

View File

@ -13,7 +13,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import type {Key} from "./common";
import {BaseObservableValue, RetainedObservableValue} from "../../observable/value";
import {KeyType} from "./index";
import {keyFromPassphrase} from "./passphrase";
import {keyFromRecoveryKey} from "./recoveryKey";
import type {Key, KeyDescription} from "./common";
import type {Platform} from "../../platform/web/Platform.js";
import type {Transaction} from "../storage/idb/Transaction";
import type {Storage} from "../storage/idb/Storage";
@ -37,11 +41,25 @@ class DecryptionError extends Error {
}
}
type AccountData = {type: string, content: Record<string, any>};
type KeyCredentials = {
type: KeyType,
credential: string
}
export class SecretStorage {
private readonly _key: Key;
// we know the id but don't have the description yet
private _keyId?: string;
// we have the description but not the credentials yet
private _keyDescription?: KeyDescription;
// we have the credentials but not the id or description yet
private _keyCredentials?: KeyCredentials;
// we have everything to compose a valid key
private _key?: Key;
private readonly _platform: Platform;
private readonly _storage: Storage;
private observedSecrets
private observedSecrets: Map<string, RetainedObservableValue<string | undefined>>;
constructor({key, platform, storage}: {key: Key, platform: Platform, storage: Storage}) {
this._key = key;
@ -49,12 +67,60 @@ export class SecretStorage {
this._storage = storage;
}
afterSync(accountData: ReadonlyArray<{type: string, content: Record<string, any>}>): void {
for(const event of accountData) {
if (type === )
load() {
// read key
}
async setKey(type: KeyType, credential: string) {
const credentials: KeyCredentials = {type, credential};
this._keyCredentials = credentials;
this.updateKey(this._keyDescription, this._keyCredentials);
}
async setKeyWithDehydratedDeviceKey() {
}
private async updateKey(keyDescription: KeyDescription | undefined, credentials: KeyCredentials | undefined, txn: Transaction) {
if (keyDescription && credentials) {
if (credentials.type === KeyType.Passphrase) {
this._key = await keyFromPassphrase(keyDescription, credentials.credential, this._platform);
} else if (credentials.type === KeyType.RecoveryKey) {
this._key = await keyFromRecoveryKey(keyDescription, credentials.credential, this._olm, this._platform);
}
//
}
}
private update(keyDescription: KeyDescription, credentials: KeyCredentials) {
}
writeSync(accountData: ReadonlyArray<AccountData>, txn: Transaction, log: ILogItem): Promise<void> {
const newDefaultKey = accountData.find(e => e.type === "m.secret_storage.default_key");
const keyId: string | undefined = newDefaultKey ? newDefaultKey.content?.key : this._keyId;
const keyEventType = keyId ? `m.secret_storage.key.${keyId}` : undefined;
let newKey = keyEventType ? accountData.find(e => e.type === keyEventType) : undefined;
if (newDefaultKey && keyEventType && !newKey) {
newKey = await txn.accountData.get(keyEventType);
}
if (newKey) {
this.setKeyDescription()
}
const keyChanged = !!newDefaultKey || !!newKey;
if (keyChanged) {
// update all values
} else {
for(const event of accountData) {
}
}
}
afterSync(): void {
}
/** this method will auto-commit any indexeddb transaction because of its use of the webcrypto api */
async hasValidKeyForAnyAccountData() {
const txn = await this._storage.readTxn([

View File

@ -30,8 +30,8 @@ const SSSS_KEY = `${SESSION_E2EE_KEY_PREFIX}ssssKey`;
const BACKUPVERSION_KEY = `${SESSION_E2EE_KEY_PREFIX}keyBackupVersion`;
export enum KeyType {
"RecoveryKey",
"Passphrase"
RecoveryKey,
Passphrase
}
async function readDefaultKeyDescription(storage: Storage): Promise<KeyDescription | undefined> {

View File

@ -27,7 +27,7 @@ const DEFAULT_BITSIZE = 256;
* @param {Platform} platform
* @return {Key}
*/
export async function keyFromPassphrase(keyDescription: KeyDescription, passphrase: string, platform: Platform): Promise<Key> {
export async function keyFromPassphrase(passphrase: string, platform: Platform): Promise<Key> {
const {passphraseParams} = keyDescription;
if (!passphraseParams) {
throw new Error("not a passphrase key");