mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-02 00:07:56 +01:00
Remove a bunch more global variables
This commit is contained in:
@@ -18,6 +18,7 @@ global.window = {
|
||||
Date,
|
||||
performance,
|
||||
SignalContext: {
|
||||
getPath: () => '/tmp',
|
||||
getVersion: () => package.version,
|
||||
config: {
|
||||
serverUrl: 'https://127.0.0.1:9',
|
||||
|
||||
3
ts/CI.ts
3
ts/CI.ts
@@ -11,6 +11,7 @@ import { explodePromise } from './util/explodePromise.js';
|
||||
import { AccessType, ipcInvoke } from './sql/channels.js';
|
||||
import { backupsService } from './services/backups/index.js';
|
||||
import { notificationService } from './services/notifications.js';
|
||||
import { challengeHandler } from './services/challengeHandler.js';
|
||||
import { AttachmentBackupManager } from './jobs/AttachmentBackupManager.js';
|
||||
import { migrateAllMessages } from './messages/migrateMessageData.js';
|
||||
import { SECOND } from './util/durations/index.js';
|
||||
@@ -154,7 +155,7 @@ export function getCI({
|
||||
}
|
||||
|
||||
function solveChallenge(response: ChallengeResponseType): void {
|
||||
window.Signal.challengeHandler?.onResponse(response);
|
||||
challengeHandler.onResponse(response);
|
||||
}
|
||||
|
||||
async function getMessagesBySentAt(sentAt: number) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { ReadStatus } from '../messages/MessageReadStatus.js';
|
||||
import { SendStatus } from '../messages/MessageSendState.js';
|
||||
import { DataWriter } from '../sql/Client.js';
|
||||
import { BodyRange } from '../types/BodyRange.js';
|
||||
import { CURRENT_SCHEMA_VERSION } from '../types/Message2.js';
|
||||
import { strictAssert } from '../util/assert.js';
|
||||
import { MINUTE } from '../util/durations/index.js';
|
||||
import { isOlderThan } from '../util/timestamp.js';
|
||||
@@ -72,7 +73,7 @@ export async function populateConversationWithMessages({
|
||||
type: isIncoming ? 'incoming' : 'outgoing',
|
||||
timestamp,
|
||||
sent_at: timestamp,
|
||||
schemaVersion: window.Signal.Types.Message.CURRENT_SCHEMA_VERSION,
|
||||
schemaVersion: CURRENT_SCHEMA_VERSION,
|
||||
received_at: incrementMessageCounter(),
|
||||
readStatus: isUnread ? ReadStatus.Unread : ReadStatus.Read,
|
||||
sourceServiceId: isIncoming
|
||||
|
||||
@@ -61,7 +61,6 @@ import { QualifiedAddress } from './types/QualifiedAddress.js';
|
||||
import { createLogger } from './logging/log.js';
|
||||
import * as Errors from './types/errors.js';
|
||||
import { MINUTE } from './util/durations/index.js';
|
||||
import { conversationJobQueue } from './jobs/conversationJobQueue.js';
|
||||
import {
|
||||
KYBER_KEY_ID_KEY,
|
||||
SIGNED_PRE_KEY_ID_KEY,
|
||||
@@ -1846,8 +1845,7 @@ export class SignalProtocolStore extends EventEmitter {
|
||||
await this.archiveSession(qualifiedAddress);
|
||||
|
||||
// Enqueue a null message with newly-created session
|
||||
await conversationJobQueue.add({
|
||||
type: 'NullMessage',
|
||||
this.emit('nullMessage', {
|
||||
conversationId: conversation.id,
|
||||
idForTracking: id,
|
||||
});
|
||||
@@ -2811,6 +2809,14 @@ export class SignalProtocolStore extends EventEmitter {
|
||||
|
||||
public override on(name: 'removeAllData', handler: () => unknown): this;
|
||||
|
||||
public override on(
|
||||
name: 'nullMessage',
|
||||
handler: (options: {
|
||||
conversationId: string;
|
||||
idForTracking: string;
|
||||
}) => unknown
|
||||
): this;
|
||||
|
||||
public override on(
|
||||
eventName: string | symbol,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -2829,6 +2835,14 @@ export class SignalProtocolStore extends EventEmitter {
|
||||
|
||||
public override emit(name: 'removeAllData'): boolean;
|
||||
|
||||
public override emit(
|
||||
name: 'nullMessage',
|
||||
options: {
|
||||
conversationId: string;
|
||||
idForTracking: string;
|
||||
}
|
||||
): boolean;
|
||||
|
||||
public override emit(
|
||||
eventName: string | symbol,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
@@ -28,8 +28,6 @@ import type { MenuOptionsType } from './types/menu.js';
|
||||
import { SocketStatus } from './types/SocketStatus.js';
|
||||
import { DEFAULT_CONVERSATION_COLOR } from './types/Colors.js';
|
||||
import { ThemeType } from './types/Util.js';
|
||||
import { ToastType } from './types/Toast.js';
|
||||
import { ChallengeHandler } from './challenge.js';
|
||||
import * as durations from './util/durations/index.js';
|
||||
import { drop } from './util/drop.js';
|
||||
import { explodePromise } from './util/explodePromise.js';
|
||||
@@ -42,6 +40,7 @@ import { areRemoteBackupsTurnedOn } from './util/isBackupEnabled.js';
|
||||
import { lightSessionResetQueue } from './util/lightSessionResetQueue.js';
|
||||
import { setAppLoadingScreenMessage } from './setAppLoadingScreenMessage.js';
|
||||
import { IdleDetector } from './IdleDetector.js';
|
||||
import { challengeHandler } from './services/challengeHandler.js';
|
||||
import {
|
||||
initialize as initializeExpiringMessageService,
|
||||
update as updateExpiringMessagesService,
|
||||
@@ -85,6 +84,7 @@ import {
|
||||
shutdownAllJobQueues,
|
||||
} from './jobs/initializeAllJobQueues.js';
|
||||
import { removeStorageKeyJobQueue } from './jobs/removeStorageKeyJobQueue.js';
|
||||
import { conversationJobQueue } from './jobs/conversationJobQueue.js';
|
||||
import { ourProfileKeyService } from './services/ourProfileKey.js';
|
||||
import { notificationService } from './services/notifications.js';
|
||||
import { areWeASubscriberService } from './services/areWeASubscriber.js';
|
||||
@@ -146,7 +146,6 @@ import {
|
||||
registerCapabilities as doRegisterCapabilities,
|
||||
registerRequestHandler,
|
||||
reportMessage,
|
||||
sendChallengeResponse,
|
||||
unregisterRequestHandler,
|
||||
} from './textsecure/WebAPI.js';
|
||||
import AccountManager from './textsecure/AccountManager.js';
|
||||
@@ -204,7 +203,6 @@ import { startInteractionMode } from './services/InteractionMode.js';
|
||||
import { calling } from './services/calling.js';
|
||||
import { ReactionSource } from './reactions/ReactionSource.js';
|
||||
import { singleProtoJobQueue } from './jobs/singleProtoJobQueue.js';
|
||||
import { conversationJobQueue } from './jobs/conversationJobQueue.js';
|
||||
import { SeenStatus } from './MessageSeenStatus.js';
|
||||
import { MessageSender } from './textsecure/SendMessage.js';
|
||||
import { onStoryRecipientUpdate } from './util/onStoryRecipientUpdate.js';
|
||||
@@ -272,6 +270,7 @@ import { isLocalBackupsEnabled } from './util/isLocalBackupsEnabled.js';
|
||||
import { NavTab, SettingsPage, ProfileEditorPage } from './types/Nav.js';
|
||||
import { initialize as initializeDonationService } from './services/donations.js';
|
||||
import { MessageRequestResponseSource } from './types/MessageRequestResponseEvent.js';
|
||||
import { CURRENT_SCHEMA_VERSION, PRIVATE, GROUP } from './types/Message2.js';
|
||||
import { JobCancelReason } from './jobs/types.js';
|
||||
import { itemStorage } from './textsecure/Storage.js';
|
||||
|
||||
@@ -322,7 +321,6 @@ export async function startApp(): Promise<void> {
|
||||
|
||||
// Initialize WebAPI as early as possible
|
||||
let messageReceiver: MessageReceiver | undefined;
|
||||
let challengeHandler: ChallengeHandler | undefined;
|
||||
let routineProfileRefresher: RoutineProfileRefresher | undefined;
|
||||
|
||||
ourProfileKeyService.initialize(itemStorage);
|
||||
@@ -399,8 +397,6 @@ export async function startApp(): Promise<void> {
|
||||
// of preload.js processing
|
||||
window.setImmediate = window.nodeSetImmediate;
|
||||
|
||||
const { Message } = window.Signal.Types;
|
||||
|
||||
log.info('page reloaded');
|
||||
log.info('environment:', getEnvironment());
|
||||
|
||||
@@ -436,6 +432,16 @@ export async function startApp(): Promise<void> {
|
||||
window.reduxActions.stories.removeAllStories();
|
||||
});
|
||||
|
||||
signalProtocolStore.on('nullMessage', ({ conversationId, idForTracking }) => {
|
||||
drop(
|
||||
conversationJobQueue.add({
|
||||
type: 'NullMessage',
|
||||
conversationId,
|
||||
idForTracking,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
window.getSocketStatus = () => {
|
||||
return getSocketStatus();
|
||||
};
|
||||
@@ -559,54 +565,10 @@ export async function startApp(): Promise<void> {
|
||||
drop(onExpiration('build'));
|
||||
});
|
||||
|
||||
challengeHandler = new ChallengeHandler({
|
||||
storage: itemStorage,
|
||||
|
||||
startQueue(conversationId: string) {
|
||||
conversationJobQueue.resolveVerificationWaiter(conversationId);
|
||||
},
|
||||
|
||||
requestChallenge(request) {
|
||||
if (window.SignalCI) {
|
||||
window.SignalCI.handleEvent('challenge', request);
|
||||
return;
|
||||
}
|
||||
window.sendChallengeRequest(request);
|
||||
},
|
||||
|
||||
async sendChallengeResponse(data) {
|
||||
await sendChallengeResponse(data);
|
||||
},
|
||||
|
||||
onChallengeFailed() {
|
||||
// TODO: DESKTOP-1530
|
||||
// Display humanized `retryAfter`
|
||||
window.reduxActions.toast.showToast({
|
||||
toastType: ToastType.CaptchaFailed,
|
||||
});
|
||||
},
|
||||
|
||||
onChallengeSolved() {
|
||||
window.reduxActions.toast.showToast({
|
||||
toastType: ToastType.CaptchaSolved,
|
||||
});
|
||||
},
|
||||
|
||||
setChallengeStatus(challengeStatus) {
|
||||
window.reduxActions.network.setChallengeStatus(challengeStatus);
|
||||
},
|
||||
});
|
||||
|
||||
window.Whisper.events.on('challengeResponse', response => {
|
||||
if (!challengeHandler) {
|
||||
throw new Error('Expected challenge handler to be there');
|
||||
}
|
||||
|
||||
challengeHandler.onResponse(response);
|
||||
});
|
||||
|
||||
window.Signal.challengeHandler = challengeHandler;
|
||||
|
||||
log.info('Initializing MessageReceiver');
|
||||
messageReceiver = new MessageReceiver({
|
||||
storage: itemStorage,
|
||||
@@ -1074,7 +1036,7 @@ export async function startApp(): Promise<void> {
|
||||
let isMigrationWithIndexComplete = false;
|
||||
let isIdleTaskProcessing = false;
|
||||
log.info(
|
||||
`Starting background data migration. Target version: ${Message.CURRENT_SCHEMA_VERSION}`
|
||||
`Starting background data migration. Target version: ${CURRENT_SCHEMA_VERSION}`
|
||||
);
|
||||
idleDetector.on('idle', async () => {
|
||||
const NUM_MESSAGES_PER_BATCH = 250;
|
||||
@@ -1592,7 +1554,7 @@ export async function startApp(): Promise<void> {
|
||||
hasAppEverBeenRegistered,
|
||||
});
|
||||
|
||||
drop(challengeHandler?.onOffline());
|
||||
drop(challengeHandler.onOffline());
|
||||
drop(AttachmentDownloadManager.stop());
|
||||
drop(AttachmentBackupManager.stop());
|
||||
|
||||
@@ -1923,7 +1885,6 @@ export async function startApp(): Promise<void> {
|
||||
|
||||
drop(handleServerAlerts(getServerAlerts()));
|
||||
|
||||
strictAssert(challengeHandler, 'afterEveryAuthConnect: challengeHandler');
|
||||
drop(challengeHandler.onOnline());
|
||||
|
||||
reconnectBackOff.reset();
|
||||
@@ -2885,7 +2846,7 @@ export async function startApp(): Promise<void> {
|
||||
const groupV2 = window.ConversationController.get(id);
|
||||
if (groupV2) {
|
||||
return {
|
||||
type: Message.GROUP,
|
||||
type: GROUP,
|
||||
id: groupV2.id,
|
||||
};
|
||||
}
|
||||
@@ -2894,7 +2855,7 @@ export async function startApp(): Promise<void> {
|
||||
const groupV1 = window.ConversationController.getByDerivedGroupV2Id(id);
|
||||
if (groupV1) {
|
||||
return {
|
||||
type: Message.GROUP,
|
||||
type: GROUP,
|
||||
id: groupV1.id,
|
||||
};
|
||||
}
|
||||
@@ -2908,7 +2869,7 @@ export async function startApp(): Promise<void> {
|
||||
});
|
||||
|
||||
return {
|
||||
type: Message.GROUP,
|
||||
type: GROUP,
|
||||
id: conversationId,
|
||||
};
|
||||
}
|
||||
@@ -2924,7 +2885,7 @@ export async function startApp(): Promise<void> {
|
||||
);
|
||||
|
||||
return {
|
||||
type: Message.PRIVATE,
|
||||
type: PRIVATE,
|
||||
id: conversation.id,
|
||||
};
|
||||
};
|
||||
@@ -3204,7 +3165,7 @@ export async function startApp(): Promise<void> {
|
||||
messageDescriptor: MessageDescriptor
|
||||
): boolean {
|
||||
if (message.groupCallUpdate) {
|
||||
if (message.groupV2 && messageDescriptor.type === Message.GROUP) {
|
||||
if (message.groupV2 && messageDescriptor.type === GROUP) {
|
||||
const conversationId = messageDescriptor.id;
|
||||
const callId =
|
||||
message.groupCallUpdate?.eraId != null
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
getCheckedGroupCredentialsForToday,
|
||||
maybeFetchNewCredentials,
|
||||
} from './services/groupCredentialFetcher.js';
|
||||
import { storageServiceUploadJob } from './services/storage.js';
|
||||
import { DataReader, DataWriter } from './sql/Client.js';
|
||||
import { toWebSafeBase64, fromWebSafeBase64 } from './util/webSafeBase64.js';
|
||||
import { assertDev, strictAssert } from './util/assert.js';
|
||||
@@ -1854,9 +1853,7 @@ export async function createGroupV2(
|
||||
}
|
||||
);
|
||||
|
||||
await conversation.queueJob('storageServiceUploadJob', async () => {
|
||||
await storageServiceUploadJob({ reason: 'createGroupV2' });
|
||||
});
|
||||
conversation.captureChange('createGroupV2');
|
||||
|
||||
const timestamp = Date.now();
|
||||
const groupV2Info = conversation.getGroupV2Info({
|
||||
|
||||
@@ -54,6 +54,7 @@ import { isInPast } from '../util/timestamp.js';
|
||||
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary.js';
|
||||
import { FIBONACCI } from '../util/BackOff.js';
|
||||
import { parseUnknown } from '../util/schemas.js';
|
||||
import { challengeHandler } from '../services/challengeHandler.js';
|
||||
|
||||
const globalLogger = createLogger('conversationJobQueue');
|
||||
|
||||
@@ -418,11 +419,7 @@ export class ConversationJobQueue extends JobQueue<ConversationQueueJobData> {
|
||||
const { conversationId, type } = data;
|
||||
|
||||
if (shouldSendShowCaptcha(data.type)) {
|
||||
strictAssert(
|
||||
window.Signal.challengeHandler,
|
||||
'conversationJobQueue.add: Missing challengeHandler!'
|
||||
);
|
||||
window.Signal.challengeHandler.maybeSolve({
|
||||
challengeHandler.maybeSolve({
|
||||
conversationId,
|
||||
reason: `conversationJobQueue.add(${conversationId}, ${type})`,
|
||||
});
|
||||
@@ -747,7 +744,7 @@ export class ConversationJobQueue extends JobQueue<ConversationQueueJobData> {
|
||||
);
|
||||
|
||||
// We're starting to retry jobs; remove the challenge handler
|
||||
drop(window.Signal.challengeHandler?.unregister(conversationId, logId));
|
||||
drop(challengeHandler.unregister(conversationId, logId));
|
||||
|
||||
this.#perConversationData.set(conversationId, {
|
||||
status: RETRY_STATUS.RUNNING,
|
||||
@@ -824,7 +821,7 @@ export class ConversationJobQueue extends JobQueue<ConversationQueueJobData> {
|
||||
}
|
||||
|
||||
const isChallengeRegistered =
|
||||
window.Signal.challengeHandler?.isRegistered(conversationId);
|
||||
challengeHandler.isRegistered(conversationId);
|
||||
if (!isChallengeRegistered) {
|
||||
this.#unblockConversationRetries(conversationId);
|
||||
}
|
||||
@@ -834,7 +831,7 @@ export class ConversationJobQueue extends JobQueue<ConversationQueueJobData> {
|
||||
throw new Error("Shutting down, can't wait for captcha challenge.");
|
||||
}
|
||||
|
||||
window.Signal.challengeHandler?.maybeSolve({
|
||||
challengeHandler.maybeSolve({
|
||||
conversationId,
|
||||
reason:
|
||||
'conversationJobQueue.run/addWaiter(' +
|
||||
@@ -1013,7 +1010,7 @@ export class ConversationJobQueue extends JobQueue<ConversationQueueJobData> {
|
||||
const silent = !shouldSendShowCaptcha(type);
|
||||
|
||||
drop(
|
||||
window.Signal.challengeHandler?.register(
|
||||
challengeHandler.register(
|
||||
{
|
||||
conversationId,
|
||||
createdAt: Date.now(),
|
||||
|
||||
@@ -34,6 +34,7 @@ import type { RawBodyRange } from '../../types/BodyRange.js';
|
||||
import type { EmbeddedContactWithUploadedAvatar } from '../../types/EmbeddedContact.js';
|
||||
import type { StoryContextType } from '../../types/Util.js';
|
||||
import type { LoggerType } from '../../types/Logging.js';
|
||||
import { GROUP } from '../../types/Message2.js';
|
||||
import type {
|
||||
ConversationQueueJobBundle,
|
||||
NormalMessageSendJobData,
|
||||
@@ -82,8 +83,6 @@ export async function sendNormalMessage(
|
||||
}: ConversationQueueJobBundle,
|
||||
data: NormalMessageSendJobData
|
||||
): Promise<void> {
|
||||
const { Message } = window.Signal.Types;
|
||||
|
||||
const { messageId, revision, editedMessageTimestamp } = data;
|
||||
const message = await getMessageById(messageId);
|
||||
if (!message) {
|
||||
@@ -306,7 +305,7 @@ export async function sendNormalMessage(
|
||||
const sendOptions = await getSendOptions(conversation.attributes);
|
||||
|
||||
let innerPromise: Promise<CallbackResultType>;
|
||||
if (conversationType === Message.GROUP) {
|
||||
if (conversationType === GROUP) {
|
||||
// Note: this will happen for all old jobs queued beore 5.32.x
|
||||
if (isGroupV2(conversation.attributes) && !isNumber(revision)) {
|
||||
log.error('No revision provided, but conversation is GroupV2');
|
||||
|
||||
@@ -36,6 +36,7 @@ import { handleMessageSend } from '../../util/handleMessageSend.js';
|
||||
import { handleMultipleSendErrors } from './handleMultipleSendErrors.js';
|
||||
import { isGroupV2, isMe } from '../../util/whatTypeOfConversation.js';
|
||||
import { ourProfileKeyService } from '../../services/ourProfileKey.js';
|
||||
import { challengeHandler } from '../../services/challengeHandler.js';
|
||||
import { sendContentMessageToGroup } from '../../util/sendToGroup.js';
|
||||
import { distributionListToSendTarget } from '../../util/distributionListToSendTarget.js';
|
||||
import { uploadAttachment } from '../../util/uploadAttachment.js';
|
||||
@@ -446,7 +447,7 @@ export async function sendStory(
|
||||
// conversationJobQueue.
|
||||
errors.forEach(error => {
|
||||
if (error instanceof SendMessageChallengeError) {
|
||||
void window.Signal.challengeHandler?.register(
|
||||
void challengeHandler.register(
|
||||
{
|
||||
conversationId: conversation.id,
|
||||
createdAt: Date.now(),
|
||||
|
||||
@@ -9,6 +9,7 @@ import { SignalService } from '../protobuf/index.js';
|
||||
import { isGiftBadge, isTapToView } from '../state/selectors/message.js';
|
||||
import type { ProcessedQuote } from '../textsecure/Types.js';
|
||||
import { IMAGE_JPEG } from '../types/MIME.js';
|
||||
import { VERSION_NEEDED_FOR_DISPLAY } from '../types/Message2.js';
|
||||
import { strictAssert } from '../util/assert.js';
|
||||
import { getQuoteBodyText } from '../util/getQuoteBodyText.js';
|
||||
import { isQuoteAMatch } from './quotes.js';
|
||||
@@ -135,10 +136,7 @@ export const copyQuoteContentFromOriginal = async (
|
||||
}
|
||||
|
||||
try {
|
||||
await messageCache.upgradeSchema(
|
||||
message,
|
||||
window.Signal.Types.Message.VERSION_NEEDED_FOR_DISPLAY
|
||||
);
|
||||
await messageCache.upgradeSchema(message, VERSION_NEEDED_FOR_DISPLAY);
|
||||
} catch (error) {
|
||||
log.error(
|
||||
'Problem upgrading message quoted message from database',
|
||||
|
||||
@@ -108,6 +108,7 @@ import { isNotNil } from '../util/isNotNil.js';
|
||||
import { signalProtocolStore } from '../SignalProtocolStore.js';
|
||||
import { shouldSaveNotificationAvatarToDisk } from '../services/notifications.js';
|
||||
import { storageServiceUploadJob } from '../services/storage.js';
|
||||
import { challengeHandler } from '../services/challengeHandler.js';
|
||||
import { getSendOptions } from '../util/getSendOptions.js';
|
||||
import type { IsConversationAcceptedOptionsType } from '../util/isConversationAccepted.js';
|
||||
import { isConversationAccepted } from '../util/isConversationAccepted.js';
|
||||
@@ -1372,10 +1373,7 @@ export class ConversationModel {
|
||||
|
||||
// If captchas are active, then we should drop typing messages because
|
||||
// they're less important and could overwhelm the queue.
|
||||
if (
|
||||
window.Signal.challengeHandler?.areAnyRegistered() &&
|
||||
this.isSealedSenderDisabled()
|
||||
) {
|
||||
if (challengeHandler.areAnyRegistered() && this.isSealedSenderDisabled()) {
|
||||
log.info(
|
||||
`sendTypingMessage(${this.idForLogging()}): Challenge is registered and can't send sealed, ignoring`
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import type { MessageAttributesType } from '../model-types.d.ts';
|
||||
import type { CallbackResultType } from '../textsecure/Types.d.ts';
|
||||
import { initializeSchemaVersion } from '../types/Message2.js';
|
||||
import { createLogger } from '../logging/log.js';
|
||||
|
||||
const log = createLogger('messages');
|
||||
@@ -44,7 +45,7 @@ export class MessageModel {
|
||||
this.#_attributes = attributes;
|
||||
|
||||
this.set(
|
||||
window.Signal.Types.Message.initializeSchemaVersion({
|
||||
initializeSchemaVersion({
|
||||
message: attributes,
|
||||
logger: log,
|
||||
}),
|
||||
|
||||
@@ -21,6 +21,7 @@ import { createLogger } from '../../logging/log.js';
|
||||
import * as Bytes from '../../Bytes.js';
|
||||
import { strictAssert } from '../../util/assert.js';
|
||||
import { drop } from '../../util/drop.js';
|
||||
import { TEMP_PATH } from '../../util/basePaths.js';
|
||||
import { waitForAllBatchers } from '../../util/batcher.js';
|
||||
import { flushAllWaitBatchers } from '../../util/waitBatcher.js';
|
||||
import { DelimitedStream } from '../../util/DelimitedStream.js';
|
||||
@@ -307,7 +308,7 @@ export class BackupsService {
|
||||
await this.#waitForEmptyQueues('backups.upload');
|
||||
|
||||
const fileName = `backup-${randomBytes(32).toString('hex')}`;
|
||||
const filePath = join(window.BasePaths.temp, fileName);
|
||||
const filePath = join(TEMP_PATH, fileName);
|
||||
|
||||
const backupLevel = await this.credentials.getBackupLevel(
|
||||
BackupCredentialType.Media
|
||||
|
||||
46
ts/services/challengeHandler.ts
Normal file
46
ts/services/challengeHandler.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { ChallengeHandler } from '../challenge.js';
|
||||
import { itemStorage } from '../textsecure/Storage.js';
|
||||
import { sendChallengeResponse as doSendChallengeResponse } from '../textsecure/WebAPI.js';
|
||||
import { conversationJobQueue } from '../jobs/conversationJobQueue.js';
|
||||
import { ToastType } from '../types/Toast.js';
|
||||
|
||||
export const challengeHandler = new ChallengeHandler({
|
||||
storage: itemStorage,
|
||||
|
||||
startQueue(conversationId: string) {
|
||||
conversationJobQueue.resolveVerificationWaiter(conversationId);
|
||||
},
|
||||
|
||||
requestChallenge(request) {
|
||||
if (window.SignalCI) {
|
||||
window.SignalCI.handleEvent('challenge', request);
|
||||
return;
|
||||
}
|
||||
window.sendChallengeRequest(request);
|
||||
},
|
||||
|
||||
async sendChallengeResponse(data) {
|
||||
await doSendChallengeResponse(data);
|
||||
},
|
||||
|
||||
onChallengeFailed() {
|
||||
// TODO: DESKTOP-1530
|
||||
// Display humanized `retryAfter`
|
||||
window.reduxActions.toast.showToast({
|
||||
toastType: ToastType.CaptchaFailed,
|
||||
});
|
||||
},
|
||||
|
||||
onChallengeSolved() {
|
||||
window.reduxActions.toast.showToast({
|
||||
toastType: ToastType.CaptchaSolved,
|
||||
});
|
||||
},
|
||||
|
||||
setChallengeStatus(challengeStatus) {
|
||||
window.reduxActions.network.setChallengeStatus(challengeStatus);
|
||||
},
|
||||
});
|
||||
14
ts/signal.ts
14
ts/signal.ts
@@ -13,8 +13,6 @@ import { DataReader, DataWriter } from './sql/Client.js';
|
||||
import * as TypesAttachment from './util/Attachment.js';
|
||||
import * as VisualAttachment from './types/VisualAttachment.js';
|
||||
import * as MessageType from './types/Message2.js';
|
||||
import { Address } from './types/Address.js';
|
||||
import { QualifiedAddress } from './types/QualifiedAddress.js';
|
||||
|
||||
// Processes / Services
|
||||
import { calling } from './services/calling.js';
|
||||
@@ -453,23 +451,15 @@ export const setup = (options: {
|
||||
backups: backupsService,
|
||||
};
|
||||
|
||||
const Types = {
|
||||
Message: MessageType,
|
||||
|
||||
// Mostly for debugging
|
||||
Address,
|
||||
QualifiedAddress,
|
||||
};
|
||||
|
||||
return {
|
||||
Migrations,
|
||||
OS,
|
||||
Services,
|
||||
Types,
|
||||
|
||||
...(isProduction(window.getVersion())
|
||||
? {}
|
||||
: {
|
||||
Services,
|
||||
|
||||
DataReader,
|
||||
DataWriter,
|
||||
}),
|
||||
|
||||
@@ -282,14 +282,12 @@ type FinishInstallOptionsType = ReadonlyDeep<{
|
||||
isLinkAndSync: boolean;
|
||||
deviceName: string;
|
||||
envelope?: ProvisionEnvelopeType;
|
||||
backupFile?: Uint8Array;
|
||||
}>;
|
||||
|
||||
function finishInstall({
|
||||
isLinkAndSync,
|
||||
envelope: providedEnvelope,
|
||||
deviceName,
|
||||
backupFile,
|
||||
}: FinishInstallOptionsType): ThunkAction<
|
||||
void,
|
||||
RootStateType,
|
||||
@@ -336,7 +334,6 @@ function finishInstall({
|
||||
Provisioner.prepareLinkData({
|
||||
envelope,
|
||||
deviceName,
|
||||
backupFile,
|
||||
})
|
||||
);
|
||||
window.IPC.removeSetupMenuItems();
|
||||
|
||||
@@ -40,6 +40,11 @@ import { getEmptyState as usernameEmptyState } from './ducks/username.js';
|
||||
import OS from '../util/os/osMain.js';
|
||||
import { getInteractionMode } from '../services/InteractionMode.js';
|
||||
import { makeLookup } from '../util/makeLookup.js';
|
||||
import {
|
||||
ATTACHMENTS_PATH,
|
||||
STICKERS_PATH,
|
||||
TEMP_PATH,
|
||||
} from '../util/basePaths.js';
|
||||
import { toCurrentChatFolders } from '../types/ChatFolder.js';
|
||||
|
||||
import type { StateType } from './reducer.js';
|
||||
@@ -216,7 +221,7 @@ export function generateUserState({
|
||||
|
||||
return {
|
||||
...userEmptyState(),
|
||||
attachmentsPath: window.BasePaths.attachments,
|
||||
attachmentsPath: ATTACHMENTS_PATH,
|
||||
i18n: window.i18n,
|
||||
interactionMode: getInteractionMode(),
|
||||
isMainWindowFullScreen: mainWindowStats.isFullScreen,
|
||||
@@ -231,8 +236,8 @@ export function generateUserState({
|
||||
ourPni,
|
||||
platform: window.platform,
|
||||
regionCode: itemStorage.get('regionCode'),
|
||||
stickersPath: window.BasePaths.stickers,
|
||||
tempPath: window.BasePaths.temp,
|
||||
stickersPath: STICKERS_PATH,
|
||||
tempPath: TEMP_PATH,
|
||||
theme,
|
||||
version: window.getVersion(),
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@ import OS from '../../util/os/osMain.js';
|
||||
import { getConversation } from '../../util/getConversation.js';
|
||||
import { getChallengeURL } from '../../challenge.js';
|
||||
import { writeProfile } from '../../services/writeProfile.js';
|
||||
import { challengeHandler } from '../../services/challengeHandler.js';
|
||||
import { SmartCallManager } from './CallManager.js';
|
||||
import { SmartGlobalModalContainer } from './GlobalModalContainer.js';
|
||||
import { SmartLightbox } from './Lightbox.js';
|
||||
@@ -60,10 +61,7 @@ function renderStoryViewer(closeView: () => unknown): JSX.Element {
|
||||
async function getCaptchaToken(): Promise<string> {
|
||||
const url = getChallengeURL('registration');
|
||||
document.location.href = url;
|
||||
if (!window.Signal.challengeHandler) {
|
||||
throw new Error('Captcha handler is not ready!');
|
||||
}
|
||||
return window.Signal.challengeHandler.requestCaptcha({
|
||||
return challengeHandler.requestCaptcha({
|
||||
reason: 'standalone registration',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
AccountEntropyPool,
|
||||
BackupKey,
|
||||
} from '@signalapp/libsignal-client/dist/AccountKeys.js';
|
||||
import { Readable } from 'node:stream';
|
||||
|
||||
import EventTarget from './EventTarget.js';
|
||||
import {
|
||||
@@ -37,7 +36,6 @@ import * as Bytes from '../Bytes.js';
|
||||
import * as Errors from '../types/errors.js';
|
||||
import { isMockEnvironment } from '../environment.js';
|
||||
import { senderCertificateService } from '../services/senderCertificate.js';
|
||||
import { backupsService } from '../services/backups/index.js';
|
||||
import {
|
||||
decryptDeviceName,
|
||||
deriveAccessKey,
|
||||
@@ -150,9 +148,6 @@ type CreateAccountSharedOptionsType = Readonly<{
|
||||
profileKey: Uint8Array;
|
||||
masterKey: Uint8Array | undefined;
|
||||
accountEntropyPool: string | undefined;
|
||||
|
||||
// Test-only
|
||||
backupFile?: Uint8Array;
|
||||
}>;
|
||||
|
||||
type CreatePrimaryDeviceOptionsType = Readonly<{
|
||||
@@ -936,7 +931,6 @@ export default class AccountManager extends EventTarget {
|
||||
mediaRootBackupKey,
|
||||
readReceipts,
|
||||
userAgent,
|
||||
backupFile,
|
||||
accountEntropyPool,
|
||||
} = options;
|
||||
|
||||
@@ -974,7 +968,7 @@ export default class AccountManager extends EventTarget {
|
||||
!previousACI && previousNumber && previousNumber !== number;
|
||||
|
||||
let cleanStart = !previousACI && !previousPNI && !previousNumber;
|
||||
if (uuidChanged || numberChanged || backupFile !== undefined) {
|
||||
if (uuidChanged || numberChanged) {
|
||||
if (uuidChanged) {
|
||||
log.warn(
|
||||
'createAccount: New uuid is different from old uuid; deleting all previous data'
|
||||
@@ -985,12 +979,6 @@ export default class AccountManager extends EventTarget {
|
||||
'createAccount: New number is different from old number; deleting all previous data'
|
||||
);
|
||||
}
|
||||
if (backupFile !== undefined) {
|
||||
log.warn(
|
||||
'createAccount: Restoring from backup; ' +
|
||||
'deleting all previous data'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await signalProtocolStore.removeAllData();
|
||||
@@ -1289,10 +1277,6 @@ export default class AccountManager extends EventTarget {
|
||||
uploadKeys(ServiceIdKind.ACI),
|
||||
uploadKeys(ServiceIdKind.PNI),
|
||||
]);
|
||||
|
||||
if (backupFile !== undefined) {
|
||||
await backupsService.importBackup(() => Readable.from([backupFile]));
|
||||
}
|
||||
}
|
||||
|
||||
// Exposed only for testing
|
||||
|
||||
@@ -88,7 +88,6 @@ export type SubscriberType = Readonly<{
|
||||
export type PrepareLinkDataOptionsType = Readonly<{
|
||||
envelope: EnvelopeType;
|
||||
deviceName: string;
|
||||
backupFile?: Uint8Array;
|
||||
}>;
|
||||
|
||||
enum SocketState {
|
||||
@@ -143,7 +142,6 @@ export class Provisioner {
|
||||
public static prepareLinkData({
|
||||
envelope,
|
||||
deviceName,
|
||||
backupFile,
|
||||
}: PrepareLinkDataOptionsType): CreateLinkedDeviceOptionsType {
|
||||
const {
|
||||
number,
|
||||
@@ -185,7 +183,6 @@ export class Provisioner {
|
||||
0,
|
||||
MAX_DEVICE_NAME_LENGTH
|
||||
),
|
||||
backupFile,
|
||||
userAgent,
|
||||
ourAci,
|
||||
ourPni,
|
||||
|
||||
16
ts/util/basePaths.ts
Normal file
16
ts/util/basePaths.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import {
|
||||
getPath,
|
||||
getDraftPath,
|
||||
getStickersPath,
|
||||
getTempPath,
|
||||
} from '../../app/attachments.js';
|
||||
|
||||
const userDataPath = window.SignalContext.getPath('userData');
|
||||
|
||||
export const ATTACHMENTS_PATH = getPath(userDataPath);
|
||||
export const DRAFT_PATH = getDraftPath(userDataPath);
|
||||
export const STICKERS_PATH = getStickersPath(userDataPath);
|
||||
export const TEMP_PATH = getTempPath(userDataPath);
|
||||
36
ts/window.d.ts
vendored
36
ts/window.d.ts
vendored
@@ -10,10 +10,7 @@ import type PQueue from 'p-queue/dist.js';
|
||||
import type { assert } from 'chai';
|
||||
import type { MochaOptions } from 'mocha';
|
||||
|
||||
import type {
|
||||
ChallengeHandler,
|
||||
IPCRequest as IPCChallengeRequest,
|
||||
} from './challenge.js';
|
||||
import type { IPCRequest as IPCChallengeRequest } from './challenge.js';
|
||||
import type AccountManager from './textsecure/AccountManager.js';
|
||||
import type { OSType } from './util/os/shared.js';
|
||||
import type {
|
||||
@@ -28,12 +25,9 @@ import type { BatcherType } from './util/batcher.js';
|
||||
import type { ScreenShareStatus } from './types/Calling.js';
|
||||
import type { MessageCache } from './services/MessageCache.js';
|
||||
import type { StateType } from './state/reducer.js';
|
||||
import type { Address } from './types/Address.js';
|
||||
import type { QualifiedAddress } from './types/QualifiedAddress.js';
|
||||
import type { CIType } from './CI.js';
|
||||
import type { IPCEventsType } from './util/createIPCEvents.js';
|
||||
import type { SignalContextType } from './windows/context.js';
|
||||
import type * as Message2 from './types/Message2.js';
|
||||
import type { initializeMigrations } from './signal.js';
|
||||
import type { PropsPreloadType as PreferencesPropsType } from './components/Preferences.js';
|
||||
import type { WindowsNotificationData } from './services/notifications.js';
|
||||
@@ -132,24 +126,18 @@ export type SignalCoreType = {
|
||||
DebugLogWindowProps?: DebugLogWindowPropsType;
|
||||
PermissionsWindowProps?: PermissionsWindowPropsType;
|
||||
ScreenShareWindowProps?: ScreenShareWindowPropsType;
|
||||
// Only for development
|
||||
Services: {
|
||||
SettingsWindowProps?: SettingsWindowPropsType;
|
||||
|
||||
OS: OSType;
|
||||
Migrations: ReturnType<typeof initializeMigrations>;
|
||||
|
||||
// Only for debugging in Dev Tools
|
||||
Services?: {
|
||||
storage: unknown;
|
||||
backups: unknown;
|
||||
calling: unknown;
|
||||
donations: unknown;
|
||||
};
|
||||
SettingsWindowProps?: SettingsWindowPropsType;
|
||||
Migrations: ReturnType<typeof initializeMigrations>;
|
||||
Types: {
|
||||
Message: typeof Message2;
|
||||
Address: typeof Address;
|
||||
QualifiedAddress: typeof QualifiedAddress;
|
||||
};
|
||||
OS: OSType;
|
||||
challengeHandler?: ChallengeHandler;
|
||||
|
||||
// Only for debugging in Dev Tools
|
||||
DataReader?: unknown;
|
||||
DataWriter?: unknown;
|
||||
};
|
||||
@@ -212,14 +200,6 @@ declare global {
|
||||
// Feature Flags
|
||||
Flags: FeatureFlagType;
|
||||
|
||||
// Paths
|
||||
BasePaths: {
|
||||
attachments: string;
|
||||
draft: string;
|
||||
stickers: string;
|
||||
temp: string;
|
||||
};
|
||||
|
||||
// Test only
|
||||
SignalCI?: CIType;
|
||||
|
||||
|
||||
@@ -9,6 +9,11 @@ import { initialize as initializeLogging } from '../../logging/set_up_renderer_l
|
||||
import { setup } from '../../signal.js';
|
||||
import { addSensitivePath } from '../../util/privacy.js';
|
||||
import * as dns from '../../util/dns.js';
|
||||
import {
|
||||
ATTACHMENTS_PATH,
|
||||
STICKERS_PATH,
|
||||
DRAFT_PATH,
|
||||
} from '../../util/basePaths.js';
|
||||
import { createLogger } from '../../logging/log.js';
|
||||
import { SignalContext } from '../context.js';
|
||||
import * as Attachments from './attachments.js';
|
||||
@@ -36,15 +41,9 @@ moment.locale(
|
||||
localeOverride != null ? [localeOverride] : preferredSystemLocales
|
||||
);
|
||||
|
||||
const userDataPath = SignalContext.getPath('userData');
|
||||
window.BasePaths = {
|
||||
attachments: Attachments.getPath(userDataPath),
|
||||
draft: Attachments.getDraftPath(userDataPath),
|
||||
stickers: Attachments.getStickersPath(userDataPath),
|
||||
temp: Attachments.getTempPath(userDataPath),
|
||||
};
|
||||
|
||||
addSensitivePath(window.BasePaths.attachments);
|
||||
addSensitivePath(ATTACHMENTS_PATH);
|
||||
addSensitivePath(STICKERS_PATH);
|
||||
addSensitivePath(DRAFT_PATH);
|
||||
if (config.crashDumpsPath) {
|
||||
addSensitivePath(config.crashDumpsPath);
|
||||
}
|
||||
@@ -58,5 +57,5 @@ window.Signal = setup({
|
||||
Attachments,
|
||||
getRegionCode: () => itemStorage.get('regionCode'),
|
||||
logger: log,
|
||||
userDataPath,
|
||||
userDataPath: window.SignalContext.getPath('userData'),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user