signal-desktop/ts/services/ourProfileKey.ts

88 lines
2.6 KiB
TypeScript
Raw Normal View History

// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { assertDev, strictAssert } from '../util/assert';
import * as log from '../logging/log';
import type { StorageInterface } from '../types/Storage.d';
export class OurProfileKeyService {
2021-09-24 00:49:05 +00:00
private getPromise: undefined | Promise<undefined | Uint8Array>;
private promisesBlockingGet: Array<Promise<unknown>> = [];
private storage?: StorageInterface;
initialize(storage: StorageInterface): void {
log.info('Our profile key service: initializing');
const storageReadyPromise = new Promise<void>(resolve => {
storage.onready(() => {
resolve();
});
});
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.promisesBlockingGet = [storageReadyPromise];
this.storage = storage;
}
2021-09-24 00:49:05 +00:00
get(): Promise<undefined | Uint8Array> {
if (this.getPromise) {
log.info(
'Our profile key service: was already fetching. Piggybacking off of that'
);
} else {
log.info('Our profile key service: kicking off a new fetch');
this.getPromise = this.doGet();
}
return this.getPromise;
}
2021-09-24 00:49:05 +00:00
async set(newValue: undefined | Uint8Array): Promise<void> {
assertDev(this.storage, 'OurProfileKeyService was not initialized');
if (newValue != null) {
strictAssert(
newValue.byteLength > 0,
'Our profile key service: Profile key cannot be empty'
);
log.info('Our profile key service: updating profile key');
await this.storage.put('profileKey', newValue);
} else {
log.info('Our profile key service: removing profile key');
await this.storage.remove('profileKey');
}
}
blockGetWithPromise(promise: Promise<unknown>): void {
this.promisesBlockingGet.push(promise);
}
2021-09-24 00:49:05 +00:00
private async doGet(): Promise<undefined | Uint8Array> {
log.info(
`Our profile key service: waiting for ${this.promisesBlockingGet.length} promises before fetching`
);
await Promise.allSettled(this.promisesBlockingGet);
this.promisesBlockingGet = [];
delete this.getPromise;
assertDev(this.storage, 'OurProfileKeyService was not initialized');
log.info('Our profile key service: fetching profile key from storage');
const result = this.storage.get('profileKey');
2021-09-24 00:49:05 +00:00
if (result === undefined || result instanceof Uint8Array) {
return result;
}
assertDev(
false,
2021-09-24 00:49:05 +00:00
'Profile key in storage was defined, but not an Uint8Array. Returning undefined'
);
return undefined;
}
}
export const ourProfileKeyService = new OurProfileKeyService();