Refactor app initialization logic

This commit is contained in:
trevor-signal
2025-02-12 13:37:30 -05:00
committed by GitHub
parent 205c477082
commit 4c3db76bde
17 changed files with 394 additions and 582 deletions

View File

@@ -1188,7 +1188,13 @@ export default class AccountManager extends EventTarget {
await storage.put('identityKeyMap', identityKeyMap);
await storage.put('registrationIdMap', registrationIdMap);
await ourProfileKeyService.set(profileKey);
const me = window.ConversationController.getOurConversationOrThrow();
await me.setProfileKey(Bytes.toBase64(profileKey), {
reason: 'registration',
});
if (userAgent) {
await storage.put('userAgent', userAgent);
}
@@ -1351,7 +1357,7 @@ export default class AccountManager extends EventTarget {
async #registrationDone(): Promise<void> {
log.info('registration done');
this.dispatchEvent(new Event('registration'));
this.dispatchEvent(new Event('endRegistration'));
}
async setPni(

View File

@@ -300,7 +300,6 @@ export default class MessageReceiver
#serverTrustRoot: Uint8Array;
#stoppingProcessing?: boolean;
#pniIdentityKeyCheckRequired?: boolean;
#isAppReadyForProcessing: boolean = false;
constructor({ storage, serverTrustRoot }: MessageReceiverOptions) {
super();
@@ -348,15 +347,6 @@ export default class MessageReceiver
maxSize: 30,
processBatch: this.#cacheRemoveBatch.bind(this),
});
window.Whisper.events.on('app-ready-for-processing', () => {
this.#isAppReadyForProcessing = true;
this.reset();
});
window.Whisper.events.on('online', () => {
this.reset();
});
}
public getAndResetProcessedCount(): number {
@@ -477,17 +467,12 @@ export default class MessageReceiver
);
}
public reset(): void {
log.info('MessageReceiver.reset');
public startProcessingQueue(): void {
log.info('MessageReceiver.startProcessingQueue');
this.#count = 0;
this.#isEmptied = false;
this.#stoppingProcessing = false;
if (!this.#isAppReadyForProcessing) {
log.info('MessageReceiver.reset: not ready yet, returning early');
return;
}
drop(this.#addCachedMessagesToQueue());
}
@@ -507,7 +492,6 @@ export default class MessageReceiver
public stopProcessing(): void {
log.info('MessageReceiver.stopProcessing');
this.#stoppingProcessing = true;
this.#isAppReadyForProcessing = false;
}
public hasEmptied(): boolean {

View File

@@ -554,7 +554,7 @@ export class SocketManager extends EventListener {
authenticated.abort();
this.#dropAuthenticated(authenticated);
}
this.#markOffline();
this.#credentials = undefined;
}

View File

@@ -1,133 +0,0 @@
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable max-classes-per-file */
import type { EventHandler } from './EventTarget';
import EventTarget from './EventTarget';
import MessageReceiver from './MessageReceiver';
import type { ContactSyncEvent } from './messageReceiverEvents';
import MessageSender from './SendMessage';
import { assertDev } from '../util/assert';
import * as log from '../logging/log';
import { singleProtoJobQueue } from '../jobs/singleProtoJobQueue';
import * as Errors from '../types/errors';
class SyncRequestInner extends EventTarget {
#started = false;
contactSync?: boolean;
timeout: any;
oncontact: (event: ContactSyncEvent) => void;
timeoutMillis: number;
constructor(
private receiver: MessageReceiver,
timeoutMillis?: number
) {
super();
if (!(receiver instanceof MessageReceiver)) {
throw new Error(
'Tried to construct a SyncRequest without MessageReceiver'
);
}
this.oncontact = this.onContactSyncComplete.bind(this);
receiver.addEventListener('contactSync', this.oncontact);
this.timeoutMillis = timeoutMillis || 60000;
}
async start(): Promise<void> {
if (this.#started) {
assertDev(
false,
'SyncRequestInner: started more than once. Doing nothing'
);
return;
}
this.#started = true;
if (window.ConversationController.areWePrimaryDevice()) {
log.warn('SyncRequest.start: We are primary device; returning early');
return;
}
log.info(
'SyncRequest created. Sending config, block, contact, and group requests...'
);
try {
await Promise.all([
singleProtoJobQueue.add(
MessageSender.getRequestConfigurationSyncMessage()
),
singleProtoJobQueue.add(MessageSender.getRequestBlockSyncMessage()),
singleProtoJobQueue.add(MessageSender.getRequestContactSyncMessage()),
]);
} catch (error: unknown) {
log.error(
'SyncRequest: Failed to add request jobs',
Errors.toLogFormat(error)
);
}
this.timeout = setTimeout(this.onTimeout.bind(this), this.timeoutMillis);
}
onContactSyncComplete() {
this.contactSync = true;
this.update();
}
update() {
if (this.contactSync) {
this.dispatchEvent(new Event('success'));
this.cleanup();
}
}
onTimeout() {
if (this.contactSync) {
this.dispatchEvent(new Event('success'));
} else {
this.dispatchEvent(new Event('timeout'));
}
this.cleanup();
}
cleanup() {
clearTimeout(this.timeout);
this.receiver.removeEventListener('contactsync', this.oncontact);
delete this.listeners;
}
}
export default class SyncRequest {
#inner: SyncRequestInner;
addEventListener: (
name: 'success' | 'timeout',
handler: EventHandler
) => void;
removeEventListener: (
name: 'success' | 'timeout',
handler: EventHandler
) => void;
constructor(receiver: MessageReceiver, timeoutMillis?: number) {
const inner = new SyncRequestInner(receiver, timeoutMillis);
this.#inner = inner;
this.addEventListener = inner.addEventListener.bind(inner);
this.removeEventListener = inner.removeEventListener.bind(inner);
}
start(): void {
void this.#inner.start();
}
}

View File

@@ -5,7 +5,6 @@ import EventTarget from './EventTarget';
import AccountManager from './AccountManager';
import MessageReceiver from './MessageReceiver';
import utils from './Helpers';
import SyncRequest from './SyncRequest';
import MessageSender from './SendMessage';
import { Storage } from './Storage';
import * as WebAPI from './WebAPI';
@@ -19,7 +18,6 @@ export type TextSecureType = {
EventTarget: typeof EventTarget;
MessageReceiver: typeof MessageReceiver;
MessageSender: typeof MessageSender;
SyncRequest: typeof SyncRequest;
WebAPI: typeof WebAPI;
WebSocketResource: typeof WebSocketResource;
@@ -35,7 +33,6 @@ export const textsecure: TextSecureType = {
EventTarget,
MessageReceiver,
MessageSender,
SyncRequest,
WebAPI,
WebSocketResource,
};

View File

@@ -0,0 +1,32 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { waitForEvent } from '../shims/events';
import * as log from '../logging/log';
import { singleProtoJobQueue } from '../jobs/singleProtoJobQueue';
import MessageSender from './SendMessage';
import { toLogFormat } from '../types/errors';
export async function sendSyncRequests(
timeout?: number
): Promise<{ contactSyncComplete: Promise<void> }> {
const contactSyncComplete = waitForEvent('contactSync:complete', timeout);
log.info('sendSyncRequests: sending sync requests');
try {
await Promise.all([
singleProtoJobQueue.add(MessageSender.getRequestContactSyncMessage()),
singleProtoJobQueue.add(
MessageSender.getRequestConfigurationSyncMessage()
),
singleProtoJobQueue.add(MessageSender.getRequestBlockSyncMessage()),
]);
} catch (error: unknown) {
log.error(
'sendSyncRequests: failed to send sync requests',
toLogFormat(error)
);
throw error;
}
return { contactSyncComplete };
}