Import log instead of using it off of window

This commit is contained in:
Josh Perez 2021-09-17 14:27:53 -04:00 committed by GitHub
parent 8eb0dd3116
commit 65ddf0a9e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
155 changed files with 3654 additions and 3433 deletions

View File

@ -291,18 +291,10 @@
type="text/javascript"
src="js/views/key_verification_view.js"
></script>
<script type="text/javascript" src="js/views/recorder_view.js"></script>
<script type="text/javascript" src="js/views/inbox_view.js"></script>
<script
type="text/javascript"
src="ts/shims/showConfirmationDialog.js"
></script>
<script type="text/javascript" src="js/views/install_view.js"></script>
<script type="text/javascript" src="js/views/phone-input-view.js"></script>
<script
type="text/javascript"
src="js/views/standalone_registration_view.js"
></script>
<script type="text/javascript" src="js/wall_clock_listener.js"></script>
<script

View File

@ -58,6 +58,5 @@
</script>
<script type="text/javascript" src="js/components.js"></script>
<script type="text/javascript" src="ts/backboneJquery.js"></script>
<script type="text/javascript" src="js/views/debug_log_view.js"></script>
<script type="text/javascript" src="js/debug_log_start.js"></script>
</html>

View File

@ -5,7 +5,6 @@
const { ipcRenderer } = require('electron');
const url = require('url');
const copyText = require('copy-text-to-clipboard');
// It is important to call this as early as possible
require('./ts/windows/context');
@ -25,7 +24,6 @@ setEnvironment(parseEnvironment(config.environment));
window.getVersion = () => config.version;
window.theme = config.theme;
window.i18n = i18n.setup(locale, localeMessages);
window.copyText = copyText;
// got.js appears to need this to successfully submit debug logs to the cloud
window.nodeSetImmediate = setImmediate;
@ -37,6 +35,7 @@ window.Backbone = require('backbone');
require('./ts/backbone/views/whisper_view');
require('./ts/backbone/views/toast_view');
require('./ts/logging/set_up_renderer_logging').initialize();
require('./ts/views/debug_log_view');
window.closeDebugLog = () => ipcRenderer.send('close-debug-log');
window.Backbone = require('backbone');

View File

