2021-05-05 16:39:16 +00:00
|
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2024-10-10 17:57:22 +00:00
|
|
|
import { assertDev, strictAssert } from '../util/assert';
|
2021-05-05 16:39:16 +00:00
|
|
|
import * as log from '../logging/log';
|
|
|
|
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { StorageInterface } from '../types/Storage.d';
|
2021-05-05 16:39:16 +00:00
|
|
|
|
|
|
|
export class OurProfileKeyService {
|
2021-09-24 00:49:05 +00:00
|
|
|
private getPromise: undefined | Promise<undefined | Uint8Array>;
|
2021-05-05 16:39:16 +00:00
|
|
|
|
|
|
|
private promisesBlockingGet: Array<Promise<unknown>> = [];
|
|
|
|
|
2021-06-15 00:09:37 +00:00
|
|
|
private storage?: StorageInterface;
|
2021-05-05 16:39:16 +00:00
|
|
|
|
2021-06-15 00:09:37 +00:00
|
|
|
initialize(storage: StorageInterface): void {
|
2021-05-05 16:39:16 +00:00
|
|
|
log.info('Our profile key service: initializing');
|
|
|
|
|
|
|
|
const storageReadyPromise = new Promise<void>(resolve => {
|
|
|
|
storage.onready(() => {
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
2024-01-24 00:11:12 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
2021-05-05 16:39:16 +00:00
|
|
|
this.promisesBlockingGet = [storageReadyPromise];
|
|
|
|
|
|
|
|
this.storage = storage;
|
|
|
|
}
|
|
|
|
|
2021-09-24 00:49:05 +00:00
|
|
|
get(): Promise<undefined | Uint8Array> {
|
2021-05-05 16:39:16 +00:00
|
|
|
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> {
|
2022-09-15 19:17:15 +00:00
|
|
|
assertDev(this.storage, 'OurProfileKeyService was not initialized');
|
2024-10-10 17:57:22 +00:00
|
|
|
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');
|
2021-05-05 16:39:16 +00:00
|
|
|
await this.storage.put('profileKey', newValue);
|
|
|
|
} else {
|
2024-10-10 17:57:22 +00:00
|
|
|
log.info('Our profile key service: removing profile key');
|
2021-05-05 16:39:16 +00:00
|
|
|
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> {
|
2021-05-05 16:39:16 +00:00
|
|
|
log.info(
|
|
|
|
`Our profile key service: waiting for ${this.promisesBlockingGet.length} promises before fetching`
|
|
|
|
);
|
|
|
|
|
|
|
|
await Promise.allSettled(this.promisesBlockingGet);
|
|
|
|
this.promisesBlockingGet = [];
|
|
|
|
|
|
|
|
delete this.getPromise;
|
|
|
|
|
2022-09-15 19:17:15 +00:00
|
|
|
assertDev(this.storage, 'OurProfileKeyService was not initialized');
|
2021-05-05 16:39:16 +00:00
|
|
|
|
|
|
|
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) {
|
2021-05-05 16:39:16 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-09-15 19:17:15 +00:00
|
|
|
assertDev(
|
2021-05-05 16:39:16 +00:00
|
|
|
false,
|
2021-09-24 00:49:05 +00:00
|
|
|
'Profile key in storage was defined, but not an Uint8Array. Returning undefined'
|
2021-05-05 16:39:16 +00:00
|
|
|
);
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const ourProfileKeyService = new OurProfileKeyService();
|