When incoming message should've been sealed sender, reply with profile key
This commit is contained in:
parent
18c86898d1
commit
8ef14e6f39
10 changed files with 384 additions and 38 deletions
87
ts/services/ourProfileKey.ts
Normal file
87
ts/services/ourProfileKey.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from '../util/assert';
|
||||
import * as log from '../logging/log';
|
||||
|
||||
// We define a stricter storage here that returns `unknown` instead of `any`.
|
||||
type Storage = {
|
||||
get(key: string): unknown;
|
||||
put(key: string, value: unknown): Promise<void>;
|
||||
remove(key: string): Promise<void>;
|
||||
onready: (callback: () => unknown) => void;
|
||||
};
|
||||
|
||||
export class OurProfileKeyService {
|
||||
private getPromise: undefined | Promise<undefined | ArrayBuffer>;
|
||||
|
||||
private promisesBlockingGet: Array<Promise<unknown>> = [];
|
||||
|
||||
private storage?: Storage;
|
||||
|
||||
initialize(storage: Storage): void {
|
||||
log.info('Our profile key service: initializing');
|
||||
|
||||
const storageReadyPromise = new Promise<void>(resolve => {
|
||||
storage.onready(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
this.promisesBlockingGet = [storageReadyPromise];
|
||||
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
get(): Promise<undefined | ArrayBuffer> {
|
||||
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;
|
||||
}
|
||||
|
||||
async set(newValue: undefined | ArrayBuffer): Promise<void> {
|
||||
log.info('Our profile key service: updating profile key');
|
||||
assert(this.storage, 'OurProfileKeyService was not initialized');
|
||||
if (newValue) {
|
||||
await this.storage.put('profileKey', newValue);
|
||||
} else {
|
||||
await this.storage.remove('profileKey');
|
||||
}
|
||||
}
|
||||
|
||||
blockGetWithPromise(promise: Promise<unknown>): void {
|
||||
this.promisesBlockingGet.push(promise);
|
||||
}
|
||||
|
||||
private async doGet(): Promise<undefined | ArrayBuffer> {
|
||||
log.info(
|
||||
`Our profile key service: waiting for ${this.promisesBlockingGet.length} promises before fetching`
|
||||
);
|
||||
|
||||
await Promise.allSettled(this.promisesBlockingGet);
|
||||
this.promisesBlockingGet = [];
|
||||
|
||||
delete this.getPromise;
|
||||
|
||||
assert(this.storage, 'OurProfileKeyService was not initialized');
|
||||
|
||||
log.info('Our profile key service: fetching profile key from storage');
|
||||
const result = this.storage.get('profileKey');
|
||||
if (result === undefined || result instanceof ArrayBuffer) {
|
||||
return result;
|
||||
}
|
||||
|
||||
assert(
|
||||
false,
|
||||
'Profile key in storage was defined, but not an ArrayBuffer. Returning undefined'
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export const ourProfileKeyService = new OurProfileKeyService();
|
Loading…
Add table
Add a link
Reference in a new issue