@ -11,7 +11,7 @@
window.Whisper.Database.nolog = true;
Whisper.Database.handleDOMException = (prefix, error, reject) => {
window.log.error(
window.SignalWindow.log.error(
`${prefix}:`,
error && error.name,
error && error.message,

View File

@ -2,7 +2,6 @@
// SPDX-License-Identifier: AGPL-3.0-only
/* global $: false */
/* global Whisper: false */
$(document).on('keydown', e => {
if (e.keyCode === 27) {
@ -16,5 +15,5 @@ $body.addClass(`${window.theme}-theme`);
// got.js appears to need this to successfully submit debug logs to the cloud
window.setImmediate = window.nodeSetImmediate;
window.view = new Whisper.DebugLogView();
window.view = new window.Whisper.DebugLogView();
window.view.$el.appendTo($body);

View File

@ -13,11 +13,13 @@
async function destroyExpiredMessages() {
try {
window.log.info('destroyExpiredMessages: Loading messages...');
window.SignalWindow.log.info(
'destroyExpiredMessages: Loading messages...'
);
const messages = await window.Signal.Data.getExpiredMessages({
MessageCollection: Whisper.MessageCollection,
});
window.log.info(
window.SignalWindow.log.info(
`destroyExpiredMessages: found ${messages.length} messages to expire`
);
@ -38,7 +40,7 @@
await Promise.all(messageCleanup);
inMemoryMessages.forEach(message => {
window.log.info('Message expired', {
window.SignalWindow.log.info('Message expired', {
sentAt: message.get('sent_at'),
});
@ -50,23 +52,27 @@
}
});
} catch (error) {
window.log.error(
window.SignalWindow.log.error(
'destroyExpiredMessages: Error deleting expired messages',
error && error.stack ? error.stack : error
);
}
window.log.info('destroyExpiredMessages: complete');
window.SignalWindow.log.info('destroyExpiredMessages: complete');
checkExpiringMessages();
}
let timeout;
async function checkExpiringMessages() {
window.log.info('checkExpiringMessages: checking for expiring messages');
window.SignalWindow.log.info(
'checkExpiringMessages: checking for expiring messages'
);
const soonestExpiry = await window.Signal.Data.getSoonestMessageExpiry();
if (!soonestExpiry) {
window.log.info('checkExpiringMessages: found no messages to expire');
window.SignalWindow.log.info(
'checkExpiringMessages: found no messages to expire'
);
return;
}
@ -82,7 +88,7 @@
wait = 2147483647;
}
window.log.info(
window.SignalWindow.log.info(
`checkExpiringMessages: next message expires ${new Date(
soonestExpiry
).toISOString()}; waiting ${wait} ms before clearing`

View File

@ -13,7 +13,9 @@
async function eraseTapToViewMessages() {
try {
window.log.info('eraseTapToViewMessages: Loading messages...');
window.SignalWindow.log.info(
'eraseTapToViewMessages: Loading messages...'
);
const messages = await window.Signal.Data.getTapToViewMessagesNeedingErase(
{
MessageCollection: Whisper.MessageCollection,
@ -24,7 +26,7 @@
messages.map(async fromDB => {
const message = MessageController.register(fromDB.id, fromDB);
window.log.info(
window.SignalWindow.log.info(
'eraseTapToViewMessages: message data erased',
message.idForLogging()
);
@ -33,13 +35,13 @@
})
);
} catch (error) {
window.log.error(
window.SignalWindow.log.error(
'eraseTapToViewMessages: Error erasing messages',
error && error.stack ? error.stack : error
);
}
window.log.info('eraseTapToViewMessages: complete');
window.SignalWindow.log.info('eraseTapToViewMessages: complete');
}
let timeout;
@ -57,7 +59,7 @@
const nextCheck = receivedAt + THIRTY_DAYS;
Whisper.TapToViewMessagesListener.nextCheck = nextCheck;
window.log.info(
window.SignalWindow.log.info(
'checkTapToViewMessages: next check at',
new Date(nextCheck).toISOString()
);

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
/* eslint-env node */
/* global log, Signal */
/* global Signal, window */
const fs = require('fs-extra');
const path = require('path');
@ -58,7 +58,7 @@ exports.createConversation = async ({
await Promise.all(
range(0, numMessages).map(async index => {
await sleep(index * 100);
log.info(`Create message ${index + 1}`);
window.SignalWindow.log.info(`Create message ${index + 1}`);
const message = await createRandomMessage({ conversationId });
return Signal.Data.saveMessage(message);
})
@ -108,7 +108,10 @@ const createRandomMessage = async ({ conversationId } = {}) => {
};
const message = _createMessage({ commonProperties, conversationId, type });
return Message.initializeSchemaVersion({ message, logger: log });
return Message.initializeSchemaVersion({
message,
logger: window.SignalWindow.log,
});
};
const _createMessage = ({ commonProperties, conversationId, type } = {}) => {

View File

@ -3,9 +3,6 @@
/* eslint-env node, browser */
// eslint-disable-next-line no-console
const log = typeof window !== 'undefined' ? window.log : console;
exports.setup = (locale, messages) => {
if (!locale) {
throw new Error('i18n: locale parameter is required');
@ -15,6 +12,10 @@ exports.setup = (locale, messages) => {
}
function getMessage(key, substitutions) {
// eslint-disable-next-line no-console
const log =
typeof window !== 'undefined' ? window.SignalWindow.log : console;
const entry = messages[key];
if (!entry) {
log.error(

View File

@ -16,7 +16,7 @@ class IdleDetector extends EventEmitter {
}
start() {
window.log.info('Start idle detector');
window.SignalWindow.log.info('Start idle detector');
this._scheduleNextCallback();
}
@ -25,7 +25,7 @@ class IdleDetector extends EventEmitter {
return;
}
window.log.info('Stop idle detector');
window.SignalWindow.log.info('Stop idle detector');
this._clearScheduledCallbacks();
}

View File

@ -12,7 +12,9 @@ module.exports = {
};
async function doesDatabaseExist() {
window.log.info('Checking for the existence of IndexedDB data...');
window.SignalWindow.log.info(
'Checking for the existence of IndexedDB data...'
);
return new Promise((resolve, reject) => {
const { id } = Whisper.Database;
const req = window.indexedDB.open(id);
@ -20,7 +22,7 @@ async function doesDatabaseExist() {
let existed = true;
setTimeout(() => {
window.log.warn(
window.SignalWindow.log.warn(
'doesDatabaseExist: Timed out attempting to check IndexedDB status'
);
return resolve(false);
@ -41,6 +43,8 @@ async function doesDatabaseExist() {
}
function removeDatabase() {
window.log.info(`Deleting IndexedDB database '${Whisper.Database.id}'`);
window.SignalWindow.log.info(
`Deleting IndexedDB database '${Whisper.Database.id}'`
);
window.indexedDB.deleteDatabase(Whisper.Database.id);
}

View File

@ -45,7 +45,7 @@ exports.processNext = async ({
}
);
} catch (error) {
window.log.error(
window.SignalWindow.log.error(
'processNext error:',
error && error.stack ? error.stack : error
);

View File

@ -53,7 +53,7 @@ function buildAvatarUpdater({ field }) {
const { hash, path } = avatar;
const exists = await doesAttachmentExist(path);
if (!exists) {
window.log.warn(
window.SignalWindow.log.warn(
`Conversation.buildAvatarUpdater: attachment ${path} did not exist`
);
}

View File

@ -133,7 +133,7 @@
}
if (status.type !== 'ok') {
window.log.info(
window.SignalWindow.log.info(
`Not updating notifications; notification status is ${status.type}. ${
status.shouldClearNotifications ? 'Also clearing notifications' : ''
}`
@ -145,7 +145,7 @@
return;
}
window.log.info('Showing a notification');
window.SignalWindow.log.info('Showing a notification');
let notificationTitle;
let notificationMessage;
@ -191,7 +191,7 @@
}
} else {
if (userSetting !== SettingNames.NO_NAME_OR_MESSAGE) {
window.log.error(
window.SignalWindow.log.error(
`Error: Unknown user notification setting: '${userSetting}'`
);
}
@ -216,7 +216,7 @@
);
},
clear() {
window.log.info('Removing notification');
window.SignalWindow.log.info('Removing notification');
this.notificationData = null;
this.update();
},

View File

@ -66,7 +66,7 @@
a2 = args[1],
a3 = args[2];
const logError = function (error) {
window.log.error(
window.SignalWindow.log.error(
'Model caught error triggering',
name,
'event:',

View File

@ -21,13 +21,13 @@
}
async function run() {
window.log.info('Rotating signed prekey...');
window.SignalWindow.log.info('Rotating signed prekey...');
try {
await getAccountManager().rotateSignedPreKey();
scheduleNextRotation();
setTimeoutForNextRun();
} catch (error) {
window.log.error(
window.SignalWindow.log.error(
'rotateSignedPrekey() failed. Trying again in five minutes'
);
setTimeout(setTimeoutForNextRun, 5 * 60 * 1000);
@ -38,7 +38,7 @@
if (navigator.onLine) {
run();
} else {
window.log.info(
window.SignalWindow.log.info(
'We are offline; keys will be rotated when we are next online'
);
const listener = () => {
@ -53,7 +53,7 @@
const now = Date.now();
const time = storage.get('nextSignedKeyRotationTime', now);
window.log.info(
window.SignalWindow.log.info(
'Next signed key rotation scheduled for',
new Date(time).toISOString()
);
@ -71,7 +71,9 @@
Whisper.RotateSignedPreKeyListener = {
init(events, newVersion) {
if (initComplete) {
window.log.info('Rotate signed prekey listener: Already initialized');
window.SignalWindow.log.info(
'Rotate signed prekey listener: Already initialized'
);
return;
}
initComplete = true;

View File

@ -1,201 +0,0 @@
// Copyright 2015-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* global i18n, Whisper, $ */
// eslint-disable-next-line func-names
(function () {
window.Whisper = window.Whisper || {};
// This enum-like object describes the load state of `DebugLogView`. It's designed to be
// unidirectional; `NotStarted` → `Started` → `LogsFetchedButNotInTextarea`, etc.
const LoadState = {
NotStarted: 0,
Started: 1,
LogsFetchedButNotInTextarea: 2,
PuttingLogsInTextarea: 3,
LogsInTextarea: 4,
};
Whisper.LoadingFullLogsToast = Whisper.ToastView.extend({
render_attributes() {
return { toastMessage: i18n('loading') };
},
});
Whisper.LinkedCopiedToast = Whisper.ToastView.extend({
render_attributes() {
return { toastMessage: i18n('debugLogLinkCopied') };
},
});
Whisper.DebugLogLinkView = Whisper.View.extend({
template: () => $('#debug-log-link').html(),
initialize(options) {
this.url = options.url;
},
events: {
'click .copy': 'copy',
},
render_attributes() {
return {
url: this.url,
reportIssue: i18n('reportIssue'),
debugLogCopy: i18n('debugLogCopy'),
debugLogCopyAlt: i18n('debugLogCopyAlt'),
};
},
copy(e) {
e.preventDefault();
window.copyText(e.currentTarget.href);
Whisper.ToastView.show(Whisper.LinkedCopiedToast, document.body);
},
});
/**
* The bulk of the logic in this view involves grabbing the logs from disk and putting
* them in a `<textarea>`. The first part isn't instant but is reasonably fast; setting
* the textarea's `value` takes a long time.
*
* After loading the logs into memory, we only put a small number of lines into the
* textarea. If the user clicks or scrolls the textarea, we pull the full logs, which
* can cause the system to lock up for a bit.
*
* Ideally, we'd only show a sampling of the logs and allow the user to download and
* edit them in their own editor. This is mostly a stopgap solution.
*/
Whisper.DebugLogView = Whisper.View.extend({
template: () => $('#debug-log').html(),
className: 'debug-log modal',
initialize() {
this.render();
this.textarea = this.$('.textarea').get(0);
if (!this.textarea) {
throw new Error('textarea not found');
}
this.textarea.setAttribute('readonly', '');
this.loadState = LoadState.NotStarted;
this.putFullLogsInTextareaPlease = false;
this.fetchLogs();
},
events: {
'click .textarea': 'putFullLogsInTextarea',
'scroll .textarea': 'putFullLogsInTextarea',
'wheel .textarea': 'putFullLogsInTextarea',
'click .submit': 'submit',
'click .close': 'close',
},
render_attributes: {
title: i18n('submitDebugLog'),
cancel: i18n('cancel'),
submit: i18n('submit'),
close: i18n('gotIt'),
debugLogExplanation: i18n('debugLogExplanation'),
},
async fetchLogs() {
if (this.loadState !== LoadState.NotStarted) {
return;
}
this.loadState = LoadState.Started;
this.textarea.value = i18n('loading');
this.$('.submit').attr('disabled', 'disabled');
this.logText = await window.log.fetch();
this.loadState = LoadState.LogsFetchedButNotInTextarea;
// This number is somewhat arbitrary; we want to show enough that it's clear that
// we need to scroll, but not so many that things get slow.
const linesToShow = Math.ceil(Math.min(window.innerHeight, 2000) / 5);
this.textarea.value = this.logText
.split(/\n/g, linesToShow)
.concat(['', i18n('loading')])
.join('\n');
this.$('.submit').removeAttr('disabled');
if (this.putFullLogsInTextareaPlease) {
this.putFullLogsInTextarea();
}
},
putFullLogsInTextarea() {
switch (this.loadState) {
case LoadState.NotStarted:
case LoadState.Started:
this.putFullLogsInTextareaPlease = true;
break;
case LoadState.LogsInTextarea:
case LoadState.PuttingLogsInTextarea:
break;
case LoadState.LogsFetchedButNotInTextarea:
if (!this.logText) {
throw new Error('Expected log text to be present');
}
this.loadState = LoadState.PuttingLogsInTextarea;
Whisper.ToastView.show(Whisper.LoadingFullLogsToast, document.body);
setTimeout(() => {
this.textarea.value = this.logText;
this.textarea.removeAttribute('readonly');
this.loadState = LoadState.LogsInTextarea;
}, 0);
break;
default:
// When we can, we should make this throw a `missingCaseError`.
break;
}
},
close() {
window.closeDebugLog();
},
async submit(e) {
e.preventDefault();
let text;
switch (this.loadState) {
case LoadState.NotStarted:
case LoadState.Started:
return;
case LoadState.LogsFetchedButNotInTextarea:
text = this.logText;
break;
case LoadState.LogsInTextarea:
text = this.textarea.value;
break;
default:
// When we can, we should make this throw a `missingCaseError`.
return;
}
if (text.length === 0) {
return;
}
this.$('.buttons, .textarea').remove();
this.$('.result').addClass('loading');
try {
const publishedLogURL = await window.log.publish(
text,
window.getVersion()
);
const view = new Whisper.DebugLogLinkView({
url: publishedLogURL,
el: this.$('.result'),
});
this.$('.loading').removeClass('loading');
view.render();
this.$('.link').focus().select();
} catch (error) {
window.log.error(
'DebugLogView error:',
error && error.stack ? error.stack : error
);
this.$('.loading').removeClass('loading');
this.$('.result').text(i18n('debugLogError'));
}
},
});
})();

View File

@ -1,242 +0,0 @@
// Copyright 2014-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* global
ConversationController,
i18n,
Whisper,
Signal,
$
*/
// eslint-disable-next-line func-names
(function () {
window.Whisper = window.Whisper || {};
Whisper.StickerPackInstallFailedToast = Whisper.ToastView.extend({
render_attributes() {
return { toastMessage: i18n('stickers--toast--InstallFailed') };
},
});
Whisper.ConversationStack = Whisper.View.extend({
className: 'conversation-stack',
lastConversation: null,
open(conversation, messageId) {
const id = `conversation-${conversation.cid}`;
if (id !== this.el.lastChild.id) {
const view = new Whisper.ConversationView({
model: conversation,
});
this.listenTo(conversation, 'unload', () =>
this.onUnload(conversation)
);
view.$el.appendTo(this.el);
if (this.lastConversation && this.lastConversation !== conversation) {
this.lastConversation.trigger(
'unload',
'opened another conversation'
);
this.stopListening(this.lastConversation);
this.lastConversation = null;
}
this.lastConversation = conversation;
conversation.trigger('opened', messageId);
} else if (messageId) {
conversation.trigger('scroll-to-message', messageId);
}
// Make sure poppers are positioned properly
window.dispatchEvent(new Event('resize'));
},
unload() {
const { lastConversation } = this;
if (!lastConversation) {
return;
}
lastConversation.trigger('unload', 'force unload requested');
},
onUnload(conversation) {
if (this.lastConversation === conversation) {
this.stopListening(this.lastConversation);
this.lastConversation = null;
}
},
});
Whisper.AppLoadingScreen = Whisper.View.extend({
template: () => $('#app-loading-screen').html(),
className: 'app-loading-screen',
updateProgress(count) {
if (count > 0) {
const message = i18n('loadingMessages', [count.toString()]);
this.$('.message').text(message);
}
},
render_attributes: {
message: i18n('loading'),
},
});
Whisper.InboxView = Whisper.View.extend({
template: () => $('#two-column').html(),
className: 'inbox index',
initialize(options = {}) {
this.ready = false;
this.render();
this.conversation_stack = new Whisper.ConversationStack({
el: this.$('.conversation-stack'),
model: { window: options.window },
});
this.renderWhatsNew();
Whisper.events.on('refreshConversation', ({ oldId, newId }) => {
const convo = this.conversation_stack.lastConversation;
if (convo && convo.get('id') === oldId) {
this.conversation_stack.open(newId);
}
});
// Close current opened conversation to reload the group information once
// linked.
Whisper.events.on('setupAsNewDevice', () => {
this.conversation_stack.unload();
});
window.Whisper.events.on('showConversation', async (id, messageId) => {
const conversation = await ConversationController.getOrCreateAndWait(
id,
'private'
);
conversation.setMarkedUnread(false);
const { openConversationExternal } = window.reduxActions.conversations;
if (openConversationExternal) {
openConversationExternal(conversation.id, messageId);
}
this.conversation_stack.open(conversation, messageId);
this.focusConversation();
});
window.Whisper.events.on('loadingProgress', count => {
const view = this.appLoadingScreen;
if (view) {
view.updateProgress(count);
}
});
if (!options.initialLoadComplete) {
this.appLoadingScreen = new Whisper.AppLoadingScreen();
this.appLoadingScreen.render();
this.appLoadingScreen.$el.prependTo(this.el);
this.startConnectionListener();
} else {
this.setupLeftPane();
}
Whisper.events.on('pack-install-failed', () => {
const toast = new Whisper.StickerPackInstallFailedToast();
toast.$el.appendTo(this.$el);
toast.render();
});
},
render_attributes: {
welcomeToSignal: i18n('welcomeToSignal'),
// TODO DESKTOP-1451: add back the selectAContact message
selectAContact: '',
},
events: {
click: 'onClick',
},
renderWhatsNew() {
if (this.whatsNewView) {
return;
}
this.whatsNewView = new Whisper.ReactWrapperView({
Component: window.Signal.Components.WhatsNew,
props: {
i18n: window.i18n,
},
});
this.$('.whats-new-placeholder').append(this.whatsNewView.el);
},
setupLeftPane() {
if (this.leftPaneView) {
return;
}
this.leftPaneView = new Whisper.ReactWrapperView({
className: 'left-pane-wrapper',
JSX: Signal.State.Roots.createLeftPane(window.reduxStore),
});
this.$('.left-pane-placeholder').append(this.leftPaneView.el);
},
startConnectionListener() {
this.interval = setInterval(() => {
const status = window.getSocketStatus();
switch (status) {
case 'CONNECTING':
break;
case 'OPEN':
clearInterval(this.interval);
// if we've connected, we can wait for real empty event
this.interval = null;
break;
case 'CLOSING':
case 'CLOSED':
clearInterval(this.interval);
this.interval = null;
// if we failed to connect, we pretend we got an empty event
this.onEmpty();
break;
default:
window.log.warn(
`startConnectionListener: Found unexpected socket status ${status}; calling onEmpty() manually.`
);
this.onEmpty();
break;
}
}, 1000);
},
onEmpty() {
this.setupLeftPane();
const view = this.appLoadingScreen;
if (view) {
this.appLoadingScreen = null;
view.remove();
const searchInput = document.querySelector(
'.module-main-header__search__input'
);
if (searchInput && searchInput.focus) {
searchInput.focus();
}
}
},
focusConversation(e) {
if (e && this.$(e.target).closest('.placeholder').length) {
return;
}
this.$('#header, .gutter').addClass('inactive');
this.$('.conversation-stack').removeClass('inactive');
},
closeRecording(e) {
if (e && this.$(e.target).closest('.capture-audio').length > 0) {
return;
}
this.$('.conversation:first .recorder').trigger('close');
},
onClick(e) {
this.closeRecording(e);
},
});
})();

View File

@ -1,238 +0,0 @@
// Copyright 2015-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* global Whisper, i18n, getAccountManager, $, textsecure, QRCode */
/* eslint-disable more/no-then */
// eslint-disable-next-line func-names
(function () {
window.Whisper = window.Whisper || {};
const Steps = {
INSTALL_SIGNAL: 2,
SCAN_QR_CODE: 3,
ENTER_NAME: 4,
PROGRESS_BAR: 5,
TOO_MANY_DEVICES: 'TooManyDevices',
NETWORK_ERROR: 'NetworkError',
};
const DEVICE_NAME_SELECTOR = 'input.device-name';
const CONNECTION_ERROR = -1;
const TOO_MANY_DEVICES = 411;
const TOO_OLD = 409;
Whisper.InstallView = Whisper.View.extend({
template: () => $('#link-flow-template').html(),
className: 'main full-screen-flow',
events: {
'click .try-again': 'connect',
'click .second': 'shutdown',
// the actual next step happens in confirmNumber() on submit form #link-phone
},
initialize(options = {}) {
window.readyForUpdates();
this.selectStep(Steps.SCAN_QR_CODE);
this.connect();
this.on('disconnected', this.reconnect);
// Keep data around if it's a re-link, or the middle of a light import
this.shouldRetainData =
window.Signal.Util.Registration.everDone() || options.hasExistingData;
},
render_attributes() {
let errorMessage;
let errorButton = i18n('installTryAgain');
let errorSecondButton = null;
if (this.error) {
if (
this.error.name === 'HTTPError' &&
this.error.code === TOO_MANY_DEVICES
) {
errorMessage = i18n('installTooManyDevices');
} else if (
this.error.name === 'HTTPError' &&
this.error.code === TOO_OLD
) {
errorMessage = i18n('installTooOld');
errorButton = i18n('upgrade');
errorSecondButton = i18n('quit');
} else if (
this.error.name === 'HTTPError' &&
this.error.code === CONNECTION_ERROR
) {
errorMessage = i18n('installConnectionFailed');
} else if (this.error.message === 'websocket closed') {
// AccountManager.registerSecondDevice uses this specific
// 'websocket closed' error message
errorMessage = i18n('installConnectionFailed');
}
return {
isError: true,
errorHeader: i18n('installErrorHeader'),
errorMessage,
errorButton,
errorSecondButton,
};
}
return {
isStep3: this.step === Steps.SCAN_QR_CODE,
linkYourPhone: i18n('linkYourPhone'),
signalSettings: i18n('signalSettings'),
linkedDevices: i18n('linkedDevices'),
androidFinalStep: i18n('plusButton'),
appleFinalStep: i18n('linkNewDevice'),
isStep4: this.step === Steps.ENTER_NAME,
chooseName: i18n('chooseDeviceName'),
finishLinkingPhoneButton: i18n('finishLinkingPhone'),
isStep5: this.step === Steps.PROGRESS_BAR,
syncing: i18n('initialSync'),
};
},
selectStep(step) {
this.step = step;
this.render();
},
shutdown() {
window.shutdown();
},
connect() {
if (
this.error &&
this.error.name === 'HTTPError' &&
this.error.code === TOO_OLD
) {
window.location = 'https://signal.org/download';
return;
}
this.error = null;
this.selectStep(Steps.SCAN_QR_CODE);
this.clearQR();
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
const accountManager = getAccountManager();
accountManager
.registerSecondDevice(
this.setProvisioningUrl.bind(this),
this.confirmNumber.bind(this)
)
.catch(this.handleDisconnect.bind(this));
},
handleDisconnect(error) {
window.log.error(
'provisioning failed',
error && error.stack ? error.stack : error
);
this.error = error;
this.render();
if (error.message === 'websocket closed') {
this.trigger('disconnected');
} else if (
error.name !== 'HTTPError' ||
(error.code !== CONNECTION_ERROR && error.code !== TOO_MANY_DEVICES)
) {
throw error;
}
},
reconnect() {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
this.timeout = setTimeout(this.connect.bind(this), 10000);
},
clearQR() {
this.$('#qr img').remove();
this.$('#qr canvas').remove();
this.$('#qr .container').show();
this.$('#qr').removeClass('ready');
},
setProvisioningUrl(url) {
if ($('#qr').length === 0) {
window.log.error('Did not find #qr element in the DOM!');
return;
}
this.clearQR();
this.$('#qr .container').hide();
this.qr = new QRCode(this.$('#qr')[0]).makeCode(url);
this.$('#qr').removeAttr('title');
this.$('#qr').addClass('ready');
},
setDeviceNameDefault() {
const deviceName = textsecure.storage.user.getDeviceName();
this.$(DEVICE_NAME_SELECTOR).val(deviceName || window.getHostName());
this.$(DEVICE_NAME_SELECTOR).focus();
},
confirmNumber() {
const tsp = textsecure.storage.protocol;
window.removeSetupMenuItems();
this.selectStep(Steps.ENTER_NAME);
this.setDeviceNameDefault();
return new Promise(resolve => {
const onDeviceName = name => {
this.selectStep(Steps.PROGRESS_BAR);
const finish = () => {
window.Signal.Util.postLinkExperience.start();
return resolve(name);
};
// Delete all data from database unless we're in the middle
// of a re-link, or we are finishing a light import. Without this,
// app restarts at certain times can cause weird things to happen,
// like data from a previous incomplete light import showing up
// after a new install.
if (this.shouldRetainData) {
return finish();
}
return tsp.removeAllData().then(finish, error => {
window.log.error(
'confirmNumber: error clearing database',
error && error.stack ? error.stack : error
);
return finish();
});
};
if (window.CI) {
onDeviceName(window.CI.deviceName);
return;
}
// eslint-disable-next-line consistent-return
this.$('#link-phone').submit(e => {
e.stopPropagation();
e.preventDefault();
let name = this.$(DEVICE_NAME_SELECTOR).val();
name = name.replace(/\0/g, ''); // strip unicode null
if (name.trim().length === 0) {
this.$(DEVICE_NAME_SELECTOR).focus();
return null;
}
onDeviceName(name);
});
});
},
});
})();

View File

@ -1,40 +0,0 @@
// Copyright 2015-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* global libphonenumber, Whisper, $ */
// eslint-disable-next-line func-names
(function () {
window.Whisper = window.Whisper || {};
Whisper.PhoneInputView = Whisper.View.extend({
tagName: 'div',
className: 'phone-input',
template: () => $('#phone-number').html(),
initialize() {
this.$('input.number').intlTelInput();
},
events: {
change: 'validateNumber',
keydown: 'validateNumber',
},
validateNumber() {
const input = this.$('input.number');
const regionCode = this.$('li.active')
.attr('data-country-code')
.toUpperCase();
const number = input.val();
const parsedNumber = libphonenumber.util.parseNumber(number, regionCode);
if (parsedNumber.isValidNumber) {
this.$('.number-container').removeClass('invalid');
this.$('.number-container').addClass('valid');
} else {
this.$('.number-container').removeClass('valid');
}
input.trigger('validation');
return parsedNumber.e164;
},
});
})();

View File

@ -49,7 +49,7 @@
try {
cb();
} catch (error) {
window.log.error(
window.SignalWindow.log.error(
'ReactWrapperView.update error:',
error && error.stack ? error.stack : error
);

View File

@ -1,149 +0,0 @@
// Copyright 2016-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* global $, Whisper, moment, WebAudioRecorder */
/* eslint-disable more/no-then */
// eslint-disable-next-line func-names
(function () {
window.Whisper = window.Whisper || {};
Whisper.RecorderView = Whisper.View.extend({
className: 'recorder clearfix',
template: () => $('#recorder').html(),
initialize() {
this.startTime = Date.now();
this.interval = setInterval(this.updateTime.bind(this), 1000);
this.onSwitchAwayBound = this.onSwitchAway.bind(this);
$(window).on('blur', this.onSwitchAwayBound);
this.handleKeyDownBound = this.handleKeyDown.bind(this);
this.$el.on('keydown', this.handleKeyDownBound);
this.start();
},
events: {
'click .close': 'remove',
'click .finish': 'finish',
close: 'remove',
},
onSwitchAway() {
this.lostFocus = true;
this.recorder.finishRecording();
},
handleKeyDown(event) {
if (event.key === 'Escape') {
this.remove();
event.preventDefault();
event.stopPropagation();
}
},
updateTime() {
const duration = moment.duration(Date.now() - this.startTime, 'ms');
const minutes = `${Math.trunc(duration.asMinutes())}`;
let seconds = `${duration.seconds()}`;
if (seconds.length < 2) {
seconds = `0${seconds}`;
}
this.$('.time').text(`${minutes}:${seconds}`);
},
remove() {
// Note: the 'close' event can be triggered by InboxView, when the user clicks
// anywhere outside the recording pane.
if (this.recorder.isRecording()) {
this.recorder.cancelRecording();
}
// Reach in and terminate the web worker used by WebAudioRecorder, otherwise
// it gets leaked due to a reference cycle with its onmessage listener
this.recorder.worker.terminate();
this.recorder = null;
if (this.interval) {
clearInterval(this.interval);
}
this.interval = null;
if (this.source) {
this.source.disconnect();
}
this.source = null;
if (this.context) {
this.context.close().then(() => {
window.log.info('audio context closed');
});
}
this.context = null;
Whisper.View.prototype.remove.call(this);
this.trigger('closed');
$(window).off('blur', this.onSwitchAwayBound);
this.$el.off('keydown', this.handleKeyDownBound);
},
finish() {
this.clickedFinish = true;
this.recorder.finishRecording();
},
handleBlob(recorder, blob) {
if (blob && this.clickedFinish) {
this.trigger('send', blob);
} else if (blob) {
this.trigger('confirm', blob, this.lostFocus);
}
this.remove();
},
start() {
this.lostFocus = false;
this.clickedFinish = false;
this.context = new AudioContext();
this.input = this.context.createGain();
this.recorder = new WebAudioRecorder(this.input, {
encoding: 'mp3',
workerDir: 'js/', // must end with slash
});
this.recorder.onComplete = this.handleBlob.bind(this);
this.recorder.onError = this.onError.bind(this);
this.recorder.onTimeout = this.onTimeout.bind(this);
navigator.webkitGetUserMedia(
{ audio: true },
stream => {
this.source = this.context.createMediaStreamSource(stream);
this.source.connect(this.input);
},
this.onError.bind(this)
);
this.recorder.startRecording();
},
onTimeout() {
this.recorder.finishRecording();
},
onError(error) {
// Protect against out-of-band errors, which can happen if the user revokes media
// permissions after successfully accessing the microphone.
if (!this.recorder) {
return;
}
this.remove();
if (error && error.name === 'NotAllowedError') {
window.log.warn(
'RecorderView.onError: Microphone access is not allowed!'
);
window.showPermissionsPopup();
} else {
window.log.error(
'RecorderView.onError:',
error && error.stack ? error.stack : error
);
}
},
});
})();

View File

@ -1,106 +0,0 @@
// Copyright 2017-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/* global Whisper, $, getAccountManager, textsecure */
/* eslint-disable more/no-then */
// eslint-disable-next-line func-names
(function () {
window.Whisper = window.Whisper || {};
Whisper.StandaloneRegistrationView = Whisper.View.extend({
template: () => $('#standalone').html(),
className: 'full-screen-flow',
initialize() {
window.readyForUpdates();
this.accountManager = getAccountManager();
this.render();
const number = textsecure.storage.user.getNumber();
if (number) {
this.$('input.number').val(number);
}
this.phoneView = new Whisper.PhoneInputView({
el: this.$('#phone-number-input'),
});
this.$('#error').hide();
},
events: {
'validation input.number': 'onValidation',
'click #request-voice': 'requestVoice',
'click #request-sms': 'requestSMSVerification',
'change #code': 'onChangeCode',
'click #verifyCode': 'verifyCode',
},
verifyCode() {
const number = this.phoneView.validateNumber();
const verificationCode = $('#code').val().replace(/\D+/g, '');
this.accountManager
.registerSingleDevice(number, verificationCode)
.then(() => {
this.$el.trigger('openInbox');
})
.catch(this.log.bind(this));
},
log(s) {
window.log.info(s);
this.$('#status').text(s);
},
validateCode() {
const verificationCode = $('#code').val().replace(/\D/g, '');
if (verificationCode.length === 6) {
return verificationCode;
}
return null;
},
displayError(error) {
this.$('#error').hide().text(error).addClass('in').fadeIn();
},
onValidation() {
if (this.$('#number-container').hasClass('valid')) {
this.$('#request-sms, #request-voice').removeAttr('disabled');
} else {
this.$('#request-sms, #request-voice').prop('disabled', 'disabled');
}
},
onChangeCode() {
if (!this.validateCode()) {
this.$('#code').addClass('invalid');
} else {
this.$('#code').removeClass('invalid');
}
},
requestVoice() {
window.removeSetupMenuItems();
this.$('#error').hide();
const number = this.phoneView.validateNumber();
if (number) {
this.accountManager
.requestVoiceVerification(number)
.catch(this.displayError.bind(this));
this.$('#step2').addClass('in').fadeIn();
} else {
this.$('#number-container').addClass('invalid');
}
},
requestSMSVerification() {
window.removeSetupMenuItems();
$('#error').hide();
const number = this.phoneView.validateNumber();
if (number) {
this.accountManager
.requestSMSVerification(number)
.catch(this.displayError.bind(this));
this.$('#step2').addClass('in').fadeIn();
} else {
this.$('#number-container').addClass('invalid');
}
},
});
})();

View File

@ -67,12 +67,12 @@ window.Whisper.events = {
before(async () => {
try {
window.log.info('Initializing SQL in renderer');
window.SignalWindow.log.info('Initializing SQL in renderer');
const isTesting = true;
await window.sqlInitializer.initialize(isTesting);
window.log.info('SQL initialized in renderer');
window.SignalWindow.log.info('SQL initialized in renderer');
} catch (err) {
window.log.error(
window.SignalWindow.log.error(
'SQL failed to initialize',
err && err.stack ? err.stack : err
);

View File

@ -854,9 +854,6 @@ function showScreenShareWindow(sourceName) {
'render-screen-sharing-controller',
sourceName
);
if (config.get('openDevTools')) {
screenShareWindow.webContents.openDevTools();
}
});
}
@ -897,9 +894,6 @@ function showAbout() {
aboutWindow.once('ready-to-show', () => {
aboutWindow.show();
if (config.get('openDevTools')) {
aboutWindow.webContents.openDevTools();
}
});
}

View File

@ -35,6 +35,8 @@ try {
setEnvironment(parseEnvironment(config.environment));
const log = require('./ts/logging/log');
let title = config.name;
if (getEnvironment() !== Environment.Production) {
title += ` - ${getEnvironment()}`;
@ -89,7 +91,7 @@ try {
try {
return semver.lt(toCheck, baseVersion);
} catch (error) {
window.log.error(
log.error(
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
error && error.stack ? error.stack : error
);
@ -100,7 +102,7 @@ try {
try {
return semver.gt(toCheck, baseVersion);
} catch (error) {
window.log.error(
log.error(
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
error && error.stack ? error.stack : error
);
@ -133,11 +135,11 @@ try {
window.eval = global.eval = () => null;
window.drawAttention = () => {
window.log.info('draw attention');
log.info('draw attention');
ipc.send('draw-attention');
};
window.showWindow = () => {
window.log.info('show window');
log.info('show window');
ipc.send('show-window');
};
@ -158,15 +160,15 @@ try {
};
window.restart = () => {
window.log.info('restart');
log.info('restart');
ipc.send('restart');
};
window.shutdown = () => {
window.log.info('shutdown');
log.info('shutdown');
ipc.send('shutdown');
};
window.showDebugLog = () => {
window.log.info('showDebugLog');
log.info('showDebugLog');
ipc.send('show-debug-log');
};
@ -286,7 +288,7 @@ try {
try {
await deleteAllData();
} catch (error) {
window.log.error('delete-all-data: error', error && error.stack);
log.error('delete-all-data: error', error && error.stack);
}
});
@ -334,7 +336,7 @@ try {
ipc.on('get-ready-for-shutdown', async () => {
const { shutdown } = window.Events || {};
if (!shutdown) {
window.log.error('preload shutdown handler: shutdown method not found');
log.error('preload shutdown handler: shutdown method not found');
ipc.send('now-ready-for-shutdown');
return;
}
@ -358,7 +360,7 @@ try {
require('./ts/logging/set_up_renderer_logging').initialize();
if (config.proxyUrl) {
window.log.info('Using provided proxy url');
log.info('Using provided proxy url');
}
window.nodeSetImmediate = setImmediate;
@ -448,7 +450,7 @@ try {
Attachments,
userDataPath,
getRegionCode: () => window.storage.get('regionCode'),
logger: window.log,
logger: log,
});
if (config.enableCI) {
@ -464,6 +466,10 @@ try {
require('./ts/backbone/views/whisper_view');
require('./ts/backbone/views/toast_view');
require('./ts/views/conversation_view');
require('./ts/views/inbox_view');
require('./ts/views/install_view');
require('./ts/views/recorder_view');
require('./ts/views/standalone_registration_view');
require('./ts/SignalProtocolStore');
require('./ts/background');
@ -486,6 +492,7 @@ try {
if (config.environment === 'test') {
require('./preload_test');
}
log.info('preload complete');
} catch (error) {
/* eslint-disable no-console */
if (console._log) {
@ -499,4 +506,3 @@ try {
}
preloadEndTime = Date.now();
window.log.info('preload complete');

View File

@ -42,7 +42,7 @@ export const UploadStage: React.ComponentType = () => {
actions.setPackMeta(packMeta);
history.push('/share');
} catch (e) {
window.log.error('Error uploading image:', e);
window.SignalWindow.log.error('Error uploading image:', e);
actions.addToast({
key: 'StickerCreator--Toasts--errorUploading',
subs: [e.message],

View File

@ -58,7 +58,7 @@ const InnerGrid = SortableContainer(
const stickerImage = await processStickerImage(path);
actions.addImageData(stickerImage);
} catch (e) {
window.log.error('Error processing image:', e);
window.SignalWindow.log.error('Error processing image:', e);
actions.removeSticker(path);
actions.addToast({
key:

View File

@ -48,7 +48,7 @@ require('../ts/logging/set_up_renderer_logging').initialize();
require('../ts/SignalProtocolStore');
window.log.info('sticker-creator starting up...');
window.SignalWindow.log.info('sticker-creator starting up...');
const Signal = require('../js/modules/signal');
@ -296,4 +296,4 @@ window.addEventListener('DOMContentLoaded', applyTheme);
window.SignalContext.nativeThemeListener.subscribe(() => applyTheme());
window.log.info('sticker-creator preload complete...');
window.SignalWindow.log.info('sticker-creator preload complete...');

View File

@ -78,12 +78,12 @@ before(async () => {
await deleteIndexedDB();
try {
window.log.info('Initializing SQL in renderer');
window.SignalWindow.log.info('Initializing SQL in renderer');
const isTesting = true;
await window.sqlInitializer.initialize(isTesting);
window.log.info('SQL initialized in renderer');
window.SignalWindow.log.info('SQL initialized in renderer');
} catch (err) {
window.log.error(
window.SignalWindow.log.error(
'SQL failed to initialize',
err && err.stack ? err.stack : err
);

View File

@ -19,10 +19,12 @@ const storageMap = new Map();
// To replicate logic we have on the client side
global.window = {
SignalContext: undefined,
log: {
info: (...args) => console.log(...args),
warn: (...args) => console.warn(...args),
error: (...args) => console.error(...args),
SignalWindow: {
log: {
info: (...args) => console.log(...args),
warn: (...args) => console.warn(...args),
error: (...args) => console.error(...args),
},
},
i18n: key => `i18n(${key})`,
storage: {

View File

@ -4,6 +4,7 @@
import { ipcRenderer } from 'electron';
import { explodePromise } from './util/explodePromise';
import * as log from './logging/log';
type ResolveType = (data: unknown) => void;
@ -24,7 +25,7 @@ export class CI {
const pendingCompleted = this.completedEvents.get(event) || [];
const pending = pendingCompleted.shift();
if (pending) {
window.log.info(`CI: resolving pending result for ${event}`, pending);
log.info(`CI: resolving pending result for ${event}`, pending);
if (pendingCompleted.length === 0) {
this.completedEvents.delete(event);
@ -33,7 +34,7 @@ export class CI {
return pending;
}
window.log.info(`CI: waiting for event ${event}`);
log.info(`CI: waiting for event ${event}`);
const { resolve, promise } = explodePromise();
let list = this.eventListeners.get(event);
@ -60,12 +61,12 @@ export class CI {
this.eventListeners.delete(event);
}
window.log.info(`CI: got event ${event} with data`, data);
log.info(`CI: got event ${event} with data`, data);
resolve(data);
return;
}
window.log.info(`CI: postponing event ${event}`);
log.info(`CI: postponing event ${event}`);
let resultList = this.completedEvents.get(event);
if (!resultList) {

View File

@ -19,6 +19,7 @@ import { isGroupV1, isGroupV2 } from './util/whatTypeOfConversation';
import { UUID } from './types/UUID';
import { Address } from './types/Address';
import { QualifiedAddress } from './types/QualifiedAddress';
import * as log from './logging/log';
const MAX_MESSAGE_BODY_LENGTH = 64 * 1024;
@ -233,7 +234,7 @@ export class ConversationController {
const create = async () => {
if (!conversation.isValid()) {
const validationError = conversation.validationError || {};
window.log.error(
log.error(
'Contact is not valid. Not saving, but adding to collection:',
conversation.idForLogging(),
validationError.stack
@ -248,7 +249,7 @@ export class ConversationController {
}
await saveConversation(conversation.attributes);
} catch (error) {
window.log.error(
log.error(
'Conversation save failed! ',
identifier,
type,
@ -368,9 +369,7 @@ export class ConversationController {
// 1. Handle no match at all
if (!convoE164 && !convoUuid) {
window.log.info(
'ensureContactIds: Creating new contact, no matches found'
);
log.info('ensureContactIds: Creating new contact, no matches found');
const newConvo = this.getOrCreate(identifier, 'private');
if (highTrust && e164) {
newConvo.updateE164(e164);
@ -388,7 +387,7 @@ export class ConversationController {
}
if (convoE164 && !convoUuid) {
const haveUuid = Boolean(normalizedUuid);
window.log.info(
log.info(
`ensureContactIds: e164-only match found (have UUID: ${haveUuid})`
);
// If we are only searching based on e164 anyway, then return the first result
@ -399,23 +398,21 @@ export class ConversationController {
// Fill in the UUID for an e164-only contact
if (normalizedUuid && !convoE164.get('uuid')) {
if (highTrust) {
window.log.info('ensureContactIds: Adding UUID to e164-only match');
log.info('ensureContactIds: Adding UUID to e164-only match');
convoE164.updateUuid(normalizedUuid);
updateConversation(convoE164.attributes);
}
return convoE164.get('id');
}
window.log.info(
log.info(
'ensureContactIds: e164 already had UUID, creating a new contact'
);
// If existing e164 match already has UUID, create a new contact...
const newConvo = this.getOrCreate(normalizedUuid, 'private');
if (highTrust) {
window.log.info(
'ensureContactIds: Moving e164 from old contact to new'
);
log.info('ensureContactIds: Moving e164 from old contact to new');
// Remove the e164 from the old contact...
convoE164.set({ e164: undefined });
@ -432,7 +429,7 @@ export class ConversationController {
}
if (!convoE164 && convoUuid) {
if (e164 && highTrust) {
window.log.info('ensureContactIds: Adding e164 to UUID-only match');
log.info('ensureContactIds: Adding e164 to UUID-only match');
convoUuid.updateE164(e164);
updateConversation(convoUuid.attributes);
}
@ -454,7 +451,7 @@ export class ConversationController {
if (highTrust) {
// Conflict: If e164 match already has a UUID, we remove its e164.
if (convoE164.get('uuid') && convoE164.get('uuid') !== normalizedUuid) {
window.log.info(
log.info(
'ensureContactIds: e164 match had different UUID than incoming pair, removing its e164.'
);
@ -469,7 +466,7 @@ export class ConversationController {
return convoUuid.get('id');
}
window.log.warn(
log.warn(
`ensureContactIds: Found a split contact - UUID ${normalizedUuid} and E164 ${e164}. Merging.`
);
@ -488,9 +485,7 @@ export class ConversationController {
})
.catch(error => {
const errorText = error && error.stack ? error.stack : error;
window.log.warn(
`ensureContactIds error combining contacts: ${errorText}`
);
log.warn(`ensureContactIds error combining contacts: ${errorText}`);
});
}
@ -498,7 +493,7 @@ export class ConversationController {
}
async checkForConflicts(): Promise<void> {
window.log.info('checkForConflicts: starting...');
log.info('checkForConflicts: starting...');
const byUuid = Object.create(null);
const byE164 = Object.create(null);
const byGroupV2Id = Object.create(null);
@ -524,9 +519,7 @@ export class ConversationController {
if (!existing) {
byUuid[uuid] = conversation;
} else {
window.log.warn(
`checkForConflicts: Found conflict with uuid ${uuid}`
);
log.warn(`checkForConflicts: Found conflict with uuid ${uuid}`);
// Keep the newer one if it has an e164, otherwise keep existing
if (conversation.get('e164')) {
@ -554,7 +547,7 @@ export class ConversationController {
existing.get('uuid') &&
conversation.get('uuid') !== existing.get('uuid')
) {
window.log.warn(
log.warn(
`checkForConflicts: Found two matches on e164 ${e164} with different truthy UUIDs. Dropping e164 on older.`
);
@ -566,9 +559,7 @@ export class ConversationController {
continue;
}
window.log.warn(
`checkForConflicts: Found conflict with e164 ${e164}`
);
log.warn(`checkForConflicts: Found conflict with e164 ${e164}`);
// Keep the newer one if it has a UUID, otherwise keep existing
if (conversation.get('uuid')) {
@ -605,7 +596,7 @@ export class ConversationController {
const logParenthetical = isGroupV1(conversation.attributes)
? ' (derived from a GV1 group ID)'
: '';
window.log.warn(
log.warn(
`checkForConflicts: Found conflict with group V2 ID ${groupV2Id}${logParenthetical}`
);
@ -625,7 +616,7 @@ export class ConversationController {
}
}
window.log.info('checkForConflicts: complete!');
log.info('checkForConflicts: complete!');
}
async combineConversations(
@ -645,14 +636,14 @@ export class ConversationController {
const obsoleteId = obsolete.get('id');
const obsoleteUuid = obsolete.get('uuid');
const currentId = current.get('id');
window.log.warn('combineConversations: Combining two conversations', {
log.warn('combineConversations: Combining two conversations', {
obsolete: obsoleteId,
current: currentId,
});
if (conversationType === 'private' && obsoleteUuid) {
if (!current.get('profileKey') && obsolete.get('profileKey')) {
window.log.warn(
log.warn(
'combineConversations: Copying profile key from old to new contact'
);
@ -663,7 +654,7 @@ export class ConversationController {
}
}
window.log.warn(
log.warn(
'combineConversations: Delete all sessions tied to old conversationId'
);
const ourUuid = window.textsecure.storage.user.getCheckedUuid();
@ -681,7 +672,7 @@ export class ConversationController {
})
);
window.log.warn(
log.warn(
'combineConversations: Delete all identity information tied to old conversationId'
);
@ -691,7 +682,7 @@ export class ConversationController {
);
}
window.log.warn(
log.warn(
'combineConversations: Ensure that all V1 groups have new conversationId instead of old'
);
const groups = await this.getAllGroupsInvolvingId(obsoleteId);
@ -709,23 +700,23 @@ export class ConversationController {
// Note: we explicitly don't want to update V2 groups
window.log.warn(
log.warn(
'combineConversations: Delete the obsolete conversation from the database'
);
await removeConversation(obsoleteId, {
Conversation: window.Whisper.Conversation,
});
window.log.warn('combineConversations: Update messages table');
log.warn('combineConversations: Update messages table');
await migrateConversationMessages(obsoleteId, currentId);
window.log.warn(
log.warn(
'combineConversations: Eliminate old conversation from ConversationController lookups'
);
this._conversations.remove(obsolete);
this._conversations.resetLookups();
window.log.warn('combineConversations: Complete!', {
log.warn('combineConversations: Complete!', {
obsolete: obsoleteId,
current: currentId,
});
@ -800,7 +791,7 @@ export class ConversationController {
}
async load(): Promise<void> {
window.log.info('ConversationController: starting initial fetch');
log.info('ConversationController: starting initial fetch');
if (this._conversations.length) {
throw new Error('ConversationController: Already loaded!');
@ -818,7 +809,7 @@ export class ConversationController {
);
if (temporaryConversations.length) {
window.log.warn(
log.warn(
`ConversationController: Removing ${temporaryConversations.length} temporary conversations`
);
}
@ -866,21 +857,19 @@ export class ConversationController {
conversation.set({ e164: undefined });
updateConversation(conversation.attributes);
window.log.info(
`Cleaning up conversation(${uuid}) with invalid e164`
);
log.info(`Cleaning up conversation(${uuid}) with invalid e164`);
}
} catch (error) {
window.log.error(
log.error(
'ConversationController.load/map: Failed to prepare a conversation',
error && error.stack ? error.stack : error
);
}
})
);
window.log.info('ConversationController: done with initial fetch');
log.info('ConversationController: done with initial fetch');
} catch (error) {
window.log.error(
log.error(
'ConversationController: initial fetch failed',
error && error.stack ? error.stack : error
);

View File

@ -8,6 +8,7 @@ import Long from 'long';
import { HKDF } from '@signalapp/signal-client';
import { calculateAgreement, generateKeyPair } from './Curve';
import * as log from './logging/log';
import {
CipherType,
@ -712,7 +713,7 @@ export async function encryptCdsDiscoveryRequest(
export function uuidToArrayBuffer(uuid: string): ArrayBuffer {
if (uuid.length !== 36) {
window.log.warn(
log.warn(
'uuidToArrayBuffer: received a string of invalid length. Returning an empty ArrayBuffer'
);
return new ArrayBuffer(0);
@ -729,7 +730,7 @@ export function arrayBufferToUuid(
arrayBuffer: ArrayBuffer
): undefined | string {
if (arrayBuffer.byteLength !== 16) {
window.log.warn(
log.warn(
'arrayBufferToUuid: received an ArrayBuffer of invalid length. Returning undefined'
);
return undefined;

View File

@ -9,6 +9,7 @@ import {
CompatPreKeyType,
CompatSignedPreKeyType,
} from './textsecure/Types.d';
import * as log from './logging/log';
export function isNonNegativeInteger(n: unknown): n is number {
return typeof n === 'number' && n % 1 === 0 && n >= 0;
@ -82,7 +83,7 @@ export function createKeyPair(incomingKey: ArrayBuffer): KeyPairType {
const copy = copyArrayBuffer(incomingKey);
clampPrivateKey(copy);
if (!constantTimeEqual(copy, incomingKey)) {
window.log.warn('createKeyPair: incoming private key was not clamped!');
log.warn('createKeyPair: incoming private key was not clamped!');
}
const incomingKeyBuffer = Buffer.from(incomingKey);

View File

@ -4,6 +4,7 @@
import { get, throttle } from 'lodash';
import type { WebAPIType } from './textsecure/WebAPI';
import * as log from './logging/log';
export type ConfigKeyType =
| 'desktop.announcementGroup'
@ -92,7 +93,7 @@ export const refreshRemoteConfig = async (
// If enablement changes at all, notify listeners
const currentListeners = listeners[name] || [];
if (hasChanged) {
window.log.info(`Remote Config: Flag ${name} has changed`);
log.info(`Remote Config: Flag ${name} has changed`);
currentListeners.forEach(listener => {
listener(configValue);
});

View File

@ -58,6 +58,7 @@ import {
QualifiedAddress,
QualifiedAddressStringType,
} from './types/QualifiedAddress';
import * as log from './logging/log';
const TIMESTAMP_THRESHOLD = 5 * 1000; // 5 seconds
@ -134,7 +135,7 @@ async function _fillCaches<ID, T extends HasIdType<ID>, HydratedType>(
});
}
window.log.info(`SignalProtocolStore: Finished caching ${field} data`);
log.info(`SignalProtocolStore: Finished caching ${field} data`);
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any
object[field] = cache as any;
}
@ -325,12 +326,12 @@ export class SignalProtocolStore extends EventsMixin {
const entry = this.preKeys.get(id);
if (!entry) {
window.log.error('Failed to fetch prekey:', id);
log.error('Failed to fetch prekey:', id);
return undefined;
}
if (entry.hydrated) {
window.log.info('Successfully fetched prekey (cache hit):', id);
log.info('Successfully fetched prekey (cache hit):', id);
return entry.item;
}
@ -340,7 +341,7 @@ export class SignalProtocolStore extends EventsMixin {
fromDB: entry.fromDB,
item,
});
window.log.info('Successfully fetched prekey (cache miss):', id);
log.info('Successfully fetched prekey (cache miss):', id);
return item;
}
@ -383,7 +384,7 @@ export class SignalProtocolStore extends EventsMixin {
try {
this.trigger('removePreKey');
} catch (error) {
window.log.error(
log.error(
'removePreKey error triggering removePreKey:',
error && error.stack ? error.stack : error
);
@ -414,12 +415,12 @@ export class SignalProtocolStore extends EventsMixin {
const entry = this.signedPreKeys.get(id);
if (!entry) {
window.log.error('Failed to fetch signed prekey:', id);
log.error('Failed to fetch signed prekey:', id);
return undefined;
}
if (entry.hydrated) {
window.log.info('Successfully fetched signed prekey (cache hit):', id);
log.info('Successfully fetched signed prekey (cache hit):', id);
return entry.item;
}
@ -429,7 +430,7 @@ export class SignalProtocolStore extends EventsMixin {
item,
fromDB: entry.fromDB,
});
window.log.info('Successfully fetched signed prekey (cache miss):', id);
log.info('Successfully fetched signed prekey (cache miss):', id);
return item;
}
@ -576,7 +577,7 @@ export class SignalProtocolStore extends EventsMixin {
});
} catch (error) {
const errorString = error && error.stack ? error.stack : error;
window.log.error(
log.error(
`saveSenderKey: failed to save senderKey ${senderId}/${distributionId}: ${errorString}`
);
}
@ -597,12 +598,12 @@ export class SignalProtocolStore extends EventsMixin {
const entry = this.senderKeys.get(id);
if (!entry) {
window.log.error('Failed to fetch sender key:', id);
log.error('Failed to fetch sender key:', id);
return undefined;
}
if (entry.hydrated) {
window.log.info('Successfully fetched sender key (cache hit):', id);
log.info('Successfully fetched sender key (cache hit):', id);
return entry.item;
}
@ -612,11 +613,11 @@ export class SignalProtocolStore extends EventsMixin {
item,
fromDB: entry.fromDB,
});
window.log.info('Successfully fetched sender key(cache miss):', id);
log.info('Successfully fetched sender key(cache miss):', id);
return item;
} catch (error) {
const errorString = error && error.stack ? error.stack : error;
window.log.error(
log.error(
`getSenderKey: failed to load sender key ${senderId}/${distributionId}: ${errorString}`
);
return undefined;
@ -641,7 +642,7 @@ export class SignalProtocolStore extends EventsMixin {
this.senderKeys.delete(id);
} catch (error) {
const errorString = error && error.stack ? error.stack : error;
window.log.error(
log.error(
`removeSenderKey: failed to remove senderKey ${senderId}/${distributionId}: ${errorString}`
);
}
@ -709,14 +710,12 @@ export class SignalProtocolStore extends EventsMixin {
if (this.currentZone && this.currentZone !== zone) {
const start = Date.now();
window.log.info(
`${debugName}: locked by ${this.currentZone.name}, waiting`
);
log.info(`${debugName}: locked by ${this.currentZone.name}, waiting`);
return new Promise<T>((resolve, reject) => {
const callback = async () => {
const duration = Date.now() - start;
window.log.info(`${debugName}: unlocked after ${duration}ms`);
log.info(`${debugName}: unlocked after ${duration}ms`);
// Call `.withZone` synchronously from `this.zoneQueue` to avoid
// extra in-between ticks while we are on microtasks queue.
@ -759,7 +758,7 @@ export class SignalProtocolStore extends EventsMixin {
return;
}
window.log.info(
log.info(
`commitZoneChanges(${name}): pending sessions ${pendingSessions.size} ` +
`pending unprocessed ${pendingUnprocessed.size}`
);
@ -786,7 +785,7 @@ export class SignalProtocolStore extends EventsMixin {
}
private async revertZoneChanges(name: string, error: Error): Promise<void> {
window.log.info(
log.info(
`revertZoneChanges(${name}): ` +
`pending sessions size ${this.pendingSessions.size} ` +
`pending unprocessed size ${this.pendingUnprocessed.size}`,
@ -807,7 +806,7 @@ export class SignalProtocolStore extends EventsMixin {
this.currentZone = zone;
if (zone !== GLOBAL_ZONE) {
window.log.info(`SignalProtocolStore.enterZone(${zone.name}:${name})`);
log.info(`SignalProtocolStore.enterZone(${zone.name}:${name})`);
}
}
}
@ -826,7 +825,7 @@ export class SignalProtocolStore extends EventsMixin {
}
if (zone !== GLOBAL_ZONE) {
window.log.info(`SignalProtocolStore.leaveZone(${zone.name})`);
log.info(`SignalProtocolStore.leaveZone(${zone.name})`);
}
this.currentZone = undefined;
@ -845,7 +844,7 @@ export class SignalProtocolStore extends EventsMixin {
toEnter.push(elem);
}
window.log.info(
log.info(
`SignalProtocolStore: running blocked ${toEnter.length} jobs in ` +
`zone ${next.zone.name}`
);
@ -888,9 +887,7 @@ export class SignalProtocolStore extends EventsMixin {
return await this._maybeMigrateSession(entry.fromDB, { zone });
} catch (error) {
const errorString = error && error.stack ? error.stack : error;
window.log.error(
`loadSession: failed to load session ${id}: ${errorString}`
);
log.error(`loadSession: failed to load session ${id}: ${errorString}`);
return undefined;
}
});
@ -957,9 +954,7 @@ export class SignalProtocolStore extends EventsMixin {
registrationId: localRegistrationId,
};
window.log.info(
`_maybeMigrateSession: Migrating session with id ${session.id}`
);
log.info(`_maybeMigrateSession: Migrating session with id ${session.id}`);
const sessionProto = sessionRecordToProtobuf(
JSON.parse(session.record),
localUserData
@ -1026,7 +1021,7 @@ export class SignalProtocolStore extends EventsMixin {
}
} catch (error) {
const errorString = error && error.stack ? error.stack : error;
window.log.error(`storeSession: Save failed for ${id}: ${errorString}`);
log.error(`storeSession: Save failed for ${id}: ${errorString}`);
throw error;
}
});
@ -1117,7 +1112,7 @@ export class SignalProtocolStore extends EventsMixin {
emptyIdentifiers,
};
} catch (error) {
window.log.error(
log.error(
'getOpenDevices: Failed to get devices',
error && error.stack ? error.stack : error
);
@ -1144,13 +1139,13 @@ export class SignalProtocolStore extends EventsMixin {
}
const id = qualifiedAddress.toString();
window.log.info('removeSession: deleting session for', id);
log.info('removeSession: deleting session for', id);
try {
await window.Signal.Data.removeSessionById(id);
this.sessions.delete(id);
this.pendingSessions.delete(id);
} catch (e) {
window.log.error(`removeSession: Failed to delete session for ${id}`);
log.error(`removeSession: Failed to delete session for ${id}`);
}
});
}
@ -1165,7 +1160,7 @@ export class SignalProtocolStore extends EventsMixin {
throw new Error('removeAllSessions: identifier was undefined/null');
}
window.log.info('removeAllSessions: deleting sessions for', identifier);
log.info('removeAllSessions: deleting sessions for', identifier);
const id = window.ConversationController.getConversationId(identifier);
strictAssert(
@ -1221,7 +1216,7 @@ export class SignalProtocolStore extends EventsMixin {
const id = qualifiedAddress.toString();
window.log.info(`archiveSession: session for ${id}`);
log.info(`archiveSession: session for ${id}`);
const entry = this.pendingSessions.get(id) || this.sessions.get(id);
@ -1240,7 +1235,7 @@ export class SignalProtocolStore extends EventsMixin {
);
}
window.log.info(
log.info(
'archiveSiblingSessions: archiving sibling sessions for',
encodedAddress.toString()
);
@ -1268,7 +1263,7 @@ export class SignalProtocolStore extends EventsMixin {
throw new Error('archiveAllSessions: this.sessions not yet cached!');
}
window.log.info(
log.info(
'archiveAllSessions: archiving all sessions for',
uuid.toString()
);
@ -1308,7 +1303,7 @@ export class SignalProtocolStore extends EventsMixin {
const ONE_HOUR = 60 * 60 * 1000;
if (lastReset && isMoreRecentThan(lastReset, ONE_HOUR)) {
window.log.warn(
log.warn(
`lightSessionReset/${id}: Skipping session reset, last reset at ${lastReset}`
);
return;
@ -1329,7 +1324,7 @@ export class SignalProtocolStore extends EventsMixin {
const conversation = window.ConversationController.get(conversationId);
assert(conversation, `lightSessionReset/${id}: missing conversation`);
window.log.warn(`lightSessionReset/${id}: Resetting session`);
log.warn(`lightSessionReset/${id}: Resetting session`);
// Archive open session with this device
await this.archiveSession(qualifiedAddress);
@ -1356,10 +1351,7 @@ export class SignalProtocolStore extends EventsMixin {
window.storage.put('sessionResets', sessionResets);
const errorString = error && error.stack ? error.stack : error;
window.log.error(
`lightSessionReset/${id}: Encountered error`,
errorString
);
log.error(`lightSessionReset/${id}: Encountered error`, errorString);
}
}
@ -1380,7 +1372,7 @@ export class SignalProtocolStore extends EventsMixin {
return entry.fromDB;
} catch (e) {
window.log.error(
log.error(
`getIdentityRecord: Failed to get identity record for identifier ${id}`
);
return undefined;
@ -1418,7 +1410,7 @@ export class SignalProtocolStore extends EventsMixin {
id: newId,
};
window.log.info(
log.info(
`SignalProtocolStore: migrating identity key from ${record.fromDB.id} ` +
`to ${newRecord.id}`
);
@ -1454,7 +1446,7 @@ export class SignalProtocolStore extends EventsMixin {
if (identityRecord && identityRecord.publicKey) {
return constantTimeEqual(identityRecord.publicKey, publicKey);
}
window.log.warn(
log.warn(
'isTrustedIdentity: No local record for our own identifier. Returning true.'
);
return true;
@ -1475,28 +1467,26 @@ export class SignalProtocolStore extends EventsMixin {
identityRecord?: IdentityKeyType
): boolean {
if (!identityRecord) {
window.log.info(
'isTrustedForSending: No previous record, returning true...'
);
log.info('isTrustedForSending: No previous record, returning true...');
return true;
}
const existing = identityRecord.publicKey;
if (!existing) {
window.log.info('isTrustedForSending: Nothing here, returning true...');
log.info('isTrustedForSending: Nothing here, returning true...');
return true;
}
if (!constantTimeEqual(existing, publicKey)) {
window.log.info("isTrustedForSending: Identity keys don't match...");
log.info("isTrustedForSending: Identity keys don't match...");
return false;
}
if (identityRecord.verified === VerifiedStatus.UNVERIFIED) {
window.log.error('isTrustedIdentity: Needs unverified approval!');
log.error('isTrustedIdentity: Needs unverified approval!');
return false;
}
if (this.isNonBlockingApprovalRequired(identityRecord)) {
window.log.error('isTrustedForSending: Needs non-blocking approval!');
log.error('isTrustedForSending: Needs non-blocking approval!');
return false;
}
@ -1560,7 +1550,7 @@ export class SignalProtocolStore extends EventsMixin {
if (!identityRecord || !identityRecord.publicKey) {
// Lookup failed, or the current key was removed, so save this one.
window.log.info('saveIdentity: Saving new identity...');
log.info('saveIdentity: Saving new identity...');
await this._saveIdentityKey({
id,
publicKey,
@ -1575,7 +1565,7 @@ export class SignalProtocolStore extends EventsMixin {
const oldpublicKey = identityRecord.publicKey;
if (!constantTimeEqual(oldpublicKey, publicKey)) {
window.log.info('saveIdentity: Replacing existing identity...');
log.info('saveIdentity: Replacing existing identity...');
const previousStatus = identityRecord.verified;
let verifiedStatus;
if (
@ -1599,7 +1589,7 @@ export class SignalProtocolStore extends EventsMixin {
try {
this.trigger('keychange', encodedAddress.uuid);
} catch (error) {
window.log.error(
log.error(
'saveIdentity: error triggering keychange:',
error && error.stack ? error.stack : error
);
@ -1614,7 +1604,7 @@ export class SignalProtocolStore extends EventsMixin {
return true;
}
if (this.isNonBlockingApprovalRequired(identityRecord)) {
window.log.info('saveIdentity: Setting approval status...');
log.info('saveIdentity: Setting approval status...');
identityRecord.nonblockingApproval = nonblockingApproval;
await this._saveIdentityKey(identityRecord);
@ -1703,9 +1693,7 @@ export class SignalProtocolStore extends EventsMixin {
await this._saveIdentityKey(identityRecord);
}
} else {
window.log.info(
'setVerified: No identity record for specified publicKey'
);
log.info('setVerified: No identity record for specified publicKey');
}
}
@ -1784,7 +1772,7 @@ export class SignalProtocolStore extends EventsMixin {
try {
this.trigger('keychange', uuid);
} catch (error) {
window.log.error(
log.error(
'processUnverifiedMessage: error triggering keychange:',
error && error.stack ? error.stack : error
);
@ -1829,9 +1817,7 @@ export class SignalProtocolStore extends EventsMixin {
}
if (!identityRecord && verifiedStatus === VerifiedStatus.DEFAULT) {
window.log.info(
'processVerifiedMessage: No existing record for default status'
);
log.info('processVerifiedMessage: No existing record for default status');
return false;
}
@ -1863,7 +1849,7 @@ export class SignalProtocolStore extends EventsMixin {
try {
this.trigger('keychange', uuid);
} catch (error) {
window.log.error(
log.error(
'processVerifiedMessage error triggering keychange:',
error && error.stack ? error.stack : error
);

View File

@ -97,6 +97,7 @@ import { onRetryRequest, onDecryptionError } from './util/handleRetry';
import { themeChanged } from './shims/themeChanged';
import { createIPCEvents } from './util/createIPCEvents';
import { RemoveAllConfiguration } from './types/RemoveAllConfiguration';
import * as log from './logging/log';
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
@ -129,14 +130,11 @@ export async function startApp(): Promise<void> {
window.startupProcessingQueue = new window.Signal.Util.StartupQueue();
window.attachmentDownloadQueue = [];
try {
window.log.info('Initializing SQL in renderer');
log.info('Initializing SQL in renderer');
await window.sqlInitializer.initialize();
window.log.info('SQL initialized in renderer');
log.info('SQL initialized in renderer');
} catch (err) {
window.log.error(
'SQL failed to initialize',
err && err.stack ? err.stack : err
);
log.error('SQL failed to initialize', err && err.stack ? err.stack : err);
}
await window.Signal.Util.initializeMessageCounter();
@ -154,7 +152,7 @@ export async function startApp(): Promise<void> {
server,
});
window.log.info('Initializing MessageReceiver');
log.info('Initializing MessageReceiver');
messageReceiver = new MessageReceiver({
server,
storage: window.storage,
@ -347,7 +345,7 @@ export async function startApp(): Promise<void> {
const c = window.ConversationController.get(conversationId);
if (!c) {
window.log.warn(
log.warn(
`deliveryReceiptBatcher: Conversation ${conversationId} does not exist! ` +
`Will not send delivery receipts for timestamps ${timestamps}`
);
@ -372,7 +370,7 @@ export async function startApp(): Promise<void> {
{ messageIds, sendType: 'deliveryReceipt' }
);
} catch (error) {
window.log.error(
log.error(
`Failed to send delivery receipt to ${senderE164}/${senderUuid} for timestamps ${timestamps}:`,
error && error.stack ? error.stack : error
);
@ -492,8 +490,8 @@ export async function startApp(): Promise<void> {
} = window.Signal.Migrations;
const { Views } = window.Signal;
window.log.info('background page reloaded');
window.log.info('environment:', window.getEnvironment());
log.info('background page reloaded');
log.info('environment:', window.getEnvironment());
let idleDetector: WhatIsThis;
let newVersion = false;
@ -522,7 +520,7 @@ export async function startApp(): Promise<void> {
window.Whisper.events.trigger('userChanged', false);
window.Signal.Util.Registration.markDone();
window.log.info('dispatching registration event');
log.info('dispatching registration event');
window.Whisper.events.trigger('registration_done');
});
return accountManager;
@ -534,9 +532,9 @@ export async function startApp(): Promise<void> {
if (!version) {
const isIndexedDBPresent = await doesDatabaseExist();
if (isIndexedDBPresent) {
window.log.info('Found IndexedDB database.');
log.info('Found IndexedDB database.');
try {
window.log.info('Confirming deletion of old data with user...');
log.info('Confirming deletion of old data with user...');
try {
await new Promise<void>((resolve, reject) => {
@ -550,7 +548,7 @@ export async function startApp(): Promise<void> {
});
});
} catch (error) {
window.log.info(
log.info(
'User chose not to delete old data. Shutting down.',
error && error.stack ? error.stack : error
);
@ -558,17 +556,17 @@ export async function startApp(): Promise<void> {
return;
}
window.log.info('Deleting all previously-migrated data in SQL...');
window.log.info('Deleting IndexedDB file...');
log.info('Deleting all previously-migrated data in SQL...');
log.info('Deleting IndexedDB file...');
await Promise.all([
removeIndexedDB(),
window.Signal.Data.removeAll(),
window.Signal.Data.removeIndexedDBFiles(),
]);
window.log.info('Done with SQL deletion and IndexedDB file deletion.');
log.info('Done with SQL deletion and IndexedDB file deletion.');
} catch (error) {
window.log.error(
log.error(
'Failed to remove IndexedDB file or remove SQL data:',
error && error.stack ? error.stack : error
);
@ -583,7 +581,7 @@ export async function startApp(): Promise<void> {
}
}
window.log.info('Storage fetch');
log.info('Storage fetch');
window.storage.fetch();
function mapOldThemeToNew(
@ -621,7 +619,7 @@ export async function startApp(): Promise<void> {
// These make key operations available to IPC handlers created in preload.js
window.Events = createIPCEvents({
shutdown: async () => {
window.log.info('background/shutdown');
log.info('background/shutdown');
window.Signal.Util.flushMessageCounter();
@ -663,7 +661,7 @@ export async function startApp(): Promise<void> {
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
if (lastHeartbeat > 0 && isOlderThan(lastHeartbeat, THIRTY_DAYS)) {
window.log.warn(
log.warn(
`This instance has not been used for 30 days. Last heartbeat: ${lastHeartbeat}. Last startup: ${previousLastStartup}.`
);
await unlinkAndDisconnect(RemoveAllConfiguration.Soft);
@ -683,13 +681,13 @@ export async function startApp(): Promise<void> {
await window.storage.put('version', currentVersion);
if (newVersion && lastVersion) {
window.log.info(
log.info(
`New version detected: ${currentVersion}; previous: ${lastVersion}`
);
const remoteBuildExpiration = window.storage.get('remoteBuildExpiration');
if (remoteBuildExpiration) {
window.log.info(
log.info(
`Clearing remoteBuildExpiration. Previous value was ${remoteBuildExpiration}`
);
window.storage.remove('remoteBuildExpiration');
@ -761,7 +759,7 @@ export async function startApp(): Promise<void> {
try {
await window.Signal.Data.cleanupOrphanedAttachments();
} catch (error) {
window.log.error(
log.error(
'background: Failed to cleanup orphaned attachments:',
error && error.stack ? error.stack : error
);
@ -775,7 +773,7 @@ export async function startApp(): Promise<void> {
idleDetector = new IdleDetector();
let isMigrationWithIndexComplete = false;
window.log.info(
log.info(
`Starting background data migration. Target version: ${Message.CURRENT_SCHEMA_VERSION}`
);
idleDetector.on('idle', async () => {
@ -790,14 +788,12 @@ export async function startApp(): Promise<void> {
window.Signal.Data.getMessagesNeedingUpgrade,
saveMessage: window.Signal.Data.saveMessage,
});
window.log.info('Upgrade message schema (with index):', batchWithIndex);
log.info('Upgrade message schema (with index):', batchWithIndex);
isMigrationWithIndexComplete = batchWithIndex.done;
}
if (isMigrationWithIndexComplete) {
window.log.info(
'Background migration complete. Stopping idle detector.'
);
log.info('Background migration complete. Stopping idle detector.');
idleDetector.stop();
}
});
@ -814,7 +810,7 @@ export async function startApp(): Promise<void> {
'retryReceiptLifeSpan'
);
} catch (error) {
window.log.warn(
log.warn(
'Failed to parse integer out of desktop.retryReceiptLifespan feature flag',
error && error.stack ? error.stack : error
);
@ -837,7 +833,7 @@ export async function startApp(): Promise<void> {
'retryRespondMaxAge'
);
} catch (error) {
window.log.warn(
log.warn(
'background/setInterval: Failed to parse integer from desktop.retryRespondMaxAge feature flag',
error && error.stack ? error.stack : error
);
@ -848,7 +844,7 @@ export async function startApp(): Promise<void> {
now - sentProtoMaxAge
);
} catch (error) {
window.log.error(
log.error(
'background/onready/setInterval: Error deleting sent protos: ',
error && error.stack ? error.stack : error
);
@ -856,7 +852,7 @@ export async function startApp(): Promise<void> {
try {
const expired = await retryPlaceholders.getExpiredAndRemove();
window.log.info(
log.info(
`retryPlaceholders/interval: Found ${expired.length} expired items`
);
expired.forEach(item => {
@ -878,7 +874,7 @@ export async function startApp(): Promise<void> {
}
});
} catch (error) {
window.log.error(
log.error(
'background/onready/setInterval: Error getting expired retry placeholders: ',
error && error.stack ? error.stack : error
);
@ -894,7 +890,7 @@ export async function startApp(): Promise<void> {
]);
await window.ConversationController.checkForConflicts();
} catch (error) {
window.log.error(
log.error(
'background.js: ConversationController failed to load:',
error && error.stack ? error.stack : error
);
@ -1036,7 +1032,7 @@ export async function startApp(): Promise<void> {
name: 'changedConvoBatcher',
processBatch(batch) {
const deduped = new Set(batch);
window.log.info(
log.info(
'changedConvoBatcher: deduped ' +
`${batch.length} into ${deduped.size}`
);
@ -1084,7 +1080,7 @@ export async function startApp(): Promise<void> {
});
if (reconnect) {
window.log.info('background: reconnecting websocket on user change');
log.info('background: reconnecting websocket on user change');
enqueueReconnectToWebSocket();
}
});
@ -1590,11 +1586,11 @@ export async function startApp(): Promise<void> {
});
window.Whisper.events.on('powerMonitorSuspend', () => {
window.log.info('powerMonitor: suspend');
log.info('powerMonitor: suspend');
});
window.Whisper.events.on('powerMonitorResume', () => {
window.log.info('powerMonitor: resume');
log.info('powerMonitor: resume');
server?.checkSockets();
});
@ -1603,14 +1599,14 @@ export async function startApp(): Promise<void> {
const enqueueReconnectToWebSocket = () => {
reconnectToWebSocketQueue.add(async () => {
if (!server) {
window.log.info('reconnectToWebSocket: No server. Early return.');
log.info('reconnectToWebSocket: No server. Early return.');
return;
}
window.log.info('reconnectToWebSocket starting...');
log.info('reconnectToWebSocket starting...');
await server.onOffline();
await server.onOnline();
window.log.info('reconnectToWebSocket complete.');
log.info('reconnectToWebSocket complete.');
});
};
@ -1627,7 +1623,7 @@ export async function startApp(): Promise<void> {
window.Signal.Services.enableStorageService();
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'background/runStorageService: We are primary device; not sending key sync request'
);
return;
@ -1695,16 +1691,16 @@ export async function startApp(): Promise<void> {
const ourConversation = window.ConversationController.getOurConversation();
const ourE164 = ourConversation?.get('e164');
if (ourE164) {
window.log.warn('Restoring E164 from our conversation');
log.warn('Restoring E164 from our conversation');
window.storage.user.setNumber(ourE164);
}
}
window.dispatchEvent(new Event('storage_ready'));
window.log.info('Expiration start timestamp cleanup: starting...');
log.info('Expiration start timestamp cleanup: starting...');
const messagesUnexpectedlyMissingExpirationStartTimestamp = await window.Signal.Data.getMessagesUnexpectedlyMissingExpirationStartTimestamp();
window.log.info(
log.info(
`Expiration start timestamp cleanup: Found ${messagesUnexpectedlyMissingExpirationStartTimestamp.length} messages for cleanup`
);
if (messagesUnexpectedlyMissingExpirationStartTimestamp.length) {
@ -1724,7 +1720,7 @@ export async function startApp(): Promise<void> {
isNotNil
)
);
window.log.info(
log.info(
`Expiration start timestamp cleanup: starting timer for ${message.type} message sent at ${message.sent_at}. Starting timer at ${message.expirationStartTimestamp}`
);
return {
@ -1736,11 +1732,11 @@ export async function startApp(): Promise<void> {
await window.Signal.Data.saveMessages(newMessageAttributes);
}
window.log.info('Expiration start timestamp cleanup: complete');
log.info('Expiration start timestamp cleanup: complete');
window.log.info('listening for registration events');
log.info('listening for registration events');
window.Whisper.events.on('registration_done', () => {
window.log.info('handling registration event');
log.info('handling registration event');
strictAssert(server !== undefined, 'WebAPI not ready');
server.authenticate(
@ -1797,7 +1793,7 @@ export async function startApp(): Promise<void> {
await window.Signal.RemoteConfig.maybeRefreshRemoteConfig(server);
} catch (error) {
if (error && window._.isNumber(error.code)) {
window.log.warn(
log.warn(
`registerForActive: Failed to to refresh remote config. Code: ${error.code}`
);
return;
@ -1876,7 +1872,7 @@ export async function startApp(): Promise<void> {
await window.storage.remove('manifestVersion');
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'onChange/desktop.storage: We are primary device; not sending key sync request'
);
return;
@ -1910,7 +1906,7 @@ export async function startApp(): Promise<void> {
let disconnectTimer: NodeJS.Timeout | undefined;
let reconnectTimer: number | undefined;
function onOffline() {
window.log.info('offline');
log.info('offline');
window.removeEventListener('offline', onOffline);
window.addEventListener('online', onOnline);
@ -1926,13 +1922,13 @@ export async function startApp(): Promise<void> {
}
function onOnline() {
window.log.info('online');
log.info('online');
window.removeEventListener('online', onOnline);
window.addEventListener('offline', onOffline);
if (disconnectTimer && isSocketOnline()) {
window.log.warn('Already online. Had a blip in online/offline status.');
log.warn('Already online. Had a blip in online/offline status.');
clearTimeout(disconnectTimer);
disconnectTimer = undefined;
return;
@ -1954,7 +1950,7 @@ export async function startApp(): Promise<void> {
}
async function disconnect() {
window.log.info('disconnect');
log.info('disconnect');
// Clear timer, since we're only called when the timer is expired
disconnectTimer = undefined;
@ -1974,7 +1970,7 @@ export async function startApp(): Promise<void> {
let connecting = false;
async function connect(firstRun?: boolean) {
if (connecting) {
window.log.warn('connect already running', { connectCount });
log.warn('connect already running', { connectCount });
return;
}
@ -1983,7 +1979,7 @@ export async function startApp(): Promise<void> {
try {
connecting = true;
window.log.info('connect', { firstRun, connectCount });
log.info('connect', { firstRun, connectCount });
if (reconnectTimer) {
clearTimeout(reconnectTimer);
@ -1995,7 +1991,7 @@ export async function startApp(): Promise<void> {
window.addEventListener('offline', onOffline);
}
if (connectCount === 0 && !navigator.onLine) {
window.log.warn(
log.warn(
'Starting up offline; will connect when we have network access'
);
window.addEventListener('online', onOnline);
@ -2033,7 +2029,7 @@ export async function startApp(): Promise<void> {
}
}
} catch (error) {
window.log.error(
log.error(
'connect: Error refreshing remote config:',
error && error.stack ? error.stack : error
);
@ -2056,7 +2052,7 @@ export async function startApp(): Promise<void> {
messaging: window.textsecure.messaging,
});
} catch (error) {
window.log.error(
log.error(
'connect: Error fetching UUIDs for lonely e164s:',
error && error.stack ? error.stack : error
);
@ -2085,7 +2081,7 @@ export async function startApp(): Promise<void> {
await server.onOnline();
AttachmentDownloads.start({
logger: window.log,
logger: log,
});
if (connectCount === 1) {
@ -2103,7 +2099,7 @@ export async function startApp(): Promise<void> {
newVersion &&
window.textsecure.storage.user.getDeviceId() !== 1
) {
window.log.info('Boot after upgrading. Requesting contact sync');
log.info('Boot after upgrading. Requesting contact sync');
window.getSyncRequest();
runStorageService();
@ -2115,7 +2111,7 @@ export async function startApp(): Promise<void> {
window.textsecure.storage.user.removeSignalingKey(),
]);
} catch (e) {
window.log.error(
log.error(
'Problem with account manager updates after starting new version: ',
e && e.stack ? e.stack : e
);
@ -2128,7 +2124,7 @@ export async function startApp(): Promise<void> {
await server.registerSupportForUnauthenticatedDelivery();
window.storage.put(udSupportKey, true);
} catch (error) {
window.log.error(
log.error(
'Error: Unable to register for unauthenticated delivery support.',
error && error.stack ? error.stack : error
);
@ -2138,7 +2134,7 @@ export async function startApp(): Promise<void> {
const deviceId = window.textsecure.storage.user.getDeviceId();
if (!window.textsecure.storage.user.getUuid()) {
window.log.error('UUID not captured during registration, unlinking');
log.error('UUID not captured during registration, unlinking');
return unlinkAndDisconnect(RemoveAllConfiguration.Full);
}
@ -2154,7 +2150,7 @@ export async function startApp(): Promise<void> {
changeNumber: true,
});
} catch (error) {
window.log.error(
log.error(
'Error: Unable to register our capabilities.',
error && error.stack ? error.stack : error
);
@ -2176,13 +2172,13 @@ export async function startApp(): Promise<void> {
const syncRequest = window.getSyncRequest();
window.Whisper.events.trigger('contactsync:begin');
syncRequest.addEventListener('success', () => {
window.log.info('sync successful');
log.info('sync successful');
window.storage.put('synced_at', Date.now());
window.Whisper.events.trigger('contactsync');
runStorageService();
});
syncRequest.addEventListener('timeout', () => {
window.log.error('sync timed out');
log.error('sync timed out');
window.Whisper.events.trigger('contactsync');
runStorageService();
});
@ -2201,7 +2197,7 @@ export async function startApp(): Promise<void> {
}));
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'background/connect: We are primary device; not sending sticker pack sync'
);
return;
@ -2214,7 +2210,7 @@ export async function startApp(): Promise<void> {
),
{ messageIds: [], sendType: 'otherSync' }
).catch(error => {
window.log.error(
log.error(
'Failed to send installed sticker packs via sync message',
error && error.stack ? error.stack : error
);
@ -2263,14 +2259,14 @@ export async function startApp(): Promise<void> {
// a given conversation's queue. But we have processed all events from the websocket.
async function waitForEmptyEventQueue() {
if (!messageReceiver) {
window.log.info(
log.info(
'waitForEmptyEventQueue: No messageReceiver available, returning early'
);
return;
}
if (!messageReceiver.hasEmptied()) {
window.log.info(
log.info(
'waitForEmptyEventQueue: Waiting for MessageReceiver empty event...'
);
let resolve: undefined | (() => void);
@ -2295,9 +2291,7 @@ export async function startApp(): Promise<void> {
await promise;
}
window.log.info(
'waitForEmptyEventQueue: Waiting for event handler queue idle...'
);
log.info('waitForEmptyEventQueue: Waiting for event handler queue idle...');
await eventHandlerQueue.onIdle();
}
@ -2308,7 +2302,7 @@ export async function startApp(): Promise<void> {
window.waitForAllBatchers(),
window.flushAllWaitBatchers(),
]);
window.log.info('onEmpty: All outstanding database requests complete');
log.info('onEmpty: All outstanding database requests complete');
window.readyForUpdates();
// Start listeners here, after we get through our queue.
@ -2333,10 +2327,7 @@ export async function startApp(): Promise<void> {
processedCount: messageReceiver && messageReceiver.getProcessedCount(),
});
if (messageReceiver) {
window.log.info(
'App loaded - messages:',
messageReceiver.getProcessedCount()
);
log.info('App loaded - messages:', messageReceiver.getProcessedCount());
}
window.Signal.Util.setBatchingStrategy(false);
@ -2359,7 +2350,7 @@ export async function startApp(): Promise<void> {
// to display the message properly.
message.hasRequiredAttachmentDownloads()
);
window.log.info(
log.info(
'Downloading recent attachments of total attachments',
attachmentsToDownload.length,
attachmentDownloadQueue.length
@ -2403,9 +2394,7 @@ export async function startApp(): Promise<void> {
return;
}
window.log.info(
`incrementProgress: Message count is ${initialStartupCount}`
);
log.info(`incrementProgress: Message count is ${initialStartupCount}`);
window.Whisper.events.trigger('loadingProgress', initialStartupCount);
}
@ -2413,11 +2402,11 @@ export async function startApp(): Promise<void> {
window.Whisper.events.on('manualConnect', manualConnect);
function manualConnect() {
if (isSocketOnline()) {
window.log.info('manualConnect: already online; not connecting again');
log.info('manualConnect: already online; not connecting again');
return;
}
window.log.info('manualConnect: calling connect()');
log.info('manualConnect: calling connect()');
connect();
}
@ -2486,15 +2475,15 @@ export async function startApp(): Promise<void> {
const ourId = window.ConversationController.getOurConversationId();
if (!senderId) {
window.log.warn('onTyping: ensureContactIds returned falsey senderId!');
log.warn('onTyping: ensureContactIds returned falsey senderId!');
return;
}
if (!ourId) {
window.log.warn("onTyping: Couldn't get our own id!");
log.warn("onTyping: Couldn't get our own id!");
return;
}
if (!conversation) {
window.log.warn(
log.warn(
`onTyping: Did not find conversation for typing indicator (groupv2(${groupV2Id}), group(${groupId}), ${sender}, ${senderUuid})`
);
return;
@ -2505,7 +2494,7 @@ export async function startApp(): Promise<void> {
!isDirectConversation(conversation.attributes) &&
!conversation.hasMember(ourId)
) {
window.log.warn(
log.warn(
`Received typing indicator for group ${conversation.idForLogging()}, which we're not a part of. Dropping.`
);
return;
@ -2528,9 +2517,7 @@ export async function startApp(): Promise<void> {
const { id, key, isInstall, isRemove } = pack || {};
if (!id || !key || (!isInstall && !isRemove)) {
window.log.warn(
'Received malformed sticker pack operation sync message'
);
log.warn('Received malformed sticker pack operation sync message');
return;
}
@ -2556,7 +2543,7 @@ export async function startApp(): Promise<void> {
}
async function onContactSyncComplete() {
window.log.info('onContactSyncComplete');
log.info('onContactSyncComplete');
await window.storage.put('synced_at', Date.now());
}
@ -2571,7 +2558,7 @@ export async function startApp(): Promise<void> {
) {
// special case for syncing details about ourselves
if (details.profileKey) {
window.log.info('Got sync message with our own profile key');
log.info('Got sync message with our own profile key');
ourProfileKeyService.set(typedArrayToArrayBuffer(details.profileKey));
}
}
@ -2583,7 +2570,7 @@ export async function startApp(): Promise<void> {
} as Partial<ConversationAttributesType>) as WhatIsThis);
const validationError = c.validate();
if (validationError) {
window.log.error(
log.error(
'Invalid contact received:',
Errors.toLogFormat(validationError)
);
@ -2674,18 +2661,18 @@ export async function startApp(): Promise<void> {
}
if (window.Signal.Util.postLinkExperience.isActive()) {
window.log.info(
log.info(
'onContactReceived: Adding the message history disclaimer on link'
);
await conversation.addMessageHistoryDisclaimer();
}
} catch (error) {
window.log.error('onContactReceived error:', Errors.toLogFormat(error));
log.error('onContactReceived error:', Errors.toLogFormat(error));
}
}
async function onGroupSyncComplete() {
window.log.info('onGroupSyncComplete');
log.info('onGroupSyncComplete');
await window.storage.put('synced_at', Date.now());
}
@ -2699,10 +2686,7 @@ export async function startApp(): Promise<void> {
'group'
);
if (isGroupV2(conversation.attributes)) {
window.log.warn(
'Got group sync for v2 group: ',
conversation.idForLogging()
);
log.warn('Got group sync for v2 group: ', conversation.idForLogging());
return;
}
@ -2751,7 +2735,7 @@ export async function startApp(): Promise<void> {
window.Signal.Data.updateConversation(conversation.attributes);
if (window.Signal.Util.postLinkExperience.isActive()) {
window.log.info(
log.info(
'onGroupReceived: Adding the message history disclaimer on link'
);
await conversation.addMessageHistoryDisclaimer();
@ -2808,10 +2792,7 @@ export async function startApp(): Promise<void> {
return;
}
} catch (error) {
window.log.error(
'respondWithProfileKeyBatcher error',
error && error.stack
);
log.error('respondWithProfileKeyBatcher error', error && error.stack);
}
sender.queueJob('sendProfileKeyUpdate', () =>
@ -2889,15 +2870,12 @@ export async function startApp(): Promise<void> {
const { reaction } = data.message;
if (!isValidReactionEmoji(reaction.emoji)) {
window.log.warn('Received an invalid reaction emoji. Dropping it');
log.warn('Received an invalid reaction emoji. Dropping it');
confirm();
return Promise.resolve();
}
window.log.info(
'Queuing incoming reaction for',
reaction.targetTimestamp
);
log.info('Queuing incoming reaction for', reaction.targetTimestamp);
const reactionModel = Reactions.getSingleton().add({
emoji: reaction.emoji,
remove: reaction.remove,
@ -2917,7 +2895,7 @@ export async function startApp(): Promise<void> {
if (data.message.delete) {
const { delete: del } = data.message;
window.log.info('Queuing incoming DOE for', del.targetSentTimestamp);
log.info('Queuing incoming DOE for', del.targetSentTimestamp);
const deleteModel = Deletes.getSingleton().add({
targetSentTimestamp: del.targetSentTimestamp,
serverTimestamp: data.serverTimestamp,
@ -2951,7 +2929,7 @@ export async function startApp(): Promise<void> {
const conversation = window.ConversationController.get(conversationId);
if (!conversation) {
window.log.error(
log.error(
'onProfileKeyUpdate: could not find conversation',
data.source,
data.sourceUuid
@ -2961,15 +2939,12 @@ export async function startApp(): Promise<void> {
}
if (!data.profileKey) {
window.log.error(
'onProfileKeyUpdate: missing profileKey',
data.profileKey
);
log.error('onProfileKeyUpdate: missing profileKey', data.profileKey);
confirm();
return;
}
window.log.info(
log.info(
'onProfileKeyUpdate: updating profileKey',
data.source,
data.sourceUuid
@ -3139,7 +3114,7 @@ export async function startApp(): Promise<void> {
throw new Error('getMessageDescriptor: GroupV1 data was missing id');
}
if (!derivedGroupV2Id) {
window.log.warn(
log.warn(
'getMessageDescriptor: GroupV1 data was missing derivedGroupV2Id'
);
} else {
@ -3233,12 +3208,12 @@ export async function startApp(): Promise<void> {
const { reaction } = data.message;
if (!isValidReactionEmoji(reaction.emoji)) {
window.log.warn('Received an invalid reaction emoji. Dropping it');
log.warn('Received an invalid reaction emoji. Dropping it');
event.confirm();
return Promise.resolve();
}
window.log.info('Queuing sent reaction for', reaction.targetTimestamp);
log.info('Queuing sent reaction for', reaction.targetTimestamp);
const reactionModel = Reactions.getSingleton().add({
emoji: reaction.emoji,
remove: reaction.remove,
@ -3257,7 +3232,7 @@ export async function startApp(): Promise<void> {
if (data.message.delete) {
const { delete: del } = data.message;
window.log.info('Queuing sent DOE for', del.targetSentTimestamp);
log.info('Queuing sent DOE for', del.targetSentTimestamp);
const deleteModel = Deletes.getSingleton().add({
targetSentTimestamp: del.targetSentTimestamp,
serverTimestamp: data.serverTimestamp,
@ -3324,7 +3299,7 @@ export async function startApp(): Promise<void> {
});
return true;
}
window.log.warn(
log.warn(
'Received a group call update for a conversation that is not a GV2 group. Ignoring that property and continuing.'
);
}
@ -3336,13 +3311,13 @@ export async function startApp(): Promise<void> {
): Promise<void> {
window.Whisper.events.trigger('unauthorized');
window.log.warn(
log.warn(
'unlinkAndDisconnect: Client is no longer authorized; ' +
'deleting local configuration'
);
if (messageReceiver) {
window.log.info('unlinkAndDisconnect: logging out');
log.info('unlinkAndDisconnect: logging out');
strictAssert(server !== undefined, 'WebAPI not initialized');
server.unregisterRequestHandler(messageReceiver);
messageReceiver.stopProcessing();
@ -3371,7 +3346,7 @@ export async function startApp(): Promise<void> {
);
try {
window.log.info('unlinkAndDisconnect: removing configuration');
log.info('unlinkAndDisconnect: removing configuration');
await window.textsecure.storage.protocol.removeAllConfiguration(mode);
// This was already done in the database with removeAllConfiguration; this does it
@ -3406,11 +3381,9 @@ export async function startApp(): Promise<void> {
}
await window.textsecure.storage.put(VERSION_KEY, window.getVersion());
window.log.info(
'unlinkAndDisconnect: Successfully cleared local configuration'
);
log.info('unlinkAndDisconnect: Successfully cleared local configuration');
} catch (eraseError) {
window.log.error(
log.error(
'unlinkAndDisconnect: Something went wrong clearing ' +
'local configuration',
eraseError && eraseError.stack ? eraseError.stack : eraseError
@ -3422,7 +3395,7 @@ export async function startApp(): Promise<void> {
function onError(ev: ErrorEvent) {
const { error } = ev;
window.log.error('background onError:', Errors.toLogFormat(error));
log.error('background onError:', Errors.toLogFormat(error));
if (
error &&
@ -3442,7 +3415,7 @@ export async function startApp(): Promise<void> {
if (navigator.onLine) {
const timeout = reconnectBackOff.getAndIncrement();
window.log.info(`retrying in ${timeout}ms`);
log.info(`retrying in ${timeout}ms`);
reconnectTimer = setTimeout(connect, timeout);
window.Whisper.events.trigger('reconnectTimer');
@ -3454,14 +3427,14 @@ export async function startApp(): Promise<void> {
return;
}
window.log.warn('background onError: Doing nothing with incoming error');
log.warn('background onError: Doing nothing with incoming error');
}
async function onViewOnceOpenSync(ev: ViewOnceOpenSyncEvent) {
ev.confirm();
const { source, sourceUuid, timestamp } = ev;
window.log.info(`view once open sync ${source} ${timestamp}`);
log.info(`view once open sync ${source} ${timestamp}`);
const sync = ViewOnceOpenSyncs.getSingleton().add({
source,
@ -3487,13 +3460,11 @@ export async function startApp(): Promise<void> {
break;
}
case FETCH_LATEST_ENUM.STORAGE_MANIFEST:
window.log.info('onFetchLatestSync: fetching latest manifest');
log.info('onFetchLatestSync: fetching latest manifest');
await window.Signal.Services.runStorageServiceSyncJob();
break;
default:
window.log.info(
`onFetchLatestSync: Unknown type encountered ${eventType}`
);
log.info(`onFetchLatestSync: Unknown type encountered ${eventType}`);
}
}
@ -3503,12 +3474,12 @@ export async function startApp(): Promise<void> {
const { storageServiceKey } = ev;
if (storageServiceKey === null) {
window.log.info('onKeysSync: deleting window.storageKey');
log.info('onKeysSync: deleting window.storageKey');
window.storage.remove('storageKey');
}
if (storageServiceKey) {
window.log.info('onKeysSync: received keys');
log.info('onKeysSync: received keys');
const storageServiceKeyBase64 = window.Signal.Crypto.arrayBufferToBase64(
storageServiceKey
);
@ -3529,7 +3500,7 @@ export async function startApp(): Promise<void> {
messageRequestResponseType,
} = ev;
window.log.info('onMessageRequestResponse', {
log.info('onMessageRequestResponse', {
threadE164,
threadUuid,
groupId: `group(${groupId})`,
@ -3587,7 +3558,7 @@ export async function startApp(): Promise<void> {
highTrust: true,
}
);
window.log.info(
log.info(
logTitle,
source,
sourceUuid,
@ -3624,7 +3595,7 @@ export async function startApp(): Promise<void> {
uuid: senderUuid,
});
window.log.info(
log.info(
'read sync',
sender,
senderUuid,
@ -3656,7 +3627,7 @@ export async function startApp(): Promise<void> {
uuid: senderUuid,
});
window.log.info(
log.info(
'view sync',
senderE164,
senderUuid,
@ -3698,7 +3669,7 @@ export async function startApp(): Promise<void> {
} as Partial<ConversationAttributesType>) as WhatIsThis);
const error = c.validate();
if (error) {
window.log.error(
log.error(
'Invalid verified sync received:',
e164,
uuid,
@ -3718,10 +3689,10 @@ export async function startApp(): Promise<void> {
state = 'UNVERIFIED';
break;
default:
window.log.error(`Got unexpected verified state: ${ev.verified.state}`);
log.error(`Got unexpected verified state: ${ev.verified.state}`);
}
window.log.info(
log.info(
'got verified sync for',
e164,
uuid,
@ -3771,7 +3742,7 @@ export async function startApp(): Promise<void> {
}
);
window.log.info(
log.info(
'delivery receipt from',
source,
sourceUuid,
@ -3783,7 +3754,7 @@ export async function startApp(): Promise<void> {
);
if (!sourceConversationId) {
window.log.info('no conversation for', source, sourceUuid);
log.info('no conversation for', source, sourceUuid);
return;
}

View File

@ -19,6 +19,7 @@ import { isOlderThan } from './util/timestamp';
import { parseRetryAfter } from './util/parseRetryAfter';
import { getEnvironment, Environment } from './environment';
import { StorageInterface } from './types/Storage.d';
import * as log from './logging/log';
export type ChallengeResponse = {
readonly captcha: string;
@ -143,7 +144,7 @@ export class ChallengeHandler {
const stored: ReadonlyArray<StoredEntity> =
this.options.storage.get('challenge:retry-message-ids') || [];
window.log.info(`challenge: loading ${stored.length} messages`);
log.info(`challenge: loading ${stored.length} messages`);
const entityMap = new Map<string, StoredEntity>();
for (const entity of stored) {
@ -162,13 +163,13 @@ export class ChallengeHandler {
const messages: Array<MinimalMessage> = maybeMessages.filter(isNotNil);
window.log.info(`challenge: loaded ${messages.length} messages`);
log.info(`challenge: loaded ${messages.length} messages`);
await Promise.all(
messages.map(async message => {
const entity = entityMap.get(message.id);
if (!entity) {
window.log.error(
log.error(
'challenge: unexpected missing entity ' +
`for ${message.idForLogging()}`
);
@ -177,9 +178,7 @@ export class ChallengeHandler {
const expireAfter = this.options.expireAfter || DEFAULT_EXPIRE_AFTER;
if (isOlderThan(entity.createdAt, expireAfter)) {
window.log.info(
`challenge: expired entity for ${message.idForLogging()}`
);
log.info(`challenge: expired entity for ${message.idForLogging()}`);
return;
}
@ -198,7 +197,7 @@ export class ChallengeHandler {
public async onOffline(): Promise<void> {
this.isOnline = false;
window.log.info('challenge: offline');
log.info('challenge: offline');
}
public async onOnline(): Promise<void> {
@ -207,7 +206,7 @@ export class ChallengeHandler {
const pending = Array.from(this.pendingRetries.values());
this.pendingRetries.clear();
window.log.info(`challenge: online, retrying ${pending.length} messages`);
log.info(`challenge: online, retrying ${pending.length} messages`);
// Retry messages that matured while we were offline
await Promise.all(pending.map(message => this.retryOne(message)));
@ -221,7 +220,7 @@ export class ChallengeHandler {
entity?: StoredEntity
): Promise<void> {
if (this.isRegistered(message)) {
window.log.info(
log.info(
`challenge: message already registered ${message.idForLogging()}`
);
return;
@ -235,7 +234,7 @@ export class ChallengeHandler {
// Message is already retryable - initiate new send
if (retry === RetryMode.Retry && shouldRetrySend(message)) {
window.log.info(
log.info(
`challenge: sending message immediately ${message.idForLogging()}`
);
await this.retryOne(message);
@ -244,7 +243,7 @@ export class ChallengeHandler {
const error = message.getLastChallengeError();
if (!error) {
window.log.error('Unexpected message without challenge error');
log.error('Unexpected message without challenge error');
return;
}
@ -262,19 +261,19 @@ export class ChallengeHandler {
}, waitTime)
);
window.log.info(
log.info(
`challenge: tracking ${message.idForLogging()} ` +
`with waitTime=${waitTime}`
);
if (!error.data.options || !error.data.options.includes('recaptcha')) {
window.log.error(
log.error(
`challenge: unexpected options ${JSON.stringify(error.data.options)}`
);
}
if (!error.data.token) {
window.log.error(
log.error(
`challenge: no token in challenge error ${JSON.stringify(error.data)}`
);
} else if (message.isNormalBubble()) {
@ -285,9 +284,7 @@ export class ChallengeHandler {
// challenge to be fully completed.
this.solve(error.data.token);
} else {
window.log.info(
`challenge: not a bubble message ${message.idForLogging()}`
);
log.info(`challenge: not a bubble message ${message.idForLogging()}`);
}
}
@ -302,7 +299,7 @@ export class ChallengeHandler {
}
public async unregister(message: MinimalMessage): Promise<void> {
window.log.info(`challenge: unregistered ${message.idForLogging()}`);
log.info(`challenge: unregistered ${message.idForLogging()}`);
this.trackedMessages.delete(message.id);
this.pendingRetries.delete(message);
@ -335,7 +332,7 @@ export class ChallengeHandler {
}
private async retrySend(force = false): Promise<void> {
window.log.info(`challenge: retrySend force=${force}`);
log.info(`challenge: retrySend force=${force}`);
const retries = Array.from(this.trackedMessages.values())
.map(({ message }) => message)
@ -360,13 +357,13 @@ export class ChallengeHandler {
}
const retryCount = this.retryCountById.get(message.id) || 0;
window.log.info(
log.info(
`challenge: retrying sending ${message.idForLogging()}, ` +
`retry count: ${retryCount}`
);
if (retryCount === MAX_RETRIES) {
window.log.info(
log.info(
`challenge: dropping message ${message.idForLogging()}, ` +
'too many failed retries'
);
@ -387,7 +384,7 @@ export class ChallengeHandler {
try {
await message.retrySend();
} catch (error) {
window.log.error(
log.error(
`challenge: failed to send ${message.idForLogging()} due to ` +
`error: ${error && error.stack}`
);
@ -396,13 +393,13 @@ export class ChallengeHandler {
}
if (sent) {
window.log.info(`challenge: message ${message.idForLogging()} sent`);
log.info(`challenge: message ${message.idForLogging()} sent`);
this.retryCountById.delete(message.id);
if (this.trackedMessages.size === 0) {
this.options.setChallengeStatus('idle');
}
} else {
window.log.info(`challenge: message ${message.idForLogging()} not sent`);
log.info(`challenge: message ${message.idForLogging()} not sent`);
this.retryCountById.set(message.id, retryCount + 1);
await this.register(message, RetryMode.NoImmediateRetry);
@ -431,7 +428,7 @@ export class ChallengeHandler {
this.options.setChallengeStatus('pending');
window.log.info('challenge: sending challenge to server');
log.info('challenge: sending challenge to server');
try {
await this.sendChallengeResponse({
@ -440,14 +437,12 @@ export class ChallengeHandler {
captcha: response.captcha,
});
} catch (error) {
window.log.error(
`challenge: challenge failure, error: ${error && error.stack}`
);
log.error(`challenge: challenge failure, error: ${error && error.stack}`);
this.options.setChallengeStatus('required');
return;
}
window.log.info('challenge: challenge success. force sending');
log.info('challenge: challenge success. force sending');
this.options.setChallengeStatus('idle');
@ -470,7 +465,7 @@ export class ChallengeHandler {
const retryAfter = parseRetryAfter(error.responseHeaders['retry-after']);
window.log.info(`challenge: retry after ${retryAfter}ms`);
log.info(`challenge: retry after ${retryAfter}ms`);
this.options.onChallengeFailed(retryAfter);
return;
}

View File

@ -35,6 +35,7 @@ import {
import { SignalClipboard } from '../quill/signal-clipboard';
import { DirectionalBlot } from '../quill/block/blot';
import { getClassNamesFor } from '../util/getClassNamesFor';
import * as log from '../logging/log';
Quill.register('formats/emoji', EmojiBlot);
Quill.register('formats/mention', MentionBlot);
@ -231,7 +232,7 @@ export function CompositionInput(props: Props): React.ReactElement {
const [text, mentions] = getTextAndMentions();
window.log.info(
log.info(
`CompositionInput: Submitting message ${timestamp} with ${mentions.length} mentions`
);
onSubmit(text, mentions, timestamp);

View File

@ -6,6 +6,7 @@ import PQueue from 'p-queue';
import LRU from 'lru-cache';
import { WaveformCache } from '../types/Audio';
import * as log from '../logging/log';
const MAX_WAVEFORM_COUNT = 1000;
const MAX_PARALLEL_COMPUTE = 8;
@ -84,11 +85,11 @@ async function doComputePeaks(
): Promise<ComputePeaksResult> {
const existing = waveformCache.get(url);
if (existing) {
window.log.info('GlobalAudioContext: waveform cache hit', url);
log.info('GlobalAudioContext: waveform cache hit', url);
return Promise.resolve(existing);
}
window.log.info('GlobalAudioContext: waveform cache miss', url);
log.info('GlobalAudioContext: waveform cache miss', url);
// Load and decode `url` into a raw PCM
const response = await fetch(url);
@ -98,7 +99,7 @@ async function doComputePeaks(
const peaks = new Array(barCount).fill(0);
if (duration > MAX_AUDIO_DURATION) {
window.log.info(
log.info(
`GlobalAudioContext: audio ${url} duration ${duration}s is too long`
);
const emptyResult = { peaks, duration };
@ -151,14 +152,11 @@ export async function computePeaks(
const pending = inProgressMap.get(computeKey);
if (pending) {
window.log.info(
'GlobalAudioContext: already computing peaks for',
computeKey
);
log.info('GlobalAudioContext: already computing peaks for', computeKey);
return pending;
}
window.log.info('GlobalAudioContext: queue computing peaks for', computeKey);
log.info('GlobalAudioContext: queue computing peaks for', computeKey);
const promise = computeQueue.add(() => doComputePeaks(url, barCount));
inProgressMap.set(computeKey, promise);

View File

@ -18,6 +18,7 @@ import { useGetCallingFrameBuffer } from '../calling/useGetCallingFrameBuffer';
import { LocalizerType } from '../types/Util';
import { usePageVisibility } from '../util/hooks';
import { nonRenderedRemoteParticipant } from '../util/ringrtc/nonRenderedRemoteParticipant';
import * as log from '../logging/log';
const MIN_RENDERED_HEIGHT = 180;
const PARTICIPANT_MARGIN = 10;
@ -197,9 +198,7 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
// the LARGER of the two could cause overflow.)
const widestRow = maxBy(rows, totalRemoteParticipantWidthAtMinHeight);
if (!widestRow) {
window.log.error(
'Unable to find the widest row, which should be impossible'
);
log.error('Unable to find the widest row, which should be impossible');
continue;
}
const widthScalar =
@ -331,7 +330,7 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
bounds
onResize={({ bounds }) => {
if (!bounds) {
window.log.error('We should be measuring the bounds');
log.error('We should be measuring the bounds');
return;
}
setContainerDimensions(bounds);
@ -346,7 +345,7 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
bounds
onResize={({ bounds }) => {
if (!bounds) {
window.log.error('We should be measuring the bounds');
log.error('We should be measuring the bounds');
return;
}
setGridDimensions(bounds);

View File

@ -5,6 +5,7 @@ import React from 'react';
import { LocalizerType, RenderTextCallbackType } from '../types/Util';
import { ReplacementValuesType } from '../types/I18N';
import * as log from '../logging/log';
export type FullJSXType = Array<JSX.Element | string> | JSX.Element | string;
@ -31,7 +32,7 @@ export class Intl extends React.Component<Props> {
const { id, components } = this.props;
if (!components) {
window.log.error(
log.error(
`Error: Intl component prop not provided; Metadata: id '${id}', index ${index}, placeholder '${placeholderName}'`
);
return null;
@ -39,7 +40,7 @@ export class Intl extends React.Component<Props> {
if (Array.isArray(components)) {
if (!components || !components.length || components.length <= index) {
window.log.error(
log.error(
`Error: Intl missing provided component for id '${id}', index ${index}`
);
@ -51,7 +52,7 @@ export class Intl extends React.Component<Props> {
const value = components[placeholderName];
if (!value) {
window.log.error(
log.error(
`Error: Intl missing provided component for id '${id}', placeholder '${placeholderName}'`
);

View File

@ -22,6 +22,7 @@ import { LocalizerType } from '../types/Util';
import { MediaItemType, MessageAttributesType } from '../types/MediaItem';
import { formatDuration } from '../util/formatDuration';
import { useRestoreFocus } from '../util/hooks/useRestoreFocus';
import * as log from '../logging/log';
export type PropsType = {
children?: ReactNode;
@ -294,7 +295,7 @@ export function Lightbox({
/>
);
} else {
window.log.info('Lightbox: Unexpected content type', { contentType });
log.info('Lightbox: Unexpected content type', { contentType });
content = (
<button

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import React, { ReactNode } from 'react';
import * as log from '../logging/log';
type InternalPropsType = Readonly<{
id: string;
@ -39,7 +40,7 @@ const onRender: InternalPropsType['onRender'] = (
start,
commit
) => {
window.log.info(
log.info(
`Profiler.tsx(${id}): actual=${actual.toFixed(1)}ms phase=${phase} ` +
`base=${base.toFixed(1)}ms start=${start.toFixed(1)}ms ` +
`commit=${commit.toFixed(1)}ms`

View File

@ -19,6 +19,7 @@ import { usePrevious } from '../../util/hooks';
import { missingCaseError } from '../../util/missingCaseError';
import { Tooltip, TooltipPlacement } from '../Tooltip';
import type { TimelineItemType } from './TimelineItem';
import * as log from '../../logging/log';
export type PropsActionsType = {
messageSizeChanged: (messageId: string, conversationId: string) => void;
@ -66,9 +67,7 @@ export const CallingNotification: React.FC<PropsType> = React.memo(props => {
timestamp = props.startedTime;
break;
default:
window.log.error(
`CallingNotification missing case: ${missingCaseError(props)}`
);
log.error(`CallingNotification missing case: ${missingCaseError(props)}`);
return null;
}
@ -79,7 +78,7 @@ export const CallingNotification: React.FC<PropsType> = React.memo(props => {
bounds
onResize={({ bounds }) => {
if (!bounds) {
window.log.error('We should be measuring the bounds');
log.error('We should be measuring the bounds');
return;
}
setHeight(bounds.height);
@ -173,7 +172,7 @@ function renderCallingNotificationButton(
break;
}
default:
window.log.error(missingCaseError(props));
log.error(missingCaseError(props));
return null;
}

View File

@ -11,6 +11,7 @@ import { LocalizerType } from '../../types/Util';
import { ConfirmationDialog } from '../ConfirmationDialog';
import { Button, ButtonSize, ButtonVariant } from '../Button';
import { shouldBlurAvatar } from '../../util/shouldBlurAvatar';
import * as log from '../../logging/log';
export type Props = {
about?: string;
@ -133,7 +134,7 @@ export const ConversationHero = ({
return;
}
window.log.info('ConversationHero: calling onHeightChange');
log.info('ConversationHero: calling onHeightChange');
onHeightChange();
}, [
about,

View File

@ -5,6 +5,7 @@ import React, { ReactNode } from 'react';
import { LocalizerType } from '../../types/Util';
import * as Errors from '../../types/errors';
import * as log from '../../logging/log';
export type Props = {
i18n: LocalizerType;
@ -27,7 +28,7 @@ export class ErrorBoundary extends React.PureComponent<Props, State> {
}
public static getDerivedStateFromError(error: Error): State {
window.log.error(
log.error(
'ErrorBoundary: captured rendering error',
Errors.toLogFormat(error)
);

View File

@ -14,6 +14,7 @@ import {
getImageDimensions,
defaultBlurHash,
} from '../../types/Attachment';
import * as log from '../../logging/log';
const MAX_GIF_REPEAT = 4;
const MAX_GIF_TIME = 8;
@ -87,7 +88,7 @@ export const GIF: React.FC<Props> = props => {
if (isPlaying) {
video.play().catch(error => {
window.log.info(
log.info(
"Failed to match GIF playback to window's state",
(error && error.stack) || error
);

View File

@ -10,6 +10,7 @@ import { ConversationType } from '../../state/ducks/conversations';
import { Intl } from '../Intl';
import { ContactName } from './ContactName';
import { GroupV1MigrationDialog } from '../GroupV1MigrationDialog';
import * as log from '../../logging/log';
export type PropsDataType = {
areWeInvited: boolean;
@ -79,9 +80,7 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
hasMigrated
i18n={i18n}
invitedMembers={invitedMembers}
migrate={() =>
window.log.warn('GroupV1Migration: Modal called migrate()')
}
migrate={() => log.warn('GroupV1Migration: Modal called migrate()')}
onClose={dismissDialog}
/>
) : null}

View File

@ -34,6 +34,7 @@ import { Emoji } from '../emoji/Emoji';
import { LinkPreviewDate } from './LinkPreviewDate';
import { LinkPreviewType } from '../../types/message/LinkPreviews';
import { shouldUseFullSizeLinkPreviewImage } from '../../linkPreviews/shouldUseFullSizeLinkPreviewImage';
import * as log from '../../logging/log';
import {
AttachmentType,
@ -386,7 +387,7 @@ export class Message extends React.PureComponent<Props, State> {
public handleImageError = (): void => {
const { id } = this.props;
window.log.info(
log.info(
`Message ${id}: Image failed to load; failing over to placeholder`
);
this.setState({
@ -492,7 +493,7 @@ export class Message extends React.PureComponent<Props, State> {
timestamp,
delta,
});
window.log.info(
log.info(
`Message.tsx: Rendered 'send complete' for message ${timestamp}; took ${delta}ms`
);
}
@ -803,7 +804,7 @@ export class Message extends React.PureComponent<Props, State> {
played = readStatus === ReadStatus.Viewed;
break;
default:
window.log.error(missingCaseError(direction));
log.error(missingCaseError(direction));
played = false;
break;
}
@ -2131,7 +2132,7 @@ export class Message extends React.PureComponent<Props, State> {
if (isTapToView) {
if (isAttachmentPending) {
window.log.info(
log.info(
'<Message> handleOpen: tap-to-view attachment is pending; not showing the lightbox'
);
return;

View File

@ -12,6 +12,7 @@ import type { DirectionType, MessageStatusType } from './Message';
import { ComputePeaksResult } from '../GlobalAudioContext';
import { MessageMetadata } from './MessageMetadata';
import * as log from '../../logging/log';
export type Props = {
renderingContext: string;
@ -214,7 +215,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
return noop;
}
window.log.info('MessageAudio: loading audio and computing waveform');
log.info('MessageAudio: loading audio and computing waveform');
let canceled = false;
@ -238,7 +239,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
setHasPeaks(true);
setDuration(Math.max(newDuration, 1e-23));
} catch (err) {
window.log.error(
log.error(
'MessageAudio: computePeaks error, marking as corrupted',
err
);
@ -271,7 +272,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
useEffect(() => {
// Owner of Audio instance changed
if (!isActive) {
window.log.info('MessageAudio: pausing old owner', id);
log.info('MessageAudio: pausing old owner', id);
setIsPlaying(false);
setCurrentTime(0);
return noop;
@ -285,7 +286,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
};
const onEnded = () => {
window.log.info('MessageAudio: ended, changing UI', id);
log.info('MessageAudio: ended, changing UI', id);
setIsPlaying(false);
setCurrentTime(0);
};
@ -296,7 +297,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
'Audio should have definite duration on `loadedmetadata` event'
);
window.log.info('MessageAudio: `loadedmetadata` event', id);
log.info('MessageAudio: `loadedmetadata` event', id);
// Sync-up audio's time in case if <audio/> loaded its source after
// user clicked on waveform
@ -304,7 +305,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
};
const onDurationChange = () => {
window.log.info('MessageAudio: `durationchange` event', id);
log.info('MessageAudio: `durationchange` event', id);
if (!Number.isNaN(audio.duration)) {
setDuration(Math.max(audio.duration, 1e-23));
@ -336,13 +337,13 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
return;
}
window.log.info('MessageAudio: resuming playback for', id);
log.info('MessageAudio: resuming playback for', id);
audio.currentTime = currentTime;
audio.play().catch(error => {
window.log.info('MessageAudio: resume error', id, error.stack || error);
log.info('MessageAudio: resume error', id, error.stack || error);
});
} else {
window.log.info('MessageAudio: pausing playback for', id);
log.info('MessageAudio: pausing playback for', id);
audio.pause();
}
}, [id, audio, isActive, isPlaying, currentTime]);
@ -351,7 +352,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
setIsPlaying(!isPlaying);
if (!isActive && !isPlaying) {
window.log.info('MessageAudio: changing owner', id);
log.info('MessageAudio: changing owner', id);
setActiveAudioID(id, renderingContext);
// Pause old audio

View File

@ -18,6 +18,7 @@ import { ConversationType } from '../../state/ducks/conversations';
import { groupBy } from '../../util/mapUtil';
import { ContactNameColorType } from '../../types/Colors';
import { SendStatus } from '../../messages/MessageSendState';
import * as log from '../../logging/log';
export type Contact = Pick<
ConversationType,
@ -292,16 +293,16 @@ export class MessageDetail extends React.Component<Props> {
contactNameColor={contactNameColor}
containerElementRef={this.messageContainerRef}
deleteMessage={() =>
window.log.warn('MessageDetail: deleteMessage called!')
log.warn('MessageDetail: deleteMessage called!')
}
deleteMessageForEveryone={() =>
window.log.warn('MessageDetail: deleteMessageForEveryone called!')
log.warn('MessageDetail: deleteMessageForEveryone called!')
}
disableMenu
disableScroll
displayTapToViewMessage={displayTapToViewMessage}
downloadAttachment={() =>
window.log.warn('MessageDetail: deleteMessageForEveryone called!')
log.warn('MessageDetail: deleteMessageForEveryone called!')
}
doubleCheckMissingQuoteReference={doubleCheckMissingQuoteReference}
i18n={i18n}
@ -320,7 +321,7 @@ export class MessageDetail extends React.Component<Props> {
retrySend={retrySend}
showForwardMessageModal={showForwardMessageModal}
scrollToQuotedMessage={() => {
window.log.warn('MessageDetail: scrollToQuotedMessage called!');
log.warn('MessageDetail: scrollToQuotedMessage called!');
}}
showContactDetail={showContactDetail}
showContactModal={showContactModal}
@ -331,9 +332,7 @@ export class MessageDetail extends React.Component<Props> {
showExpiredOutgoingTapToViewToast
}
showMessageDetail={() => {
window.log.warn(
'MessageDetail: deleteMessageForEveryone called!'
);
log.warn('MessageDetail: deleteMessageForEveryone called!');
}}
showVisualAttachment={showVisualAttachment}
/>

View File

@ -69,6 +69,7 @@ import {
ProfileChangeNotification,
PropsType as ProfileChangeNotificationPropsType,
} from './ProfileChangeNotification';
import * as log from '../../logging/log';
type CallHistoryType = {
type: 'callHistory';
@ -203,7 +204,7 @@ export class TimelineItem extends React.PureComponent<PropsType> {
} = this.props;
if (!item) {
window.log.warn(`TimelineItem: item ${id} provided was falsey`);
log.warn(`TimelineItem: item ${id} provided was falsey`);
return null;
}

View File

@ -8,6 +8,7 @@ import { SystemMessage } from './SystemMessage';
import { Intl } from '../Intl';
import { LocalizerType } from '../../types/Util';
import * as expirationTimer from '../../util/expirationTimer';
import * as log from '../../logging/log';
export type TimerNotificationType =
| 'fromOther'
@ -78,7 +79,7 @@ export const TimerNotification: FunctionComponent<Props> = props => {
: i18n('timerSetByMember', [timespan]);
break;
default:
window.log.warn('TimerNotification: unsupported type provided:', type);
log.warn('TimerNotification: unsupported type provided:', type);
break;
}

View File

@ -10,6 +10,7 @@ import {
} from '../../../util/GoogleChrome';
import { LocalizerType } from '../../../types/Util';
import { MediaItemType } from '../../../types/MediaItem';
import * as log from '../../../logging/log';
export type Props = {
mediaItem: MediaItemType;
@ -35,7 +36,7 @@ export class MediaGridItem extends React.Component<Props, State> {
}
public onImageError(): void {
window.log.info(
log.info(
'MediaGridItem: Image failed to load; failing over to placeholder'
);
this.setState({

View File

@ -21,6 +21,7 @@ import Fuse from 'fuse.js';
import PQueue from 'p-queue';
import is from '@sindresorhus/is';
import { getOwn } from '../../util/getOwn';
import * as log from '../../logging/log';
export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF'];
@ -108,7 +109,7 @@ export const preloadImages = async (): Promise<void> => {
setTimeout(reject, 5000);
});
window.log.info('Preloading emoji images');
log.info('Preloading emoji images');
const start = Date.now();
data.forEach(emoji => {
@ -124,7 +125,7 @@ export const preloadImages = async (): Promise<void> => {
await imageQueue.onEmpty();
const end = Date.now();
window.log.info(`Done preloading emoji images in ${end - start}ms`);
log.info(`Done preloading emoji images in ${end - start}ms`);
};
const dataByShortName = keyBy(data, 'short_name');

View File

@ -8,6 +8,7 @@ import { missingCaseError } from './util/missingCaseError';
import { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups';
import { SignalService as Proto } from './protobuf';
import * as log from './logging/log';
export type SmartContactRendererType = (conversationId: string) => FullJSXType;
export type StringRendererType = (
@ -137,7 +138,7 @@ export function renderChangeDetail(
}
return renderString('GroupV2--access-attributes--all--unknown', i18n);
}
window.log.warn(
log.warn(
`access-attributes change type, privilege ${newPrivilege} is unknown`
);
return '';
@ -167,7 +168,7 @@ export function renderChangeDetail(
}
return renderString('GroupV2--access-members--all--unknown', i18n);
}
window.log.warn(
log.warn(
`access-members change type, privilege ${newPrivilege} is unknown`
);
return '';
@ -207,7 +208,7 @@ export function renderChangeDetail(
i18n
);
}
window.log.warn(
log.warn(
`access-invite-link change type, privilege ${newPrivilege} is unknown`
);
return '';
@ -318,7 +319,7 @@ export function renderChangeDetail(
// Note: this shouldn't happen, because we only capture 'add-from-link' status
// from group change events, which always have a sender.
window.log.warn('member-add-from-link change type; we have no from!');
log.warn('member-add-from-link change type; we have no from!');
return renderString('GroupV2--member-add--other--unknown', i18n, [
renderContact(conversationId),
]);
@ -338,7 +339,7 @@ export function renderChangeDetail(
// Note: this shouldn't happen, because we only capture 'add-from-admin-approval'
// status from group change events, which always have a sender.
window.log.warn(
log.warn(
'member-add-from-admin-approval change type; we have no from, and we are joiner!'
);
return renderString(
@ -367,9 +368,7 @@ export function renderChangeDetail(
// Note: this shouldn't happen, because we only capture 'add-from-admin-approval'
// status from group change events, which always have a sender.
window.log.warn(
'member-add-from-admin-approval change type; we have no from'
);
log.warn('member-add-from-admin-approval change type; we have no from');
return renderString(
'GroupV2--member-add-from-admin-approval--other--unknown',
i18n,
@ -493,7 +492,7 @@ export function renderChangeDetail(
[renderContact(conversationId)]
);
}
window.log.warn(
log.warn(
`member-privilege change type, privilege ${newPrivilege} is unknown`
);
return '';
@ -800,9 +799,7 @@ export function renderChangeDetail(
}
return renderString('GroupV2--group-link-add--disabled--unknown', i18n);
}
window.log.warn(
`group-link-add change type, privilege ${privilege} is unknown`
);
log.warn(`group-link-add change type, privilege ${privilege} is unknown`);
return '';
}
if (detail.type === 'group-link-reset') {

View File

@ -13,6 +13,7 @@ import {
import { ClientZkGroupCipher } from 'zkgroup';
import { v4 as getGuid } from 'uuid';
import LRU from 'lru-cache';
import * as log from './logging/log';
import {
getCredentialsForToday,
GROUP_CREDENTIALS_KEY,
@ -400,10 +401,7 @@ async function uploadAvatar(
key,
};
} catch (error) {
window.log.warn(
`uploadAvatar/${logId} Failed to upload avatar`,
error.stack
);
log.warn(`uploadAvatar/${logId} Failed to upload avatar`, error.stack);
throw error;
}
}
@ -1248,20 +1246,20 @@ export async function modifyGroupV2({
const MAX_ATTEMPTS = 5;
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {
window.log.info(`modifyGroupV2/${idLog}: Starting attempt ${attempt}`);
log.info(`modifyGroupV2/${idLog}: Starting attempt ${attempt}`);
try {
// eslint-disable-next-line no-await-in-loop
await window.waitForEmptyEventQueue();
window.log.info(`modifyGroupV2/${idLog}: Queuing attempt ${attempt}`);
log.info(`modifyGroupV2/${idLog}: Queuing attempt ${attempt}`);
// eslint-disable-next-line no-await-in-loop
await conversation.queueJob('modifyGroupV2', async () => {
window.log.info(`modifyGroupV2/${idLog}: Running attempt ${attempt}`);
log.info(`modifyGroupV2/${idLog}: Running attempt ${attempt}`);
const actions = await createGroupChange();
if (!actions) {
window.log.warn(
log.warn(
`modifyGroupV2/${idLog}: No change actions. Returning early.`
);
return;
@ -1346,20 +1344,20 @@ export async function modifyGroupV2({
});
// If we've gotten here with no error, we exit!
window.log.info(
log.info(
`modifyGroupV2/${idLog}: Update complete, with attempt ${attempt}!`
);
break;
} catch (error) {
if (error.code === 409 && Date.now() <= timeoutTime) {
window.log.info(
log.info(
`modifyGroupV2/${idLog}: Conflict while updating. Trying again...`
);
// eslint-disable-next-line no-await-in-loop
await conversation.fetchLatestGroupV2Data({ force: true });
} else if (error.code === 409) {
window.log.error(
log.error(
`modifyGroupV2/${idLog}: Conflict while updating. Timed out; not retrying.`
);
// We don't wait here because we're breaking out of the loop immediately.
@ -1367,9 +1365,7 @@ export async function modifyGroupV2({
throw error;
} else {
const errorString = error && error.stack ? error.stack : error;
window.log.error(
`modifyGroupV2/${idLog}: Error updating: ${errorString}`
);
log.error(`modifyGroupV2/${idLog}: Error updating: ${errorString}`);
throw error;
}
}
@ -1396,7 +1392,7 @@ export function deriveGroupFields(masterKey: Uint8Array): GroupFields {
return cached;
}
window.log.info('deriveGroupFields: cache miss');
log.info('deriveGroupFields: cache miss');
const secretParams = deriveGroupSecretParams(masterKey);
const publicParams = deriveGroupPublicParams(secretParams);
@ -1448,7 +1444,7 @@ async function makeRequestWithTemporalRetry<T>({
return await request(sender, todayOptions);
} catch (todayError) {
if (todayError.code === TEMPORAL_AUTH_REJECTED_CODE) {
window.log.warn(
log.warn(
`makeRequestWithTemporalRetry/${logId}: Trying again with tomorrow's credentials`
);
const tomorrowOptions = getGroupCredentials({
@ -1657,7 +1653,7 @@ export async function createGroupV2({
hash: uploadedAvatar.hash,
};
} catch (err) {
window.log.warn(
log.warn(
`createGroupV2/${logId}: avatar failed to save to disk. Continuing on`
);
}
@ -1753,7 +1749,7 @@ export async function hasV1GroupBeenMigrated(
const logId = conversation.idForLogging();
const isGroupV1 = getIsGroupV1(conversation.attributes);
if (!isGroupV1) {
window.log.warn(
log.warn(
`checkForGV2Existence/${logId}: Called for non-GroupV1 conversation!`
);
return false;
@ -1887,21 +1883,21 @@ export async function getGroupMigrationMembers(
);
}
if (!isMe(contact.attributes) && window.GV2_MIGRATION_DISABLE_ADD) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: membersV2 - skipping ${e164} due to GV2_MIGRATION_DISABLE_ADD flag`
);
return null;
}
if (!contact.get('uuid')) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: membersV2 - missing uuid for ${e164}, skipping.`
);
return null;
}
if (!contact.get('profileKey')) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: membersV2 - missing profileKey for member ${e164}, skipping.`
);
return null;
@ -1921,19 +1917,19 @@ export async function getGroupMigrationMembers(
capabilities = contact.get('capabilities');
if (!capabilities || !capabilities.gv2) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv2 capability, skipping.`
);
return null;
}
if (!capabilities || !capabilities['gv1-migration']) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv1-migration capability, skipping.`
);
return null;
}
if (!contact.get('profileKeyCredential')) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: membersV2 - no profileKeyCredential for ${e164}, skipping.`
);
return null;
@ -1974,7 +1970,7 @@ export async function getGroupMigrationMembers(
}
if (!isMe(contact.attributes) && window.GV2_MIGRATION_DISABLE_INVITE) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: pendingMembersV2 - skipping ${e164} due to GV2_MIGRATION_DISABLE_INVITE flag`
);
droppedGV2MemberIds.push(conversationId);
@ -1982,7 +1978,7 @@ export async function getGroupMigrationMembers(
}
if (!contact.get('uuid')) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: pendingMembersV2 - missing uuid for ${e164}, skipping.`
);
droppedGV2MemberIds.push(conversationId);
@ -1991,14 +1987,14 @@ export async function getGroupMigrationMembers(
const capabilities = contact.get('capabilities');
if (!capabilities || !capabilities.gv2) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv2 capability, skipping.`
);
droppedGV2MemberIds.push(conversationId);
return null;
}
if (!capabilities || !capabilities['gv1-migration']) {
window.log.warn(
log.warn(
`getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv1-migration capability, skipping.`
);
droppedGV2MemberIds.push(conversationId);
@ -2062,7 +2058,7 @@ export async function initiateMigrationToGroupV2(
const groupId = Bytes.toBase64(fields.id);
const logId = `groupv2(${groupId})`;
window.log.info(
log.info(
`initiateMigrationToGroupV2/${logId}: Migrating from ${conversation.idForLogging()}`
);
@ -2166,7 +2162,7 @@ export async function initiateMigrationToGroupV2(
request: (sender, options) => sender.createGroup(groupProto, options),
});
} catch (error) {
window.log.error(
log.error(
`initiateMigrationToGroupV2/${logId}: Error creating group:`,
error.stack
);
@ -2206,7 +2202,7 @@ export async function initiateMigrationToGroupV2(
const alreadyMigrated = await hasV1GroupBeenMigrated(conversation);
if (!alreadyMigrated) {
window.log.error(
log.error(
`initiateMigrationToGroupV2/${logId}: Group has not already been migrated, re-throwing error`
);
throw error;
@ -2315,7 +2311,7 @@ export async function wrapWithSyncMessageSend({
}
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
`wrapWithSyncMessageSend/${logId}: We are primary device; not sync message`
);
return;
@ -2349,7 +2345,7 @@ export async function waitThenRespondToGroupV2Migration(
// And finally try to migrate the group
await respondToGroupV2Migration(options);
} catch (error) {
window.log.error(
log.error(
`waitThenRespondToGroupV2Migration/${conversation.idForLogging()}: respondToGroupV2Migration failure:`,
error && error.stack ? error.stack : error
);
@ -2420,7 +2416,7 @@ export async function joinGroupV2ViaLinkAndMigrate({
const groupId = Bytes.toBase64(fields.id);
const logId = idForLogging(groupId);
window.log.info(
log.info(
`joinGroupV2ViaLinkAndMigrate/${logId}: Migrating from ${conversation.idForLogging()}`
);
@ -2518,7 +2514,7 @@ export async function respondToGroupV2Migration({
const groupId = Bytes.toBase64(fields.id);
const logId = idForLogging(groupId);
window.log.info(
log.info(
`respondToGroupV2Migration/${logId}: Migrating from ${conversation.idForLogging()}`
);
@ -2567,7 +2563,7 @@ export async function respondToGroupV2Migration({
firstGroupState = response?.changes?.groupChanges?.[0]?.groupState;
} catch (error) {
if (error.code === GROUP_ACCESS_DENIED_CODE) {
window.log.info(
log.info(
`respondToGroupV2Migration/${logId}: Failed to access log endpoint; fetching full group state`
);
try {
@ -2579,7 +2575,7 @@ export async function respondToGroupV2Migration({
});
} catch (secondError) {
if (secondError.code === GROUP_ACCESS_DENIED_CODE) {
window.log.info(
log.info(
`respondToGroupV2Migration/${logId}: Failed to access state endpoint; user is no longer part of group`
);
@ -2723,7 +2719,7 @@ export async function waitThenMaybeUpdateGroup(
const { conversation } = options;
if (conversation.isBlocked()) {
window.log.info(
log.info(
`waitThenMaybeUpdateGroup: Group ${conversation.idForLogging()} is blocked, returning early`
);
return;
@ -2739,7 +2735,7 @@ export async function waitThenMaybeUpdateGroup(
isMoreRecentThan(lastSuccessfulGroupFetch, FIVE_MINUTES)
) {
const waitTime = lastSuccessfulGroupFetch + FIVE_MINUTES - Date.now();
window.log.info(
log.info(
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: group update ` +
`was fetched recently, skipping for ${waitTime}ms`
);
@ -2754,7 +2750,7 @@ export async function waitThenMaybeUpdateGroup(
conversation.lastSuccessfulGroupFetch = Date.now();
} catch (error) {
window.log.error(
log.error(
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: maybeUpdateGroup failure:`,
error && error.stack ? error.stack : error
);
@ -2792,7 +2788,7 @@ export async function maybeUpdateGroup(
{ viaSync }
);
} catch (error) {
window.log.error(
log.error(
`maybeUpdateGroup/${logId}: Failed to update group:`,
error && error.stack ? error.stack : error
);
@ -2915,7 +2911,7 @@ async function getGroupUpdates({
}): Promise<UpdatesResultType> {
const logId = idForLogging(group.groupId);
window.log.info(`getGroupUpdates/${logId}: Starting...`);
log.info(`getGroupUpdates/${logId}: Starting...`);
const currentRevision = group.revision;
const isFirstFetch = !isNumber(group.revision);
@ -2936,7 +2932,7 @@ async function getGroupUpdates({
isNumber(newRevision) &&
(isInitialCreationMessage || weAreAwaitingApproval || isOneVersionUp)
) {
window.log.info(`getGroupUpdates/${logId}: Processing just one change`);
log.info(`getGroupUpdates/${logId}: Processing just one change`);
const groupChangeBuffer = Bytes.fromBase64(groupChangeBase64);
const groupChange = Proto.GroupChange.decode(groupChangeBuffer);
const isChangeSupported =
@ -2952,7 +2948,7 @@ async function getGroupUpdates({
});
}
window.log.info(
log.info(
`getGroupUpdates/${logId}: Failing over; group change unsupported`
);
}
@ -2969,12 +2965,12 @@ async function getGroupUpdates({
} catch (error) {
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
// We will fail over to the updateGroupViaState call below
window.log.info(
log.info(
`getGroupUpdates/${logId}: Temporal credential failure, now fetching full group state`
);
} else if (error.code === GROUP_ACCESS_DENIED_CODE) {
// We will fail over to the updateGroupViaState call below
window.log.info(
log.info(
`getGroupUpdates/${logId}: Log access denied, now fetching full group state`
);
} else {
@ -2991,7 +2987,7 @@ async function getGroupUpdates({
});
}
window.log.warn(
log.warn(
`getGroupUpdates/${logId}: No processing was legal! Returning empty changeset.`
);
return {
@ -3025,9 +3021,7 @@ async function updateGroupViaState({
authCredentialBase64: groupCredentials.today.credential,
};
try {
window.log.info(
`updateGroupViaState/${logId}: Getting full group state...`
);
log.info(`updateGroupViaState/${logId}: Getting full group state...`);
// We await this here so our try/catch below takes effect
const result = await getCurrentGroupState(stateOptions);
@ -3037,7 +3031,7 @@ async function updateGroupViaState({
return generateLeftGroupChanges(group);
}
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
window.log.info(
log.info(
`updateGroupViaState/${logId}: Credential for today failed, failing over to tomorrow...`
);
try {
@ -3120,7 +3114,7 @@ async function updateGroupViaLogs({
authCredentialBase64: groupCredentials.today.credential,
};
try {
window.log.info(
log.info(
`updateGroupViaLogs/${logId}: Getting group delta from ${group.revision} to ${newRevision} for group groupv2(${group.groupId})...`
);
const result = await getGroupDelta(deltaOptions);
@ -3128,7 +3122,7 @@ async function updateGroupViaLogs({
return result;
} catch (error) {
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
window.log.info(
log.info(
`updateGroupViaLogs/${logId}: Credential for today failed, failing over to tomorrow...`
);
@ -3153,7 +3147,7 @@ async function generateLeftGroupChanges(
group: ConversationAttributesType
): Promise<UpdatesResultType> {
const logId = idForLogging(group.groupId);
window.log.info(`generateLeftGroupChanges/${logId}: Starting...`);
log.info(`generateLeftGroupChanges/${logId}: Starting...`);
const ourConversationId = window.ConversationController.getOurConversationId();
if (!ourConversationId) {
throw new Error(
@ -3166,7 +3160,7 @@ async function generateLeftGroupChanges(
try {
if (masterKey && groupInviteLinkPassword) {
window.log.info(
log.info(
`generateLeftGroupChanges/${logId}: Have invite link. Attempting to fetch latest revision with it.`
);
const preJoinInfo = await getPreJoinGroupInfo(
@ -3177,7 +3171,7 @@ async function generateLeftGroupChanges(
revision = preJoinInfo.version;
}
} catch (error) {
window.log.warn(
log.warn(
'generateLeftGroupChanges: Failed to fetch latest revision via group link. Code:',
error.code
);
@ -3323,7 +3317,7 @@ async function integrateGroupChanges({
const { groupChange, groupState } = changeState;
if (!groupChange && !groupState) {
window.log.warn(
log.warn(
'integrateGroupChanges: item had neither groupState nor groupChange. Skipping.'
);
continue;
@ -3346,7 +3340,7 @@ async function integrateGroupChanges({
finalMessages.push(groupChangeMessages);
finalMembers.push(members);
} catch (error) {
window.log.error(
log.error(
`integrateGroupChanges/${logId}: Failed to apply change log, continuing to apply remaining change logs.`,
error && error.stack ? error.stack : error
);
@ -3482,7 +3476,7 @@ async function integrateGroupChange({
);
}
window.log.info(
log.info(
`integrateGroupChange/${logId}: Applying full group state, from version ${group.revision} to ${groupState.version}`,
{
isChangePresent: Boolean(groupChange),
@ -3522,7 +3516,7 @@ async function integrateGroupChange({
);
}
window.log.info(
log.info(
`integrateGroupChange/${logId}: Applying group change actions, from version ${group.revision} to ${groupChangeActions.version}`
);
@ -3583,7 +3577,7 @@ async function getCurrentGroupState({
const oldVersion = group.revision;
const newVersion = decryptedGroupState.version;
window.log.info(
log.info(
`getCurrentGroupState/${logId}: Applying full group state, from version ${oldVersion} to ${newVersion}.`
);
const { newAttributes, newProfileKeys } = await applyGroupState({
@ -3831,7 +3825,7 @@ function extractDiffs({
conversationId: lastPendingConversationId,
});
} else {
window.log.warn(
log.warn(
`extractDiffs/${logId}: pendingCount was 1, no last conversationId available`
);
}
@ -4016,7 +4010,7 @@ function extractDiffs({
const result = compact([message, timerNotification]);
window.log.info(
log.info(
`extractDiffs/${logId} complete, generated ${result.length} change messages`
);
@ -4090,7 +4084,7 @@ async function applyGroupChange({
);
if (members[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to add member failed; already in members.`
);
return;
@ -4104,7 +4098,7 @@ async function applyGroupChange({
};
if (pendingMembers[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Removing newly-added member from pendingMembers.`
);
delete pendingMembers[conversation.id];
@ -4144,7 +4138,7 @@ async function applyGroupChange({
if (members[conversation.id]) {
delete members[conversation.id];
} else {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to remove member failed; was not in members.`
);
}
@ -4207,13 +4201,13 @@ async function applyGroupChange({
);
if (members[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to add pendingMember failed; was already in members.`
);
return;
}
if (pendingMembers[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to add pendingMember failed; was already in pendingMembers.`
);
return;
@ -4253,7 +4247,7 @@ async function applyGroupChange({
if (pendingMembers[conversation.id]) {
delete pendingMembers[conversation.id];
} else {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to remove pendingMember failed; was not in pendingMembers.`
);
}
@ -4280,13 +4274,13 @@ async function applyGroupChange({
if (pendingMembers[conversation.id]) {
delete pendingMembers[conversation.id];
} else {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was not in pendingMembers.`
);
}
if (members[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was already in members.`
);
return;
@ -4310,7 +4304,7 @@ async function applyGroupChange({
if (title && title.content === 'title') {
result.name = title.title;
} else {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Clearing group title due to missing data.`
);
result.name = undefined;
@ -4335,7 +4329,7 @@ async function applyGroupChange({
result.expireTimer =
disappearingMessagesTimer.disappearingMessagesDuration;
} else {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Clearing group expireTimer due to missing data.`
);
result.expireTimer = undefined;
@ -4395,19 +4389,19 @@ async function applyGroupChange({
);
if (members[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in members.`
);
return;
}
if (pendingMembers[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in pendingMembers.`
);
return;
}
if (pendingAdminApprovalMembers[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in pendingAdminApprovalMembers.`
);
return;
@ -4447,7 +4441,7 @@ async function applyGroupChange({
if (pendingAdminApprovalMembers[conversation.id]) {
delete pendingAdminApprovalMembers[conversation.id];
} else {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to remove pendingAdminApproval failed; was not in pendingAdminApprovalMembers.`
);
}
@ -4474,19 +4468,19 @@ async function applyGroupChange({
if (pendingAdminApprovalMembers[conversation.id]) {
delete pendingAdminApprovalMembers[conversation.id];
} else {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to promote pendingAdminApproval failed; was not in pendingAdminApprovalMembers.`
);
}
if (pendingMembers[conversation.id]) {
delete pendingAdminApprovalMembers[conversation.id];
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Deleted pendingAdminApproval from pendingMembers.`
);
}
if (members[conversation.id]) {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was already in members.`
);
return;
@ -4517,7 +4511,7 @@ async function applyGroupChange({
if (descriptionBytes && descriptionBytes.content === 'descriptionText') {
result.description = descriptionBytes.descriptionText;
} else {
window.log.warn(
log.warn(
`applyGroupChange/${logId}: Clearing group description due to missing data.`
);
result.description = undefined;
@ -4608,7 +4602,7 @@ export async function applyNewAvatar(
}
}
} catch (error) {
window.log.warn(
log.warn(
`applyNewAvatar/${logId} Failed to handle avatar, clearing it`,
error.stack
);
@ -4952,14 +4946,14 @@ function decryptGroupChange(
'actions.sourceUuid'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt sourceUuid.`,
error && error.stack ? error.stack : error
);
}
if (!window.isValidGuid(result.sourceUuid)) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Invalid sourceUuid. Clearing sourceUuid.`
);
result.sourceUuid = undefined;
@ -5007,7 +5001,7 @@ function decryptGroupChange(
'actions.deleteMembers.deletedUserId'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt deleteMembers.deletedUserId. Dropping member.`,
error && error.stack ? error.stack : error
);
@ -5015,7 +5009,7 @@ function decryptGroupChange(
}
if (!window.isValidGuid(userId)) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Dropping deleteMember due to invalid userId`
);
@ -5041,7 +5035,7 @@ function decryptGroupChange(
'actions.modifyMemberRoles.userId'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt modifyMemberRole.userId. Dropping member.`,
error && error.stack ? error.stack : error
);
@ -5049,7 +5043,7 @@ function decryptGroupChange(
}
if (!window.isValidGuid(userId)) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Dropping modifyMemberRole due to invalid userId`
);
@ -5093,7 +5087,7 @@ function decryptGroupChange(
}
if (!window.isValidGuid(decryptedPresentation.uuid)) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Dropping modifyMemberProfileKey due to invalid userId`
);
@ -5151,7 +5145,7 @@ function decryptGroupChange(
'actions.deletePendingMembers.deletedUserId'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt deletePendingMembers.deletedUserId. Dropping member.`,
error && error.stack ? error.stack : error
);
@ -5159,7 +5153,7 @@ function decryptGroupChange(
}
if (!window.isValidGuid(userId)) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Dropping deletePendingMember due to invalid deletedUserId`
);
@ -5194,7 +5188,7 @@ function decryptGroupChange(
}
if (!window.isValidGuid(decryptedPresentation.uuid)) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Dropping modifyMemberProfileKey due to invalid userId`
);
@ -5223,7 +5217,7 @@ function decryptGroupChange(
),
};
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt modifyTitle.title`,
error && error.stack ? error.stack : error
);
@ -5250,7 +5244,7 @@ function decryptGroupChange(
),
};
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt modifyDisappearingMessagesTimer.timer`,
error && error.stack ? error.stack : error
);
@ -5323,7 +5317,7 @@ function decryptGroupChange(
logId
);
if (!decrypted) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt addPendingAdminApproval.added. Dropping member.`
);
return null;
@ -5353,14 +5347,14 @@ function decryptGroupChange(
'actions.deleteMemberPendingAdminApprovals'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt deletePendingApproval.deletedUserId. Dropping member.`,
error && error.stack ? error.stack : error
);
return null;
}
if (!window.isValidGuid(userId)) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Dropping deletePendingApproval due to invalid deletedUserId`
);
@ -5391,7 +5385,7 @@ function decryptGroupChange(
'actions.promoteMemberPendingAdminApprovals.userId'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt promoteAdminApproval.userId. Dropping member.`,
error && error.stack ? error.stack : error
);
@ -5433,7 +5427,7 @@ function decryptGroupChange(
),
};
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupChange/${logId}: Unable to decrypt modifyDescription.descriptionBytes`,
error && error.stack ? error.stack : error
);
@ -5526,7 +5520,7 @@ function decryptGroupState(
decryptGroupBlob(clientZkGroupCipher, groupState.title)
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupState/${logId}: Unable to decrypt title. Clearing it.`,
error && error.stack ? error.stack : error
);
@ -5549,7 +5543,7 @@ function decryptGroupState(
)
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupState/${logId}: Unable to decrypt disappearing message timer. Clearing it.`,
error && error.stack ? error.stack : error
);
@ -5633,7 +5627,7 @@ function decryptGroupState(
decryptGroupBlob(clientZkGroupCipher, groupState.descriptionBytes)
);
} catch (error) {
window.log.warn(
log.warn(
`decryptGroupState/${logId}: Unable to decrypt descriptionBytes. Clearing it.`,
error && error.stack ? error.stack : error
);
@ -5674,7 +5668,7 @@ function decryptMember(
'decryptMember.userId'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptMember/${logId}: Unable to decrypt member userid. Dropping member.`,
error && error.stack ? error.stack : error
);
@ -5682,9 +5676,7 @@ function decryptMember(
}
if (!window.isValidGuid(userId)) {
window.log.warn(
`decryptMember/${logId}: Dropping member due to invalid userId`
);
log.warn(`decryptMember/${logId}: Dropping member due to invalid userId`);
return undefined;
}
@ -5747,7 +5739,7 @@ function decryptMemberPendingProfileKey(
'decryptMemberPendingProfileKey.addedByUserId'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member addedByUserId. Dropping member.`,
error && error.stack ? error.stack : error
);
@ -5755,7 +5747,7 @@ function decryptMemberPendingProfileKey(
}
if (!window.isValidGuid(addedByUserId)) {
window.log.warn(
log.warn(
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to invalid addedByUserId`
);
return undefined;
@ -5765,7 +5757,7 @@ function decryptMemberPendingProfileKey(
const timestamp = normalizeTimestamp(member.timestamp);
if (!member.member) {
window.log.warn(
log.warn(
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to missing member details`
);
@ -5787,7 +5779,7 @@ function decryptMemberPendingProfileKey(
'decryptMemberPendingProfileKey.member.userId'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member userId. Dropping member.`,
error && error.stack ? error.stack : error
);
@ -5795,7 +5787,7 @@ function decryptMemberPendingProfileKey(
}
if (!window.isValidGuid(decryptedUserId)) {
window.log.warn(
log.warn(
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to invalid member.userId`
);
@ -5812,14 +5804,14 @@ function decryptMemberPendingProfileKey(
decryptedUserId
);
} catch (error) {
window.log.warn(
log.warn(
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member profileKey. Dropping profileKey.`,
error && error.stack ? error.stack : error
);
}
if (!isValidProfileKey(decryptedProfileKey)) {
window.log.warn(
log.warn(
`decryptMemberPendingProfileKey/${logId}: Dropping profileKey, since it was invalid`
);
decryptedProfileKey = undefined;
@ -5874,7 +5866,7 @@ function decryptMemberPendingAdminApproval(
'decryptMemberPendingAdminApproval.userId'
);
} catch (error) {
window.log.warn(
log.warn(
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt pending member userId. Dropping member.`,
error && error.stack ? error.stack : error
);
@ -5882,7 +5874,7 @@ function decryptMemberPendingAdminApproval(
}
if (!window.isValidGuid(decryptedUserId)) {
window.log.warn(
log.warn(
`decryptMemberPendingAdminApproval/${logId}: Invalid userId. Dropping member.`
);
@ -5899,14 +5891,14 @@ function decryptMemberPendingAdminApproval(
decryptedUserId
);
} catch (error) {
window.log.warn(
log.warn(
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt profileKey. Dropping profileKey.`,
error && error.stack ? error.stack : error
);
}
if (!isValidProfileKey(decryptedProfileKey)) {
window.log.warn(
log.warn(
`decryptMemberPendingAdminApproval/${logId}: Dropping profileKey, since it was invalid`
);

View File

@ -20,6 +20,7 @@ import type { ConversationAttributesType } from '../model-types.d';
import type { ConversationModel } from '../models/conversations';
import type { PreJoinConversationType } from '../state/ducks/conversations';
import { SignalService as Proto } from '../protobuf';
import * as log from '../logging/log';
export async function joinViaLink(hash: string): Promise<void> {
let inviteLinkPassword: string;
@ -28,7 +29,7 @@ export async function joinViaLink(hash: string): Promise<void> {
({ inviteLinkPassword, masterKey } = parseGroupLink(hash));
} catch (error) {
const errorString = error && error.stack ? error.stack : error;
window.log.error(`joinViaLink: Failed to parse group link ${errorString}`);
log.error(`joinViaLink: Failed to parse group link ${errorString}`);
if (error && error.name === LINK_VERSION_ERROR) {
showErrorDialog(
window.i18n('GroupV2--join--unknown-link-version'),
@ -58,7 +59,7 @@ export async function joinViaLink(hash: string): Promise<void> {
existingConversation &&
existingConversation.hasMember(ourConversationId)
) {
window.log.warn(
log.warn(
`joinViaLink/${logId}: Already a member of group, opening conversation`
);
window.reduxActions.conversations.openConversationInternal({
@ -84,7 +85,7 @@ export async function joinViaLink(hash: string): Promise<void> {
});
} catch (error) {
const errorString = error && error.stack ? error.stack : error;
window.log.error(
log.error(
`joinViaLink/${logId}: Failed to fetch group info - ${errorString}`
);
@ -104,7 +105,7 @@ export async function joinViaLink(hash: string): Promise<void> {
result.addFromInviteLink !== ACCESS_ENUM.ADMINISTRATOR &&
result.addFromInviteLink !== ACCESS_ENUM.ANY
) {
window.log.error(
log.error(
`joinViaLink/${logId}: addFromInviteLink value of ${result.addFromInviteLink} is invalid`
);
showErrorDialog(
@ -136,7 +137,7 @@ export async function joinViaLink(hash: string): Promise<void> {
existingConversation &&
existingConversation.isMemberAwaitingApproval(ourConversationId)
) {
window.log.warn(
log.warn(
`joinViaLink/${logId}: Already awaiting approval, opening conversation`
);
window.reduxActions.conversations.openConversationInternal({
@ -226,7 +227,7 @@ export async function joinViaLink(hash: string): Promise<void> {
(approvalRequired &&
targetConversation.isMemberAwaitingApproval(ourConversationId)))
) {
window.log.warn(
log.warn(
`joinViaLink/${logId}: User is part of group on second check, opening conversation`
);
window.reduxActions.conversations.openConversationInternal({
@ -339,7 +340,7 @@ export async function joinViaLink(hash: string): Promise<void> {
getPreJoinConversation()
);
window.log.info(`joinViaLink/${logId}: Showing modal`);
log.info(`joinViaLink/${logId}: Showing modal`);
let groupV2InfoDialog:
| Backbone.View

View File

@ -1,7 +1,7 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { LoggerType } from '../logging/log';
import type { LoggerType } from '../types/Logging';
import type { ParsedJob } from './types';
export class JobLogger implements LoggerType {

View File

@ -12,6 +12,7 @@ import { assert } from '../util/assert';
import * as log from '../logging/log';
import { JobLogger } from './JobLogger';
import * as Errors from '../types/errors';
import type { LoggerType } from '../types/Logging';
const noopOnCompleteCallbacks = {
resolve: noop,
@ -39,7 +40,7 @@ type JobQueueOptions = {
/**
* A custom logger. Might be overwritten in test.
*/
logger?: log.LoggerType;
logger?: LoggerType;
};
export abstract class JobQueue<T> {
@ -49,7 +50,7 @@ export abstract class JobQueue<T> {
private readonly store: JobQueueStore;
private readonly logger: log.LoggerType;
private readonly logger: LoggerType;
private readonly logPrefix: string;
@ -111,7 +112,7 @@ export abstract class JobQueue<T> {
*/
protected abstract run(
job: Readonly<ParsedJob<T>>,
extra?: Readonly<{ attempt?: number; log?: log.LoggerType }>
extra?: Readonly<{ attempt?: number; log?: LoggerType }>
): Promise<void>;
/**

View File

@ -1,7 +1,7 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { LoggerType } from '../../logging/log';
import type { LoggerType } from '../../types/Logging';
import { waitForOnline } from '../../util/waitForOnline';
import { sleep } from '../../util/sleep';
import { exponentialBackoffSleepTime } from '../../util/exponentialBackoff';

View File

@ -1,7 +1,7 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { LoggerType } from '../../logging/log';
import type { LoggerType } from '../../types/Logging';
import { parseIntWithFallback } from '../../util/parseIntWithFallback';
import { sleepFor413RetryAfterTimeIfApplicable } from './sleepFor413RetryAfterTimeIfApplicable';

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { chunk } from 'lodash';
import type { LoggerType } from '../../logging/log';
import type { LoggerType } from '../../types/Logging';
import { getSendOptions } from '../../util/getSendOptions';
import { handleMessageSend, SendTypesType } from '../../util/handleMessageSend';
import { isNotNil } from '../../util/isNotNil';

View File

@ -1,7 +1,7 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { LoggerType } from '../../logging/log';
import type { LoggerType } from '../../types/Logging';
import { sleep } from '../../util/sleep';
import { parseRetryAfter } from '../../util/parseRetryAfter';
import { isRecord } from '../../util/isRecord';

View File

@ -4,7 +4,7 @@
/* eslint-disable class-methods-use-this */
import PQueue from 'p-queue';
import type { LoggerType } from '../logging/log';
import type { LoggerType } from '../types/Logging';
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
import { commonShouldJobContinue } from './helpers/commonShouldJobContinue';
import { sleepFor413RetryAfterTimeIfApplicable } from './helpers/sleepFor413RetryAfterTimeIfApplicable';

View File

@ -4,7 +4,7 @@
/* eslint-disable class-methods-use-this */
import * as durations from '../util/durations';
import type { LoggerType } from '../logging/log';
import type { LoggerType } from '../types/Logging';
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
import {
SyncType,

View File

@ -7,7 +7,7 @@ import * as durations from '../util/durations';
import { strictAssert } from '../util/assert';
import { waitForOnline } from '../util/waitForOnline';
import { isDone as isDeviceLinked } from '../util/registration';
import type { LoggerType } from '../logging/log';
import type { LoggerType } from '../types/Logging';
import { map } from '../util/iterables';
import { sleep } from '../util/sleep';

View File

@ -4,7 +4,7 @@
/* eslint-disable class-methods-use-this */
import * as durations from '../util/durations';
import type { LoggerType } from '../logging/log';
import type { LoggerType } from '../types/Logging';
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
import {
SyncType,

View File

@ -5,7 +5,7 @@
import { z } from 'zod';
import * as durations from '../util/durations';
import type { LoggerType } from '../logging/log';
import type { LoggerType } from '../types/Logging';
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
import { commonShouldJobContinue } from './helpers/commonShouldJobContinue';
import { sendViewedReceipt } from '../util/sendViewedReceipt';

View File

@ -13,6 +13,7 @@ import {
MIMEType,
stringToMIMEType,
} from '../types/MIME';
import * as log from '../logging/log';
const USER_AGENT = 'WhatsApp/2';
@ -82,7 +83,7 @@ async function fetchWithRedirects(
let nextHrefToLoad = href;
for (let i = 0; i < MAX_REQUEST_COUNT_WITH_REDIRECTS; i += 1) {
if (urlsSeen.has(nextHrefToLoad)) {
window.log.warn('fetchWithRedirects: found a redirect loop');
log.warn('fetchWithRedirects: found a redirect loop');
throw new Error('redirect loop');
}
urlsSeen.add(nextHrefToLoad);
@ -100,7 +101,7 @@ async function fetchWithRedirects(
const location = response.headers.get('location');
if (!location) {
window.log.warn(
log.warn(
'fetchWithRedirects: got a redirect status code but no Location header; bailing'
);
throw new Error('no location with redirect');
@ -108,7 +109,7 @@ async function fetchWithRedirects(
const newUrl = maybeParseUrl(location, nextHrefToLoad);
if (newUrl?.protocol !== 'https:') {
window.log.warn(
log.warn(
'fetchWithRedirects: got a redirect status code and an invalid Location header'
);
throw new Error('invalid location');
@ -117,7 +118,7 @@ async function fetchWithRedirects(
nextHrefToLoad = newUrl.href;
}
window.log.warn('fetchWithRedirects: too many redirects');
log.warn('fetchWithRedirects: too many redirects');
throw new Error('too many redirects');
}
@ -321,7 +322,7 @@ const getHtmlDocument = async (
}
}
} catch (err) {
window.log.warn(
log.warn(
'getHtmlDocument: error when reading body; continuing with what we got'
);
}
@ -370,9 +371,7 @@ const parseMetadata = (
const title =
getOpenGraphContent(document, ['og:title']) || document.title.trim();
if (!title) {
window.log.warn(
"parseMetadata: HTML document doesn't have a title; bailing"
);
log.warn("parseMetadata: HTML document doesn't have a title; bailing");
return null;
}
@ -449,28 +448,28 @@ export async function fetchLinkPreviewMetadata(
signal: abortSignal as AbortSignalForNodeFetch,
});
} catch (err) {
window.log.warn(
log.warn(
'fetchLinkPreviewMetadata: failed to fetch link preview HTML; bailing'
);
return null;
}
if (!response.ok) {
window.log.warn(
log.warn(
`fetchLinkPreviewMetadata: got a ${response.status} status code; bailing`
);
return null;
}
if (!response.body) {
window.log.warn('fetchLinkPreviewMetadata: no response body; bailing');
log.warn('fetchLinkPreviewMetadata: no response body; bailing');
return null;
}
if (
!isInlineContentDisposition(response.headers.get('Content-Disposition'))
) {
window.log.warn(
log.warn(
'fetchLinkPreviewMetadata: Content-Disposition header is not inline; bailing'
);
return null;
@ -484,17 +483,13 @@ export async function fetchLinkPreviewMetadata(
response.headers.get('Content-Length')
);
if (contentLength < MIN_HTML_CONTENT_LENGTH) {
window.log.warn(
'fetchLinkPreviewMetadata: Content-Length is too short; bailing'
);
log.warn('fetchLinkPreviewMetadata: Content-Length is too short; bailing');
return null;
}
const contentType = parseContentType(response.headers.get('Content-Type'));
if (contentType.type !== 'text/html') {
window.log.warn(
'fetchLinkPreviewMetadata: Content-Type is not HTML; bailing'
);
log.warn('fetchLinkPreviewMetadata: Content-Type is not HTML; bailing');
return null;
}
@ -546,7 +541,7 @@ export async function fetchLinkPreviewImage(
signal: abortSignal as AbortSignalForNodeFetch,
});
} catch (err) {
window.log.warn('fetchLinkPreviewImage: failed to fetch image; bailing');
log.warn('fetchLinkPreviewImage: failed to fetch image; bailing');
return null;
}
@ -555,7 +550,7 @@ export async function fetchLinkPreviewImage(
}
if (!response.ok) {
window.log.warn(
log.warn(
`fetchLinkPreviewImage: got a ${response.status} status code; bailing`
);
return null;
@ -565,13 +560,11 @@ export async function fetchLinkPreviewImage(
response.headers.get('Content-Length')
);
if (contentLength < MIN_IMAGE_CONTENT_LENGTH) {
window.log.warn(
'fetchLinkPreviewImage: Content-Length is too short; bailing'
);
log.warn('fetchLinkPreviewImage: Content-Length is too short; bailing');
return null;
}
if (contentLength > MAX_IMAGE_CONTENT_LENGTH) {
window.log.warn(
log.warn(
'fetchLinkPreviewImage: Content-Length is too large or is unset; bailing'
);
return null;
@ -581,9 +574,7 @@ export async function fetchLinkPreviewImage(
response.headers.get('Content-Type')
);
if (!contentType || !VALID_IMAGE_MIME_TYPES.has(contentType)) {
window.log.warn(
'fetchLinkPreviewImage: Content-Type is not an image; bailing'
);
log.warn('fetchLinkPreviewImage: Content-Type is not an image; bailing');
return null;
}
@ -591,7 +582,7 @@ export async function fetchLinkPreviewImage(
try {
data = await response.arrayBuffer();
} catch (err) {
window.log.warn('fetchLinkPreviewImage: failed to read body; bailing');
log.warn('fetchLinkPreviewImage: failed to read body; bailing');
return null;
}

View File

@ -1,6 +1,8 @@
// Copyright 2018-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { memoize, sortBy } from 'lodash';
import { ipcRenderer as ipc } from 'electron';
import { z } from 'zod';
import FormData from 'form-data';
import { gzip } from 'zlib';
@ -8,6 +10,19 @@ import pify from 'pify';
import got, { Response } from 'got';
import { getUserAgent } from '../util/getUserAgent';
import { maybeParseUrl } from '../util/url';
import * as log from './log';
import { reallyJsonStringify } from '../util/reallyJsonStringify';
import {
FetchLogIpcData,
LogEntryType,
LogLevel,
getLogLevelString,
isFetchLogIpcData,
isLogEntry,
levelMaxLength,
} from './shared';
import { redactAll } from '../util/privacy';
import { getEnvironment } from '../environment';
const BASE_URL = 'https://debuglogs.org';
@ -34,7 +49,7 @@ const parseTokenBody = (
return body;
};
export const uploadDebugLogs = async (
export const upload = async (
content: string,
appVersion: string
): Promise<string> => {
@ -62,7 +77,7 @@ export const uploadDebugLogs = async (
filename: `signal-desktop-debug-log-${appVersion}.txt.gz`,
});
window.log.info('Debug log upload starting...');
log.info('Debug log upload starting...');
try {
const { statusCode, body } = await got.post(url, { headers, body: form });
if (statusCode !== 204) {
@ -76,7 +91,92 @@ export const uploadDebugLogs = async (
`Got threw on upload to S3, got status ${response?.statusCode}, body '${response?.body}' `
);
}
window.log.info('Debug log upload complete.');
log.info('Debug log upload complete.');
return `${BASE_URL}/${uploadKey}`;
};
// The mechanics of preparing a log for publish
const headerSectionTitle = (title: string) => `========= ${title} =========`;
const headerSection = (
title: string,
data: Readonly<Record<string, unknown>>
): string => {
const sortedEntries = sortBy(Object.entries(data), ([key]) => key);
return [
headerSectionTitle(title),
...sortedEntries.map(
([key, value]) => `${key}: ${redactAll(String(value))}`
),
'',
].join('\n');
};
const getHeader = ({
capabilities,
remoteConfig,
statistics,
user,
}: Omit<FetchLogIpcData, 'logEntries'>): string =>
[
headerSection('System info', {
Time: Date.now(),
'User agent': window.navigator.userAgent,
'Node version': window.getNodeVersion(),
Environment: getEnvironment(),
'App version': window.getVersion(),
}),
headerSection('User info', user),
headerSection('Capabilities', capabilities),
headerSection('Remote config', remoteConfig),
headerSection('Statistics', statistics),
headerSectionTitle('Logs'),
].join('\n');
const getLevel = memoize((level: LogLevel): string => {
const text = getLogLevelString(level);
return text.toUpperCase().padEnd(levelMaxLength, ' ');
});
function formatLine(mightBeEntry: unknown): string {
const entry: LogEntryType = isLogEntry(mightBeEntry)
? mightBeEntry
: {
level: LogLevel.Error,
msg: `Invalid IPC data when fetching logs. Here's what we could recover: ${reallyJsonStringify(
mightBeEntry
)}`,
time: new Date().toISOString(),
};
return `${getLevel(entry.level)} ${entry.time} ${entry.msg}`;
}
export function fetch(): Promise<string> {
return new Promise(resolve => {
ipc.send('fetch-log');
ipc.on('fetched-log', (_event, data: unknown) => {
let header: string;
let body: string;
if (isFetchLogIpcData(data)) {
const { logEntries } = data;
header = getHeader(data);
body = logEntries.map(formatLine).join('\n');
} else {
header = headerSectionTitle('Partial logs');
const entry: LogEntryType = {
level: LogLevel.Error,
msg: 'Invalid IPC data when fetching logs; dropping all logs',
time: new Date().toISOString(),
};
body = formatLine(entry);
}
const result = `${header}\n${body}`;
resolve(result);
});
});
}

View File

@ -3,6 +3,7 @@
import { noop } from 'lodash';
import { LogLevel } from './shared';
import { LogFunction } from '../types/Logging';
type LogAtLevelFnType = (
level: LogLevel,
@ -12,23 +13,18 @@ type LogAtLevelFnType = (
let logAtLevel: LogAtLevelFnType = noop;
let hasInitialized = false;
type LogFn = (...args: ReadonlyArray<unknown>) => void;
export type LoggerType = {
fatal: LogFn;
error: LogFn;
warn: LogFn;
info: LogFn;
debug: LogFn;
trace: LogFn;
};
export const fatal: LogFn = (...args) => logAtLevel(LogLevel.Fatal, ...args);
export const error: LogFn = (...args) => logAtLevel(LogLevel.Error, ...args);
export const warn: LogFn = (...args) => logAtLevel(LogLevel.Warn, ...args);
export const info: LogFn = (...args) => logAtLevel(LogLevel.Info, ...args);
export const debug: LogFn = (...args) => logAtLevel(LogLevel.Debug, ...args);
export const trace: LogFn = (...args) => logAtLevel(LogLevel.Trace, ...args);
export const fatal: LogFunction = (...args) =>
logAtLevel(LogLevel.Fatal, ...args);
export const error: LogFunction = (...args) =>
logAtLevel(LogLevel.Error, ...args);
export const warn: LogFunction = (...args) =>
logAtLevel(LogLevel.Warn, ...args);
export const info: LogFunction = (...args) =>
logAtLevel(LogLevel.Info, ...args);
export const debug: LogFunction = (...args) =>
logAtLevel(LogLevel.Debug, ...args);
export const trace: LogFunction = (...args) =>
logAtLevel(LogLevel.Trace, ...args);
/**
* Sets the low-level logging interface. Should be called early in a process's life, and

View File

@ -6,7 +6,6 @@
/* eslint-disable no-console */
import { ipcRenderer as ipc } from 'electron';
import _ from 'lodash';
import * as path from 'path';
import pino from 'pino';
import { createStream } from 'rotating-file-stream';
@ -16,28 +15,15 @@ import {
LogLevel as SignalClientLogLevel,
} from '@signalapp/signal-client';
import { uploadDebugLogs } from './debuglogs';
import { redactAll } from '../util/privacy';
import {
FetchLogIpcData,
LogEntryType,
LogLevel,
cleanArgs,
getLogLevelString,
isFetchLogIpcData,
isLogEntry,
levelMaxLength,
} from './shared';
import * as log from './log';
import { reallyJsonStringify } from '../util/reallyJsonStringify';
import { Environment, getEnvironment } from '../environment';
// To make it easier to visually scan logs, we make all levels the same length
const levelFromName = pino().levels.values;
const levelMaxLength: number = Object.keys(levelFromName).reduce(
(maxLength, level) => Math.max(maxLength, level.length),
0
);
// Backwards-compatible logging, simple strings and no level (defaulted to INFO)
function now() {
const date = new Date();
@ -53,91 +39,6 @@ if (window.console) {
console.log = consoleLog;
}
// The mechanics of preparing a log for publish
const headerSectionTitle = (title: string) => `========= ${title} =========`;
const headerSection = (
title: string,
data: Readonly<Record<string, unknown>>
): string => {
const sortedEntries = _.sortBy(Object.entries(data), ([key]) => key);
return [
headerSectionTitle(title),
...sortedEntries.map(
([key, value]) => `${key}: ${redactAll(String(value))}`
),
'',
].join('\n');
};
const getHeader = ({
capabilities,
remoteConfig,
statistics,
user,
}: Omit<FetchLogIpcData, 'logEntries'>): string =>
[
headerSection('System info', {
Time: Date.now(),
'User agent': window.navigator.userAgent,
'Node version': window.getNodeVersion(),
Environment: getEnvironment(),
'App version': window.getVersion(),
}),
headerSection('User info', user),
headerSection('Capabilities', capabilities),
headerSection('Remote config', remoteConfig),
headerSection('Statistics', statistics),
headerSectionTitle('Logs'),
].join('\n');
const getLevel = _.memoize((level: LogLevel): string => {
const text = getLogLevelString(level);
return text.toUpperCase().padEnd(levelMaxLength, ' ');
});
function formatLine(mightBeEntry: unknown): string {
const entry: LogEntryType = isLogEntry(mightBeEntry)
? mightBeEntry
: {
level: LogLevel.Error,
msg: `Invalid IPC data when fetching logs. Here's what we could recover: ${reallyJsonStringify(
mightBeEntry
)}`,
time: new Date().toISOString(),
};
return `${getLevel(entry.level)} ${entry.time} ${entry.msg}`;
}
function fetch(): Promise<string> {
return new Promise(resolve => {
ipc.send('fetch-log');
ipc.on('fetched-log', (_event, data: unknown) => {
let header: string;
let body: string;
if (isFetchLogIpcData(data)) {
const { logEntries } = data;
header = getHeader(data);
body = logEntries.map(formatLine).join('\n');
} else {
header = headerSectionTitle('Partial logs');
const entry: LogEntryType = {
level: LogLevel.Error,
msg: 'Invalid IPC data when fetching logs; dropping all logs',
time: new Date().toISOString(),
};
body = formatLine(entry);
}
const result = `${header}\n${body}`;
resolve(result);
});
});
}
let globalLogger: undefined | pino.Logger;
let shouldRestart = false;
@ -176,8 +77,6 @@ export function initialize(): void {
);
}
const publish = uploadDebugLogs;
// A modern logging interface for the browser
function logAtLevel(level: LogLevel, ...args: ReadonlyArray<unknown>): void {
@ -201,27 +100,26 @@ function logAtLevel(level: LogLevel, ...args: ReadonlyArray<unknown>): void {
log.setLogAtLevel(logAtLevel);
window.log = {
window.SignalWindow = window.SignalWindow || {};
window.SignalWindow.log = {
fatal: log.fatal,
error: log.error,
warn: log.warn,
info: log.info,
debug: log.debug,
trace: log.trace,
fetch,
publish,
};
window.onerror = (_message, _script, _line, _col, error) => {
const errorInfo = error && error.stack ? error.stack : JSON.stringify(error);
window.log.error(`Top-level unhandled error: ${errorInfo}`);
log.error(`Top-level unhandled error: ${errorInfo}`);
};
window.addEventListener('unhandledrejection', rejectionEvent => {
const error = rejectionEvent.reason;
const errorString =
error && error.stack ? error.stack : JSON.stringify(error);
window.log.error(`Top-level unhandled promise rejection: ${errorString}`);
log.error(`Top-level unhandled promise rejection: ${errorString}`);
});
initLogger(

View File

@ -1,7 +1,7 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as pino from 'pino';
import pino from 'pino';
import { isRecord } from '../util/isRecord';
import { redactAll } from '../util/privacy';
import { missingCaseError } from '../util/missingCaseError';
@ -106,3 +106,10 @@ export function cleanArgs(args: ReadonlyArray<unknown>): string {
.join(' ')
);
}
// To make it easier to visually scan logs, we make all levels the same length
const levelFromName = pino().levels.values;
export const levelMaxLength: number = Object.keys(levelFromName).reduce(
(maxLength, level) => Math.max(maxLength, level.length),
0
);

View File

@ -15,7 +15,8 @@ import {
import { MessageModel } from '../models/messages';
import { AttachmentType } from '../types/Attachment';
import { LoggerType } from '../window.d';
import { LoggerType } from '../types/Logging';
import * as log from '../logging/log';
const {
getMessageById,
@ -179,7 +180,7 @@ async function _maybeStartJob(): Promise<void> {
async function _runJob(job?: AttachmentDownloadJobType): Promise<void> {
if (!job) {
window.log.warn('_runJob: Job was missing!');
log.warn('_runJob: Job was missing!');
return;
}

View File

@ -5,6 +5,7 @@
import { Collection, Model } from 'backbone';
import { MessageModel } from '../models/messages';
import * as log from '../logging/log';
type DeleteAttributesType = {
targetSentTimestamp: number;
@ -34,7 +35,7 @@ export class Deletes extends Collection<DeleteModel> {
});
if (matchingDeletes.length > 0) {
window.log.info('Found early DOE for message');
log.info('Found early DOE for message');
this.remove(matchingDeletes);
return matchingDeletes;
}
@ -52,7 +53,7 @@ export class Deletes extends Collection<DeleteModel> {
);
if (!targetConversation) {
window.log.info(
log.info(
'No target conversation for DOE',
del.get('fromId'),
del.get('targetSentTimestamp')
@ -63,7 +64,7 @@ export class Deletes extends Collection<DeleteModel> {
// Do not await, since this can deadlock the queue
targetConversation.queueJob('Deletes.onDelete', async () => {
window.log.info('Handling DOE for', del.get('targetSentTimestamp'));
log.info('Handling DOE for', del.get('targetSentTimestamp'));
const messages = await window.Signal.Data.getMessagesBySentAt(
del.get('targetSentTimestamp'),
@ -77,7 +78,7 @@ export class Deletes extends Collection<DeleteModel> {
);
if (!targetMessage) {
window.log.info(
log.info(
'No message for DOE',
del.get('fromId'),
del.get('targetSentTimestamp')
@ -96,7 +97,7 @@ export class Deletes extends Collection<DeleteModel> {
this.remove(del);
});
} catch (error) {
window.log.error(
log.error(
'Deletes.onDelete error:',
error && error.stack ? error.stack : error
);

View File

@ -21,6 +21,7 @@ import {
} from '../messages/MessageSendState';
import type { DeleteSentProtoRecipientOptionsType } from '../sql/Interface';
import dataInterface from '../sql/Client';
import * as log from '../logging/log';
const { deleteSentProtoRecipient } = dataInterface;
@ -47,7 +48,7 @@ const deleteSentProtoBatcher = createWaitBatcher({
wait: 250,
maxSize: 30,
async processBatch(items: Array<DeleteSentProtoRecipientOptionsType>) {
window.log.info(
log.info(
`MessageReceipts: Batching ${items.length} sent proto recipients deletes`
);
await deleteSentProtoRecipient(items);
@ -125,7 +126,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
ids.includes(receipt.get('sourceConversationId'))
);
if (receipts.length) {
window.log.info('Found early receipts for message');
log.info('Found early receipts for message');
this.remove(receipts);
}
return receipts;
@ -146,7 +147,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
const message = await getTargetMessage(sourceConversationId, messages);
if (!message) {
window.log.info(
log.info(
'No message for receipt',
type,
sourceConversationId,
@ -222,7 +223,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
deviceId,
});
} else {
window.log.warn(
log.warn(
`MessageReceipts.onReceipt: Missing uuid or deviceId for deliveredTo ${sourceConversationId}`
);
}
@ -230,7 +231,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
this.remove(receipt);
} catch (error) {
window.log.error(
log.error(
'MessageReceipts.onReceipt error:',
error && error.stack ? error.stack : error
);

View File

@ -5,6 +5,7 @@
import { Collection, Model } from 'backbone';
import { ConversationModel } from '../models/conversations';
import * as log from '../logging/log';
type MessageRequestAttributesType = {
threadE164?: string;
@ -33,7 +34,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
threadE164: conversation.get('e164'),
});
if (syncByE164) {
window.log.info(
log.info(
`Found early message request response for E164 ${conversation.idForLogging()}`
);
this.remove(syncByE164);
@ -46,7 +47,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
threadUuid: conversation.get('uuid'),
});
if (syncByUuid) {
window.log.info(
log.info(
`Found early message request response for UUID ${conversation.idForLogging()}`
);
this.remove(syncByUuid);
@ -60,7 +61,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
groupId: conversation.get('groupId'),
});
if (syncByGroupId) {
window.log.info(
log.info(
`Found early message request response for group v1 ID ${conversation.idForLogging()}`
);
this.remove(syncByGroupId);
@ -74,7 +75,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
groupV2Id: conversation.get('groupId'),
});
if (syncByGroupId) {
window.log.info(
log.info(
`Found early message request response for group v2 ID ${conversation.idForLogging()}`
);
this.remove(syncByGroupId);
@ -111,7 +112,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
}
if (!conversation) {
window.log.warn(
log.warn(
`Received message request response for unknown conversation: groupv2(${groupV2Id}) group(${groupId}) ${threadUuid} ${threadE164}`
);
return;
@ -123,7 +124,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
this.remove(sync);
} catch (error) {
window.log.error(
log.error(
'MessageRequests.onResponse error:',
error && error.stack ? error.stack : error
);

View File

@ -7,6 +7,7 @@ import { Collection, Model } from 'backbone';
import { MessageModel } from '../models/messages';
import { isOutgoing } from '../state/selectors/message';
import { ReactionAttributesType } from '../model-types.d';
import * as log from '../logging/log';
export class ReactionModel extends Model<ReactionAttributesType> {}
@ -28,7 +29,7 @@ export class Reactions extends Collection {
);
if (outgoingReactions.length > 0) {
window.log.info('Found early reaction for outgoing message');
log.info('Found early reaction for outgoing message');
this.remove(outgoingReactions);
return outgoingReactions;
}
@ -45,7 +46,7 @@ export class Reactions extends Collection {
});
if (reactionsBySource.length > 0) {
window.log.info('Found early reaction for message');
log.info('Found early reaction for message');
this.remove(reactionsBySource);
return reactionsBySource;
}
@ -75,7 +76,7 @@ export class Reactions extends Collection {
reaction.get('targetTimestamp')
);
if (!targetConversation) {
window.log.info(
log.info(
'No target conversation for reaction',
reaction.get('targetAuthorUuid'),
reaction.get('targetTimestamp')
@ -87,10 +88,7 @@ export class Reactions extends Collection {
return await targetConversation.queueJob(
'Reactions.onReaction',
async () => {
window.log.info(
'Handling reaction for',
reaction.get('targetTimestamp')
);
log.info('Handling reaction for', reaction.get('targetTimestamp'));
const messages = await window.Signal.Data.getMessagesBySentAt(
reaction.get('targetTimestamp'),
@ -115,7 +113,7 @@ export class Reactions extends Collection {
});
if (!targetMessage) {
window.log.info(
log.info(
'No message for reaction',
reaction.get('targetAuthorUuid'),
reaction.get('targetTimestamp')
@ -149,7 +147,7 @@ export class Reactions extends Collection {
}
);
} catch (error) {
window.log.error(
log.error(
'Reactions.onReaction error:',
error && error.stack ? error.stack : error
);

View File

@ -8,6 +8,7 @@ import { Collection, Model } from 'backbone';
import { MessageModel } from '../models/messages';
import { isIncoming } from '../state/selectors/message';
import { isMessageUnread } from '../util/isMessageUnread';
import * as log from '../logging/log';
type ReadSyncAttributesType = {
senderId: string;
@ -28,7 +29,7 @@ async function maybeItIsAReactionReadSync(sync: ReadSyncModel): Promise<void> {
);
if (!readReaction) {
window.log.info(
log.info(
'Nothing found for read sync',
sync.get('senderId'),
sync.get('sender'),
@ -67,9 +68,7 @@ export class ReadSyncs extends Collection {
);
});
if (sync) {
window.log.info(
`Found early read sync for message ${sync.get('timestamp')}`
);
log.info(`Found early read sync for message ${sync.get('timestamp')}`);
this.remove(sync);
return sync;
}
@ -145,7 +144,7 @@ export class ReadSyncs extends Collection {
this.remove(sync);
} catch (error) {
window.log.error(
log.error(
'ReadSyncs.onSync error:',
error && error.stack ? error.stack : error
);

View File

@ -5,6 +5,7 @@
import { Collection, Model } from 'backbone';
import { MessageModel } from '../models/messages';
import * as log from '../logging/log';
type ViewOnceOpenSyncAttributesType = {
source?: string;
@ -33,7 +34,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
);
});
if (syncBySourceUuid) {
window.log.info('Found early view once open sync for message');
log.info('Found early view once open sync for message');
this.remove(syncBySourceUuid);
return syncBySourceUuid;
}
@ -45,7 +46,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
);
});
if (syncBySource) {
window.log.info('Found early view once open sync for message');
log.info('Found early view once open sync for message');
this.remove(syncBySource);
return syncBySource;
}
@ -80,7 +81,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
const syncSourceUuid = sync.get('sourceUuid');
const syncTimestamp = sync.get('timestamp');
const wasMessageFound = Boolean(found);
window.log.info('Receive view once open sync:', {
log.info('Receive view once open sync:', {
syncSource,
syncSourceUuid,
syncTimestamp,
@ -96,7 +97,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
this.remove(sync);
} catch (error) {
window.log.error(
log.error(
'ViewOnceOpenSyncs.onSync error:',
error && error.stack ? error.stack : error
);

View File

@ -9,6 +9,7 @@ import { MessageModel } from '../models/messages';
import { ReadStatus } from '../messages/MessageReadStatus';
import { markViewed } from '../services/MessageUpdater';
import { isIncoming } from '../state/selectors/message';
import * as log from '../logging/log';
type ViewSyncAttributesType = {
senderId: string;
@ -43,7 +44,7 @@ export class ViewSyncs extends Collection {
);
});
if (syncs.length) {
window.log.info(
log.info(
`Found ${syncs.length} early view sync(s) for message ${message.get(
'sent_at'
)}`
@ -72,7 +73,7 @@ export class ViewSyncs extends Collection {
});
if (!found) {
window.log.info(
log.info(
'Nothing found for view sync',
sync.get('senderId'),
sync.get('senderE164'),
@ -92,7 +93,7 @@ export class ViewSyncs extends Collection {
this.remove(sync);
} catch (error) {
window.log.error(
log.error(
'ViewSyncs.onSync error:',
error && error.stack ? error.stack : error
);

View File

@ -92,6 +92,7 @@ import { getProfile } from '../util/getProfile';
import { SEALED_SENDER } from '../types/SealedSender';
import { getAvatarData } from '../util/getAvatarData';
import { createIdenticon } from '../util/createIdenticon';
import * as log from '../logging/log';
// TODO: remove once we move away from ArrayBuffers
const FIXMEU8 = Uint8Array;
@ -399,7 +400,7 @@ export class ConversationModel extends window.Backbone
const bothFalsey = Boolean(current) === false && Boolean(seconds) === false;
if (current === seconds || bothFalsey) {
window.log.warn(
log.warn(
`updateExpirationTimerInGroupV2/${idLog}: Requested timer ${seconds} is unchanged from existing ${current}.`
);
return undefined;
@ -420,7 +421,7 @@ export class ConversationModel extends window.Backbone
// button press and when we get here. It's especially important to check here
// in conflict/retry cases.
if (!this.isMemberPending(conversationId)) {
window.log.warn(
log.warn(
`promotePendingMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
);
return undefined;
@ -464,7 +465,7 @@ export class ConversationModel extends window.Backbone
// button press and when we get here. It's especially important to check here
// in conflict/retry cases.
if (!this.isMemberRequestingToJoin(conversationId)) {
window.log.warn(
log.warn(
`approvePendingApprovalRequest/${idLog}: ${conversationId} is not requesting to join the group. Returning early.`
);
return undefined;
@ -499,7 +500,7 @@ export class ConversationModel extends window.Backbone
// button press and when we get here. It's especially important to check here
// in conflict/retry cases.
if (!this.isMemberRequestingToJoin(conversationId)) {
window.log.warn(
log.warn(
`denyPendingApprovalRequest/${idLog}: ${conversationId} is not requesting to join the group. Returning early.`
);
return undefined;
@ -544,9 +545,7 @@ export class ConversationModel extends window.Backbone
this.get('announcementsOnly') &&
!toRequest.get('capabilities')?.announcementGroup
) {
window.log.warn(
`addPendingApprovalRequest/${idLog}: member needs to upgrade.`
);
log.warn(`addPendingApprovalRequest/${idLog}: member needs to upgrade.`);
return undefined;
}
@ -569,7 +568,7 @@ export class ConversationModel extends window.Backbone
// button press and when we get here. It's especially important to check here
// in conflict/retry cases.
if (this.isMemberAwaitingApproval(conversationId)) {
window.log.warn(
log.warn(
`addPendingApprovalRequest/${idLog}: ${conversationId} already in pending approval.`
);
return undefined;
@ -598,9 +597,7 @@ export class ConversationModel extends window.Backbone
this.get('announcementsOnly') &&
!toRequest.get('capabilities')?.announcementGroup
) {
window.log.warn(
`addMember/${idLog}: ${conversationId} needs to upgrade.`
);
log.warn(`addMember/${idLog}: ${conversationId} needs to upgrade.`);
return undefined;
}
@ -623,9 +620,7 @@ export class ConversationModel extends window.Backbone
// button press and when we get here. It's especially important to check here
// in conflict/retry cases.
if (this.isMember(conversationId)) {
window.log.warn(
`addMember/${idLog}: ${conversationId} already a member.`
);
log.warn(`addMember/${idLog}: ${conversationId} already a member.`);
return undefined;
}
@ -647,7 +642,7 @@ export class ConversationModel extends window.Backbone
// button press and when we get here. It's especially important to check here
// in conflict/retry cases.
if (!this.isMemberPending(conversationId)) {
window.log.warn(
log.warn(
`removePendingMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
);
return undefined;
@ -655,7 +650,7 @@ export class ConversationModel extends window.Backbone
const pendingMember = window.ConversationController.get(conversationId);
if (!pendingMember) {
window.log.warn(
log.warn(
`removePendingMember/${idLog}: No conversation found for conversation ${conversationId}`
);
return undefined;
@ -663,7 +658,7 @@ export class ConversationModel extends window.Backbone
const uuid = pendingMember.get('uuid');
if (!uuid) {
window.log.warn(
log.warn(
`removePendingMember/${idLog}: Missing uuid for conversation ${pendingMember.idForLogging()}`
);
return undefined;
@ -691,7 +686,7 @@ export class ConversationModel extends window.Backbone
// button press and when we get here. It's especially important to check here
// in conflict/retry cases.
if (!this.isMember(conversationId)) {
window.log.warn(
log.warn(
`removeMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
);
return undefined;
@ -727,7 +722,7 @@ export class ConversationModel extends window.Backbone
const idLog = this.idForLogging();
if (!this.isMember(conversationId)) {
window.log.warn(
log.warn(
`toggleAdminChange/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
);
return undefined;
@ -796,7 +791,7 @@ export class ConversationModel extends window.Backbone
}
setUnregistered(): void {
window.log.info(`Conversation ${this.idForLogging()} is now unregistered`);
log.info(`Conversation ${this.idForLogging()} is now unregistered`);
this.set({
discoveredUnregisteredAt: Date.now(),
});
@ -808,9 +803,7 @@ export class ConversationModel extends window.Backbone
return;
}
window.log.info(
`Conversation ${this.idForLogging()} is registered once again`
);
log.info(`Conversation ${this.idForLogging()} is registered once again`);
this.set({
discoveredUnregisteredAt: undefined,
});
@ -900,7 +893,7 @@ export class ConversationModel extends window.Backbone
}
enableProfileSharing({ viaStorageServiceSync = false } = {}): void {
window.log.info(
log.info(
`enableProfileSharing: ${this.idForLogging()} storage? ${viaStorageServiceSync}`
);
const before = this.get('profileSharing');
@ -915,7 +908,7 @@ export class ConversationModel extends window.Backbone
}
disableProfileSharing({ viaStorageServiceSync = false } = {}): void {
window.log.info(
log.info(
`disableProfileSharing: ${this.idForLogging()} storage? ${viaStorageServiceSync}`
);
const before = this.get('profileSharing');
@ -1041,7 +1034,7 @@ export class ConversationModel extends window.Backbone
return;
}
window.log.info(
log.info(
`Fetching uuid for a sms-only conversation ${this.idForLogging()}`
);
@ -1060,7 +1053,7 @@ export class ConversationModel extends window.Backbone
this.isFetchingUUID = false;
this.trigger('change', this);
window.log.info(
log.info(
`Done fetching uuid for a sms-only conversation ${this.idForLogging()}`
);
}
@ -1110,7 +1103,7 @@ export class ConversationModel extends window.Backbone
return;
}
window.log.info(`Repairing GroupV2 conversation ${this.idForLogging()}`);
log.info(`Repairing GroupV2 conversation ${this.idForLogging()}`);
const { masterKey, secretParams, publicParams } = data;
this.set({ masterKey, secretParams, publicParams, groupVersion: 2 });
@ -1325,7 +1318,7 @@ export class ConversationModel extends window.Backbone
}
const { stack } = new Error('for stack');
window.log.warn(
log.warn(
`Conversation.format()/${this.idForLogging()} reentrant call! ${stack}`
);
@ -1701,11 +1694,11 @@ export class ConversationModel extends window.Backbone
isGroupV2(this.attributes) &&
this.isMember(ourConversationId)
) {
window.log.info(
log.info(
'applyMessageRequestResponse/accept: Already a member of v2 group'
);
} else {
window.log.error(
log.error(
'applyMessageRequestResponse/accept: Neither member nor pending member of v2 group'
);
}
@ -1822,7 +1815,7 @@ export class ConversationModel extends window.Backbone
if (errorDetails !== ALREADY_REQUESTED_TO_JOIN) {
throw error;
} else {
window.log.info(
log.info(
'joinGroupV2ViaLink: Got 400, but server is telling us we have already requested to join. Forcing that local state'
);
this.set({
@ -1938,7 +1931,7 @@ export class ConversationModel extends window.Backbone
createGroupChange: () => this.removeMember(ourConversationId),
});
} else {
window.log.error(
log.error(
'leaveGroupV2: We were neither a member nor a pending member of the group'
);
}
@ -1950,7 +1943,7 @@ export class ConversationModel extends window.Backbone
}
if (!this.isMember(conversationId)) {
window.log.error(
log.error(
`toggleAdmin: Member ${conversationId} is not a member of the group`
);
return;
@ -2036,7 +2029,7 @@ export class ConversationModel extends window.Backbone
extraConversationsForSend: [conversationId],
});
} else {
window.log.error(
log.error(
`removeFromGroupV2: Member ${conversationId} is neither a member nor a pending member of the group`
);
}
@ -2055,7 +2048,7 @@ export class ConversationModel extends window.Backbone
const groupId = this.getGroupIdBuffer();
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'syncMessageRequestResponse: We are primary device; not sending message request sync'
);
return;
@ -2209,9 +2202,7 @@ export class ConversationModel extends window.Backbone
verified
);
} else {
window.log.warn(
`_setVerified(${this.id}): no uuid to update protocol storage`
);
log.warn(`_setVerified(${this.id}): no uuid to update protocol storage`);
}
this.set({ verified });
@ -2262,7 +2253,7 @@ export class ConversationModel extends window.Backbone
}
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'sendVerifySyncMessage: We are primary device; not sending sync'
);
return;
@ -2366,7 +2357,7 @@ export class ConversationModel extends window.Backbone
const uuid = this.get('uuid');
if (!uuid) {
window.log.warn(`setApproved(${this.id}): no uuid, ignoring`);
log.warn(`setApproved(${this.id}): no uuid, ignoring`);
return;
}
@ -2475,10 +2466,9 @@ export class ConversationModel extends window.Backbone
receivedAt: number;
receivedAtCounter: number;
}): Promise<void> {
window.log.info(
`addChatSessionRefreshed: adding for ${this.idForLogging()}`,
{ receivedAt }
);
log.info(`addChatSessionRefreshed: adding for ${this.idForLogging()}`, {
receivedAt,
});
const message = ({
conversationId: this.id,
@ -2514,7 +2504,7 @@ export class ConversationModel extends window.Backbone
senderUuid: string;
sentAt: number;
}): Promise<void> {
window.log.info(`addDeliveryIssue: adding for ${this.idForLogging()}`, {
log.info(`addDeliveryIssue: adding for ${this.idForLogging()}`, {
sentAt,
senderUuid,
});
@ -2546,7 +2536,7 @@ export class ConversationModel extends window.Backbone
}
async addKeyChange(keyChangedId: UUID): Promise<void> {
window.log.info(
log.info(
'adding key change advisory for',
this.idForLogging(),
keyChangedId.toString(),
@ -2596,15 +2586,13 @@ export class ConversationModel extends window.Backbone
window._.defaults(options, { local: true });
if (isMe(this.attributes)) {
window.log.info(
'refusing to add verified change advisory for our own number'
);
log.info('refusing to add verified change advisory for our own number');
return;
}
const lastMessage = this.get('timestamp') || Date.now();
window.log.info(
log.info(
'adding verified change advisory for',
this.idForLogging(),
verifiedChangeId,
@ -2851,7 +2839,7 @@ export class ConversationModel extends window.Backbone
}
async addChangeNumberNotification(): Promise<void> {
window.log.info(
log.info(
`Conversation ${this.idForLogging()}: adding change number notification`
);
@ -2981,9 +2969,7 @@ export class ConversationModel extends window.Backbone
const waitTime = startedAt - queuedAt;
if (waitTime > JOB_REPORTING_THRESHOLD_MS) {
window.log.info(
`Conversation job ${name} was blocked for ${waitTime}ms`
);
log.info(`Conversation job ${name} was blocked for ${waitTime}ms`);
}
try {
@ -2992,7 +2978,7 @@ export class ConversationModel extends window.Backbone
const duration = Date.now() - startedAt;
if (duration > JOB_REPORTING_THRESHOLD_MS) {
window.log.info(`Conversation job ${name} took ${duration}ms`);
log.info(`Conversation job ${name} took ${duration}ms`);
}
}
});
@ -3241,7 +3227,7 @@ export class ConversationModel extends window.Backbone
const packData = Stickers.getStickerPack(packId);
const stickerData = Stickers.getSticker(packId, stickerId);
if (!stickerData || !packData) {
window.log.warn(
log.warn(
`Attempted to send nonexistent (${packId}, ${stickerId}) sticker!`
);
return;
@ -3262,9 +3248,7 @@ export class ConversationModel extends window.Backbone
if (sniffedMimeType) {
contentType = sniffedMimeType;
} else {
window.log.warn(
'Unable to sniff sticker MIME type; falling back to WebP'
);
log.warn('Unable to sniff sticker MIME type; falling back to WebP');
contentType = IMAGE_WEBP;
}
@ -3305,7 +3289,7 @@ export class ConversationModel extends window.Backbone
const destination = this.getSendTarget()!;
await this.queueJob('sendDeleteForEveryone', async () => {
window.log.info(
log.info(
'Sending deleteForEveryone to conversation',
this.idForLogging(),
'with timestamp',
@ -3395,7 +3379,7 @@ export class ConversationModel extends window.Backbone
return result;
}).catch(error => {
window.log.error(
log.error(
'Error sending deleteForEveryone',
deleteModel,
targetTimestamp,
@ -3434,7 +3418,7 @@ export class ConversationModel extends window.Backbone
const destination = this.getSendTarget()!;
return this.queueJob('sendReactionMessage', async () => {
window.log.info(
log.info(
'Sending reaction to conversation',
this.idForLogging(),
'with timestamp',
@ -3570,17 +3554,17 @@ export class ConversationModel extends window.Backbone
const id = this.get('id');
const recipients = this.getRecipients();
if (!this.get('profileSharing')) {
window.log.error(
log.error(
'Attempted to send profileKeyUpdate to conversation without profileSharing enabled',
id,
recipients
);
return;
}
window.log.info('Sending profileKeyUpdate to conversation', id, recipients);
log.info('Sending profileKeyUpdate to conversation', id, recipients);
const profileKey = await ourProfileKeyService.get();
if (!profileKey) {
window.log.error(
log.error(
'Attempted to send profileKeyUpdate but our profile key was not found'
);
return;
@ -3640,7 +3624,7 @@ export class ConversationModel extends window.Backbone
const expireTimer = this.get('expireTimer');
window.log.info(
log.info(
'Sending message to conversation',
this.idForLogging(),
'with timestamp',
@ -3709,7 +3693,7 @@ export class ConversationModel extends window.Backbone
await normalMessageSendJobQueue.add(
{ messageId: message.id, conversationId: this.id },
async jobToInsert => {
window.log.info(
log.info(
`enqueueMessageForSend: saving message ${message.id} and job ${jobToInsert.id}`
);
await window.Signal.Data.saveMessage(message.attributes, {
@ -3721,7 +3705,7 @@ export class ConversationModel extends window.Backbone
const dbDuration = Date.now() - dbStart;
if (dbDuration > SEND_REPORTING_THRESHOLD_MS) {
window.log.info(
log.info(
`ConversationModel(${this.idForLogging()}.sendMessage(${now}): ` +
`db save took ${dbDuration}ms`
);
@ -3755,7 +3739,7 @@ export class ConversationModel extends window.Backbone
const renderDuration = Date.now() - renderStart;
if (renderDuration > SEND_REPORTING_THRESHOLD_MS) {
window.log.info(
log.info(
`ConversationModel(${this.idForLogging()}.sendMessage(${now}): ` +
`render save took ${renderDuration}ms`
);
@ -3902,7 +3886,7 @@ export class ConversationModel extends window.Backbone
window.Signal.Groups.generateGroupInviteLinkPassword()
);
window.log.info('refreshGroupLink for conversation', this.idForLogging());
log.info('refreshGroupLink for conversation', this.idForLogging());
await this.modifyGroupV2({
name: 'updateInviteLinkPassword',
@ -3929,11 +3913,7 @@ export class ConversationModel extends window.Backbone
window.Signal.Groups.generateGroupInviteLinkPassword()
);
window.log.info(
'toggleGroupLink for conversation',
this.idForLogging(),
value
);
log.info('toggleGroupLink for conversation', this.idForLogging(), value);
const ACCESS_ENUM = Proto.AccessControl.AccessRequired;
const addFromInviteLink = value
@ -4108,7 +4088,7 @@ export class ConversationModel extends window.Backbone
return null;
}
window.log.info("Update conversation 'expireTimer'", {
log.info("Update conversation 'expireTimer'", {
id: this.idForLogging(),
expireTimer,
source,
@ -4223,7 +4203,7 @@ export class ConversationModel extends window.Backbone
const timestamp = Date.now();
if (this.hasAddedHistoryDisclaimer) {
window.log.warn(
log.warn(
`addMessageHistoryDisclaimer/${this.idForLogging()}: Refusing to add another this session`
);
return;
@ -4489,7 +4469,7 @@ export class ConversationModel extends window.Backbone
): Promise<void> {
// profileKey is a string so we can compare it directly
if (this.get('profileKey') !== profileKey) {
window.log.info(
log.info(
`Setting sealedSender to UNKNOWN for conversation ${this.idForLogging()}`
);
this.set({
@ -4780,18 +4760,14 @@ export class ConversationModel extends window.Backbone
// [X] dontNotifyForMentionsIfMuted
captureChange(logMessage: string): void {
if (!window.Signal.RemoteConfig.isEnabled('desktop.storageWrite3')) {
window.log.info(
log.info(
'conversation.captureChange: Returning early; desktop.storageWrite3 is falsey'
);
return;
}
window.log.info(
'storageService[captureChange]',
logMessage,
this.idForLogging()
);
log.info('storageService[captureChange]', logMessage, this.idForLogging());
this.set({ needsStorageServiceSync: true });
this.queueJob('captureChange', async () => {
@ -5003,7 +4979,7 @@ export class ConversationModel extends window.Backbone
return;
}
window.log.info('pinning', this.idForLogging());
log.info('pinning', this.idForLogging());
const pinnedConversationIds = new Set(
window.storage.get('pinnedConversationIds', new Array<string>())
);
@ -5025,7 +5001,7 @@ export class ConversationModel extends window.Backbone
return;
}
window.log.info('un-pinning', this.idForLogging());
log.info('un-pinning', this.idForLogging());
const pinnedConversationIds = new Set(
window.storage.get('pinnedConversationIds', new Array<string>())

View File

@ -113,6 +113,7 @@ import * as LinkPreview from '../types/LinkPreview';
import { SignalService as Proto } from '../protobuf';
import { normalMessageSendJobQueue } from '../jobs/normalMessageSendJobQueue';
import type { PreviewType as OutgoingPreviewType } from '../textsecure/SendMessage';
import * as log from '../logging/log';
/* eslint-disable camelcase */
/* eslint-disable more/no-then */
@ -198,7 +199,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
this.set(
TypedMessage.initializeSchemaVersion({
message: attributes,
logger: window.log,
logger: log,
})
);
}
@ -630,7 +631,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
const { emoji } = sticker || {};
if (!emoji) {
window.log.warn('Unable to get emoji for sticker');
log.warn('Unable to get emoji for sticker');
}
return {
text: window.i18n('message--getNotificationText--stickers'),
@ -651,9 +652,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
};
}
window.log.error(
"This call history message doesn't have valid call history"
);
log.error("This call history message doesn't have valid call history");
}
if (isExpirationTimerUpdate(attributes)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@ -756,7 +755,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const required = ['conversationId', 'received_at', 'sent_at'];
const missing = _.filter(required, attr => !attributes[attr]);
if (missing.length) {
window.log.warn(`Message missing attributes: ${missing}`);
log.warn(`Message missing attributes: ${missing}`);
}
}
@ -846,13 +845,13 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const { fromSync } = options || {};
if (!this.isValidTapToView()) {
window.log.warn(
log.warn(
`markViewOnceMessageViewed: Message ${this.idForLogging()} is not a valid tap to view message!`
);
return;
}
if (this.isErased()) {
window.log.warn(
log.warn(
`markViewOnceMessageViewed: Message ${this.idForLogging()} is already erased!`
);
return;
@ -879,7 +878,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
});
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'markViewOnceMessageViewed: We are primary device; not sending view once open sync'
);
return;
@ -901,9 +900,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const logId = this.idForLogging();
const quote = this.get('quote');
if (!quote) {
window.log.warn(
`doubleCheckMissingQuoteReference/${logId}: Missing quote!`
);
log.warn(`doubleCheckMissingQuoteReference/${logId}: Missing quote!`);
return;
}
@ -913,7 +910,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// Is the quote really without a reference? Check with our in memory store
// first to make sure it's not there.
if (referencedMessageNotFound && contact) {
window.log.info(
log.info(
`doubleCheckMissingQuoteReference/${logId}: Verifying reference to ${sentAt}`
);
const inMemoryMessages = window.MessageController.filterBySentAt(
@ -923,7 +920,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
isQuoteAMatch(message, this.get('conversationId'), quote)
);
if (!matchingMessage) {
window.log.info(
log.info(
`doubleCheckMissingQuoteReference/${logId}: No match for ${sentAt}.`
);
@ -937,7 +934,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
},
});
window.log.info(
log.info(
`doubleCheckMissingQuoteReference/${logId}: Found match for ${sentAt}, updating.`
);
@ -960,7 +957,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
additionalProperties = {},
shouldPersist = true
): Promise<void> {
window.log.info(`Erasing data for message ${this.idForLogging()}`);
log.info(`Erasing data for message ${this.idForLogging()}`);
// Note: There are cases where we want to re-erase a given message. For example, when
// a viewed (or outgoing) View-Once message is deleted for everyone.
@ -968,7 +965,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
try {
await this.deleteData();
} catch (error) {
window.log.error(
log.error(
`Error erasing data for message ${this.idForLogging()}:`,
error && error.stack ? error.stack : error
);
@ -1075,7 +1072,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
return this.get('source');
}
if (!isOutgoing(this.attributes)) {
window.log.warn(
log.warn(
'Message.getSource: Called for non-incoming/non-outoing message'
);
}
@ -1090,7 +1087,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
return sourceDevice;
}
if (!isOutgoing(this.attributes)) {
window.log.warn(
log.warn(
'Message.getSourceDevice: Called for non-incoming/non-outoing message'
);
}
@ -1103,7 +1100,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
return this.get('sourceUuid');
}
if (!isOutgoing(this.attributes)) {
window.log.warn(
log.warn(
'Message.getSourceUuid: Called for non-incoming/non-outoing message'
);
}
@ -1145,7 +1142,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}
errors.forEach(e => {
window.log.error(
log.error(
'Message.saveErrors:',
e && e.reason ? e.reason : null,
e && e.stack ? e.stack : e
@ -1207,7 +1204,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const retryOptions = this.get('retryOptions');
if (retryOptions) {
if (!window.textsecure.messaging) {
window.log.error('retrySend: Cannot retry since we are offline!');
log.error('retrySend: Cannot retry since we are offline!');
return;
}
this.unset('errors');
@ -1611,7 +1608,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
});
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'sendSyncMessage: We are primary device; not sending sync message'
);
this.set({ dataMessage: undefined });
@ -1832,7 +1829,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
let count = 0;
let bodyPending;
window.log.info(
log.info(
`Queueing ${
attachmentsToQueue.length
} attachment downloads for message ${this.idForLogging()}`
@ -1846,12 +1843,12 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
if (longMessageAttachments.length > 1) {
window.log.error(
log.error(
`Received more than one long message attachment in message ${this.idForLogging()}`
);
}
window.log.info(
log.info(
`Queueing ${
longMessageAttachments.length
} long message attachment downloads for message ${this.idForLogging()}`
@ -1867,7 +1864,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
});
}
window.log.info(
log.info(
`Queueing ${
normalAttachments.length
} normal attachment downloads for message ${this.idForLogging()}`
@ -1879,7 +1876,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}
// We've already downloaded this!
if (attachment.path) {
window.log.info(
log.info(
`Normal attachment already downloaded for message ${this.idForLogging()}`
);
return attachment;
@ -1896,7 +1893,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
const previewsToQueue = this.get('preview') || [];
window.log.info(
log.info(
`Queueing ${
previewsToQueue.length
} preview attachment downloads for message ${this.idForLogging()}`
@ -1908,7 +1905,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}
// We've already downloaded this!
if (item.image.path) {
window.log.info(
log.info(
`Preview attachment already downloaded for message ${this.idForLogging()}`
);
return item;
@ -1927,7 +1924,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
const contactsToQueue = this.get('contact') || [];
window.log.info(
log.info(
`Queueing ${
contactsToQueue.length
} contact attachment downloads for message ${this.idForLogging()}`
@ -1939,7 +1936,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}
// We've already downloaded this!
if (item.avatar.avatar.path) {
window.log.info(
log.info(
`Contact attachment already downloaded for message ${this.idForLogging()}`
);
return item;
@ -1964,7 +1961,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
let quote = this.get('quote')!;
const quoteAttachmentsToQueue =
quote && quote.attachments ? quote.attachments : [];
window.log.info(
log.info(
`Queueing ${
quoteAttachmentsToQueue.length
} quote attachment downloads for message ${this.idForLogging()}`
@ -1979,7 +1976,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}
// We've already downloaded this!
if (item.thumbnail.path) {
window.log.info(
log.info(
`Quote attachment already downloaded for message ${this.idForLogging()}`
);
return item;
@ -2002,13 +1999,11 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
let sticker = this.get('sticker')!;
if (sticker && sticker.data && sticker.data.path) {
window.log.info(
log.info(
`Sticker attachment already downloaded for message ${this.idForLogging()}`
);
} else if (sticker) {
window.log.info(
`Queueing sticker download for message ${this.idForLogging()}`
);
log.info(`Queueing sticker download for message ${this.idForLogging()}`);
count += 1;
const { packId, stickerId, packKey } = sticker;
@ -2026,7 +2021,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
contentType: IMAGE_WEBP,
};
} catch (error) {
window.log.error(
log.error(
`Problem copying sticker (${packId}, ${stickerId}) to attachments:`,
error && error.stack ? error.stack : error
);
@ -2059,7 +2054,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
};
}
window.log.info(
log.info(
`Queued ${count} total attachment downloads for message ${this.idForLogging()}`
);
@ -2111,9 +2106,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
}
window.log.info(
'markAttachmentAsCorrupted: marking an attachment as corrupted'
);
log.info('markAttachmentAsCorrupted: marking an attachment as corrupted');
this.set({
attachments: newAttachments,
@ -2171,7 +2164,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (matchingMessage) {
queryMessage = matchingMessage;
} else {
window.log.info('copyFromQuotedMessage: db lookup needed', id);
log.info('copyFromQuotedMessage: db lookup needed', id);
const collection = await window.Signal.Data.getMessagesBySentAt(id, {
MessageCollection: window.Whisper.MessageCollection,
});
@ -2252,7 +2245,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
await window.Signal.Data.saveMessage(upgradedMessage);
}
} catch (error) {
window.log.error(
log.error(
'Problem upgrading message quoted message from database',
Errors.toLogFormat(error)
);
@ -2322,7 +2315,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const conversation = window.ConversationController.get(conversationId)!;
return conversation.queueJob('handleDataMessage', async () => {
window.log.info(
log.info(
`Starting handleDataMessage for message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
);
@ -2331,12 +2324,9 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
this.getSenderIdentifier()
);
if (inMemoryMessage) {
window.log.info(
'handleDataMessage: cache hit',
this.getSenderIdentifier()
);
log.info('handleDataMessage: cache hit', this.getSenderIdentifier());
} else {
window.log.info(
log.info(
'handleDataMessage: duplicate check db lookup needed',
this.getSenderIdentifier()
);
@ -2349,13 +2339,13 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const isUpdate = Boolean(data && data.isRecipientUpdate);
if (existingMessage && type === 'incoming') {
window.log.warn('Received duplicate message', this.idForLogging());
log.warn('Received duplicate message', this.idForLogging());
confirm();
return;
}
if (type === 'outgoing') {
if (isUpdate && existingMessage) {
window.log.info(
log.info(
`handleDataMessage: Updating message ${message.idForLogging()} with received transcript`
);
@ -2431,7 +2421,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
return;
}
if (isUpdate) {
window.log.warn(
log.warn(
`handleDataMessage: Received update transcript, but no existing entry for message ${message.idForLogging()}. Dropping.`
);
@ -2439,7 +2429,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
return;
}
if (existingMessage) {
window.log.warn(
log.warn(
`handleDataMessage: Received duplicate transcript for message ${message.idForLogging()}, but it was not an update transcript. Dropping.`
);
@ -2494,7 +2484,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
});
} catch (error) {
const errorText = error && error.stack ? error.stack : error;
window.log.error(
log.error(
`handleDataMessage: Failed to process group update for ${conversation.idForLogging()} as part of message ${message.idForLogging()}: ${errorText}`
);
throw error;
@ -2525,7 +2515,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
!conversation.hasMember(ourConversationId) ||
!conversation.hasMember(senderId))
) {
window.log.warn(
log.warn(
`Received message destined for group ${conversation.idForLogging()}, which we or the sender are not a part of. Dropping.`
);
confirm();
@ -2545,7 +2535,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
conversation.get('members') &&
(conversation.get('left') || !conversation.hasMember(ourConversationId))
) {
window.log.warn(
log.warn(
`Received message destined for group ${conversation.idForLogging()}, which we're not a part of. Dropping.`
);
confirm();
@ -2555,7 +2545,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// Because GroupV1 messages can now be multiplexed into GroupV2 conversations, we
// drop GroupV1 updates in GroupV2 groups.
if (isV1GroupUpdate && isGroupV2(conversation.attributes)) {
window.log.warn(
log.warn(
`Received GroupV1 update in GroupV2 conversation ${conversation.idForLogging()}. Dropping.`
);
confirm();
@ -2615,7 +2605,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
LinkPreview.isLinkSafeToPreview(item.url)
);
if (preview.length < incomingPreview.length) {
window.log.info(
log.info(
`${message.idForLogging()}: Eliminated ${
preview.length - incomingPreview.length
} previews with invalid urls'`
@ -2705,9 +2695,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
}
} catch (err) {
window.log.info(
'handleDataMessage: group avatar download failed'
);
log.info('handleDataMessage: group avatar download failed');
}
}
@ -2747,7 +2735,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
pendingGroupUpdate.avatarUpdated = true;
} else {
window.log.info(
log.info(
'handleDataMessage: Group avatar hash matched; not replacing group avatar'
);
}
@ -2766,7 +2754,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
pendingGroupUpdate.joined = [...e164s];
}
if (conversation.get('left')) {
window.log.warn('re-added to a left group');
log.warn('re-added to a left group');
attributes.left = false;
conversation.set({ addedBy: message.getContactId() });
}
@ -2779,7 +2767,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
if (!inGroup) {
const senderString = sender ? sender.idForLogging() : null;
window.log.info(
log.info(
`Got 'left' message from someone not in group: ${senderString}. Dropping.`
);
return;
@ -2806,7 +2794,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// message.set call and after GroupV1 processing to make sure all possible
// properties are set before we determine that a message is empty.
if (message.isEmpty()) {
window.log.info(
log.info(
`handleDataMessage: Dropping empty message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
);
confirm();
@ -2840,7 +2828,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const shouldLogExpireTimerChange =
isExpirationTimerUpdate(message.attributes) || expireTimer;
if (shouldLogExpireTimerChange) {
window.log.info("Update conversation 'expireTimer'", {
log.info("Update conversation 'expireTimer'", {
id: conversation.idForLogging(),
expireTimer,
source: 'handleDataMessage',
@ -2908,7 +2896,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
isTapToView(message.attributes) &&
!message.isValidTapToView()
) {
window.log.warn(
log.warn(
`Received tap to view message ${message.idForLogging()} with invalid data. Erasing contents.`
);
message.set({
@ -2949,7 +2937,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
) {
if (window.attachmentDownloadQueue) {
window.attachmentDownloadQueue.unshift(message);
window.log.info(
log.info(
'Adding to attachmentDownloadQueue',
message.get('sent_at')
);
@ -2961,14 +2949,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const isFirstRun = true;
await this.modifyTargetMessage(conversation, isFirstRun);
window.log.info(
log.info(
'handleDataMessage: Batching save for',
message.get('sent_at')
);
this.saveAndNotify(conversation, confirm);
} catch (error) {
const errorForLog = error && error.stack ? error.stack : error;
window.log.error(
log.error(
'handleDataMessage',
message.idForLogging(),
'error:',
@ -2985,7 +2973,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
): Promise<void> {
await window.Signal.Util.saveNewMessageBatcher.add(this.attributes);
window.log.info('Message saved', this.get('sent_at'));
log.info('Message saved', this.get('sent_at'));
conversation.trigger('newmessage', this);
@ -3057,7 +3045,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
) => {
const oldSendState = getOwn(result, destinationConversationId);
if (!oldSendState) {
window.log.warn(
log.warn(
`Got a receipt for a conversation (${destinationConversationId}), but we have no record of sending to them`
);
return result;
@ -3177,7 +3165,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
if (changed && !isFirstRun) {
window.log.info(
log.info(
`modifyTargetMessage/${this.idForLogging()}: Changes in second run; saving.`
);
await window.Signal.Data.saveMessage(this.attributes);
@ -3219,7 +3207,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
let oldReaction: ReactionAttributesType | undefined;
if (reaction.get('remove')) {
window.log.info('Removing reaction for message', messageId);
log.info('Removing reaction for message', messageId);
const newReactions = reactions.filter(
re =>
re.emoji !== reaction.get('emoji') ||
@ -3240,7 +3228,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
targetTimestamp: reaction.get('targetTimestamp'),
});
} else {
window.log.info('Adding reaction for message', messageId);
log.info('Adding reaction for message', messageId);
const newReactions = reactions.filter(
re => re.fromId !== reaction.get('fromId')
);
@ -3281,7 +3269,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}
const newCount = (this.get('reactions') || []).length;
window.log.info(
log.info(
`Done processing reaction for message ${messageId}. Went from ${count} to ${newCount} reactions.`
);
@ -3296,7 +3284,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
del: typeof window.WhatIsThis,
shouldPersist = true
): Promise<void> {
window.log.info('Handling DOE.', {
log.info('Handling DOE.', {
fromId: del.get('fromId'),
targetSentTimestamp: del.get('targetSentTimestamp'),
messageServerTimestamp: this.get('serverTimestamp'),

View File

@ -53,7 +53,7 @@ export async function routineProfileRefresh({
async function refreshConversation(
conversation: ConversationModel
): Promise<void> {
window.log.info(
log.info(
`routineProfileRefresh: refreshing profile for ${conversation.idForLogging()}`
);
@ -63,12 +63,12 @@ export async function routineProfileRefresh({
conversation.get('uuid'),
conversation.get('e164')
);
window.log.info(
log.info(
`routineProfileRefresh: refreshed profile for ${conversation.idForLogging()}`
);
successCount += 1;
} catch (err) {
window.log.error(
log.error(
`routineProfileRefresh: refreshed profile for ${conversation.idForLogging()}`,
err?.stack || err
);

View File

@ -83,6 +83,7 @@ import { notify } from './notify';
import { getSendOptions } from '../util/getSendOptions';
import { SignalService as Proto } from '../protobuf';
import dataInterface from '../sql/Client';
import * as log from '../logging/log';
const {
processGroupCallRingRequest,
@ -275,11 +276,11 @@ export class CallingClass {
conversationId: string,
isVideoCall: boolean
): Promise<void> {
window.log.info('CallingClass.startCallingLobby()');
log.info('CallingClass.startCallingLobby()');
const conversation = window.ConversationController.get(conversationId);
if (!conversation) {
window.log.error('Could not find conversation, cannot start call lobby');
log.error('Could not find conversation, cannot start call lobby');
return;
}
@ -287,15 +288,11 @@ export class CallingClass {
const callMode = getConversationCallMode(conversationProps);
switch (callMode) {
case CallMode.None:
window.log.error(
'Conversation does not support calls, new call not allowed.'
);
log.error('Conversation does not support calls, new call not allowed.');
return;
case CallMode.Direct:
if (!this.getRemoteUserIdFromConversation(conversation)) {
window.log.error(
'Missing remote user identifier, new call not allowed.'
);
log.error('Missing remote user identifier, new call not allowed.');
return;
}
break;
@ -306,24 +303,22 @@ export class CallingClass {
}
if (!this.uxActions) {
window.log.error('Missing uxActions, new call not allowed.');
log.error('Missing uxActions, new call not allowed.');
return;
}
if (!this.localDeviceId) {
window.log.error(
'Missing local device identifier, new call not allowed.'
);
log.error('Missing local device identifier, new call not allowed.');
return;
}
const haveMediaPermissions = await this.requestPermissions(isVideoCall);
if (!haveMediaPermissions) {
window.log.info('Permissions were denied, new call not allowed.');
log.info('Permissions were denied, new call not allowed.');
return;
}
window.log.info('CallingClass.startCallingLobby(): Starting lobby');
log.info('CallingClass.startCallingLobby(): Starting lobby');
// It's important that this function comes before any calls to
// `videoCapturer.enableCapture` or `videoCapturer.enableCaptureAndSend` because of
@ -358,7 +353,7 @@ export class CallingClass {
!conversationProps.publicParams ||
!conversationProps.secretParams
) {
window.log.error(
log.error(
'Conversation is missing required parameters. Cannot connect group call'
);
return;
@ -406,7 +401,7 @@ export class CallingClass {
hasLocalAudio: boolean,
hasLocalVideo: boolean
): Promise<void> {
window.log.info('CallingClass.startOutgoingDirectCall()');
log.info('CallingClass.startOutgoingDirectCall()');
if (!this.uxActions) {
throw new Error('Redux actions not available');
@ -415,41 +410,37 @@ export class CallingClass {
const conversation = window.ConversationController.get(conversationId);
if (!conversation) {
window.log.error('Could not find conversation, cannot start call');
log.error('Could not find conversation, cannot start call');
this.stopCallingLobby();
return;
}
const remoteUserId = this.getRemoteUserIdFromConversation(conversation);
if (!remoteUserId || !this.localDeviceId) {
window.log.error('Missing identifier, new call not allowed.');
log.error('Missing identifier, new call not allowed.');
this.stopCallingLobby();
return;
}
const haveMediaPermissions = await this.requestPermissions(hasLocalVideo);
if (!haveMediaPermissions) {
window.log.info('Permissions were denied, new call not allowed.');
log.info('Permissions were denied, new call not allowed.');
this.stopCallingLobby();
return;
}
window.log.info(
'CallingClass.startOutgoingDirectCall(): Getting call settings'
);
log.info('CallingClass.startOutgoingDirectCall(): Getting call settings');
const callSettings = await this.getCallSettings(conversation);
// Check state after awaiting to debounce call button.
if (RingRTC.call && RingRTC.call.state !== CallState.Ended) {
window.log.info('Call already in progress, new call not allowed.');
log.info('Call already in progress, new call not allowed.');
this.stopCallingLobby();
return;
}
window.log.info(
'CallingClass.startOutgoingDirectCall(): Starting in RingRTC'
);
log.info('CallingClass.startOutgoingDirectCall(): Starting in RingRTC');
// We could make this faster by getting the call object
// from the RingRTC before we lookup the ICE servers.
@ -655,7 +646,7 @@ export class CallingClass {
groupCall.setMembershipProof(Buffer.from(Bytes.fromString(proof)));
}
} catch (err) {
window.log.error('Failed to fetch membership proof', err);
log.error('Failed to fetch membership proof', err);
} finally {
isRequestingMembershipProof = false;
}
@ -689,7 +680,7 @@ export class CallingClass {
conversationId
)?.format();
if (!conversation) {
window.log.error('Missing conversation; not joining group call');
log.error('Missing conversation; not joining group call');
return;
}
@ -698,7 +689,7 @@ export class CallingClass {
!conversation.publicParams ||
!conversation.secretParams
) {
window.log.error(
log.error(
'Conversation is missing required parameters. Cannot join group call'
);
return;
@ -782,7 +773,7 @@ export class CallingClass {
uuids: peekInfo.joinedMembers.map(uuidBuffer => {
let uuid = arrayBufferToUuid(typedArrayToArrayBuffer(uuidBuffer));
if (!uuid) {
window.log.error(
log.error(
'Calling.formatGroupCallPeekInfoForRedux: could not convert peek UUID ArrayBuffer to string; using fallback UUID'
);
uuid = '00000000-0000-0000-0000-000000000000';
@ -832,7 +823,7 @@ export class CallingClass {
typedArrayToArrayBuffer(remoteDeviceState.userId)
);
if (!uuid) {
window.log.error(
log.error(
'Calling.formatGroupCallForRedux: could not convert remote participant UUID ArrayBuffer to string; using fallback UUID'
);
uuid = '00000000-0000-0000-0000-000000000000';
@ -891,7 +882,7 @@ export class CallingClass {
): Promise<void> {
const conversation = window.ConversationController.get(conversationId);
if (!conversation) {
window.log.error(
log.error(
'Unable to send group call update message for non-existent conversation'
);
return;
@ -900,7 +891,7 @@ export class CallingClass {
const groupV2 = conversation.getGroupV2Info();
const sendOptions = await getSendOptions(conversation.attributes);
if (!groupV2) {
window.log.error(
log.error(
'Unable to send group call update message for conversation that lacks groupV2 info'
);
return;
@ -926,7 +917,7 @@ export class CallingClass {
sendType: 'callingMessage',
timestamp,
}).catch(err => {
window.log.error(
log.error(
'Failed to send group call update:',
err && err.stack ? err.stack : err
);
@ -937,11 +928,11 @@ export class CallingClass {
conversationId: string,
asVideoCall: boolean
): Promise<void> {
window.log.info('CallingClass.acceptDirectCall()');
log.info('CallingClass.acceptDirectCall()');
const callId = this.getCallIdForConversation(conversationId);
if (!callId) {
window.log.warn('Trying to accept a non-existent call');
log.warn('Trying to accept a non-existent call');
return;
}
@ -952,19 +943,17 @@ export class CallingClass {
RingRTC.setVideoRenderer(callId, this.videoRenderer);
RingRTC.accept(callId, asVideoCall);
} else {
window.log.info('Permissions were denied, call not allowed, hanging up.');
log.info('Permissions were denied, call not allowed, hanging up.');
RingRTC.hangup(callId);
}
}
declineDirectCall(conversationId: string): void {
window.log.info('CallingClass.declineDirectCall()');
log.info('CallingClass.declineDirectCall()');
const callId = this.getCallIdForConversation(conversationId);
if (!callId) {
window.log.warn(
'declineDirectCall: Trying to decline a non-existent call'
);
log.warn('declineDirectCall: Trying to decline a non-existent call');
return;
}
@ -972,13 +961,13 @@ export class CallingClass {
}
declineGroupCall(conversationId: string, ringId: bigint): void {
window.log.info('CallingClass.declineGroupCall()');
log.info('CallingClass.declineGroupCall()');
const groupId = window.ConversationController.get(conversationId)?.get(
'groupId'
);
if (!groupId) {
window.log.error(
log.error(
'declineGroupCall: could not find the group ID for that conversation'
);
return;
@ -993,11 +982,11 @@ export class CallingClass {
}
hangup(conversationId: string): void {
window.log.info('CallingClass.hangup()');
log.info('CallingClass.hangup()');
const call = getOwn(this.callsByConversation, conversationId);
if (!call) {
window.log.warn('Trying to hang up a non-existent call');
log.warn('Trying to hang up a non-existent call');
return;
}
@ -1018,7 +1007,7 @@ export class CallingClass {
setOutgoingAudio(conversationId: string, enabled: boolean): void {
const call = getOwn(this.callsByConversation, conversationId);
if (!call) {
window.log.warn('Trying to set outgoing audio for a non-existent call');
log.warn('Trying to set outgoing audio for a non-existent call');
return;
}
@ -1034,7 +1023,7 @@ export class CallingClass {
setOutgoingVideo(conversationId: string, enabled: boolean): void {
const call = getOwn(this.callsByConversation, conversationId);
if (!call) {
window.log.warn('Trying to set outgoing video for a non-existent call');
log.warn('Trying to set outgoing video for a non-existent call');
return;
}
@ -1099,7 +1088,7 @@ export class CallingClass {
): void {
const call = getOwn(this.callsByConversation, conversationId);
if (!call) {
window.log.warn('Trying to set presenting for a non-existent call');
log.warn('Trying to set presenting for a non-existent call');
return;
}
@ -1243,7 +1232,7 @@ export class CallingClass {
if (
!this.mediaDeviceSettingsEqual(this.lastMediaDeviceSettings, newSettings)
) {
window.log.info(
log.info(
'MediaDevice: available devices changed (from->to)',
this.lastMediaDeviceSettings,
newSettings
@ -1354,13 +1343,13 @@ export class CallingClass {
}
setPreferredMicrophone(device: AudioDevice): void {
window.log.info('MediaDevice: setPreferredMicrophone', device);
log.info('MediaDevice: setPreferredMicrophone', device);
window.Events.setPreferredAudioInputDevice(device);
RingRTC.setAudioInput(device.index);
}
setPreferredSpeaker(device: AudioDevice): void {
window.log.info('MediaDevice: setPreferredSpeaker', device);
log.info('MediaDevice: setPreferredSpeaker', device);
window.Events.setPreferredAudioOutputDevice(device);
RingRTC.setAudioOutput(device.index);
}
@ -1374,7 +1363,7 @@ export class CallingClass {
}
async setPreferredCamera(device: string): Promise<void> {
window.log.info('MediaDevice: setPreferredCamera', device);
log.info('MediaDevice: setPreferredCamera', device);
window.Events.setPreferredVideoInputDevice(device);
await this.videoCapturer.setPreferredDevice(device);
}
@ -1383,19 +1372,19 @@ export class CallingClass {
envelope: ProcessedEnvelope,
callingMessage: Proto.ICallingMessage
): Promise<void> {
window.log.info('CallingClass.handleCallingMessage()');
log.info('CallingClass.handleCallingMessage()');
const enableIncomingCalls = window.Events.getIncomingCallNotification();
if (callingMessage.offer && !enableIncomingCalls) {
// Drop offers silently if incoming call notifications are disabled.
window.log.info('Incoming calls are disabled, ignoring call offer.');
log.info('Incoming calls are disabled, ignoring call offer.');
return;
}
const remoteUserId = envelope.sourceUuid;
const remoteDeviceId = this.parseDeviceId(envelope.sourceDevice);
if (!remoteUserId || !remoteDeviceId || !this.localDeviceId) {
window.log.error('Missing identifier, ignoring call message.');
log.error('Missing identifier, ignoring call message.');
return;
}
@ -1405,9 +1394,7 @@ export class CallingClass {
new UUID(remoteUserId)
);
if (!senderIdentityRecord) {
window.log.error(
'Missing sender identity record; ignoring call message.'
);
log.error('Missing sender identity record; ignoring call message.');
return;
}
const senderIdentityKey = senderIdentityRecord.publicKey.slice(1); // Ignore the type header, it is not used.
@ -1416,21 +1403,19 @@ export class CallingClass {
const receiverIdentityRecord = storage.protocol.getIdentityRecord(ourUuid);
if (!receiverIdentityRecord) {
window.log.error(
'Missing receiver identity record; ignoring call message.'
);
log.error('Missing receiver identity record; ignoring call message.');
return;
}
const receiverIdentityKey = receiverIdentityRecord.publicKey.slice(1); // Ignore the type header, it is not used.
const conversation = window.ConversationController.get(remoteUserId);
if (!conversation) {
window.log.error('Missing conversation; ignoring call message.');
log.error('Missing conversation; ignoring call message.');
return;
}
if (callingMessage.offer && !conversation.getAccepted()) {
window.log.info(
log.info(
'Conversation was not approved by user; rejecting call message.'
);
@ -1460,7 +1445,7 @@ export class CallingClass {
const messageAgeSec = envelope.messageAgeSec ? envelope.messageAgeSec : 0;
window.log.info('CallingClass.handleCallingMessage(): Handling in RingRTC');
log.info('CallingClass.handleCallingMessage(): Handling in RingRTC');
RingRTC.handleCallingMessage(
remoteUserId,
@ -1483,14 +1468,14 @@ export class CallingClass {
settings.selectedCamera &&
this.lastMediaDeviceSettings.selectedCamera !== settings.selectedCamera)
) {
window.log.info('MediaDevice: selecting camera', settings.selectedCamera);
log.info('MediaDevice: selecting camera', settings.selectedCamera);
await this.videoCapturer.setPreferredDevice(settings.selectedCamera);
}
// Assume that the MediaDeviceSettings have been obtained very recently and
// the index is still valid (no devices have been plugged in in between).
if (settings.selectedMicrophone) {
window.log.info(
log.info(
'MediaDevice: selecting microphone',
settings.selectedMicrophone
);
@ -1498,10 +1483,7 @@ export class CallingClass {
}
if (settings.selectedSpeaker) {
window.log.info(
'MediaDevice: selecting speaker',
settings.selectedSpeaker
);
log.info('MediaDevice: selecting speaker', settings.selectedSpeaker);
RingRTC.setAudioOutput(settings.selectedSpeaker.index);
}
}
@ -1550,7 +1532,7 @@ export class CallingClass {
): Promise<boolean> {
const userId = arrayBufferToUuid(typedArrayToArrayBuffer(recipient));
if (!userId) {
window.log.error('handleSendCallMessage(): bad recipient UUID');
log.error('handleSendCallMessage(): bad recipient UUID');
return false;
}
const message = new CallingMessage();
@ -1567,9 +1549,7 @@ export class CallingClass {
const groupId = groupIdBytes.toString('base64');
const conversation = window.ConversationController.get(groupId);
if (!conversation) {
window.log.error(
'handleSendCallMessageToGroup(): could not find conversation'
);
log.error('handleSendCallMessageToGroup(): could not find conversation');
return;
}
@ -1609,21 +1589,19 @@ export class CallingClass {
ringerBytes: Buffer,
update: RingUpdate
): Promise<void> {
window.log.info(`handleGroupCallRingUpdate(): got ring update ${update}`);
log.info(`handleGroupCallRingUpdate(): got ring update ${update}`);
const groupId = groupIdBytes.toString('base64');
const ringerUuid = arrayBufferToUuid(typedArrayToArrayBuffer(ringerBytes));
if (!ringerUuid) {
window.log.error('handleGroupCallRingUpdate(): ringerUuid was invalid');
log.error('handleGroupCallRingUpdate(): ringerUuid was invalid');
return;
}
const conversation = window.ConversationController.get(groupId);
if (!conversation) {
window.log.error(
'handleGroupCallRingUpdate(): could not find conversation'
);
log.error('handleGroupCallRingUpdate(): could not find conversation');
return;
}
const conversationId = conversation.id;
@ -1650,14 +1628,14 @@ export class CallingClass {
}
if (shouldRing) {
window.log.info('handleGroupCallRingUpdate: ringing');
log.info('handleGroupCallRingUpdate: ringing');
this.uxActions?.receiveIncomingGroupCall({
conversationId,
ringId,
ringerUuid,
});
} else {
window.log.info('handleGroupCallRingUpdate: canceling any existing ring');
log.info('handleGroupCallRingUpdate: canceling any existing ring');
this.uxActions?.cancelIncomingGroupCallRing({
conversationId,
ringId,
@ -1676,7 +1654,7 @@ export class CallingClass {
: undefined;
if (!window.textsecure.messaging) {
window.log.warn('handleOutgoingSignaling() returning false; offline');
log.warn('handleOutgoingSignaling() returning false; offline');
return false;
}
@ -1694,15 +1672,13 @@ export class CallingClass {
throw result.errors[0];
}
window.log.info('handleOutgoingSignaling() completed successfully');
log.info('handleOutgoingSignaling() completed successfully');
return true;
} catch (err) {
if (err && err.errors && err.errors.length > 0) {
window.log.error(
`handleOutgoingSignaling() failed: ${err.errors[0].reason}`
);
log.error(`handleOutgoingSignaling() failed: ${err.errors[0].reason}`);
} else {
window.log.error('handleOutgoingSignaling() failed');
log.error('handleOutgoingSignaling() failed');
}
return false;
}
@ -1710,16 +1686,16 @@ export class CallingClass {
// If we return null here, we hang up the call.
private async handleIncomingCall(call: Call): Promise<CallSettings | null> {
window.log.info('CallingClass.handleIncomingCall()');
log.info('CallingClass.handleIncomingCall()');
if (!this.uxActions || !this.localDeviceId) {
window.log.error('Missing required objects, ignoring incoming call.');
log.error('Missing required objects, ignoring incoming call.');
return null;
}
const conversation = window.ConversationController.get(call.remoteUserId);
if (!conversation) {
window.log.error('Missing conversation, ignoring incoming call.');
log.error('Missing conversation, ignoring incoming call.');
return null;
}
@ -1732,7 +1708,7 @@ export class CallingClass {
verifiedEnum ===
window.textsecure.storage.protocol.VerifiedStatus.UNVERIFIED
) {
window.log.info(
log.info(
`Peer is not trusted, ignoring incoming call for conversation: ${conversation.idForLogging()}`
);
this.addCallHistoryForFailedIncomingCall(
@ -1750,11 +1726,11 @@ export class CallingClass {
isVideoCall: call.isVideoCall,
});
window.log.info('CallingClass.handleIncomingCall(): Proceeding');
log.info('CallingClass.handleIncomingCall(): Proceeding');
return await this.getCallSettings(conversation);
} catch (err) {
window.log.error(`Ignoring incoming call: ${err.stack}`);
log.error(`Ignoring incoming call: ${err.stack}`);
this.addCallHistoryForFailedIncomingCall(
conversation,
call.isVideoCall,
@ -1831,13 +1807,13 @@ export class CallingClass {
) {
switch (level) {
case CallLogLevel.Info:
window.log.info(`${fileName}:${line} ${message}`);
log.info(`${fileName}:${line} ${message}`);
break;
case CallLogLevel.Warn:
window.log.warn(`${fileName}:${line} ${message}`);
log.warn(`${fileName}:${line} ${message}`);
break;
case CallLogLevel.Error:
window.log.error(`${fileName}:${line} ${message}`);
log.error(`${fileName}:${line} ${message}`);
break;
default:
break;
@ -1880,7 +1856,7 @@ export class CallingClass {
// it an empty one.
RingRTC.receivedHttpResponse(requestId, err.code, Buffer.alloc(0));
} else {
window.log.error('handleSendHttpRequest: fetch failed with error', err);
log.error('handleSendHttpRequest: fetch failed with error', err);
RingRTC.httpRequestFailed(requestId, String(err));
}
return;
@ -2017,15 +1993,13 @@ export class CallingClass {
typedArrayToArrayBuffer(peekInfo.creator)
);
if (!creatorUuid) {
window.log.error('updateCallHistoryForGroupCall(): bad creator UUID');
log.error('updateCallHistoryForGroupCall(): bad creator UUID');
return;
}
const conversation = window.ConversationController.get(conversationId);
if (!conversation) {
window.log.error(
'updateCallHistoryForGroupCall(): could not find conversation'
);
log.error('updateCallHistoryForGroupCall(): could not find conversation');
return;
}

View File

@ -14,6 +14,7 @@ import { GroupCredentialType } from '../textsecure/WebAPI';
import * as durations from '../util/durations';
import { BackOff } from '../util/BackOff';
import { sleep } from '../util/sleep';
import * as log from '../logging/log';
export const GROUP_CREDENTIALS_KEY = 'groupCredentials';
@ -38,7 +39,7 @@ export async function initializeGroupCredentialFetcher(): Promise<void> {
return;
}
window.log.info('initializeGroupCredentialFetcher: starting...');
log.info('initializeGroupCredentialFetcher: starting...');
started = true;
// Because we fetch eight days of credentials at a time, we really only need to run
@ -71,7 +72,7 @@ export async function runWithRetry(
return;
} catch (error) {
const wait = backOff.getAndIncrement();
window.log.info(
log.info(
`runWithRetry: ${fn.name} failed. Waiting ${wait}ms for retry. Error: ${error.stack}`
);
// eslint-disable-next-line no-await-in-loop
@ -83,7 +84,7 @@ export async function runWithRetry(
// could end up with multiple endlessly-retrying runs.
const duration = options.scheduleAnother;
if (duration) {
window.log.info(
log.info(
`runWithRetry: scheduling another run with a setTimeout duration of ${duration}ms`
);
setTimeout(async () => runWithRetry(fn, options), duration);
@ -117,7 +118,7 @@ export function getCredentialsForToday(
export async function maybeFetchNewCredentials(): Promise<void> {
const uuid = window.textsecure.storage.user.getUuid()?.toString();
if (!uuid) {
window.log.info('maybeFetchCredentials: no UUID, returning early');
log.info('maybeFetchCredentials: no UUID, returning early');
return;
}
const previous: CredentialsDataType | undefined = window.storage.get(
@ -125,18 +126,18 @@ export async function maybeFetchNewCredentials(): Promise<void> {
);
const requestDates = getDatesForRequest(previous);
if (!requestDates) {
window.log.info('maybeFetchCredentials: no new credentials needed');
log.info('maybeFetchCredentials: no new credentials needed');
return;
}
const accountManager = window.getAccountManager();
if (!accountManager) {
window.log.info('maybeFetchCredentials: unable to get AccountManager');
log.info('maybeFetchCredentials: unable to get AccountManager');
return;
}
const { startDay, endDay } = requestDates;
window.log.info(
log.info(
`maybeFetchCredentials: fetching credentials for ${startDay} through ${endDay}`
);
@ -168,10 +169,10 @@ export async function maybeFetchNewCredentials(): Promise<void> {
: [];
const finalCredentials = [...previousCleaned, ...newCredentials];
window.log.info('maybeFetchCredentials: Saving new credentials...');
log.info('maybeFetchCredentials: Saving new credentials...');
// Note: we don't wait for this to finish
window.storage.put(GROUP_CREDENTIALS_KEY, finalCredentials);
window.log.info('maybeFetchCredentials: Save complete.');
log.info('maybeFetchCredentials: Save complete.');
}
export function getDatesForRequest(

View File

@ -6,6 +6,7 @@ import {
NetworkActionType,
} from '../state/ducks/network';
import { getSocketStatus } from '../shims/socketStatus';
import * as log from '../logging/log';
type NetworkActions = {
checkNetworkStatus: (x: CheckNetworkStatusPayloadType) => NetworkActionType;
@ -17,7 +18,6 @@ const REFRESH_INTERVAL = 5000;
export function initializeNetworkObserver(
networkActions: NetworkActions
): void {
const { log } = window;
log.info(`Initializing network observer every ${REFRESH_INTERVAL}ms`);
const refresh = () => {

View File

@ -40,6 +40,7 @@ import {
typeofConversation,
} from '../util/whatTypeOfConversation';
import { SignalService as Proto } from '../protobuf';
import * as log from '../logging/log';
type IManifestRecordIdentifier = Proto.ManifestRecord.IIdentifier;
@ -136,7 +137,7 @@ async function generateManifest(
previousManifest?: Proto.IManifestRecord,
isNewManifest = false
): Promise<GeneratedManifestType> {
window.log.info(
log.info(
'storageService.generateManifest: generating manifest',
version,
isNewManifest
@ -186,7 +187,7 @@ async function generateManifest(
storageRecord.groupV1 = await toGroupV1Record(conversation);
identifier.type = ITEM_TYPE.GROUPV1;
} else {
window.log.info(
log.info(
'storageService.generateManifest: unknown conversation',
conversation.idForLogging()
);
@ -209,7 +210,7 @@ async function generateManifest(
// eslint-disable-next-line no-await-in-loop
storageItem = await encryptRecord(storageID, storageRecord);
} catch (err) {
window.log.error(
log.error(
'storageService.generateManifest: encrypt record failed:',
err && err.stack ? err.stack : String(err)
);
@ -224,13 +225,13 @@ async function generateManifest(
if (storageID) {
insertKeys.push(storageID);
window.log.info(
log.info(
'storageService.generateManifest: new key',
conversation.idForLogging(),
redactStorageID(storageID)
);
} else {
window.log.info(
log.info(
'storageService.generateManifest: no storage id',
conversation.idForLogging()
);
@ -238,7 +239,7 @@ async function generateManifest(
const oldStorageID = conversation.get('storageID');
if (oldStorageID) {
window.log.info(
log.info(
'storageService.generateManifest: deleting key',
redactStorageID(oldStorageID)
);
@ -259,7 +260,7 @@ async function generateManifest(
window.storage.get('storage-service-unknown-records') || []
).filter((record: UnknownRecord) => !validRecordTypes.has(record.itemType));
window.log.info(
log.info(
'storageService.generateManifest: adding unknown records:',
unknownRecordsArray.length
);
@ -279,7 +280,7 @@ async function generateManifest(
new Array<UnknownRecord>()
);
window.log.info(
log.info(
'storageService.generateManifest: adding records that had errors in the previous merge',
recordsWithErrors.length
);
@ -311,7 +312,7 @@ async function generateManifest(
rawDuplicates.has(identifier.raw) ||
typeRawDuplicates.has(typeAndRaw)
) {
window.log.info(
log.info(
'storageService.generateManifest: removing duplicate identifier from manifest',
identifier.type
);
@ -325,7 +326,7 @@ async function generateManifest(
key => arrayBufferToBase64(key) === storageID
);
if (hasDeleteKey) {
window.log.info(
log.info(
'storageService.generateManifest: removing key which has been deleted',
identifier.type
);
@ -335,9 +336,7 @@ async function generateManifest(
// Ensure that there is *exactly* one Account type in the manifest
if (identifier.type === ITEM_TYPE.ACCOUNT) {
if (hasAccountType) {
window.log.info(
'storageService.generateManifest: removing duplicate account'
);
log.info('storageService.generateManifest: removing duplicate account');
manifestRecordKeys.delete(identifier);
}
hasAccountType = true;
@ -355,7 +354,7 @@ async function generateManifest(
const storageID = Bytes.toBase64(storageItem.key);
if (storageKeyDuplicates.has(storageID)) {
window.log.info(
log.info(
'storageService.generateManifest: removing duplicate identifier from inserts',
redactStorageID(storageID)
);
@ -405,7 +404,7 @@ async function generateManifest(
);
const remoteDeletes: Array<string> = [];
pendingDeletes.forEach(id => remoteDeletes.push(redactStorageID(id)));
window.log.error(
log.error(
'Delete key sizes do not match',
'local',
localDeletes.join(','),
@ -480,13 +479,13 @@ async function uploadManifest(
}
if (newItems.size === 0 && deleteKeys.length === 0) {
window.log.info('storageService.uploadManifest: nothing to upload');
log.info('storageService.uploadManifest: nothing to upload');
return;
}
const credentials = window.storage.get('storageCredentials');
try {
window.log.info(
log.info(
'storageService.uploadManifest: keys inserting, deleting:',
newItems.size,
deleteKeys.length
@ -497,7 +496,7 @@ async function uploadManifest(
writeOperation.insertItem = Array.from(newItems);
writeOperation.deleteKey = deleteKeys.map(key => new FIXMEU8(key));
window.log.info('storageService.uploadManifest: uploading...', version);
log.info('storageService.uploadManifest: uploading...', version);
await window.textsecure.messaging.modifyStorageRecords(
typedArrayToArrayBuffer(
Proto.WriteOperation.encode(writeOperation).finish()
@ -507,7 +506,7 @@ async function uploadManifest(
}
);
window.log.info(
log.info(
'storageService.uploadManifest: upload done, updating conversation(s) with new storageIDs:',
conversationsToUpdate.length
);
@ -521,20 +520,20 @@ async function uploadManifest(
updateConversation(conversation.attributes);
});
} catch (err) {
window.log.error(
log.error(
'storageService.uploadManifest: failed!',
err && err.stack ? err.stack : String(err)
);
if (err.code === 409) {
if (conflictBackOff.isFull()) {
window.log.error(
log.error(
'storageService.uploadManifest: Exceeded maximum consecutive conflicts'
);
return;
}
window.log.info(
log.info(
`storageService.uploadManifest: Conflict found with v${version}, running sync job times(${conflictBackOff.getIndex()})`
);
@ -544,7 +543,7 @@ async function uploadManifest(
throw err;
}
window.log.info(
log.info(
'storageService.uploadManifest: setting new manifestVersion',
version
);
@ -553,7 +552,7 @@ async function uploadManifest(
backOff.reset();
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'uploadManifest: We are primary device; not sending sync manifest'
);
return;
@ -566,26 +565,26 @@ async function uploadManifest(
}
async function stopStorageServiceSync() {
window.log.info('storageService.stopStorageServiceSync');
log.info('storageService.stopStorageServiceSync');
await window.storage.remove('storageKey');
if (backOff.isFull()) {
window.log.info(
log.info(
'storageService.stopStorageServiceSync: too many consecutive stops'
);
return;
}
await sleep(backOff.getAndIncrement());
window.log.info('storageService.stopStorageServiceSync: requesting new keys');
log.info('storageService.stopStorageServiceSync: requesting new keys');
setTimeout(() => {
if (!window.textsecure.messaging) {
throw new Error('storageService.stopStorageServiceSync: We are offline!');
}
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'stopStorageServiceSync: We are primary device; not sending key sync request'
);
return;
@ -599,7 +598,7 @@ async function stopStorageServiceSync() {
}
async function createNewManifest() {
window.log.info('storageService.createNewManifest: creating new manifest');
log.info('storageService.createNewManifest: creating new manifest');
const version = window.storage.get('manifestVersion', 0);
@ -645,7 +644,7 @@ async function decryptManifest(
async function fetchManifest(
manifestVersion: number
): Promise<Proto.ManifestRecord | undefined> {
window.log.info('storageService.fetchManifest');
log.info('storageService.fetchManifest');
if (!window.textsecure.messaging) {
throw new Error('storageService.fetchManifest: We are offline!');
@ -667,7 +666,7 @@ async function fetchManifest(
// if we don't get a value we're assuming that there's no newer manifest
if (!encryptedManifest.value || !encryptedManifest.version) {
window.log.info('storageService.fetchManifest: nothing changed');
log.info('storageService.fetchManifest: nothing changed');
return;
}
@ -678,7 +677,7 @@ async function fetchManifest(
return;
}
} catch (err) {
window.log.error(
log.error(
'storageService.fetchManifest: failed!',
err && err.stack ? err.stack : String(err)
);
@ -721,10 +720,7 @@ async function mergeRecord(
try {
if (itemType === ITEM_TYPE.UNKNOWN) {
window.log.info(
'storageService.mergeRecord: Unknown item type',
storageID
);
log.info('storageService.mergeRecord: Unknown item type', storageID);
} else if (itemType === ITEM_TYPE.CONTACT && storageRecord.contact) {
hasConflict = await mergeContactRecord(storageID, storageRecord.contact);
} else if (itemType === ITEM_TYPE.GROUPV1 && storageRecord.groupV1) {
@ -735,9 +731,9 @@ async function mergeRecord(
hasConflict = await mergeAccountRecord(storageID, storageRecord.account);
} else {
isUnsupported = true;
window.log.info('storageService.mergeRecord: Unknown record:', itemType);
log.info('storageService.mergeRecord: Unknown record:', itemType);
}
window.log.info(
log.info(
'storageService.mergeRecord: merged',
redactStorageID(storageID),
itemType,
@ -745,7 +741,7 @@ async function mergeRecord(
);
} catch (err) {
hasError = true;
window.log.error(
log.error(
'storageService.mergeRecord: Error with',
redactStorageID(storageID),
itemType,
@ -798,22 +794,16 @@ async function processManifest(
return true;
});
window.log.info(
log.info(
'storageService.processManifest: local records:',
conversations.length
);
window.log.info(
'storageService.processManifest: local keys:',
localKeys.size
);
window.log.info(
log.info('storageService.processManifest: local keys:', localKeys.size);
log.info(
'storageService.processManifest: unknown records:',
stillUnknown.length
);
window.log.info(
'storageService.processManifest: remote keys:',
remoteKeys.size
);
log.info('storageService.processManifest: remote keys:', remoteKeys.size);
const remoteOnlySet: Set<string> = new Set();
remoteKeys.forEach((key: string) => {
@ -822,7 +812,7 @@ async function processManifest(
}
});
window.log.info(
log.info(
'storageService.processManifest: remote ids:',
Array.from(remoteOnlySet).map(redactStorageID).join(',')
);
@ -845,7 +835,7 @@ async function processManifest(
window.getConversations().forEach((conversation: ConversationModel) => {
const storageID = conversation.get('storageID');
if (storageID && !remoteKeys.has(storageID)) {
window.log.info(
log.info(
'storageService.processManifest: local key was not in remote manifest',
redactStorageID(storageID),
conversation.idForLogging()
@ -867,7 +857,7 @@ async function processRemoteRecords(
}
const storageKey = base64ToArrayBuffer(storageKeyBase64);
window.log.info(
log.info(
'storageService.processRemoteRecords: remote only keys',
remoteOnlyRecords.size
);
@ -890,9 +880,7 @@ async function processRemoteRecords(
);
if (!storageItems.items) {
window.log.info(
'storageService.processRemoteRecords: No storage items retrieved'
);
log.info('storageService.processRemoteRecords: No storage items retrieved');
return 0;
}
@ -904,7 +892,7 @@ async function processRemoteRecords(
const { key, value: storageItemCiphertext } = storageRecordWrapper;
if (!key || !storageItemCiphertext) {
window.log.error(
log.error(
'storageService.processRemoteRecords: No key or Ciphertext available'
);
await stopStorageServiceSync();
@ -927,7 +915,7 @@ async function processRemoteRecords(
storageItemKey
);
} catch (err) {
window.log.error(
log.error(
'storageService.processRemoteRecords: Error decrypting storage item'
);
await stopStorageServiceSync();
@ -964,13 +952,13 @@ async function processRemoteRecords(
);
try {
window.log.info(
log.info(
`storageService.processRemoteRecords: Attempting to merge ${sortedStorageItems.length} records`
);
const mergedRecords = await pMap(sortedStorageItems, mergeRecord, {
concurrency: 5,
});
window.log.info(
log.info(
`storageService.processRemoteRecords: Processed ${mergedRecords.length} records`
);
@ -1012,13 +1000,13 @@ async function processRemoteRecords(
(record: UnknownRecord) => !validRecordTypes.has(record.itemType)
);
window.log.info(
log.info(
'storageService.processRemoteRecords: Unknown records found:',
newUnknownRecords.length
);
window.storage.put('storage-service-unknown-records', newUnknownRecords);
window.log.info(
log.info(
'storageService.processRemoteRecords: Records with errors:',
newRecordsWithErrors.length
);
@ -1028,7 +1016,7 @@ async function processRemoteRecords(
window.storage.put('storage-service-error-records', newRecordsWithErrors);
if (conflictCount !== 0) {
window.log.info(
log.info(
'storageService.processRemoteRecords: ' +
`${conflictCount} conflicts found, uploading changes`
);
@ -1038,7 +1026,7 @@ async function processRemoteRecords(
conflictBackOff.reset();
} catch (err) {
window.log.error(
log.error(
'storageService.processRemoteRecords: failed!',
err && err.stack ? err.stack : String(err)
);
@ -1051,9 +1039,7 @@ async function sync(
ignoreConflicts = false
): Promise<Proto.ManifestRecord | undefined> {
if (!isStorageWriteFeatureEnabled()) {
window.log.info(
'storageService.sync: Not starting desktop.storage is falsey'
);
log.info('storageService.sync: Not starting desktop.storage is falsey');
return undefined;
}
@ -1062,7 +1048,7 @@ async function sync(
throw new Error('storageService.sync: Cannot start; no storage key!');
}
window.log.info('storageService.sync: starting...');
log.info('storageService.sync: starting...');
let manifest: Proto.ManifestRecord | undefined;
try {
@ -1078,7 +1064,7 @@ async function sync(
// Guarding against no manifests being returned, everything should be ok
if (!manifest) {
window.log.info('storageService.sync: no new manifest');
log.info('storageService.sync: no new manifest');
return undefined;
}
@ -1088,7 +1074,7 @@ async function sync(
);
const version = normalizeNumber(manifest.version);
window.log.info(
log.info(
`storageService.sync: manifest versions - previous: ${localManifestVersion}, current: ${version}`
);
@ -1102,20 +1088,20 @@ async function sync(
// We now know that we've successfully completed a storage service fetch
window.storage.put('storageFetchComplete', true);
} catch (err) {
window.log.error(
log.error(
'storageService.sync: error processing manifest',
err && err.stack ? err.stack : String(err)
);
}
window.Signal.Util.postLinkExperience.stop();
window.log.info('storageService.sync: complete');
log.info('storageService.sync: complete');
return manifest;
}
async function upload(fromSync = false): Promise<void> {
if (!isStorageWriteFeatureEnabled()) {
window.log.info(
log.info(
'storageService.upload: Not starting because the feature is not enabled'
);
@ -1145,15 +1131,11 @@ async function upload(fromSync = false): Promise<void> {
if (!window.storage.get('storageKey')) {
// requesting new keys runs the sync job which will detect the conflict
// and re-run the upload job once we're merged and up-to-date.
window.log.info(
'storageService.upload: no storageKey, requesting new keys'
);
log.info('storageService.upload: no storageKey, requesting new keys');
backOff.reset();
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
'upload: We are primary device; not sending key sync request'
);
log.warn('upload: We are primary device; not sending key sync request');
return;
}
@ -1178,10 +1160,7 @@ async function upload(fromSync = false): Promise<void> {
const localManifestVersion = window.storage.get('manifestVersion', 0);
const version = Number(localManifestVersion) + 1;
window.log.info(
'storageService.upload: will update to manifest version',
version
);
log.info('storageService.upload: will update to manifest version', version);
try {
const generatedManifest = await generateManifest(version, previousManifest);
@ -1189,14 +1168,14 @@ async function upload(fromSync = false): Promise<void> {
} catch (err) {
if (err.code === 409) {
await sleep(conflictBackOff.getAndIncrement());
window.log.info('storageService.upload: pushing sync on the queue');
log.info('storageService.upload: pushing sync on the queue');
// The sync job will check for conflicts and as part of that conflict
// check if an item needs sync and doesn't match with the remote record
// it'll kick off another upload.
setTimeout(runStorageServiceSyncJob);
return;
}
window.log.error(
log.error(
'storageService.upload',
err && err.stack ? err.stack : String(err)
);
@ -1212,21 +1191,19 @@ export function enableStorageService(): void {
// Note: this function is meant to be called before ConversationController is hydrated.
// It goes directly to the database, so in-memory conversations will be out of date.
export async function eraseAllStorageServiceState(): Promise<void> {
window.log.info('storageService.eraseAllStorageServiceState: starting...');
log.info('storageService.eraseAllStorageServiceState: starting...');
await Promise.all([
window.storage.remove('manifestVersion'),
window.storage.remove('storage-service-unknown-records'),
window.storage.remove('storageCredentials'),
]);
await eraseStorageServiceStateFromConversations();
window.log.info('storageService.eraseAllStorageServiceState: complete');
log.info('storageService.eraseAllStorageServiceState: complete');
}
export const storageServiceUploadJob = debounce(() => {
if (!storageServiceEnabled) {
window.log.info(
'storageService.storageServiceUploadJob: called before enabled'
);
log.info('storageService.storageServiceUploadJob: called before enabled');
return;
}
@ -1237,9 +1214,7 @@ export const storageServiceUploadJob = debounce(() => {
export const runStorageServiceSyncJob = debounce(() => {
if (!storageServiceEnabled) {
window.log.info(
'storageService.runStorageServiceSyncJob: called before enabled'
);
log.info('storageService.runStorageServiceSyncJob: called before enabled');
return;
}

View File

@ -39,6 +39,7 @@ import * as preferredReactionEmoji from '../reactions/preferredReactionEmoji';
import { UUID } from '../types/UUID';
import * as Errors from '../types/errors';
import { SignalService as Proto } from '../protobuf';
import * as log from '../logging/log';
const { updateConversation } = dataInterface;
@ -70,7 +71,7 @@ function addUnknownFields(
conversation: ConversationModel
): void {
if (record.__unknownFields) {
window.log.info(
log.info(
'storageService.addUnknownFields: Unknown fields found for',
conversation.idForLogging()
);
@ -82,7 +83,7 @@ function addUnknownFields(
} else if (conversation.get('storageUnknownFields')) {
// If the record doesn't have unknown fields attached but we have them
// saved locally then we need to clear it out
window.log.info(
log.info(
'storageService.addUnknownFields: Clearing unknown fields for',
conversation.idForLogging()
);
@ -96,7 +97,7 @@ function applyUnknownFields(
): void {
const storageUnknownFields = conversation.get('storageUnknownFields');
if (storageUnknownFields) {
window.log.info(
log.info(
'storageService.applyUnknownFields: Applying unknown fields for',
conversation.get('id')
);
@ -126,9 +127,7 @@ export async function toContactRecord(
try {
maybeUuid = uuid ? new UUID(uuid) : undefined;
} catch (error) {
window.log.warn(
`Invalid uuid in contact record: ${Errors.toLogFormat(error)}`
);
log.warn(`Invalid uuid in contact record: ${Errors.toLogFormat(error)}`);
}
const identityKey = maybeUuid
@ -296,7 +295,7 @@ export async function toAccountRecord(
pinnedConversationClass !== undefined
);
window.log.info(
log.info(
'storageService.toAccountRecord: pinnedConversations',
pinnedConversations.length
);
@ -403,7 +402,7 @@ function doRecordsConflict(
if (localValue instanceof Uint8Array) {
const areEqual = Bytes.areEqual(localValue, remoteValue);
if (!areEqual) {
window.log.info(
log.info(
'storageService.doRecordsConflict: Conflict found for ArrayBuffer',
key,
idForLogging
@ -422,7 +421,7 @@ function doRecordsConflict(
Long.fromValue(remoteValue)
);
if (!areEqual) {
window.log.info(
log.info(
'storageService.doRecordsConflict: Conflict found for Long',
key,
idForLogging
@ -434,7 +433,7 @@ function doRecordsConflict(
if (key === 'pinnedConversations') {
const areEqual = arePinnedConversationsEqual(localValue, remoteValue);
if (!areEqual) {
window.log.info(
log.info(
'storageService.doRecordsConflict: Conflict found for pinnedConversations',
idForLogging
);
@ -462,7 +461,7 @@ function doRecordsConflict(
const areEqual = isEqual(localValue, remoteValue);
if (!areEqual) {
window.log.info(
log.info(
'storageService.doRecordsConflict: Conflict found for',
key,
idForLogging
@ -532,14 +531,14 @@ export async function mergeGroupV1Record(
const fields = deriveGroupFields(new FIXMEU8(masterKeyBuffer));
const derivedGroupV2Id = Bytes.toBase64(fields.id);
window.log.info(
log.info(
'storageService.mergeGroupV1Record: failed to find group by v1 id ' +
`attempting lookup by v2 groupv2(${derivedGroupV2Id})`
);
conversation = window.ConversationController.get(derivedGroupV2Id);
}
if (conversation) {
window.log.info(
log.info(
'storageService.mergeGroupV1Record: found existing group',
conversation.idForLogging()
);
@ -552,7 +551,7 @@ export async function mergeGroupV1Record(
groupId,
'group'
);
window.log.info(
log.info(
'storageService.mergeGroupV1Record: created a new group locally',
conversation.idForLogging()
);
@ -587,7 +586,7 @@ export async function mergeGroupV1Record(
// We cannot preserve unknown fields if local group is V2 and the remote is
// still V1, because the storageItem that we'll put into manifest will have
// a different record type.
window.log.info(
log.info(
'storageService.mergeGroupV1Record marking v1' +
' group for an update to v2',
conversation.idForLogging()
@ -660,10 +659,7 @@ export async function mergeGroupV2Record(
const masterKeyBuffer = groupV2Record.masterKey;
const conversation = await getGroupV2Conversation(masterKeyBuffer);
window.log.info(
'storageService.mergeGroupV2Record:',
conversation.idForLogging()
);
log.info('storageService.mergeGroupV2Record:', conversation.idForLogging());
conversation.set({
isArchived: Boolean(groupV2Record.archived),
@ -763,10 +759,7 @@ export async function mergeContactRecord(
'private'
);
window.log.info(
'storageService.mergeContactRecord:',
conversation.idForLogging()
);
log.info('storageService.mergeContactRecord:', conversation.idForLogging());
if (contactRecord.profileKey) {
await conversation.setProfileKey(Bytes.toBase64(contactRecord.profileKey), {
@ -924,7 +917,7 @@ export async function mergeAccountRecord(
.filter(id => !modelPinnedConversationIds.includes(id));
if (missingStoragePinnedConversationIds.length !== 0) {
window.log.info(
log.info(
'mergeAccountRecord: pinnedConversationIds in storage does not match pinned Conversation models'
);
}
@ -940,11 +933,11 @@ export async function mergeAccountRecord(
)
);
window.log.info(
log.info(
'storageService.mergeAccountRecord: Local pinned',
locallyPinnedConversations.length
);
window.log.info(
log.info(
'storageService.mergeAccountRecord: Remote pinned',
pinnedConversations.length
);
@ -965,13 +958,13 @@ export async function mergeAccountRecord(
conversationId = groupId;
} else {
window.log.error(
log.error(
'storageService.mergeAccountRecord: Invalid identifier received'
);
}
if (!conversationId) {
window.log.error(
log.error(
'storageService.mergeAccountRecord: missing conversation id.'
);
return undefined;
@ -996,12 +989,12 @@ export async function mergeAccountRecord(
({ id }) => !remotelyPinnedConversationIds.includes(id)
);
window.log.info(
log.info(
'storageService.mergeAccountRecord: unpinning',
conversationsToUnpin.length
);
window.log.info(
log.info(
'storageService.mergeAccountRecord: pinning',
remotelyPinnedConversations.length
);

View File

@ -1,29 +1,31 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as log from '../logging/log';
export async function deleteAllData(): Promise<void> {
try {
await window.Signal.Logs.deleteAll();
window.log.info('deleteAllData: deleted all logs');
log.info('deleteAllData: deleted all logs');
await window.Signal.Data.removeAll();
window.log.info('deleteAllData: emptied database');
log.info('deleteAllData: emptied database');
await window.Signal.Data.close();
window.log.info('deleteAllData: closed database');
log.info('deleteAllData: closed database');
await window.Signal.Data.removeDB();
window.log.info('deleteAllData: removed database');
log.info('deleteAllData: removed database');
await window.Signal.Data.removeOtherData();
window.log.info('deleteAllData: removed all other data');
log.info('deleteAllData: removed all other data');
} catch (error) {
window.log.error(
log.error(
'Something went wrong deleting all data:',
error && error.stack ? error.stack : error
);

View File

@ -3,13 +3,14 @@
import { handleMessageSend } from '../util/handleMessageSend';
import { getSendOptions } from '../util/getSendOptions';
import * as log from '../logging/log';
export async function sendStickerPackSync(
packId: string,
packKey: string,
installed: boolean
): Promise<void> {
const { ConversationController, textsecure, log } = window;
const { ConversationController, textsecure } = window;
const ourConversation = ConversationController.getOurConversationOrThrow();
const sendOptions = await getSendOptions(ourConversation.attributes, {
syncMessage: true,
@ -24,7 +25,7 @@ export async function sendStickerPackSync(
}
if (window.ConversationController.areWePrimaryDevice()) {
window.log.warn(
log.warn(
'shims/sendStickerPackSync: We are primary device; not sending sync'
);
return;

View File

@ -34,6 +34,7 @@ import { ReactionType } from '../types/Reactions';
import { ConversationColorType, CustomColorType } from '../types/Colors';
import type { ProcessGroupCallRingRequestResult } from '../types/Calling';
import type { RemoveAllConfiguration } from '../types/RemoveAllConfiguration';
import * as log from '../logging/log';
import {
ConversationModelCollectionType,
@ -88,7 +89,7 @@ import { ConversationModel } from '../models/conversations';
if (ipcRenderer && ipcRenderer.setMaxListeners) {
ipcRenderer.setMaxListeners(0);
} else {
window.log.warn('sql/Client: ipcRenderer is not available!');
log.warn('sql/Client: ipcRenderer is not available!');
}
const DATABASE_UPDATE_TIMEOUT = 2 * durations.MINUTE;
@ -305,14 +306,12 @@ export default dataInterface;
async function goBackToMainProcess(): Promise<void> {
if (!shouldUseRendererProcess) {
window.log.info(
'data.goBackToMainProcess: already switched to main process'
);
log.info('data.goBackToMainProcess: already switched to main process');
return;
}
// We don't need to wait for pending queries since they are synchronous.
window.log.info('data.goBackToMainProcess: switching to main process');
log.info('data.goBackToMainProcess: switching to main process');
// Close the database in the renderer process.
const closePromise = close();
@ -331,7 +330,7 @@ async function goBackToMainProcess(): Promise<void> {
.sort((a, b) => b[1] - a[1])
.filter(([_, duration]) => duration > MIN_TRACE_DURATION)
.forEach(([query, duration]) => {
window.log.info(`startup query: ${query} ${duration}ms`);
log.info(`startup query: ${query} ${duration}ms`);
});
}
@ -355,7 +354,7 @@ function _cleanData(
const { cleaned, pathsChanged } = cleanDataForIpc(data);
if (pathsChanged.length) {
window.log.info(
log.info(
`_cleanData cleaned the following paths: ${pathsChanged.join(', ')}`
);
}
@ -374,7 +373,7 @@ function _cleanMessageData(data: MessageType): MessageType {
async function _shutdown() {
const jobKeys = Object.keys(_jobs);
window.log.info(
log.info(
`data.shutdown: shutdown requested. ${jobKeys.length} jobs outstanding`
);
@ -394,7 +393,7 @@ async function _shutdown() {
// Outstanding jobs; we need to wait until the last one is done
_shutdownPromise = new Promise<void>((resolve, reject) => {
_shutdownCallback = (error: Error) => {
window.log.info('data.shutdown: process complete');
log.info('data.shutdown: process complete');
if (error) {
reject(error);
@ -419,7 +418,7 @@ function _makeJob(fnName: string) {
const id = _jobCounter;
if (_DEBUG) {
window.log.info(`SQL channel job ${id} (${fnName}) started`);
log.info(`SQL channel job ${id} (${fnName}) started`);
}
_jobs[id] = {
fnName,
@ -440,7 +439,7 @@ function _updateJob(id: number, data: ClientJobUpdateType) {
_removeJob(id);
const end = Date.now();
if (_DEBUG) {
window.log.info(
log.info(
`SQL channel job ${id} (${fnName}) succeeded in ${end - start}ms`
);
}
@ -450,9 +449,7 @@ function _updateJob(id: number, data: ClientJobUpdateType) {
reject: (error: Error) => {
_removeJob(id);
const end = Date.now();
window.log.info(
`SQL channel job ${id} (${fnName}) failed in ${end - start}ms`
);
log.info(`SQL channel job ${id} (${fnName}) failed in ${end - start}ms`);
return reject(error);
},
@ -511,7 +508,7 @@ if (ipcRenderer && ipcRenderer.on) {
}
);
} else {
window.log.warn('sql/Client: ipcRenderer.on is not available!');
log.warn('sql/Client: ipcRenderer.on is not available!');
}
function makeChannel(fnName: string) {
@ -531,13 +528,13 @@ function makeChannel(fnName: string) {
return await Server[serverFnName](...args);
} catch (error) {
if (isCorruptionError(error)) {
window.log.error(
log.error(
'Detected sql corruption in renderer process. ' +
`Restarting the application immediately. Error: ${error.message}`
);
ipcRenderer?.send('database-error', error.stack);
}
window.log.error(
log.error(
`Renderer SQL channel job (${fnName}) error ${error.message}`
);
throw error;
@ -550,7 +547,7 @@ function makeChannel(fnName: string) {
);
if (duration > MIN_TRACE_DURATION || _DEBUG) {
window.log.info(
log.info(
`Renderer SQL channel job (${fnName}) completed in ${duration}ms`
);
}
@ -1339,7 +1336,7 @@ async function removeAllMessagesInConversation(
let messages;
do {
const chunkSize = 20;
window.log.info(
log.info(
`removeAllMessagesInConversation/${logId}: Fetching chunk of ${chunkSize} messages`
);
// Yes, we really want the await in the loop. We're deleting a chunk at a
@ -1355,7 +1352,7 @@ async function removeAllMessagesInConversation(
const ids = messages.map((message: MessageModel) => message.id);
window.log.info(`removeAllMessagesInConversation/${logId}: Cleanup...`);
log.info(`removeAllMessagesInConversation/${logId}: Cleanup...`);
// Note: It's very important that these models are fully hydrated because
// we need to delete all associated on-disk files along with the database delete.
const queue = new window.PQueue({ concurrency: 3, timeout: 1000 * 60 * 2 });
@ -1364,7 +1361,7 @@ async function removeAllMessagesInConversation(
);
await queue.onIdle();
window.log.info(`removeAllMessagesInConversation/${logId}: Deleting...`);
log.info(`removeAllMessagesInConversation/${logId}: Deleting...`);
await channels.removeMessages(ids);
} while (messages.length > 0);
}

View File

@ -48,6 +48,7 @@ import { ConversationColorType, CustomColorType } from '../types/Colors';
import { ProcessGroupCallRingRequestResult } from '../types/Calling';
import { RemoveAllConfiguration } from '../types/RemoveAllConfiguration';
import type { LoggerType } from '../types/Logging';
import * as log from '../logging/log';
import {
AllItemsType,
@ -2742,7 +2743,7 @@ async function initializeRenderer({
// test database
await getMessageCount();
} catch (error) {
window.log.error('Database startup error:', error.stack);
log.error('Database startup error:', error.stack);
throw error;
}
}

View File

@ -3,6 +3,7 @@
import { ThunkAction } from 'redux-thunk';
import { StateType as RootStateType } from '../reducer';
import * as log from '../../logging/log';
// State
@ -67,7 +68,7 @@ function openInbox(): ThunkAction<
OpenInboxActionType
> {
return async dispatch => {
window.log.info('open inbox');
log.info('open inbox');
await window.ConversationController.loadPromise();

View File

@ -33,6 +33,7 @@ import { isGroupCallOutboundRingEnabled } from '../../util/isGroupCallOutboundRi
import { sleep } from '../../util/sleep';
import { LatestQueue } from '../../util/LatestQueue';
import type { ConversationChangedActionType } from './conversations';
import * as log from '../../logging/log';
// State
@ -506,7 +507,7 @@ function acceptCall(
const call = getOwn(getState().calling.callsByConversation, conversationId);
if (!call) {
window.log.error('Trying to accept a non-existent call');
log.error('Trying to accept a non-existent call');
return;
}
@ -611,7 +612,7 @@ function declineCall(
const call = getOwn(getState().calling.callsByConversation, conversationId);
if (!call) {
window.log.error('Trying to decline a non-existent call');
log.error('Trying to decline a non-existent call');
return;
}
@ -626,7 +627,7 @@ function declineCall(
case CallMode.Group: {
const { ringId } = call;
if (ringId === undefined) {
window.log.error('Trying to decline a group call without a ring ID');
log.error('Trying to decline a group call without a ring ID');
} else {
calling.declineGroupCall(conversationId, ringId);
dispatch({
@ -861,7 +862,7 @@ function peekNotConnectedGroupCall(
try {
peekInfo = await calling.peekGroupCall(conversationId);
} catch (err) {
window.log.error('Group call peeking failed', err);
log.error('Group call peeking failed', err);
return;
}
@ -938,7 +939,7 @@ function setLocalAudio(
return (dispatch, getState) => {
const activeCall = getActiveCall(getState().calling);
if (!activeCall) {
window.log.warn('Trying to set local audio when no call is active');
log.warn('Trying to set local audio when no call is active');
return;
}
@ -957,7 +958,7 @@ function setLocalVideo(
return async (dispatch, getState) => {
const activeCall = getActiveCall(getState().calling);
if (!activeCall) {
window.log.warn('Trying to set local video when no call is active');
log.warn('Trying to set local video when no call is active');
return;
}
@ -1012,7 +1013,7 @@ function setPresenting(
const { activeCallState } = callingState;
const activeCall = getActiveCall(callingState);
if (!activeCall || !activeCallState) {
window.log.warn('Trying to present when no call is active');
log.warn('Trying to present when no call is active');
return;
}
@ -1314,7 +1315,7 @@ export function reducer(
if (action.type === ACCEPT_CALL_PENDING) {
if (!has(state.callsByConversation, action.payload.conversationId)) {
window.log.warn('Unable to accept a non-existent call');
log.warn('Unable to accept a non-existent call');
return state;
}
@ -1341,7 +1342,7 @@ export function reducer(
) {
const activeCall = getActiveCall(state);
if (!activeCall) {
window.log.warn('No active call to remove');
log.warn('No active call to remove');
return state;
}
switch (activeCall.callMode) {
@ -1421,11 +1422,11 @@ export function reducer(
const existingGroupCall = getGroupCall(conversationId, state);
if (existingGroupCall) {
if (existingGroupCall.ringerUuid) {
window.log.info('Group call was already ringing');
log.info('Group call was already ringing');
return state;
}
if (existingGroupCall.joinState !== GroupCallJoinState.NotJoined) {
window.log.info("Got a ring for a call we're already in");
log.info("Got a ring for a call we're already in");
return state;
}
@ -1503,7 +1504,7 @@ export function reducer(
action.payload.conversationId
);
if (call?.callMode !== CallMode.Direct) {
window.log.warn('Cannot update state for a non-direct call');
log.warn('Cannot update state for a non-direct call');
return state;
}
@ -1676,7 +1677,7 @@ export function reducer(
const { conversationId, isSharingScreen } = action.payload;
const call = getOwn(state.callsByConversation, conversationId);
if (call?.callMode !== CallMode.Direct) {
window.log.warn('Cannot update remote video for a non-direct call');
log.warn('Cannot update remote video for a non-direct call');
return state;
}
@ -1696,7 +1697,7 @@ export function reducer(
const { conversationId, hasVideo } = action.payload;
const call = getOwn(state.callsByConversation, conversationId);
if (call?.callMode !== CallMode.Direct) {
window.log.warn('Cannot update remote video for a non-direct call');
log.warn('Cannot update remote video for a non-direct call');
return state;
}
@ -1715,9 +1716,7 @@ export function reducer(
if (action.type === RETURN_TO_ACTIVE_CALL) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn(
'Cannot return to active call if there is no active call'
);
log.warn('Cannot return to active call if there is no active call');
return state;
}
@ -1732,7 +1731,7 @@ export function reducer(
if (action.type === SET_LOCAL_AUDIO_FULFILLED) {
if (!state.activeCallState) {
window.log.warn('Cannot set local audio with no active call');
log.warn('Cannot set local audio with no active call');
return state;
}
@ -1747,7 +1746,7 @@ export function reducer(
if (action.type === SET_LOCAL_VIDEO_FULFILLED) {
if (!state.activeCallState) {
window.log.warn('Cannot set local video with no active call');
log.warn('Cannot set local video with no active call');
return state;
}
@ -1802,7 +1801,7 @@ export function reducer(
if (action.type === TOGGLE_SETTINGS) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn('Cannot toggle settings when there is no active call');
log.warn('Cannot toggle settings when there is no active call');
return state;
}
@ -1818,9 +1817,7 @@ export function reducer(
if (action.type === TOGGLE_PARTICIPANTS) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn(
'Cannot toggle participants list when there is no active call'
);
log.warn('Cannot toggle participants list when there is no active call');
return state;
}
@ -1836,7 +1833,7 @@ export function reducer(
if (action.type === TOGGLE_PIP) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn('Cannot toggle PiP when there is no active call');
log.warn('Cannot toggle PiP when there is no active call');
return state;
}
@ -1852,7 +1849,7 @@ export function reducer(
if (action.type === SET_PRESENTING) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn('Cannot toggle presenting when there is no active call');
log.warn('Cannot toggle presenting when there is no active call');
return state;
}
@ -1869,9 +1866,7 @@ export function reducer(
if (action.type === SET_PRESENTING_SOURCES) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn(
'Cannot set presenting sources when there is no active call'
);
log.warn('Cannot set presenting sources when there is no active call');
return state;
}
@ -1887,7 +1882,7 @@ export function reducer(
if (action.type === SET_OUTGOING_RING) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn('Cannot set outgoing ring when there is no active call');
log.warn('Cannot set outgoing ring when there is no active call');
return state;
}
@ -1903,9 +1898,7 @@ export function reducer(
if (action.type === TOGGLE_NEEDS_SCREEN_RECORDING_PERMISSIONS) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn(
'Cannot set presenting sources when there is no active call'
);
log.warn('Cannot set presenting sources when there is no active call');
return state;
}
@ -1921,9 +1914,7 @@ export function reducer(
if (action.type === TOGGLE_SPEAKER_VIEW) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn(
'Cannot toggle speaker view when there is no active call'
);
log.warn('Cannot toggle speaker view when there is no active call');
return state;
}
@ -1939,9 +1930,7 @@ export function reducer(
if (action.type === MARK_CALL_UNTRUSTED) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn(
'Cannot mark call as untrusted when there is no active call'
);
log.warn('Cannot mark call as untrusted when there is no active call');
return state;
}
@ -1962,9 +1951,7 @@ export function reducer(
if (action.type === MARK_CALL_TRUSTED) {
const { activeCallState } = state;
if (!activeCallState) {
window.log.warn(
'Cannot mark call as trusted when there is no active call'
);
log.warn('Cannot mark call as trusted when there is no active call');
return state;
}

View File

@ -861,7 +861,7 @@ function deleteAvatarFromDisk(
if (avatarData.imagePath) {
await window.Signal.Migrations.deleteAvatar(avatarData.imagePath);
} else {
window.log.info(
log.info(
'No imagePath for avatarData. Removing from userAvatarData, but not disk'
);
}
@ -1155,7 +1155,7 @@ function composeDeleteAvatarFromDisk(
if (avatarData.imagePath) {
await window.Signal.Migrations.deleteAvatar(avatarData.imagePath);
} else {
window.log.info(
log.info(
'No imagePath for avatarData. Removing from userAvatarData, but not disk'
);
}
@ -1325,10 +1325,7 @@ function createGroup(): ThunkAction<
switchToAssociatedView: true,
})(dispatch, getState, ...args);
} catch (err) {
window.log.error(
'Failed to create group',
err && err.stack ? err.stack : err
);
log.error('Failed to create group', err && err.stack ? err.stack : err);
dispatch({ type: 'CREATE_GROUP_REJECTED' });
}
};

View File

@ -7,6 +7,7 @@ import {
reloadProfiles,
toggleVerification,
} from '../../shims/contactVerification';
import * as log from '../../logging/log';
export type SafetyNumberContactType = {
safetyNumber: string;
@ -107,7 +108,7 @@ async function alterVerification(contact: ConversationType): Promise<void> {
if (result.name === 'OutgoingIdentityKeyError') {
throw result;
} else {
window.log.error(
log.error(
'failed to toggle verified:',
result && result.stack ? result.stack : result
);
@ -120,7 +121,7 @@ async function alterVerification(contact: ConversationType): Promise<void> {
throw keyError;
} else {
result.errors.forEach((error: Error) => {
window.log.error(
log.error(
'failed to toggle verified:',
error && error.stack ? error.stack : error
);

Some files were not shown because too many files have changed in this diff Show More