Import log instead of using it off of window
This commit is contained in:
parent
8eb0dd3116
commit
65ddf0a9e8
155 changed files with 3654 additions and 3433 deletions
|
@ -291,18 +291,10 @@
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="js/views/key_verification_view.js"
|
src="js/views/key_verification_view.js"
|
||||||
></script>
|
></script>
|
||||||
<script type="text/javascript" src="js/views/recorder_view.js"></script>
|
|
||||||
<script type="text/javascript" src="js/views/inbox_view.js"></script>
|
|
||||||
<script
|
<script
|
||||||
type="text/javascript"
|
type="text/javascript"
|
||||||
src="ts/shims/showConfirmationDialog.js"
|
src="ts/shims/showConfirmationDialog.js"
|
||||||
></script>
|
></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 type="text/javascript" src="js/wall_clock_listener.js"></script>
|
||||||
<script
|
<script
|
||||||
|
|
|
@ -58,6 +58,5 @@
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="js/components.js"></script>
|
<script type="text/javascript" src="js/components.js"></script>
|
||||||
<script type="text/javascript" src="ts/backboneJquery.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>
|
<script type="text/javascript" src="js/debug_log_start.js"></script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
const { ipcRenderer } = require('electron');
|
const { ipcRenderer } = require('electron');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
const copyText = require('copy-text-to-clipboard');
|
|
||||||
|
|
||||||
// It is important to call this as early as possible
|
// It is important to call this as early as possible
|
||||||
require('./ts/windows/context');
|
require('./ts/windows/context');
|
||||||
|
@ -25,7 +24,6 @@ setEnvironment(parseEnvironment(config.environment));
|
||||||
window.getVersion = () => config.version;
|
window.getVersion = () => config.version;
|
||||||
window.theme = config.theme;
|
window.theme = config.theme;
|
||||||
window.i18n = i18n.setup(locale, localeMessages);
|
window.i18n = i18n.setup(locale, localeMessages);
|
||||||
window.copyText = copyText;
|
|
||||||
|
|
||||||
// got.js appears to need this to successfully submit debug logs to the cloud
|
// got.js appears to need this to successfully submit debug logs to the cloud
|
||||||
window.nodeSetImmediate = setImmediate;
|
window.nodeSetImmediate = setImmediate;
|
||||||
|
@ -37,6 +35,7 @@ window.Backbone = require('backbone');
|
||||||
require('./ts/backbone/views/whisper_view');
|
require('./ts/backbone/views/whisper_view');
|
||||||
require('./ts/backbone/views/toast_view');
|
require('./ts/backbone/views/toast_view');
|
||||||
require('./ts/logging/set_up_renderer_logging').initialize();
|
require('./ts/logging/set_up_renderer_logging').initialize();
|
||||||
|
require('./ts/views/debug_log_view');
|
||||||
|
|
||||||
window.closeDebugLog = () => ipcRenderer.send('close-debug-log');
|
window.closeDebugLog = () => ipcRenderer.send('close-debug-log');
|
||||||
window.Backbone = require('backbone');
|
window.Backbone = require('backbone');
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
window.Whisper.Database.nolog = true;
|
window.Whisper.Database.nolog = true;
|
||||||
|
|
||||||
Whisper.Database.handleDOMException = (prefix, error, reject) => {
|
Whisper.Database.handleDOMException = (prefix, error, reject) => {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
`${prefix}:`,
|
`${prefix}:`,
|
||||||
error && error.name,
|
error && error.name,
|
||||||
error && error.message,
|
error && error.message,
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* global $: false */
|
/* global $: false */
|
||||||
/* global Whisper: false */
|
|
||||||
|
|
||||||
$(document).on('keydown', e => {
|
$(document).on('keydown', e => {
|
||||||
if (e.keyCode === 27) {
|
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
|
// got.js appears to need this to successfully submit debug logs to the cloud
|
||||||
window.setImmediate = window.nodeSetImmediate;
|
window.setImmediate = window.nodeSetImmediate;
|
||||||
|
|
||||||
window.view = new Whisper.DebugLogView();
|
window.view = new window.Whisper.DebugLogView();
|
||||||
window.view.$el.appendTo($body);
|
window.view.$el.appendTo($body);
|
||||||
|
|
|
@ -13,11 +13,13 @@
|
||||||
|
|
||||||
async function destroyExpiredMessages() {
|
async function destroyExpiredMessages() {
|
||||||
try {
|
try {
|
||||||
window.log.info('destroyExpiredMessages: Loading messages...');
|
window.SignalWindow.log.info(
|
||||||
|
'destroyExpiredMessages: Loading messages...'
|
||||||
|
);
|
||||||
const messages = await window.Signal.Data.getExpiredMessages({
|
const messages = await window.Signal.Data.getExpiredMessages({
|
||||||
MessageCollection: Whisper.MessageCollection,
|
MessageCollection: Whisper.MessageCollection,
|
||||||
});
|
});
|
||||||
window.log.info(
|
window.SignalWindow.log.info(
|
||||||
`destroyExpiredMessages: found ${messages.length} messages to expire`
|
`destroyExpiredMessages: found ${messages.length} messages to expire`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@
|
||||||
await Promise.all(messageCleanup);
|
await Promise.all(messageCleanup);
|
||||||
|
|
||||||
inMemoryMessages.forEach(message => {
|
inMemoryMessages.forEach(message => {
|
||||||
window.log.info('Message expired', {
|
window.SignalWindow.log.info('Message expired', {
|
||||||
sentAt: message.get('sent_at'),
|
sentAt: message.get('sent_at'),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -50,23 +52,27 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
'destroyExpiredMessages: Error deleting expired messages',
|
'destroyExpiredMessages: Error deleting expired messages',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('destroyExpiredMessages: complete');
|
window.SignalWindow.log.info('destroyExpiredMessages: complete');
|
||||||
checkExpiringMessages();
|
checkExpiringMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
let timeout;
|
let timeout;
|
||||||
async function checkExpiringMessages() {
|
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();
|
const soonestExpiry = await window.Signal.Data.getSoonestMessageExpiry();
|
||||||
if (!soonestExpiry) {
|
if (!soonestExpiry) {
|
||||||
window.log.info('checkExpiringMessages: found no messages to expire');
|
window.SignalWindow.log.info(
|
||||||
|
'checkExpiringMessages: found no messages to expire'
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +88,7 @@
|
||||||
wait = 2147483647;
|
wait = 2147483647;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
window.SignalWindow.log.info(
|
||||||
`checkExpiringMessages: next message expires ${new Date(
|
`checkExpiringMessages: next message expires ${new Date(
|
||||||
soonestExpiry
|
soonestExpiry
|
||||||
).toISOString()}; waiting ${wait} ms before clearing`
|
).toISOString()}; waiting ${wait} ms before clearing`
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
|
|
||||||
async function eraseTapToViewMessages() {
|
async function eraseTapToViewMessages() {
|
||||||
try {
|
try {
|
||||||
window.log.info('eraseTapToViewMessages: Loading messages...');
|
window.SignalWindow.log.info(
|
||||||
|
'eraseTapToViewMessages: Loading messages...'
|
||||||
|
);
|
||||||
const messages = await window.Signal.Data.getTapToViewMessagesNeedingErase(
|
const messages = await window.Signal.Data.getTapToViewMessagesNeedingErase(
|
||||||
{
|
{
|
||||||
MessageCollection: Whisper.MessageCollection,
|
MessageCollection: Whisper.MessageCollection,
|
||||||
|
@ -24,7 +26,7 @@
|
||||||
messages.map(async fromDB => {
|
messages.map(async fromDB => {
|
||||||
const message = MessageController.register(fromDB.id, fromDB);
|
const message = MessageController.register(fromDB.id, fromDB);
|
||||||
|
|
||||||
window.log.info(
|
window.SignalWindow.log.info(
|
||||||
'eraseTapToViewMessages: message data erased',
|
'eraseTapToViewMessages: message data erased',
|
||||||
message.idForLogging()
|
message.idForLogging()
|
||||||
);
|
);
|
||||||
|
@ -33,13 +35,13 @@
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
'eraseTapToViewMessages: Error erasing messages',
|
'eraseTapToViewMessages: Error erasing messages',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('eraseTapToViewMessages: complete');
|
window.SignalWindow.log.info('eraseTapToViewMessages: complete');
|
||||||
}
|
}
|
||||||
|
|
||||||
let timeout;
|
let timeout;
|
||||||
|
@ -57,7 +59,7 @@
|
||||||
const nextCheck = receivedAt + THIRTY_DAYS;
|
const nextCheck = receivedAt + THIRTY_DAYS;
|
||||||
|
|
||||||
Whisper.TapToViewMessagesListener.nextCheck = nextCheck;
|
Whisper.TapToViewMessagesListener.nextCheck = nextCheck;
|
||||||
window.log.info(
|
window.SignalWindow.log.info(
|
||||||
'checkTapToViewMessages: next check at',
|
'checkTapToViewMessages: next check at',
|
||||||
new Date(nextCheck).toISOString()
|
new Date(nextCheck).toISOString()
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
/* eslint-env node */
|
/* eslint-env node */
|
||||||
/* global log, Signal */
|
/* global Signal, window */
|
||||||
|
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
@ -58,7 +58,7 @@ exports.createConversation = async ({
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
range(0, numMessages).map(async index => {
|
range(0, numMessages).map(async index => {
|
||||||
await sleep(index * 100);
|
await sleep(index * 100);
|
||||||
log.info(`Create message ${index + 1}`);
|
window.SignalWindow.log.info(`Create message ${index + 1}`);
|
||||||
const message = await createRandomMessage({ conversationId });
|
const message = await createRandomMessage({ conversationId });
|
||||||
return Signal.Data.saveMessage(message);
|
return Signal.Data.saveMessage(message);
|
||||||
})
|
})
|
||||||
|
@ -108,7 +108,10 @@ const createRandomMessage = async ({ conversationId } = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const message = _createMessage({ commonProperties, conversationId, type });
|
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 } = {}) => {
|
const _createMessage = ({ commonProperties, conversationId, type } = {}) => {
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
|
|
||||||
/* eslint-env node, browser */
|
/* eslint-env node, browser */
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
const log = typeof window !== 'undefined' ? window.log : console;
|
|
||||||
|
|
||||||
exports.setup = (locale, messages) => {
|
exports.setup = (locale, messages) => {
|
||||||
if (!locale) {
|
if (!locale) {
|
||||||
throw new Error('i18n: locale parameter is required');
|
throw new Error('i18n: locale parameter is required');
|
||||||
|
@ -15,6 +12,10 @@ exports.setup = (locale, messages) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMessage(key, substitutions) {
|
function getMessage(key, substitutions) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
const log =
|
||||||
|
typeof window !== 'undefined' ? window.SignalWindow.log : console;
|
||||||
|
|
||||||
const entry = messages[key];
|
const entry = messages[key];
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
log.error(
|
log.error(
|
||||||
|
|
|
@ -16,7 +16,7 @@ class IdleDetector extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
window.log.info('Start idle detector');
|
window.SignalWindow.log.info('Start idle detector');
|
||||||
this._scheduleNextCallback();
|
this._scheduleNextCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class IdleDetector extends EventEmitter {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('Stop idle detector');
|
window.SignalWindow.log.info('Stop idle detector');
|
||||||
this._clearScheduledCallbacks();
|
this._clearScheduledCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@ module.exports = {
|
||||||
};
|
};
|
||||||
|
|
||||||
async function doesDatabaseExist() {
|
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) => {
|
return new Promise((resolve, reject) => {
|
||||||
const { id } = Whisper.Database;
|
const { id } = Whisper.Database;
|
||||||
const req = window.indexedDB.open(id);
|
const req = window.indexedDB.open(id);
|
||||||
|
@ -20,7 +22,7 @@ async function doesDatabaseExist() {
|
||||||
let existed = true;
|
let existed = true;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.log.warn(
|
window.SignalWindow.log.warn(
|
||||||
'doesDatabaseExist: Timed out attempting to check IndexedDB status'
|
'doesDatabaseExist: Timed out attempting to check IndexedDB status'
|
||||||
);
|
);
|
||||||
return resolve(false);
|
return resolve(false);
|
||||||
|
@ -41,6 +43,8 @@ async function doesDatabaseExist() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeDatabase() {
|
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);
|
window.indexedDB.deleteDatabase(Whisper.Database.id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ exports.processNext = async ({
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
'processNext error:',
|
'processNext error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -53,7 +53,7 @@ function buildAvatarUpdater({ field }) {
|
||||||
const { hash, path } = avatar;
|
const { hash, path } = avatar;
|
||||||
const exists = await doesAttachmentExist(path);
|
const exists = await doesAttachmentExist(path);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
window.log.warn(
|
window.SignalWindow.log.warn(
|
||||||
`Conversation.buildAvatarUpdater: attachment ${path} did not exist`
|
`Conversation.buildAvatarUpdater: attachment ${path} did not exist`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status.type !== 'ok') {
|
if (status.type !== 'ok') {
|
||||||
window.log.info(
|
window.SignalWindow.log.info(
|
||||||
`Not updating notifications; notification status is ${status.type}. ${
|
`Not updating notifications; notification status is ${status.type}. ${
|
||||||
status.shouldClearNotifications ? 'Also clearing notifications' : ''
|
status.shouldClearNotifications ? 'Also clearing notifications' : ''
|
||||||
}`
|
}`
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
window.log.info('Showing a notification');
|
window.SignalWindow.log.info('Showing a notification');
|
||||||
|
|
||||||
let notificationTitle;
|
let notificationTitle;
|
||||||
let notificationMessage;
|
let notificationMessage;
|
||||||
|
@ -191,7 +191,7 @@
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (userSetting !== SettingNames.NO_NAME_OR_MESSAGE) {
|
if (userSetting !== SettingNames.NO_NAME_OR_MESSAGE) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
`Error: Unknown user notification setting: '${userSetting}'`
|
`Error: Unknown user notification setting: '${userSetting}'`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
clear() {
|
clear() {
|
||||||
window.log.info('Removing notification');
|
window.SignalWindow.log.info('Removing notification');
|
||||||
this.notificationData = null;
|
this.notificationData = null;
|
||||||
this.update();
|
this.update();
|
||||||
},
|
},
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
a2 = args[1],
|
a2 = args[1],
|
||||||
a3 = args[2];
|
a3 = args[2];
|
||||||
const logError = function (error) {
|
const logError = function (error) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
'Model caught error triggering',
|
'Model caught error triggering',
|
||||||
name,
|
name,
|
||||||
'event:',
|
'event:',
|
||||||
|
|
|
@ -21,13 +21,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
window.log.info('Rotating signed prekey...');
|
window.SignalWindow.log.info('Rotating signed prekey...');
|
||||||
try {
|
try {
|
||||||
await getAccountManager().rotateSignedPreKey();
|
await getAccountManager().rotateSignedPreKey();
|
||||||
scheduleNextRotation();
|
scheduleNextRotation();
|
||||||
setTimeoutForNextRun();
|
setTimeoutForNextRun();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
'rotateSignedPrekey() failed. Trying again in five minutes'
|
'rotateSignedPrekey() failed. Trying again in five minutes'
|
||||||
);
|
);
|
||||||
setTimeout(setTimeoutForNextRun, 5 * 60 * 1000);
|
setTimeout(setTimeoutForNextRun, 5 * 60 * 1000);
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
if (navigator.onLine) {
|
if (navigator.onLine) {
|
||||||
run();
|
run();
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
window.SignalWindow.log.info(
|
||||||
'We are offline; keys will be rotated when we are next online'
|
'We are offline; keys will be rotated when we are next online'
|
||||||
);
|
);
|
||||||
const listener = () => {
|
const listener = () => {
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const time = storage.get('nextSignedKeyRotationTime', now);
|
const time = storage.get('nextSignedKeyRotationTime', now);
|
||||||
|
|
||||||
window.log.info(
|
window.SignalWindow.log.info(
|
||||||
'Next signed key rotation scheduled for',
|
'Next signed key rotation scheduled for',
|
||||||
new Date(time).toISOString()
|
new Date(time).toISOString()
|
||||||
);
|
);
|
||||||
|
@ -71,7 +71,9 @@
|
||||||
Whisper.RotateSignedPreKeyListener = {
|
Whisper.RotateSignedPreKeyListener = {
|
||||||
init(events, newVersion) {
|
init(events, newVersion) {
|
||||||
if (initComplete) {
|
if (initComplete) {
|
||||||
window.log.info('Rotate signed prekey listener: Already initialized');
|
window.SignalWindow.log.info(
|
||||||
|
'Rotate signed prekey listener: Already initialized'
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
initComplete = true;
|
initComplete = true;
|
||||||
|
|
|
@ -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'));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -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);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -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;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -49,7 +49,7 @@
|
||||||
try {
|
try {
|
||||||
cb();
|
cb();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
'ReactWrapperView.update error:',
|
'ReactWrapperView.update error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -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');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -67,12 +67,12 @@ window.Whisper.events = {
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
try {
|
try {
|
||||||
window.log.info('Initializing SQL in renderer');
|
window.SignalWindow.log.info('Initializing SQL in renderer');
|
||||||
const isTesting = true;
|
const isTesting = true;
|
||||||
await window.sqlInitializer.initialize(isTesting);
|
await window.sqlInitializer.initialize(isTesting);
|
||||||
window.log.info('SQL initialized in renderer');
|
window.SignalWindow.log.info('SQL initialized in renderer');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
'SQL failed to initialize',
|
'SQL failed to initialize',
|
||||||
err && err.stack ? err.stack : err
|
err && err.stack ? err.stack : err
|
||||||
);
|
);
|
||||||
|
|
6
main.js
6
main.js
|
@ -854,9 +854,6 @@ function showScreenShareWindow(sourceName) {
|
||||||
'render-screen-sharing-controller',
|
'render-screen-sharing-controller',
|
||||||
sourceName
|
sourceName
|
||||||
);
|
);
|
||||||
if (config.get('openDevTools')) {
|
|
||||||
screenShareWindow.webContents.openDevTools();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,9 +894,6 @@ function showAbout() {
|
||||||
|
|
||||||
aboutWindow.once('ready-to-show', () => {
|
aboutWindow.once('ready-to-show', () => {
|
||||||
aboutWindow.show();
|
aboutWindow.show();
|
||||||
if (config.get('openDevTools')) {
|
|
||||||
aboutWindow.webContents.openDevTools();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
30
preload.js
30
preload.js
|
@ -35,6 +35,8 @@ try {
|
||||||
|
|
||||||
setEnvironment(parseEnvironment(config.environment));
|
setEnvironment(parseEnvironment(config.environment));
|
||||||
|
|
||||||
|
const log = require('./ts/logging/log');
|
||||||
|
|
||||||
let title = config.name;
|
let title = config.name;
|
||||||
if (getEnvironment() !== Environment.Production) {
|
if (getEnvironment() !== Environment.Production) {
|
||||||
title += ` - ${getEnvironment()}`;
|
title += ` - ${getEnvironment()}`;
|
||||||
|
@ -89,7 +91,7 @@ try {
|
||||||
try {
|
try {
|
||||||
return semver.lt(toCheck, baseVersion);
|
return semver.lt(toCheck, baseVersion);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -100,7 +102,7 @@ try {
|
||||||
try {
|
try {
|
||||||
return semver.gt(toCheck, baseVersion);
|
return semver.gt(toCheck, baseVersion);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -133,11 +135,11 @@ try {
|
||||||
window.eval = global.eval = () => null;
|
window.eval = global.eval = () => null;
|
||||||
|
|
||||||
window.drawAttention = () => {
|
window.drawAttention = () => {
|
||||||
window.log.info('draw attention');
|
log.info('draw attention');
|
||||||
ipc.send('draw-attention');
|
ipc.send('draw-attention');
|
||||||
};
|
};
|
||||||
window.showWindow = () => {
|
window.showWindow = () => {
|
||||||
window.log.info('show window');
|
log.info('show window');
|
||||||
ipc.send('show-window');
|
ipc.send('show-window');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,15 +160,15 @@ try {
|
||||||
};
|
};
|
||||||
|
|
||||||
window.restart = () => {
|
window.restart = () => {
|
||||||
window.log.info('restart');
|
log.info('restart');
|
||||||
ipc.send('restart');
|
ipc.send('restart');
|
||||||
};
|
};
|
||||||
window.shutdown = () => {
|
window.shutdown = () => {
|
||||||
window.log.info('shutdown');
|
log.info('shutdown');
|
||||||
ipc.send('shutdown');
|
ipc.send('shutdown');
|
||||||
};
|
};
|
||||||
window.showDebugLog = () => {
|
window.showDebugLog = () => {
|
||||||
window.log.info('showDebugLog');
|
log.info('showDebugLog');
|
||||||
ipc.send('show-debug-log');
|
ipc.send('show-debug-log');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -286,7 +288,7 @@ try {
|
||||||
try {
|
try {
|
||||||
await deleteAllData();
|
await deleteAllData();
|
||||||
} catch (error) {
|
} 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 () => {
|
ipc.on('get-ready-for-shutdown', async () => {
|
||||||
const { shutdown } = window.Events || {};
|
const { shutdown } = window.Events || {};
|
||||||
if (!shutdown) {
|
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');
|
ipc.send('now-ready-for-shutdown');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +360,7 @@ try {
|
||||||
require('./ts/logging/set_up_renderer_logging').initialize();
|
require('./ts/logging/set_up_renderer_logging').initialize();
|
||||||
|
|
||||||
if (config.proxyUrl) {
|
if (config.proxyUrl) {
|
||||||
window.log.info('Using provided proxy url');
|
log.info('Using provided proxy url');
|
||||||
}
|
}
|
||||||
|
|
||||||
window.nodeSetImmediate = setImmediate;
|
window.nodeSetImmediate = setImmediate;
|
||||||
|
@ -448,7 +450,7 @@ try {
|
||||||
Attachments,
|
Attachments,
|
||||||
userDataPath,
|
userDataPath,
|
||||||
getRegionCode: () => window.storage.get('regionCode'),
|
getRegionCode: () => window.storage.get('regionCode'),
|
||||||
logger: window.log,
|
logger: log,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (config.enableCI) {
|
if (config.enableCI) {
|
||||||
|
@ -464,6 +466,10 @@ try {
|
||||||
require('./ts/backbone/views/whisper_view');
|
require('./ts/backbone/views/whisper_view');
|
||||||
require('./ts/backbone/views/toast_view');
|
require('./ts/backbone/views/toast_view');
|
||||||
require('./ts/views/conversation_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/SignalProtocolStore');
|
||||||
require('./ts/background');
|
require('./ts/background');
|
||||||
|
|
||||||
|
@ -486,6 +492,7 @@ try {
|
||||||
if (config.environment === 'test') {
|
if (config.environment === 'test') {
|
||||||
require('./preload_test');
|
require('./preload_test');
|
||||||
}
|
}
|
||||||
|
log.info('preload complete');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
if (console._log) {
|
if (console._log) {
|
||||||
|
@ -499,4 +506,3 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
preloadEndTime = Date.now();
|
preloadEndTime = Date.now();
|
||||||
window.log.info('preload complete');
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ export const UploadStage: React.ComponentType = () => {
|
||||||
actions.setPackMeta(packMeta);
|
actions.setPackMeta(packMeta);
|
||||||
history.push('/share');
|
history.push('/share');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.log.error('Error uploading image:', e);
|
window.SignalWindow.log.error('Error uploading image:', e);
|
||||||
actions.addToast({
|
actions.addToast({
|
||||||
key: 'StickerCreator--Toasts--errorUploading',
|
key: 'StickerCreator--Toasts--errorUploading',
|
||||||
subs: [e.message],
|
subs: [e.message],
|
||||||
|
|
|
@ -58,7 +58,7 @@ const InnerGrid = SortableContainer(
|
||||||
const stickerImage = await processStickerImage(path);
|
const stickerImage = await processStickerImage(path);
|
||||||
actions.addImageData(stickerImage);
|
actions.addImageData(stickerImage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.log.error('Error processing image:', e);
|
window.SignalWindow.log.error('Error processing image:', e);
|
||||||
actions.removeSticker(path);
|
actions.removeSticker(path);
|
||||||
actions.addToast({
|
actions.addToast({
|
||||||
key:
|
key:
|
||||||
|
|
|
@ -48,7 +48,7 @@ require('../ts/logging/set_up_renderer_logging').initialize();
|
||||||
|
|
||||||
require('../ts/SignalProtocolStore');
|
require('../ts/SignalProtocolStore');
|
||||||
|
|
||||||
window.log.info('sticker-creator starting up...');
|
window.SignalWindow.log.info('sticker-creator starting up...');
|
||||||
|
|
||||||
const Signal = require('../js/modules/signal');
|
const Signal = require('../js/modules/signal');
|
||||||
|
|
||||||
|
@ -296,4 +296,4 @@ window.addEventListener('DOMContentLoaded', applyTheme);
|
||||||
|
|
||||||
window.SignalContext.nativeThemeListener.subscribe(() => applyTheme());
|
window.SignalContext.nativeThemeListener.subscribe(() => applyTheme());
|
||||||
|
|
||||||
window.log.info('sticker-creator preload complete...');
|
window.SignalWindow.log.info('sticker-creator preload complete...');
|
||||||
|
|
|
@ -78,12 +78,12 @@ before(async () => {
|
||||||
|
|
||||||
await deleteIndexedDB();
|
await deleteIndexedDB();
|
||||||
try {
|
try {
|
||||||
window.log.info('Initializing SQL in renderer');
|
window.SignalWindow.log.info('Initializing SQL in renderer');
|
||||||
const isTesting = true;
|
const isTesting = true;
|
||||||
await window.sqlInitializer.initialize(isTesting);
|
await window.sqlInitializer.initialize(isTesting);
|
||||||
window.log.info('SQL initialized in renderer');
|
window.SignalWindow.log.info('SQL initialized in renderer');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
window.SignalWindow.log.error(
|
||||||
'SQL failed to initialize',
|
'SQL failed to initialize',
|
||||||
err && err.stack ? err.stack : err
|
err && err.stack ? err.stack : err
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,10 +19,12 @@ const storageMap = new Map();
|
||||||
// To replicate logic we have on the client side
|
// To replicate logic we have on the client side
|
||||||
global.window = {
|
global.window = {
|
||||||
SignalContext: undefined,
|
SignalContext: undefined,
|
||||||
log: {
|
SignalWindow: {
|
||||||
info: (...args) => console.log(...args),
|
log: {
|
||||||
warn: (...args) => console.warn(...args),
|
info: (...args) => console.log(...args),
|
||||||
error: (...args) => console.error(...args),
|
warn: (...args) => console.warn(...args),
|
||||||
|
error: (...args) => console.error(...args),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
i18n: key => `i18n(${key})`,
|
i18n: key => `i18n(${key})`,
|
||||||
storage: {
|
storage: {
|
||||||
|
|
9
ts/CI.ts
9
ts/CI.ts
|
@ -4,6 +4,7 @@
|
||||||
import { ipcRenderer } from 'electron';
|
import { ipcRenderer } from 'electron';
|
||||||
|
|
||||||
import { explodePromise } from './util/explodePromise';
|
import { explodePromise } from './util/explodePromise';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
type ResolveType = (data: unknown) => void;
|
type ResolveType = (data: unknown) => void;
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ export class CI {
|
||||||
const pendingCompleted = this.completedEvents.get(event) || [];
|
const pendingCompleted = this.completedEvents.get(event) || [];
|
||||||
const pending = pendingCompleted.shift();
|
const pending = pendingCompleted.shift();
|
||||||
if (pending) {
|
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) {
|
if (pendingCompleted.length === 0) {
|
||||||
this.completedEvents.delete(event);
|
this.completedEvents.delete(event);
|
||||||
|
@ -33,7 +34,7 @@ export class CI {
|
||||||
return pending;
|
return pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(`CI: waiting for event ${event}`);
|
log.info(`CI: waiting for event ${event}`);
|
||||||
const { resolve, promise } = explodePromise();
|
const { resolve, promise } = explodePromise();
|
||||||
|
|
||||||
let list = this.eventListeners.get(event);
|
let list = this.eventListeners.get(event);
|
||||||
|
@ -60,12 +61,12 @@ export class CI {
|
||||||
this.eventListeners.delete(event);
|
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);
|
resolve(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(`CI: postponing event ${event}`);
|
log.info(`CI: postponing event ${event}`);
|
||||||
|
|
||||||
let resultList = this.completedEvents.get(event);
|
let resultList = this.completedEvents.get(event);
|
||||||
if (!resultList) {
|
if (!resultList) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { isGroupV1, isGroupV2 } from './util/whatTypeOfConversation';
|
||||||
import { UUID } from './types/UUID';
|
import { UUID } from './types/UUID';
|
||||||
import { Address } from './types/Address';
|
import { Address } from './types/Address';
|
||||||
import { QualifiedAddress } from './types/QualifiedAddress';
|
import { QualifiedAddress } from './types/QualifiedAddress';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
const MAX_MESSAGE_BODY_LENGTH = 64 * 1024;
|
const MAX_MESSAGE_BODY_LENGTH = 64 * 1024;
|
||||||
|
|
||||||
|
@ -233,7 +234,7 @@ export class ConversationController {
|
||||||
const create = async () => {
|
const create = async () => {
|
||||||
if (!conversation.isValid()) {
|
if (!conversation.isValid()) {
|
||||||
const validationError = conversation.validationError || {};
|
const validationError = conversation.validationError || {};
|
||||||
window.log.error(
|
log.error(
|
||||||
'Contact is not valid. Not saving, but adding to collection:',
|
'Contact is not valid. Not saving, but adding to collection:',
|
||||||
conversation.idForLogging(),
|
conversation.idForLogging(),
|
||||||
validationError.stack
|
validationError.stack
|
||||||
|
@ -248,7 +249,7 @@ export class ConversationController {
|
||||||
}
|
}
|
||||||
await saveConversation(conversation.attributes);
|
await saveConversation(conversation.attributes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Conversation save failed! ',
|
'Conversation save failed! ',
|
||||||
identifier,
|
identifier,
|
||||||
type,
|
type,
|
||||||
|
@ -368,9 +369,7 @@ export class ConversationController {
|
||||||
|
|
||||||
// 1. Handle no match at all
|
// 1. Handle no match at all
|
||||||
if (!convoE164 && !convoUuid) {
|
if (!convoE164 && !convoUuid) {
|
||||||
window.log.info(
|
log.info('ensureContactIds: Creating new contact, no matches found');
|
||||||
'ensureContactIds: Creating new contact, no matches found'
|
|
||||||
);
|
|
||||||
const newConvo = this.getOrCreate(identifier, 'private');
|
const newConvo = this.getOrCreate(identifier, 'private');
|
||||||
if (highTrust && e164) {
|
if (highTrust && e164) {
|
||||||
newConvo.updateE164(e164);
|
newConvo.updateE164(e164);
|
||||||
|
@ -388,7 +387,7 @@ export class ConversationController {
|
||||||
}
|
}
|
||||||
if (convoE164 && !convoUuid) {
|
if (convoE164 && !convoUuid) {
|
||||||
const haveUuid = Boolean(normalizedUuid);
|
const haveUuid = Boolean(normalizedUuid);
|
||||||
window.log.info(
|
log.info(
|
||||||
`ensureContactIds: e164-only match found (have UUID: ${haveUuid})`
|
`ensureContactIds: e164-only match found (have UUID: ${haveUuid})`
|
||||||
);
|
);
|
||||||
// If we are only searching based on e164 anyway, then return the first result
|
// 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
|
// Fill in the UUID for an e164-only contact
|
||||||
if (normalizedUuid && !convoE164.get('uuid')) {
|
if (normalizedUuid && !convoE164.get('uuid')) {
|
||||||
if (highTrust) {
|
if (highTrust) {
|
||||||
window.log.info('ensureContactIds: Adding UUID to e164-only match');
|
log.info('ensureContactIds: Adding UUID to e164-only match');
|
||||||
convoE164.updateUuid(normalizedUuid);
|
convoE164.updateUuid(normalizedUuid);
|
||||||
updateConversation(convoE164.attributes);
|
updateConversation(convoE164.attributes);
|
||||||
}
|
}
|
||||||
return convoE164.get('id');
|
return convoE164.get('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'ensureContactIds: e164 already had UUID, creating a new contact'
|
'ensureContactIds: e164 already had UUID, creating a new contact'
|
||||||
);
|
);
|
||||||
// If existing e164 match already has UUID, create a new contact...
|
// If existing e164 match already has UUID, create a new contact...
|
||||||
const newConvo = this.getOrCreate(normalizedUuid, 'private');
|
const newConvo = this.getOrCreate(normalizedUuid, 'private');
|
||||||
|
|
||||||
if (highTrust) {
|
if (highTrust) {
|
||||||
window.log.info(
|
log.info('ensureContactIds: Moving e164 from old contact to new');
|
||||||
'ensureContactIds: Moving e164 from old contact to new'
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove the e164 from the old contact...
|
// Remove the e164 from the old contact...
|
||||||
convoE164.set({ e164: undefined });
|
convoE164.set({ e164: undefined });
|
||||||
|
@ -432,7 +429,7 @@ export class ConversationController {
|
||||||
}
|
}
|
||||||
if (!convoE164 && convoUuid) {
|
if (!convoE164 && convoUuid) {
|
||||||
if (e164 && highTrust) {
|
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);
|
convoUuid.updateE164(e164);
|
||||||
updateConversation(convoUuid.attributes);
|
updateConversation(convoUuid.attributes);
|
||||||
}
|
}
|
||||||
|
@ -454,7 +451,7 @@ export class ConversationController {
|
||||||
if (highTrust) {
|
if (highTrust) {
|
||||||
// Conflict: If e164 match already has a UUID, we remove its e164.
|
// Conflict: If e164 match already has a UUID, we remove its e164.
|
||||||
if (convoE164.get('uuid') && convoE164.get('uuid') !== normalizedUuid) {
|
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.'
|
'ensureContactIds: e164 match had different UUID than incoming pair, removing its e164.'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -469,7 +466,7 @@ export class ConversationController {
|
||||||
return convoUuid.get('id');
|
return convoUuid.get('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`ensureContactIds: Found a split contact - UUID ${normalizedUuid} and E164 ${e164}. Merging.`
|
`ensureContactIds: Found a split contact - UUID ${normalizedUuid} and E164 ${e164}. Merging.`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -488,9 +485,7 @@ export class ConversationController {
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
const errorText = error && error.stack ? error.stack : error;
|
const errorText = error && error.stack ? error.stack : error;
|
||||||
window.log.warn(
|
log.warn(`ensureContactIds error combining contacts: ${errorText}`);
|
||||||
`ensureContactIds error combining contacts: ${errorText}`
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +493,7 @@ export class ConversationController {
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkForConflicts(): Promise<void> {
|
async checkForConflicts(): Promise<void> {
|
||||||
window.log.info('checkForConflicts: starting...');
|
log.info('checkForConflicts: starting...');
|
||||||
const byUuid = Object.create(null);
|
const byUuid = Object.create(null);
|
||||||
const byE164 = Object.create(null);
|
const byE164 = Object.create(null);
|
||||||
const byGroupV2Id = Object.create(null);
|
const byGroupV2Id = Object.create(null);
|
||||||
|
@ -524,9 +519,7 @@ export class ConversationController {
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
byUuid[uuid] = conversation;
|
byUuid[uuid] = conversation;
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(`checkForConflicts: Found conflict with uuid ${uuid}`);
|
||||||
`checkForConflicts: Found conflict with uuid ${uuid}`
|
|
||||||
);
|
|
||||||
|
|
||||||
// Keep the newer one if it has an e164, otherwise keep existing
|
// Keep the newer one if it has an e164, otherwise keep existing
|
||||||
if (conversation.get('e164')) {
|
if (conversation.get('e164')) {
|
||||||
|
@ -554,7 +547,7 @@ export class ConversationController {
|
||||||
existing.get('uuid') &&
|
existing.get('uuid') &&
|
||||||
conversation.get('uuid') !== 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.`
|
`checkForConflicts: Found two matches on e164 ${e164} with different truthy UUIDs. Dropping e164 on older.`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -566,9 +559,7 @@ export class ConversationController {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.warn(
|
log.warn(`checkForConflicts: Found conflict with e164 ${e164}`);
|
||||||
`checkForConflicts: Found conflict with e164 ${e164}`
|
|
||||||
);
|
|
||||||
|
|
||||||
// Keep the newer one if it has a UUID, otherwise keep existing
|
// Keep the newer one if it has a UUID, otherwise keep existing
|
||||||
if (conversation.get('uuid')) {
|
if (conversation.get('uuid')) {
|
||||||
|
@ -605,7 +596,7 @@ export class ConversationController {
|
||||||
const logParenthetical = isGroupV1(conversation.attributes)
|
const logParenthetical = isGroupV1(conversation.attributes)
|
||||||
? ' (derived from a GV1 group ID)'
|
? ' (derived from a GV1 group ID)'
|
||||||
: '';
|
: '';
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`checkForConflicts: Found conflict with group V2 ID ${groupV2Id}${logParenthetical}`
|
`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(
|
async combineConversations(
|
||||||
|
@ -645,14 +636,14 @@ export class ConversationController {
|
||||||
const obsoleteId = obsolete.get('id');
|
const obsoleteId = obsolete.get('id');
|
||||||
const obsoleteUuid = obsolete.get('uuid');
|
const obsoleteUuid = obsolete.get('uuid');
|
||||||
const currentId = current.get('id');
|
const currentId = current.get('id');
|
||||||
window.log.warn('combineConversations: Combining two conversations', {
|
log.warn('combineConversations: Combining two conversations', {
|
||||||
obsolete: obsoleteId,
|
obsolete: obsoleteId,
|
||||||
current: currentId,
|
current: currentId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (conversationType === 'private' && obsoleteUuid) {
|
if (conversationType === 'private' && obsoleteUuid) {
|
||||||
if (!current.get('profileKey') && obsolete.get('profileKey')) {
|
if (!current.get('profileKey') && obsolete.get('profileKey')) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'combineConversations: Copying profile key from old to new contact'
|
'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'
|
'combineConversations: Delete all sessions tied to old conversationId'
|
||||||
);
|
);
|
||||||
const ourUuid = window.textsecure.storage.user.getCheckedUuid();
|
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'
|
'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'
|
'combineConversations: Ensure that all V1 groups have new conversationId instead of old'
|
||||||
);
|
);
|
||||||
const groups = await this.getAllGroupsInvolvingId(obsoleteId);
|
const groups = await this.getAllGroupsInvolvingId(obsoleteId);
|
||||||
|
@ -709,23 +700,23 @@ export class ConversationController {
|
||||||
|
|
||||||
// Note: we explicitly don't want to update V2 groups
|
// Note: we explicitly don't want to update V2 groups
|
||||||
|
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'combineConversations: Delete the obsolete conversation from the database'
|
'combineConversations: Delete the obsolete conversation from the database'
|
||||||
);
|
);
|
||||||
await removeConversation(obsoleteId, {
|
await removeConversation(obsoleteId, {
|
||||||
Conversation: window.Whisper.Conversation,
|
Conversation: window.Whisper.Conversation,
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.warn('combineConversations: Update messages table');
|
log.warn('combineConversations: Update messages table');
|
||||||
await migrateConversationMessages(obsoleteId, currentId);
|
await migrateConversationMessages(obsoleteId, currentId);
|
||||||
|
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'combineConversations: Eliminate old conversation from ConversationController lookups'
|
'combineConversations: Eliminate old conversation from ConversationController lookups'
|
||||||
);
|
);
|
||||||
this._conversations.remove(obsolete);
|
this._conversations.remove(obsolete);
|
||||||
this._conversations.resetLookups();
|
this._conversations.resetLookups();
|
||||||
|
|
||||||
window.log.warn('combineConversations: Complete!', {
|
log.warn('combineConversations: Complete!', {
|
||||||
obsolete: obsoleteId,
|
obsolete: obsoleteId,
|
||||||
current: currentId,
|
current: currentId,
|
||||||
});
|
});
|
||||||
|
@ -800,7 +791,7 @@ export class ConversationController {
|
||||||
}
|
}
|
||||||
|
|
||||||
async load(): Promise<void> {
|
async load(): Promise<void> {
|
||||||
window.log.info('ConversationController: starting initial fetch');
|
log.info('ConversationController: starting initial fetch');
|
||||||
|
|
||||||
if (this._conversations.length) {
|
if (this._conversations.length) {
|
||||||
throw new Error('ConversationController: Already loaded!');
|
throw new Error('ConversationController: Already loaded!');
|
||||||
|
@ -818,7 +809,7 @@ export class ConversationController {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (temporaryConversations.length) {
|
if (temporaryConversations.length) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`ConversationController: Removing ${temporaryConversations.length} temporary conversations`
|
`ConversationController: Removing ${temporaryConversations.length} temporary conversations`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -866,21 +857,19 @@ export class ConversationController {
|
||||||
conversation.set({ e164: undefined });
|
conversation.set({ e164: undefined });
|
||||||
updateConversation(conversation.attributes);
|
updateConversation(conversation.attributes);
|
||||||
|
|
||||||
window.log.info(
|
log.info(`Cleaning up conversation(${uuid}) with invalid e164`);
|
||||||
`Cleaning up conversation(${uuid}) with invalid e164`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'ConversationController.load/map: Failed to prepare a conversation',
|
'ConversationController.load/map: Failed to prepare a conversation',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
window.log.info('ConversationController: done with initial fetch');
|
log.info('ConversationController: done with initial fetch');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'ConversationController: initial fetch failed',
|
'ConversationController: initial fetch failed',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import Long from 'long';
|
||||||
import { HKDF } from '@signalapp/signal-client';
|
import { HKDF } from '@signalapp/signal-client';
|
||||||
|
|
||||||
import { calculateAgreement, generateKeyPair } from './Curve';
|
import { calculateAgreement, generateKeyPair } from './Curve';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CipherType,
|
CipherType,
|
||||||
|
@ -712,7 +713,7 @@ export async function encryptCdsDiscoveryRequest(
|
||||||
|
|
||||||
export function uuidToArrayBuffer(uuid: string): ArrayBuffer {
|
export function uuidToArrayBuffer(uuid: string): ArrayBuffer {
|
||||||
if (uuid.length !== 36) {
|
if (uuid.length !== 36) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'uuidToArrayBuffer: received a string of invalid length. Returning an empty ArrayBuffer'
|
'uuidToArrayBuffer: received a string of invalid length. Returning an empty ArrayBuffer'
|
||||||
);
|
);
|
||||||
return new ArrayBuffer(0);
|
return new ArrayBuffer(0);
|
||||||
|
@ -729,7 +730,7 @@ export function arrayBufferToUuid(
|
||||||
arrayBuffer: ArrayBuffer
|
arrayBuffer: ArrayBuffer
|
||||||
): undefined | string {
|
): undefined | string {
|
||||||
if (arrayBuffer.byteLength !== 16) {
|
if (arrayBuffer.byteLength !== 16) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'arrayBufferToUuid: received an ArrayBuffer of invalid length. Returning undefined'
|
'arrayBufferToUuid: received an ArrayBuffer of invalid length. Returning undefined'
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
CompatPreKeyType,
|
CompatPreKeyType,
|
||||||
CompatSignedPreKeyType,
|
CompatSignedPreKeyType,
|
||||||
} from './textsecure/Types.d';
|
} from './textsecure/Types.d';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
export function isNonNegativeInteger(n: unknown): n is number {
|
export function isNonNegativeInteger(n: unknown): n is number {
|
||||||
return typeof n === 'number' && n % 1 === 0 && n >= 0;
|
return typeof n === 'number' && n % 1 === 0 && n >= 0;
|
||||||
|
@ -82,7 +83,7 @@ export function createKeyPair(incomingKey: ArrayBuffer): KeyPairType {
|
||||||
const copy = copyArrayBuffer(incomingKey);
|
const copy = copyArrayBuffer(incomingKey);
|
||||||
clampPrivateKey(copy);
|
clampPrivateKey(copy);
|
||||||
if (!constantTimeEqual(copy, incomingKey)) {
|
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);
|
const incomingKeyBuffer = Buffer.from(incomingKey);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import { get, throttle } from 'lodash';
|
import { get, throttle } from 'lodash';
|
||||||
|
|
||||||
import type { WebAPIType } from './textsecure/WebAPI';
|
import type { WebAPIType } from './textsecure/WebAPI';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
export type ConfigKeyType =
|
export type ConfigKeyType =
|
||||||
| 'desktop.announcementGroup'
|
| 'desktop.announcementGroup'
|
||||||
|
@ -92,7 +93,7 @@ export const refreshRemoteConfig = async (
|
||||||
// If enablement changes at all, notify listeners
|
// If enablement changes at all, notify listeners
|
||||||
const currentListeners = listeners[name] || [];
|
const currentListeners = listeners[name] || [];
|
||||||
if (hasChanged) {
|
if (hasChanged) {
|
||||||
window.log.info(`Remote Config: Flag ${name} has changed`);
|
log.info(`Remote Config: Flag ${name} has changed`);
|
||||||
currentListeners.forEach(listener => {
|
currentListeners.forEach(listener => {
|
||||||
listener(configValue);
|
listener(configValue);
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,6 +58,7 @@ import {
|
||||||
QualifiedAddress,
|
QualifiedAddress,
|
||||||
QualifiedAddressStringType,
|
QualifiedAddressStringType,
|
||||||
} from './types/QualifiedAddress';
|
} from './types/QualifiedAddress';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
const TIMESTAMP_THRESHOLD = 5 * 1000; // 5 seconds
|
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
|
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any
|
||||||
object[field] = cache as any;
|
object[field] = cache as any;
|
||||||
}
|
}
|
||||||
|
@ -325,12 +326,12 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
|
|
||||||
const entry = this.preKeys.get(id);
|
const entry = this.preKeys.get(id);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
window.log.error('Failed to fetch prekey:', id);
|
log.error('Failed to fetch prekey:', id);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.hydrated) {
|
if (entry.hydrated) {
|
||||||
window.log.info('Successfully fetched prekey (cache hit):', id);
|
log.info('Successfully fetched prekey (cache hit):', id);
|
||||||
return entry.item;
|
return entry.item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +341,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
fromDB: entry.fromDB,
|
fromDB: entry.fromDB,
|
||||||
item,
|
item,
|
||||||
});
|
});
|
||||||
window.log.info('Successfully fetched prekey (cache miss):', id);
|
log.info('Successfully fetched prekey (cache miss):', id);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +384,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
try {
|
try {
|
||||||
this.trigger('removePreKey');
|
this.trigger('removePreKey');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'removePreKey error triggering removePreKey:',
|
'removePreKey error triggering removePreKey:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -414,12 +415,12 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
|
|
||||||
const entry = this.signedPreKeys.get(id);
|
const entry = this.signedPreKeys.get(id);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
window.log.error('Failed to fetch signed prekey:', id);
|
log.error('Failed to fetch signed prekey:', id);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.hydrated) {
|
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;
|
return entry.item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +430,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
item,
|
item,
|
||||||
fromDB: entry.fromDB,
|
fromDB: entry.fromDB,
|
||||||
});
|
});
|
||||||
window.log.info('Successfully fetched signed prekey (cache miss):', id);
|
log.info('Successfully fetched signed prekey (cache miss):', id);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,7 +577,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = error && error.stack ? error.stack : error;
|
||||||
window.log.error(
|
log.error(
|
||||||
`saveSenderKey: failed to save senderKey ${senderId}/${distributionId}: ${errorString}`
|
`saveSenderKey: failed to save senderKey ${senderId}/${distributionId}: ${errorString}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -597,12 +598,12 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
|
|
||||||
const entry = this.senderKeys.get(id);
|
const entry = this.senderKeys.get(id);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
window.log.error('Failed to fetch sender key:', id);
|
log.error('Failed to fetch sender key:', id);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.hydrated) {
|
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;
|
return entry.item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,11 +613,11 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
item,
|
item,
|
||||||
fromDB: entry.fromDB,
|
fromDB: entry.fromDB,
|
||||||
});
|
});
|
||||||
window.log.info('Successfully fetched sender key(cache miss):', id);
|
log.info('Successfully fetched sender key(cache miss):', id);
|
||||||
return item;
|
return item;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = error && error.stack ? error.stack : error;
|
||||||
window.log.error(
|
log.error(
|
||||||
`getSenderKey: failed to load sender key ${senderId}/${distributionId}: ${errorString}`
|
`getSenderKey: failed to load sender key ${senderId}/${distributionId}: ${errorString}`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -641,7 +642,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
this.senderKeys.delete(id);
|
this.senderKeys.delete(id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = error && error.stack ? error.stack : error;
|
||||||
window.log.error(
|
log.error(
|
||||||
`removeSenderKey: failed to remove senderKey ${senderId}/${distributionId}: ${errorString}`
|
`removeSenderKey: failed to remove senderKey ${senderId}/${distributionId}: ${errorString}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -709,14 +710,12 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
if (this.currentZone && this.currentZone !== zone) {
|
if (this.currentZone && this.currentZone !== zone) {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
|
||||||
window.log.info(
|
log.info(`${debugName}: locked by ${this.currentZone.name}, waiting`);
|
||||||
`${debugName}: locked by ${this.currentZone.name}, waiting`
|
|
||||||
);
|
|
||||||
|
|
||||||
return new Promise<T>((resolve, reject) => {
|
return new Promise<T>((resolve, reject) => {
|
||||||
const callback = async () => {
|
const callback = async () => {
|
||||||
const duration = Date.now() - start;
|
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
|
// Call `.withZone` synchronously from `this.zoneQueue` to avoid
|
||||||
// extra in-between ticks while we are on microtasks queue.
|
// extra in-between ticks while we are on microtasks queue.
|
||||||
|
@ -759,7 +758,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`commitZoneChanges(${name}): pending sessions ${pendingSessions.size} ` +
|
`commitZoneChanges(${name}): pending sessions ${pendingSessions.size} ` +
|
||||||
`pending unprocessed ${pendingUnprocessed.size}`
|
`pending unprocessed ${pendingUnprocessed.size}`
|
||||||
);
|
);
|
||||||
|
@ -786,7 +785,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async revertZoneChanges(name: string, error: Error): Promise<void> {
|
private async revertZoneChanges(name: string, error: Error): Promise<void> {
|
||||||
window.log.info(
|
log.info(
|
||||||
`revertZoneChanges(${name}): ` +
|
`revertZoneChanges(${name}): ` +
|
||||||
`pending sessions size ${this.pendingSessions.size} ` +
|
`pending sessions size ${this.pendingSessions.size} ` +
|
||||||
`pending unprocessed size ${this.pendingUnprocessed.size}`,
|
`pending unprocessed size ${this.pendingUnprocessed.size}`,
|
||||||
|
@ -807,7 +806,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
this.currentZone = zone;
|
this.currentZone = zone;
|
||||||
|
|
||||||
if (zone !== GLOBAL_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) {
|
if (zone !== GLOBAL_ZONE) {
|
||||||
window.log.info(`SignalProtocolStore.leaveZone(${zone.name})`);
|
log.info(`SignalProtocolStore.leaveZone(${zone.name})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentZone = undefined;
|
this.currentZone = undefined;
|
||||||
|
@ -845,7 +844,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
toEnter.push(elem);
|
toEnter.push(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`SignalProtocolStore: running blocked ${toEnter.length} jobs in ` +
|
`SignalProtocolStore: running blocked ${toEnter.length} jobs in ` +
|
||||||
`zone ${next.zone.name}`
|
`zone ${next.zone.name}`
|
||||||
);
|
);
|
||||||
|
@ -888,9 +887,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
return await this._maybeMigrateSession(entry.fromDB, { zone });
|
return await this._maybeMigrateSession(entry.fromDB, { zone });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = error && error.stack ? error.stack : error;
|
||||||
window.log.error(
|
log.error(`loadSession: failed to load session ${id}: ${errorString}`);
|
||||||
`loadSession: failed to load session ${id}: ${errorString}`
|
|
||||||
);
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -957,9 +954,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
registrationId: localRegistrationId,
|
registrationId: localRegistrationId,
|
||||||
};
|
};
|
||||||
|
|
||||||
window.log.info(
|
log.info(`_maybeMigrateSession: Migrating session with id ${session.id}`);
|
||||||
`_maybeMigrateSession: Migrating session with id ${session.id}`
|
|
||||||
);
|
|
||||||
const sessionProto = sessionRecordToProtobuf(
|
const sessionProto = sessionRecordToProtobuf(
|
||||||
JSON.parse(session.record),
|
JSON.parse(session.record),
|
||||||
localUserData
|
localUserData
|
||||||
|
@ -1026,7 +1021,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : 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;
|
throw error;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1117,7 +1112,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
emptyIdentifiers,
|
emptyIdentifiers,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'getOpenDevices: Failed to get devices',
|
'getOpenDevices: Failed to get devices',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -1144,13 +1139,13 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = qualifiedAddress.toString();
|
const id = qualifiedAddress.toString();
|
||||||
window.log.info('removeSession: deleting session for', id);
|
log.info('removeSession: deleting session for', id);
|
||||||
try {
|
try {
|
||||||
await window.Signal.Data.removeSessionById(id);
|
await window.Signal.Data.removeSessionById(id);
|
||||||
this.sessions.delete(id);
|
this.sessions.delete(id);
|
||||||
this.pendingSessions.delete(id);
|
this.pendingSessions.delete(id);
|
||||||
} catch (e) {
|
} 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');
|
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);
|
const id = window.ConversationController.getConversationId(identifier);
|
||||||
strictAssert(
|
strictAssert(
|
||||||
|
@ -1221,7 +1216,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
|
|
||||||
const id = qualifiedAddress.toString();
|
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);
|
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',
|
'archiveSiblingSessions: archiving sibling sessions for',
|
||||||
encodedAddress.toString()
|
encodedAddress.toString()
|
||||||
);
|
);
|
||||||
|
@ -1268,7 +1263,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
throw new Error('archiveAllSessions: this.sessions not yet cached!');
|
throw new Error('archiveAllSessions: this.sessions not yet cached!');
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'archiveAllSessions: archiving all sessions for',
|
'archiveAllSessions: archiving all sessions for',
|
||||||
uuid.toString()
|
uuid.toString()
|
||||||
);
|
);
|
||||||
|
@ -1308,7 +1303,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
|
|
||||||
const ONE_HOUR = 60 * 60 * 1000;
|
const ONE_HOUR = 60 * 60 * 1000;
|
||||||
if (lastReset && isMoreRecentThan(lastReset, ONE_HOUR)) {
|
if (lastReset && isMoreRecentThan(lastReset, ONE_HOUR)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`lightSessionReset/${id}: Skipping session reset, last reset at ${lastReset}`
|
`lightSessionReset/${id}: Skipping session reset, last reset at ${lastReset}`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -1329,7 +1324,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
const conversation = window.ConversationController.get(conversationId);
|
const conversation = window.ConversationController.get(conversationId);
|
||||||
assert(conversation, `lightSessionReset/${id}: missing conversation`);
|
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
|
// Archive open session with this device
|
||||||
await this.archiveSession(qualifiedAddress);
|
await this.archiveSession(qualifiedAddress);
|
||||||
|
@ -1356,10 +1351,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
window.storage.put('sessionResets', sessionResets);
|
window.storage.put('sessionResets', sessionResets);
|
||||||
|
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = error && error.stack ? error.stack : error;
|
||||||
window.log.error(
|
log.error(`lightSessionReset/${id}: Encountered error`, errorString);
|
||||||
`lightSessionReset/${id}: Encountered error`,
|
|
||||||
errorString
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1380,7 +1372,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
|
|
||||||
return entry.fromDB;
|
return entry.fromDB;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`getIdentityRecord: Failed to get identity record for identifier ${id}`
|
`getIdentityRecord: Failed to get identity record for identifier ${id}`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -1418,7 +1410,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
id: newId,
|
id: newId,
|
||||||
};
|
};
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`SignalProtocolStore: migrating identity key from ${record.fromDB.id} ` +
|
`SignalProtocolStore: migrating identity key from ${record.fromDB.id} ` +
|
||||||
`to ${newRecord.id}`
|
`to ${newRecord.id}`
|
||||||
);
|
);
|
||||||
|
@ -1454,7 +1446,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
if (identityRecord && identityRecord.publicKey) {
|
if (identityRecord && identityRecord.publicKey) {
|
||||||
return constantTimeEqual(identityRecord.publicKey, publicKey);
|
return constantTimeEqual(identityRecord.publicKey, publicKey);
|
||||||
}
|
}
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'isTrustedIdentity: No local record for our own identifier. Returning true.'
|
'isTrustedIdentity: No local record for our own identifier. Returning true.'
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1475,28 +1467,26 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
identityRecord?: IdentityKeyType
|
identityRecord?: IdentityKeyType
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!identityRecord) {
|
if (!identityRecord) {
|
||||||
window.log.info(
|
log.info('isTrustedForSending: No previous record, returning true...');
|
||||||
'isTrustedForSending: No previous record, returning true...'
|
|
||||||
);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const existing = identityRecord.publicKey;
|
const existing = identityRecord.publicKey;
|
||||||
|
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
window.log.info('isTrustedForSending: Nothing here, returning true...');
|
log.info('isTrustedForSending: Nothing here, returning true...');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!constantTimeEqual(existing, publicKey)) {
|
if (!constantTimeEqual(existing, publicKey)) {
|
||||||
window.log.info("isTrustedForSending: Identity keys don't match...");
|
log.info("isTrustedForSending: Identity keys don't match...");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (identityRecord.verified === VerifiedStatus.UNVERIFIED) {
|
if (identityRecord.verified === VerifiedStatus.UNVERIFIED) {
|
||||||
window.log.error('isTrustedIdentity: Needs unverified approval!');
|
log.error('isTrustedIdentity: Needs unverified approval!');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.isNonBlockingApprovalRequired(identityRecord)) {
|
if (this.isNonBlockingApprovalRequired(identityRecord)) {
|
||||||
window.log.error('isTrustedForSending: Needs non-blocking approval!');
|
log.error('isTrustedForSending: Needs non-blocking approval!');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1560,7 +1550,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
|
|
||||||
if (!identityRecord || !identityRecord.publicKey) {
|
if (!identityRecord || !identityRecord.publicKey) {
|
||||||
// Lookup failed, or the current key was removed, so save this one.
|
// 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({
|
await this._saveIdentityKey({
|
||||||
id,
|
id,
|
||||||
publicKey,
|
publicKey,
|
||||||
|
@ -1575,7 +1565,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
|
|
||||||
const oldpublicKey = identityRecord.publicKey;
|
const oldpublicKey = identityRecord.publicKey;
|
||||||
if (!constantTimeEqual(oldpublicKey, publicKey)) {
|
if (!constantTimeEqual(oldpublicKey, publicKey)) {
|
||||||
window.log.info('saveIdentity: Replacing existing identity...');
|
log.info('saveIdentity: Replacing existing identity...');
|
||||||
const previousStatus = identityRecord.verified;
|
const previousStatus = identityRecord.verified;
|
||||||
let verifiedStatus;
|
let verifiedStatus;
|
||||||
if (
|
if (
|
||||||
|
@ -1599,7 +1589,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
try {
|
try {
|
||||||
this.trigger('keychange', encodedAddress.uuid);
|
this.trigger('keychange', encodedAddress.uuid);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'saveIdentity: error triggering keychange:',
|
'saveIdentity: error triggering keychange:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -1614,7 +1604,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (this.isNonBlockingApprovalRequired(identityRecord)) {
|
if (this.isNonBlockingApprovalRequired(identityRecord)) {
|
||||||
window.log.info('saveIdentity: Setting approval status...');
|
log.info('saveIdentity: Setting approval status...');
|
||||||
|
|
||||||
identityRecord.nonblockingApproval = nonblockingApproval;
|
identityRecord.nonblockingApproval = nonblockingApproval;
|
||||||
await this._saveIdentityKey(identityRecord);
|
await this._saveIdentityKey(identityRecord);
|
||||||
|
@ -1703,9 +1693,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
await this._saveIdentityKey(identityRecord);
|
await this._saveIdentityKey(identityRecord);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info('setVerified: No identity record for specified publicKey');
|
||||||
'setVerified: No identity record for specified publicKey'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1784,7 +1772,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
try {
|
try {
|
||||||
this.trigger('keychange', uuid);
|
this.trigger('keychange', uuid);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'processUnverifiedMessage: error triggering keychange:',
|
'processUnverifiedMessage: error triggering keychange:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -1829,9 +1817,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!identityRecord && verifiedStatus === VerifiedStatus.DEFAULT) {
|
if (!identityRecord && verifiedStatus === VerifiedStatus.DEFAULT) {
|
||||||
window.log.info(
|
log.info('processVerifiedMessage: No existing record for default status');
|
||||||
'processVerifiedMessage: No existing record for default status'
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1863,7 +1849,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
try {
|
try {
|
||||||
this.trigger('keychange', uuid);
|
this.trigger('keychange', uuid);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'processVerifiedMessage error triggering keychange:',
|
'processVerifiedMessage error triggering keychange:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
277
ts/background.ts
277
ts/background.ts
|
@ -97,6 +97,7 @@ import { onRetryRequest, onDecryptionError } from './util/handleRetry';
|
||||||
import { themeChanged } from './shims/themeChanged';
|
import { themeChanged } from './shims/themeChanged';
|
||||||
import { createIPCEvents } from './util/createIPCEvents';
|
import { createIPCEvents } from './util/createIPCEvents';
|
||||||
import { RemoveAllConfiguration } from './types/RemoveAllConfiguration';
|
import { RemoveAllConfiguration } from './types/RemoveAllConfiguration';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
|
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.startupProcessingQueue = new window.Signal.Util.StartupQueue();
|
||||||
window.attachmentDownloadQueue = [];
|
window.attachmentDownloadQueue = [];
|
||||||
try {
|
try {
|
||||||
window.log.info('Initializing SQL in renderer');
|
log.info('Initializing SQL in renderer');
|
||||||
await window.sqlInitializer.initialize();
|
await window.sqlInitializer.initialize();
|
||||||
window.log.info('SQL initialized in renderer');
|
log.info('SQL initialized in renderer');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error('SQL failed to initialize', err && err.stack ? err.stack : err);
|
||||||
'SQL failed to initialize',
|
|
||||||
err && err.stack ? err.stack : err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await window.Signal.Util.initializeMessageCounter();
|
await window.Signal.Util.initializeMessageCounter();
|
||||||
|
@ -154,7 +152,7 @@ export async function startApp(): Promise<void> {
|
||||||
server,
|
server,
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.info('Initializing MessageReceiver');
|
log.info('Initializing MessageReceiver');
|
||||||
messageReceiver = new MessageReceiver({
|
messageReceiver = new MessageReceiver({
|
||||||
server,
|
server,
|
||||||
storage: window.storage,
|
storage: window.storage,
|
||||||
|
@ -347,7 +345,7 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
const c = window.ConversationController.get(conversationId);
|
const c = window.ConversationController.get(conversationId);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`deliveryReceiptBatcher: Conversation ${conversationId} does not exist! ` +
|
`deliveryReceiptBatcher: Conversation ${conversationId} does not exist! ` +
|
||||||
`Will not send delivery receipts for timestamps ${timestamps}`
|
`Will not send delivery receipts for timestamps ${timestamps}`
|
||||||
);
|
);
|
||||||
|
@ -372,7 +370,7 @@ export async function startApp(): Promise<void> {
|
||||||
{ messageIds, sendType: 'deliveryReceipt' }
|
{ messageIds, sendType: 'deliveryReceipt' }
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`Failed to send delivery receipt to ${senderE164}/${senderUuid} for timestamps ${timestamps}:`,
|
`Failed to send delivery receipt to ${senderE164}/${senderUuid} for timestamps ${timestamps}:`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -492,8 +490,8 @@ export async function startApp(): Promise<void> {
|
||||||
} = window.Signal.Migrations;
|
} = window.Signal.Migrations;
|
||||||
const { Views } = window.Signal;
|
const { Views } = window.Signal;
|
||||||
|
|
||||||
window.log.info('background page reloaded');
|
log.info('background page reloaded');
|
||||||
window.log.info('environment:', window.getEnvironment());
|
log.info('environment:', window.getEnvironment());
|
||||||
|
|
||||||
let idleDetector: WhatIsThis;
|
let idleDetector: WhatIsThis;
|
||||||
let newVersion = false;
|
let newVersion = false;
|
||||||
|
@ -522,7 +520,7 @@ export async function startApp(): Promise<void> {
|
||||||
window.Whisper.events.trigger('userChanged', false);
|
window.Whisper.events.trigger('userChanged', false);
|
||||||
|
|
||||||
window.Signal.Util.Registration.markDone();
|
window.Signal.Util.Registration.markDone();
|
||||||
window.log.info('dispatching registration event');
|
log.info('dispatching registration event');
|
||||||
window.Whisper.events.trigger('registration_done');
|
window.Whisper.events.trigger('registration_done');
|
||||||
});
|
});
|
||||||
return accountManager;
|
return accountManager;
|
||||||
|
@ -534,9 +532,9 @@ export async function startApp(): Promise<void> {
|
||||||
if (!version) {
|
if (!version) {
|
||||||
const isIndexedDBPresent = await doesDatabaseExist();
|
const isIndexedDBPresent = await doesDatabaseExist();
|
||||||
if (isIndexedDBPresent) {
|
if (isIndexedDBPresent) {
|
||||||
window.log.info('Found IndexedDB database.');
|
log.info('Found IndexedDB database.');
|
||||||
try {
|
try {
|
||||||
window.log.info('Confirming deletion of old data with user...');
|
log.info('Confirming deletion of old data with user...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
@ -550,7 +548,7 @@ export async function startApp(): Promise<void> {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'User chose not to delete old data. Shutting down.',
|
'User chose not to delete old data. Shutting down.',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -558,17 +556,17 @@ export async function startApp(): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('Deleting all previously-migrated data in SQL...');
|
log.info('Deleting all previously-migrated data in SQL...');
|
||||||
window.log.info('Deleting IndexedDB file...');
|
log.info('Deleting IndexedDB file...');
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
removeIndexedDB(),
|
removeIndexedDB(),
|
||||||
window.Signal.Data.removeAll(),
|
window.Signal.Data.removeAll(),
|
||||||
window.Signal.Data.removeIndexedDBFiles(),
|
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) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Failed to remove IndexedDB file or remove SQL data:',
|
'Failed to remove IndexedDB file or remove SQL data:',
|
||||||
error && error.stack ? error.stack : error
|
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();
|
window.storage.fetch();
|
||||||
|
|
||||||
function mapOldThemeToNew(
|
function mapOldThemeToNew(
|
||||||
|
@ -621,7 +619,7 @@ export async function startApp(): Promise<void> {
|
||||||
// These make key operations available to IPC handlers created in preload.js
|
// These make key operations available to IPC handlers created in preload.js
|
||||||
window.Events = createIPCEvents({
|
window.Events = createIPCEvents({
|
||||||
shutdown: async () => {
|
shutdown: async () => {
|
||||||
window.log.info('background/shutdown');
|
log.info('background/shutdown');
|
||||||
|
|
||||||
window.Signal.Util.flushMessageCounter();
|
window.Signal.Util.flushMessageCounter();
|
||||||
|
|
||||||
|
@ -663,7 +661,7 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
|
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
|
||||||
if (lastHeartbeat > 0 && isOlderThan(lastHeartbeat, THIRTY_DAYS)) {
|
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}.`
|
`This instance has not been used for 30 days. Last heartbeat: ${lastHeartbeat}. Last startup: ${previousLastStartup}.`
|
||||||
);
|
);
|
||||||
await unlinkAndDisconnect(RemoveAllConfiguration.Soft);
|
await unlinkAndDisconnect(RemoveAllConfiguration.Soft);
|
||||||
|
@ -683,13 +681,13 @@ export async function startApp(): Promise<void> {
|
||||||
await window.storage.put('version', currentVersion);
|
await window.storage.put('version', currentVersion);
|
||||||
|
|
||||||
if (newVersion && lastVersion) {
|
if (newVersion && lastVersion) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`New version detected: ${currentVersion}; previous: ${lastVersion}`
|
`New version detected: ${currentVersion}; previous: ${lastVersion}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const remoteBuildExpiration = window.storage.get('remoteBuildExpiration');
|
const remoteBuildExpiration = window.storage.get('remoteBuildExpiration');
|
||||||
if (remoteBuildExpiration) {
|
if (remoteBuildExpiration) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Clearing remoteBuildExpiration. Previous value was ${remoteBuildExpiration}`
|
`Clearing remoteBuildExpiration. Previous value was ${remoteBuildExpiration}`
|
||||||
);
|
);
|
||||||
window.storage.remove('remoteBuildExpiration');
|
window.storage.remove('remoteBuildExpiration');
|
||||||
|
@ -761,7 +759,7 @@ export async function startApp(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await window.Signal.Data.cleanupOrphanedAttachments();
|
await window.Signal.Data.cleanupOrphanedAttachments();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'background: Failed to cleanup orphaned attachments:',
|
'background: Failed to cleanup orphaned attachments:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -775,7 +773,7 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
idleDetector = new IdleDetector();
|
idleDetector = new IdleDetector();
|
||||||
let isMigrationWithIndexComplete = false;
|
let isMigrationWithIndexComplete = false;
|
||||||
window.log.info(
|
log.info(
|
||||||
`Starting background data migration. Target version: ${Message.CURRENT_SCHEMA_VERSION}`
|
`Starting background data migration. Target version: ${Message.CURRENT_SCHEMA_VERSION}`
|
||||||
);
|
);
|
||||||
idleDetector.on('idle', async () => {
|
idleDetector.on('idle', async () => {
|
||||||
|
@ -790,14 +788,12 @@ export async function startApp(): Promise<void> {
|
||||||
window.Signal.Data.getMessagesNeedingUpgrade,
|
window.Signal.Data.getMessagesNeedingUpgrade,
|
||||||
saveMessage: window.Signal.Data.saveMessage,
|
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;
|
isMigrationWithIndexComplete = batchWithIndex.done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMigrationWithIndexComplete) {
|
if (isMigrationWithIndexComplete) {
|
||||||
window.log.info(
|
log.info('Background migration complete. Stopping idle detector.');
|
||||||
'Background migration complete. Stopping idle detector.'
|
|
||||||
);
|
|
||||||
idleDetector.stop();
|
idleDetector.stop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -814,7 +810,7 @@ export async function startApp(): Promise<void> {
|
||||||
'retryReceiptLifeSpan'
|
'retryReceiptLifeSpan'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'Failed to parse integer out of desktop.retryReceiptLifespan feature flag',
|
'Failed to parse integer out of desktop.retryReceiptLifespan feature flag',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -837,7 +833,7 @@ export async function startApp(): Promise<void> {
|
||||||
'retryRespondMaxAge'
|
'retryRespondMaxAge'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'background/setInterval: Failed to parse integer from desktop.retryRespondMaxAge feature flag',
|
'background/setInterval: Failed to parse integer from desktop.retryRespondMaxAge feature flag',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -848,7 +844,7 @@ export async function startApp(): Promise<void> {
|
||||||
now - sentProtoMaxAge
|
now - sentProtoMaxAge
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'background/onready/setInterval: Error deleting sent protos: ',
|
'background/onready/setInterval: Error deleting sent protos: ',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -856,7 +852,7 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const expired = await retryPlaceholders.getExpiredAndRemove();
|
const expired = await retryPlaceholders.getExpiredAndRemove();
|
||||||
window.log.info(
|
log.info(
|
||||||
`retryPlaceholders/interval: Found ${expired.length} expired items`
|
`retryPlaceholders/interval: Found ${expired.length} expired items`
|
||||||
);
|
);
|
||||||
expired.forEach(item => {
|
expired.forEach(item => {
|
||||||
|
@ -878,7 +874,7 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'background/onready/setInterval: Error getting expired retry placeholders: ',
|
'background/onready/setInterval: Error getting expired retry placeholders: ',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -894,7 +890,7 @@ export async function startApp(): Promise<void> {
|
||||||
]);
|
]);
|
||||||
await window.ConversationController.checkForConflicts();
|
await window.ConversationController.checkForConflicts();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'background.js: ConversationController failed to load:',
|
'background.js: ConversationController failed to load:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -1036,7 +1032,7 @@ export async function startApp(): Promise<void> {
|
||||||
name: 'changedConvoBatcher',
|
name: 'changedConvoBatcher',
|
||||||
processBatch(batch) {
|
processBatch(batch) {
|
||||||
const deduped = new Set(batch);
|
const deduped = new Set(batch);
|
||||||
window.log.info(
|
log.info(
|
||||||
'changedConvoBatcher: deduped ' +
|
'changedConvoBatcher: deduped ' +
|
||||||
`${batch.length} into ${deduped.size}`
|
`${batch.length} into ${deduped.size}`
|
||||||
);
|
);
|
||||||
|
@ -1084,7 +1080,7 @@ export async function startApp(): Promise<void> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (reconnect) {
|
if (reconnect) {
|
||||||
window.log.info('background: reconnecting websocket on user change');
|
log.info('background: reconnecting websocket on user change');
|
||||||
enqueueReconnectToWebSocket();
|
enqueueReconnectToWebSocket();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1590,11 +1586,11 @@ export async function startApp(): Promise<void> {
|
||||||
});
|
});
|
||||||
|
|
||||||
window.Whisper.events.on('powerMonitorSuspend', () => {
|
window.Whisper.events.on('powerMonitorSuspend', () => {
|
||||||
window.log.info('powerMonitor: suspend');
|
log.info('powerMonitor: suspend');
|
||||||
});
|
});
|
||||||
|
|
||||||
window.Whisper.events.on('powerMonitorResume', () => {
|
window.Whisper.events.on('powerMonitorResume', () => {
|
||||||
window.log.info('powerMonitor: resume');
|
log.info('powerMonitor: resume');
|
||||||
server?.checkSockets();
|
server?.checkSockets();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1603,14 +1599,14 @@ export async function startApp(): Promise<void> {
|
||||||
const enqueueReconnectToWebSocket = () => {
|
const enqueueReconnectToWebSocket = () => {
|
||||||
reconnectToWebSocketQueue.add(async () => {
|
reconnectToWebSocketQueue.add(async () => {
|
||||||
if (!server) {
|
if (!server) {
|
||||||
window.log.info('reconnectToWebSocket: No server. Early return.');
|
log.info('reconnectToWebSocket: No server. Early return.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('reconnectToWebSocket starting...');
|
log.info('reconnectToWebSocket starting...');
|
||||||
await server.onOffline();
|
await server.onOffline();
|
||||||
await server.onOnline();
|
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();
|
window.Signal.Services.enableStorageService();
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'background/runStorageService: We are primary device; not sending key sync request'
|
'background/runStorageService: We are primary device; not sending key sync request'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -1695,16 +1691,16 @@ export async function startApp(): Promise<void> {
|
||||||
const ourConversation = window.ConversationController.getOurConversation();
|
const ourConversation = window.ConversationController.getOurConversation();
|
||||||
const ourE164 = ourConversation?.get('e164');
|
const ourE164 = ourConversation?.get('e164');
|
||||||
if (ourE164) {
|
if (ourE164) {
|
||||||
window.log.warn('Restoring E164 from our conversation');
|
log.warn('Restoring E164 from our conversation');
|
||||||
window.storage.user.setNumber(ourE164);
|
window.storage.user.setNumber(ourE164);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.dispatchEvent(new Event('storage_ready'));
|
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();
|
const messagesUnexpectedlyMissingExpirationStartTimestamp = await window.Signal.Data.getMessagesUnexpectedlyMissingExpirationStartTimestamp();
|
||||||
window.log.info(
|
log.info(
|
||||||
`Expiration start timestamp cleanup: Found ${messagesUnexpectedlyMissingExpirationStartTimestamp.length} messages for cleanup`
|
`Expiration start timestamp cleanup: Found ${messagesUnexpectedlyMissingExpirationStartTimestamp.length} messages for cleanup`
|
||||||
);
|
);
|
||||||
if (messagesUnexpectedlyMissingExpirationStartTimestamp.length) {
|
if (messagesUnexpectedlyMissingExpirationStartTimestamp.length) {
|
||||||
|
@ -1724,7 +1720,7 @@ export async function startApp(): Promise<void> {
|
||||||
isNotNil
|
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}`
|
`Expiration start timestamp cleanup: starting timer for ${message.type} message sent at ${message.sent_at}. Starting timer at ${message.expirationStartTimestamp}`
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
|
@ -1736,11 +1732,11 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
await window.Signal.Data.saveMessages(newMessageAttributes);
|
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.Whisper.events.on('registration_done', () => {
|
||||||
window.log.info('handling registration event');
|
log.info('handling registration event');
|
||||||
|
|
||||||
strictAssert(server !== undefined, 'WebAPI not ready');
|
strictAssert(server !== undefined, 'WebAPI not ready');
|
||||||
server.authenticate(
|
server.authenticate(
|
||||||
|
@ -1797,7 +1793,7 @@ export async function startApp(): Promise<void> {
|
||||||
await window.Signal.RemoteConfig.maybeRefreshRemoteConfig(server);
|
await window.Signal.RemoteConfig.maybeRefreshRemoteConfig(server);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error && window._.isNumber(error.code)) {
|
if (error && window._.isNumber(error.code)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`registerForActive: Failed to to refresh remote config. Code: ${error.code}`
|
`registerForActive: Failed to to refresh remote config. Code: ${error.code}`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -1876,7 +1872,7 @@ export async function startApp(): Promise<void> {
|
||||||
await window.storage.remove('manifestVersion');
|
await window.storage.remove('manifestVersion');
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'onChange/desktop.storage: We are primary device; not sending key sync request'
|
'onChange/desktop.storage: We are primary device; not sending key sync request'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -1910,7 +1906,7 @@ export async function startApp(): Promise<void> {
|
||||||
let disconnectTimer: NodeJS.Timeout | undefined;
|
let disconnectTimer: NodeJS.Timeout | undefined;
|
||||||
let reconnectTimer: number | undefined;
|
let reconnectTimer: number | undefined;
|
||||||
function onOffline() {
|
function onOffline() {
|
||||||
window.log.info('offline');
|
log.info('offline');
|
||||||
|
|
||||||
window.removeEventListener('offline', onOffline);
|
window.removeEventListener('offline', onOffline);
|
||||||
window.addEventListener('online', onOnline);
|
window.addEventListener('online', onOnline);
|
||||||
|
@ -1926,13 +1922,13 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onOnline() {
|
function onOnline() {
|
||||||
window.log.info('online');
|
log.info('online');
|
||||||
|
|
||||||
window.removeEventListener('online', onOnline);
|
window.removeEventListener('online', onOnline);
|
||||||
window.addEventListener('offline', onOffline);
|
window.addEventListener('offline', onOffline);
|
||||||
|
|
||||||
if (disconnectTimer && isSocketOnline()) {
|
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);
|
clearTimeout(disconnectTimer);
|
||||||
disconnectTimer = undefined;
|
disconnectTimer = undefined;
|
||||||
return;
|
return;
|
||||||
|
@ -1954,7 +1950,7 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function disconnect() {
|
async function disconnect() {
|
||||||
window.log.info('disconnect');
|
log.info('disconnect');
|
||||||
|
|
||||||
// Clear timer, since we're only called when the timer is expired
|
// Clear timer, since we're only called when the timer is expired
|
||||||
disconnectTimer = undefined;
|
disconnectTimer = undefined;
|
||||||
|
@ -1974,7 +1970,7 @@ export async function startApp(): Promise<void> {
|
||||||
let connecting = false;
|
let connecting = false;
|
||||||
async function connect(firstRun?: boolean) {
|
async function connect(firstRun?: boolean) {
|
||||||
if (connecting) {
|
if (connecting) {
|
||||||
window.log.warn('connect already running', { connectCount });
|
log.warn('connect already running', { connectCount });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1983,7 +1979,7 @@ export async function startApp(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
connecting = true;
|
connecting = true;
|
||||||
|
|
||||||
window.log.info('connect', { firstRun, connectCount });
|
log.info('connect', { firstRun, connectCount });
|
||||||
|
|
||||||
if (reconnectTimer) {
|
if (reconnectTimer) {
|
||||||
clearTimeout(reconnectTimer);
|
clearTimeout(reconnectTimer);
|
||||||
|
@ -1995,7 +1991,7 @@ export async function startApp(): Promise<void> {
|
||||||
window.addEventListener('offline', onOffline);
|
window.addEventListener('offline', onOffline);
|
||||||
}
|
}
|
||||||
if (connectCount === 0 && !navigator.onLine) {
|
if (connectCount === 0 && !navigator.onLine) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'Starting up offline; will connect when we have network access'
|
'Starting up offline; will connect when we have network access'
|
||||||
);
|
);
|
||||||
window.addEventListener('online', onOnline);
|
window.addEventListener('online', onOnline);
|
||||||
|
@ -2033,7 +2029,7 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'connect: Error refreshing remote config:',
|
'connect: Error refreshing remote config:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -2056,7 +2052,7 @@ export async function startApp(): Promise<void> {
|
||||||
messaging: window.textsecure.messaging,
|
messaging: window.textsecure.messaging,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'connect: Error fetching UUIDs for lonely e164s:',
|
'connect: Error fetching UUIDs for lonely e164s:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -2085,7 +2081,7 @@ export async function startApp(): Promise<void> {
|
||||||
await server.onOnline();
|
await server.onOnline();
|
||||||
|
|
||||||
AttachmentDownloads.start({
|
AttachmentDownloads.start({
|
||||||
logger: window.log,
|
logger: log,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (connectCount === 1) {
|
if (connectCount === 1) {
|
||||||
|
@ -2103,7 +2099,7 @@ export async function startApp(): Promise<void> {
|
||||||
newVersion &&
|
newVersion &&
|
||||||
window.textsecure.storage.user.getDeviceId() !== 1
|
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();
|
window.getSyncRequest();
|
||||||
|
|
||||||
runStorageService();
|
runStorageService();
|
||||||
|
@ -2115,7 +2111,7 @@ export async function startApp(): Promise<void> {
|
||||||
window.textsecure.storage.user.removeSignalingKey(),
|
window.textsecure.storage.user.removeSignalingKey(),
|
||||||
]);
|
]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Problem with account manager updates after starting new version: ',
|
'Problem with account manager updates after starting new version: ',
|
||||||
e && e.stack ? e.stack : e
|
e && e.stack ? e.stack : e
|
||||||
);
|
);
|
||||||
|
@ -2128,7 +2124,7 @@ export async function startApp(): Promise<void> {
|
||||||
await server.registerSupportForUnauthenticatedDelivery();
|
await server.registerSupportForUnauthenticatedDelivery();
|
||||||
window.storage.put(udSupportKey, true);
|
window.storage.put(udSupportKey, true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Error: Unable to register for unauthenticated delivery support.',
|
'Error: Unable to register for unauthenticated delivery support.',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -2138,7 +2134,7 @@ export async function startApp(): Promise<void> {
|
||||||
const deviceId = window.textsecure.storage.user.getDeviceId();
|
const deviceId = window.textsecure.storage.user.getDeviceId();
|
||||||
|
|
||||||
if (!window.textsecure.storage.user.getUuid()) {
|
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);
|
return unlinkAndDisconnect(RemoveAllConfiguration.Full);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2154,7 +2150,7 @@ export async function startApp(): Promise<void> {
|
||||||
changeNumber: true,
|
changeNumber: true,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Error: Unable to register our capabilities.',
|
'Error: Unable to register our capabilities.',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -2176,13 +2172,13 @@ export async function startApp(): Promise<void> {
|
||||||
const syncRequest = window.getSyncRequest();
|
const syncRequest = window.getSyncRequest();
|
||||||
window.Whisper.events.trigger('contactsync:begin');
|
window.Whisper.events.trigger('contactsync:begin');
|
||||||
syncRequest.addEventListener('success', () => {
|
syncRequest.addEventListener('success', () => {
|
||||||
window.log.info('sync successful');
|
log.info('sync successful');
|
||||||
window.storage.put('synced_at', Date.now());
|
window.storage.put('synced_at', Date.now());
|
||||||
window.Whisper.events.trigger('contactsync');
|
window.Whisper.events.trigger('contactsync');
|
||||||
runStorageService();
|
runStorageService();
|
||||||
});
|
});
|
||||||
syncRequest.addEventListener('timeout', () => {
|
syncRequest.addEventListener('timeout', () => {
|
||||||
window.log.error('sync timed out');
|
log.error('sync timed out');
|
||||||
window.Whisper.events.trigger('contactsync');
|
window.Whisper.events.trigger('contactsync');
|
||||||
runStorageService();
|
runStorageService();
|
||||||
});
|
});
|
||||||
|
@ -2201,7 +2197,7 @@ export async function startApp(): Promise<void> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'background/connect: We are primary device; not sending sticker pack sync'
|
'background/connect: We are primary device; not sending sticker pack sync'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -2214,7 +2210,7 @@ export async function startApp(): Promise<void> {
|
||||||
),
|
),
|
||||||
{ messageIds: [], sendType: 'otherSync' }
|
{ messageIds: [], sendType: 'otherSync' }
|
||||||
).catch(error => {
|
).catch(error => {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Failed to send installed sticker packs via sync message',
|
'Failed to send installed sticker packs via sync message',
|
||||||
error && error.stack ? error.stack : error
|
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.
|
// a given conversation's queue. But we have processed all events from the websocket.
|
||||||
async function waitForEmptyEventQueue() {
|
async function waitForEmptyEventQueue() {
|
||||||
if (!messageReceiver) {
|
if (!messageReceiver) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'waitForEmptyEventQueue: No messageReceiver available, returning early'
|
'waitForEmptyEventQueue: No messageReceiver available, returning early'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!messageReceiver.hasEmptied()) {
|
if (!messageReceiver.hasEmptied()) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'waitForEmptyEventQueue: Waiting for MessageReceiver empty event...'
|
'waitForEmptyEventQueue: Waiting for MessageReceiver empty event...'
|
||||||
);
|
);
|
||||||
let resolve: undefined | (() => void);
|
let resolve: undefined | (() => void);
|
||||||
|
@ -2295,9 +2291,7 @@ export async function startApp(): Promise<void> {
|
||||||
await promise;
|
await promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info('waitForEmptyEventQueue: Waiting for event handler queue idle...');
|
||||||
'waitForEmptyEventQueue: Waiting for event handler queue idle...'
|
|
||||||
);
|
|
||||||
await eventHandlerQueue.onIdle();
|
await eventHandlerQueue.onIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2308,7 +2302,7 @@ export async function startApp(): Promise<void> {
|
||||||
window.waitForAllBatchers(),
|
window.waitForAllBatchers(),
|
||||||
window.flushAllWaitBatchers(),
|
window.flushAllWaitBatchers(),
|
||||||
]);
|
]);
|
||||||
window.log.info('onEmpty: All outstanding database requests complete');
|
log.info('onEmpty: All outstanding database requests complete');
|
||||||
window.readyForUpdates();
|
window.readyForUpdates();
|
||||||
|
|
||||||
// Start listeners here, after we get through our queue.
|
// Start listeners here, after we get through our queue.
|
||||||
|
@ -2333,10 +2327,7 @@ export async function startApp(): Promise<void> {
|
||||||
processedCount: messageReceiver && messageReceiver.getProcessedCount(),
|
processedCount: messageReceiver && messageReceiver.getProcessedCount(),
|
||||||
});
|
});
|
||||||
if (messageReceiver) {
|
if (messageReceiver) {
|
||||||
window.log.info(
|
log.info('App loaded - messages:', messageReceiver.getProcessedCount());
|
||||||
'App loaded - messages:',
|
|
||||||
messageReceiver.getProcessedCount()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.Signal.Util.setBatchingStrategy(false);
|
window.Signal.Util.setBatchingStrategy(false);
|
||||||
|
@ -2359,7 +2350,7 @@ export async function startApp(): Promise<void> {
|
||||||
// to display the message properly.
|
// to display the message properly.
|
||||||
message.hasRequiredAttachmentDownloads()
|
message.hasRequiredAttachmentDownloads()
|
||||||
);
|
);
|
||||||
window.log.info(
|
log.info(
|
||||||
'Downloading recent attachments of total attachments',
|
'Downloading recent attachments of total attachments',
|
||||||
attachmentsToDownload.length,
|
attachmentsToDownload.length,
|
||||||
attachmentDownloadQueue.length
|
attachmentDownloadQueue.length
|
||||||
|
@ -2403,9 +2394,7 @@ export async function startApp(): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(`incrementProgress: Message count is ${initialStartupCount}`);
|
||||||
`incrementProgress: Message count is ${initialStartupCount}`
|
|
||||||
);
|
|
||||||
|
|
||||||
window.Whisper.events.trigger('loadingProgress', initialStartupCount);
|
window.Whisper.events.trigger('loadingProgress', initialStartupCount);
|
||||||
}
|
}
|
||||||
|
@ -2413,11 +2402,11 @@ export async function startApp(): Promise<void> {
|
||||||
window.Whisper.events.on('manualConnect', manualConnect);
|
window.Whisper.events.on('manualConnect', manualConnect);
|
||||||
function manualConnect() {
|
function manualConnect() {
|
||||||
if (isSocketOnline()) {
|
if (isSocketOnline()) {
|
||||||
window.log.info('manualConnect: already online; not connecting again');
|
log.info('manualConnect: already online; not connecting again');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('manualConnect: calling connect()');
|
log.info('manualConnect: calling connect()');
|
||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2486,15 +2475,15 @@ export async function startApp(): Promise<void> {
|
||||||
const ourId = window.ConversationController.getOurConversationId();
|
const ourId = window.ConversationController.getOurConversationId();
|
||||||
|
|
||||||
if (!senderId) {
|
if (!senderId) {
|
||||||
window.log.warn('onTyping: ensureContactIds returned falsey senderId!');
|
log.warn('onTyping: ensureContactIds returned falsey senderId!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ourId) {
|
if (!ourId) {
|
||||||
window.log.warn("onTyping: Couldn't get our own id!");
|
log.warn("onTyping: Couldn't get our own id!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`onTyping: Did not find conversation for typing indicator (groupv2(${groupV2Id}), group(${groupId}), ${sender}, ${senderUuid})`
|
`onTyping: Did not find conversation for typing indicator (groupv2(${groupV2Id}), group(${groupId}), ${sender}, ${senderUuid})`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -2505,7 +2494,7 @@ export async function startApp(): Promise<void> {
|
||||||
!isDirectConversation(conversation.attributes) &&
|
!isDirectConversation(conversation.attributes) &&
|
||||||
!conversation.hasMember(ourId)
|
!conversation.hasMember(ourId)
|
||||||
) {
|
) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`Received typing indicator for group ${conversation.idForLogging()}, which we're not a part of. Dropping.`
|
`Received typing indicator for group ${conversation.idForLogging()}, which we're not a part of. Dropping.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -2528,9 +2517,7 @@ export async function startApp(): Promise<void> {
|
||||||
const { id, key, isInstall, isRemove } = pack || {};
|
const { id, key, isInstall, isRemove } = pack || {};
|
||||||
|
|
||||||
if (!id || !key || (!isInstall && !isRemove)) {
|
if (!id || !key || (!isInstall && !isRemove)) {
|
||||||
window.log.warn(
|
log.warn('Received malformed sticker pack operation sync message');
|
||||||
'Received malformed sticker pack operation sync message'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2556,7 +2543,7 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onContactSyncComplete() {
|
async function onContactSyncComplete() {
|
||||||
window.log.info('onContactSyncComplete');
|
log.info('onContactSyncComplete');
|
||||||
await window.storage.put('synced_at', Date.now());
|
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
|
// special case for syncing details about ourselves
|
||||||
if (details.profileKey) {
|
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));
|
ourProfileKeyService.set(typedArrayToArrayBuffer(details.profileKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2583,7 +2570,7 @@ export async function startApp(): Promise<void> {
|
||||||
} as Partial<ConversationAttributesType>) as WhatIsThis);
|
} as Partial<ConversationAttributesType>) as WhatIsThis);
|
||||||
const validationError = c.validate();
|
const validationError = c.validate();
|
||||||
if (validationError) {
|
if (validationError) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Invalid contact received:',
|
'Invalid contact received:',
|
||||||
Errors.toLogFormat(validationError)
|
Errors.toLogFormat(validationError)
|
||||||
);
|
);
|
||||||
|
@ -2674,18 +2661,18 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.Signal.Util.postLinkExperience.isActive()) {
|
if (window.Signal.Util.postLinkExperience.isActive()) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'onContactReceived: Adding the message history disclaimer on link'
|
'onContactReceived: Adding the message history disclaimer on link'
|
||||||
);
|
);
|
||||||
await conversation.addMessageHistoryDisclaimer();
|
await conversation.addMessageHistoryDisclaimer();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error('onContactReceived error:', Errors.toLogFormat(error));
|
log.error('onContactReceived error:', Errors.toLogFormat(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onGroupSyncComplete() {
|
async function onGroupSyncComplete() {
|
||||||
window.log.info('onGroupSyncComplete');
|
log.info('onGroupSyncComplete');
|
||||||
await window.storage.put('synced_at', Date.now());
|
await window.storage.put('synced_at', Date.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2699,10 +2686,7 @@ export async function startApp(): Promise<void> {
|
||||||
'group'
|
'group'
|
||||||
);
|
);
|
||||||
if (isGroupV2(conversation.attributes)) {
|
if (isGroupV2(conversation.attributes)) {
|
||||||
window.log.warn(
|
log.warn('Got group sync for v2 group: ', conversation.idForLogging());
|
||||||
'Got group sync for v2 group: ',
|
|
||||||
conversation.idForLogging()
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2751,7 +2735,7 @@ export async function startApp(): Promise<void> {
|
||||||
window.Signal.Data.updateConversation(conversation.attributes);
|
window.Signal.Data.updateConversation(conversation.attributes);
|
||||||
|
|
||||||
if (window.Signal.Util.postLinkExperience.isActive()) {
|
if (window.Signal.Util.postLinkExperience.isActive()) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'onGroupReceived: Adding the message history disclaimer on link'
|
'onGroupReceived: Adding the message history disclaimer on link'
|
||||||
);
|
);
|
||||||
await conversation.addMessageHistoryDisclaimer();
|
await conversation.addMessageHistoryDisclaimer();
|
||||||
|
@ -2808,10 +2792,7 @@ export async function startApp(): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error('respondWithProfileKeyBatcher error', error && error.stack);
|
||||||
'respondWithProfileKeyBatcher error',
|
|
||||||
error && error.stack
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.queueJob('sendProfileKeyUpdate', () =>
|
sender.queueJob('sendProfileKeyUpdate', () =>
|
||||||
|
@ -2889,15 +2870,12 @@ export async function startApp(): Promise<void> {
|
||||||
const { reaction } = data.message;
|
const { reaction } = data.message;
|
||||||
|
|
||||||
if (!isValidReactionEmoji(reaction.emoji)) {
|
if (!isValidReactionEmoji(reaction.emoji)) {
|
||||||
window.log.warn('Received an invalid reaction emoji. Dropping it');
|
log.warn('Received an invalid reaction emoji. Dropping it');
|
||||||
confirm();
|
confirm();
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info('Queuing incoming reaction for', reaction.targetTimestamp);
|
||||||
'Queuing incoming reaction for',
|
|
||||||
reaction.targetTimestamp
|
|
||||||
);
|
|
||||||
const reactionModel = Reactions.getSingleton().add({
|
const reactionModel = Reactions.getSingleton().add({
|
||||||
emoji: reaction.emoji,
|
emoji: reaction.emoji,
|
||||||
remove: reaction.remove,
|
remove: reaction.remove,
|
||||||
|
@ -2917,7 +2895,7 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
if (data.message.delete) {
|
if (data.message.delete) {
|
||||||
const { delete: del } = data.message;
|
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({
|
const deleteModel = Deletes.getSingleton().add({
|
||||||
targetSentTimestamp: del.targetSentTimestamp,
|
targetSentTimestamp: del.targetSentTimestamp,
|
||||||
serverTimestamp: data.serverTimestamp,
|
serverTimestamp: data.serverTimestamp,
|
||||||
|
@ -2951,7 +2929,7 @@ export async function startApp(): Promise<void> {
|
||||||
const conversation = window.ConversationController.get(conversationId);
|
const conversation = window.ConversationController.get(conversationId);
|
||||||
|
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'onProfileKeyUpdate: could not find conversation',
|
'onProfileKeyUpdate: could not find conversation',
|
||||||
data.source,
|
data.source,
|
||||||
data.sourceUuid
|
data.sourceUuid
|
||||||
|
@ -2961,15 +2939,12 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.profileKey) {
|
if (!data.profileKey) {
|
||||||
window.log.error(
|
log.error('onProfileKeyUpdate: missing profileKey', data.profileKey);
|
||||||
'onProfileKeyUpdate: missing profileKey',
|
|
||||||
data.profileKey
|
|
||||||
);
|
|
||||||
confirm();
|
confirm();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'onProfileKeyUpdate: updating profileKey',
|
'onProfileKeyUpdate: updating profileKey',
|
||||||
data.source,
|
data.source,
|
||||||
data.sourceUuid
|
data.sourceUuid
|
||||||
|
@ -3139,7 +3114,7 @@ export async function startApp(): Promise<void> {
|
||||||
throw new Error('getMessageDescriptor: GroupV1 data was missing id');
|
throw new Error('getMessageDescriptor: GroupV1 data was missing id');
|
||||||
}
|
}
|
||||||
if (!derivedGroupV2Id) {
|
if (!derivedGroupV2Id) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'getMessageDescriptor: GroupV1 data was missing derivedGroupV2Id'
|
'getMessageDescriptor: GroupV1 data was missing derivedGroupV2Id'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3233,12 +3208,12 @@ export async function startApp(): Promise<void> {
|
||||||
const { reaction } = data.message;
|
const { reaction } = data.message;
|
||||||
|
|
||||||
if (!isValidReactionEmoji(reaction.emoji)) {
|
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();
|
event.confirm();
|
||||||
return Promise.resolve();
|
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({
|
const reactionModel = Reactions.getSingleton().add({
|
||||||
emoji: reaction.emoji,
|
emoji: reaction.emoji,
|
||||||
remove: reaction.remove,
|
remove: reaction.remove,
|
||||||
|
@ -3257,7 +3232,7 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
if (data.message.delete) {
|
if (data.message.delete) {
|
||||||
const { delete: del } = data.message;
|
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({
|
const deleteModel = Deletes.getSingleton().add({
|
||||||
targetSentTimestamp: del.targetSentTimestamp,
|
targetSentTimestamp: del.targetSentTimestamp,
|
||||||
serverTimestamp: data.serverTimestamp,
|
serverTimestamp: data.serverTimestamp,
|
||||||
|
@ -3324,7 +3299,7 @@ export async function startApp(): Promise<void> {
|
||||||
});
|
});
|
||||||
return true;
|
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.'
|
'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> {
|
): Promise<void> {
|
||||||
window.Whisper.events.trigger('unauthorized');
|
window.Whisper.events.trigger('unauthorized');
|
||||||
|
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'unlinkAndDisconnect: Client is no longer authorized; ' +
|
'unlinkAndDisconnect: Client is no longer authorized; ' +
|
||||||
'deleting local configuration'
|
'deleting local configuration'
|
||||||
);
|
);
|
||||||
|
|
||||||
if (messageReceiver) {
|
if (messageReceiver) {
|
||||||
window.log.info('unlinkAndDisconnect: logging out');
|
log.info('unlinkAndDisconnect: logging out');
|
||||||
strictAssert(server !== undefined, 'WebAPI not initialized');
|
strictAssert(server !== undefined, 'WebAPI not initialized');
|
||||||
server.unregisterRequestHandler(messageReceiver);
|
server.unregisterRequestHandler(messageReceiver);
|
||||||
messageReceiver.stopProcessing();
|
messageReceiver.stopProcessing();
|
||||||
|
@ -3371,7 +3346,7 @@ export async function startApp(): Promise<void> {
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
window.log.info('unlinkAndDisconnect: removing configuration');
|
log.info('unlinkAndDisconnect: removing configuration');
|
||||||
await window.textsecure.storage.protocol.removeAllConfiguration(mode);
|
await window.textsecure.storage.protocol.removeAllConfiguration(mode);
|
||||||
|
|
||||||
// This was already done in the database with removeAllConfiguration; this does it
|
// 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());
|
await window.textsecure.storage.put(VERSION_KEY, window.getVersion());
|
||||||
|
|
||||||
window.log.info(
|
log.info('unlinkAndDisconnect: Successfully cleared local configuration');
|
||||||
'unlinkAndDisconnect: Successfully cleared local configuration'
|
|
||||||
);
|
|
||||||
} catch (eraseError) {
|
} catch (eraseError) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'unlinkAndDisconnect: Something went wrong clearing ' +
|
'unlinkAndDisconnect: Something went wrong clearing ' +
|
||||||
'local configuration',
|
'local configuration',
|
||||||
eraseError && eraseError.stack ? eraseError.stack : eraseError
|
eraseError && eraseError.stack ? eraseError.stack : eraseError
|
||||||
|
@ -3422,7 +3395,7 @@ export async function startApp(): Promise<void> {
|
||||||
|
|
||||||
function onError(ev: ErrorEvent) {
|
function onError(ev: ErrorEvent) {
|
||||||
const { error } = ev;
|
const { error } = ev;
|
||||||
window.log.error('background onError:', Errors.toLogFormat(error));
|
log.error('background onError:', Errors.toLogFormat(error));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
error &&
|
error &&
|
||||||
|
@ -3442,7 +3415,7 @@ export async function startApp(): Promise<void> {
|
||||||
if (navigator.onLine) {
|
if (navigator.onLine) {
|
||||||
const timeout = reconnectBackOff.getAndIncrement();
|
const timeout = reconnectBackOff.getAndIncrement();
|
||||||
|
|
||||||
window.log.info(`retrying in ${timeout}ms`);
|
log.info(`retrying in ${timeout}ms`);
|
||||||
reconnectTimer = setTimeout(connect, timeout);
|
reconnectTimer = setTimeout(connect, timeout);
|
||||||
|
|
||||||
window.Whisper.events.trigger('reconnectTimer');
|
window.Whisper.events.trigger('reconnectTimer');
|
||||||
|
@ -3454,14 +3427,14 @@ export async function startApp(): Promise<void> {
|
||||||
return;
|
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) {
|
async function onViewOnceOpenSync(ev: ViewOnceOpenSyncEvent) {
|
||||||
ev.confirm();
|
ev.confirm();
|
||||||
|
|
||||||
const { source, sourceUuid, timestamp } = ev;
|
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({
|
const sync = ViewOnceOpenSyncs.getSingleton().add({
|
||||||
source,
|
source,
|
||||||
|
@ -3487,13 +3460,11 @@ export async function startApp(): Promise<void> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FETCH_LATEST_ENUM.STORAGE_MANIFEST:
|
case FETCH_LATEST_ENUM.STORAGE_MANIFEST:
|
||||||
window.log.info('onFetchLatestSync: fetching latest manifest');
|
log.info('onFetchLatestSync: fetching latest manifest');
|
||||||
await window.Signal.Services.runStorageServiceSyncJob();
|
await window.Signal.Services.runStorageServiceSyncJob();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
window.log.info(
|
log.info(`onFetchLatestSync: Unknown type encountered ${eventType}`);
|
||||||
`onFetchLatestSync: Unknown type encountered ${eventType}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3503,12 +3474,12 @@ export async function startApp(): Promise<void> {
|
||||||
const { storageServiceKey } = ev;
|
const { storageServiceKey } = ev;
|
||||||
|
|
||||||
if (storageServiceKey === null) {
|
if (storageServiceKey === null) {
|
||||||
window.log.info('onKeysSync: deleting window.storageKey');
|
log.info('onKeysSync: deleting window.storageKey');
|
||||||
window.storage.remove('storageKey');
|
window.storage.remove('storageKey');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storageServiceKey) {
|
if (storageServiceKey) {
|
||||||
window.log.info('onKeysSync: received keys');
|
log.info('onKeysSync: received keys');
|
||||||
const storageServiceKeyBase64 = window.Signal.Crypto.arrayBufferToBase64(
|
const storageServiceKeyBase64 = window.Signal.Crypto.arrayBufferToBase64(
|
||||||
storageServiceKey
|
storageServiceKey
|
||||||
);
|
);
|
||||||
|
@ -3529,7 +3500,7 @@ export async function startApp(): Promise<void> {
|
||||||
messageRequestResponseType,
|
messageRequestResponseType,
|
||||||
} = ev;
|
} = ev;
|
||||||
|
|
||||||
window.log.info('onMessageRequestResponse', {
|
log.info('onMessageRequestResponse', {
|
||||||
threadE164,
|
threadE164,
|
||||||
threadUuid,
|
threadUuid,
|
||||||
groupId: `group(${groupId})`,
|
groupId: `group(${groupId})`,
|
||||||
|
@ -3587,7 +3558,7 @@ export async function startApp(): Promise<void> {
|
||||||
highTrust: true,
|
highTrust: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
window.log.info(
|
log.info(
|
||||||
logTitle,
|
logTitle,
|
||||||
source,
|
source,
|
||||||
sourceUuid,
|
sourceUuid,
|
||||||
|
@ -3624,7 +3595,7 @@ export async function startApp(): Promise<void> {
|
||||||
uuid: senderUuid,
|
uuid: senderUuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'read sync',
|
'read sync',
|
||||||
sender,
|
sender,
|
||||||
senderUuid,
|
senderUuid,
|
||||||
|
@ -3656,7 +3627,7 @@ export async function startApp(): Promise<void> {
|
||||||
uuid: senderUuid,
|
uuid: senderUuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'view sync',
|
'view sync',
|
||||||
senderE164,
|
senderE164,
|
||||||
senderUuid,
|
senderUuid,
|
||||||
|
@ -3698,7 +3669,7 @@ export async function startApp(): Promise<void> {
|
||||||
} as Partial<ConversationAttributesType>) as WhatIsThis);
|
} as Partial<ConversationAttributesType>) as WhatIsThis);
|
||||||
const error = c.validate();
|
const error = c.validate();
|
||||||
if (error) {
|
if (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Invalid verified sync received:',
|
'Invalid verified sync received:',
|
||||||
e164,
|
e164,
|
||||||
uuid,
|
uuid,
|
||||||
|
@ -3718,10 +3689,10 @@ export async function startApp(): Promise<void> {
|
||||||
state = 'UNVERIFIED';
|
state = 'UNVERIFIED';
|
||||||
break;
|
break;
|
||||||
default:
|
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',
|
'got verified sync for',
|
||||||
e164,
|
e164,
|
||||||
uuid,
|
uuid,
|
||||||
|
@ -3771,7 +3742,7 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'delivery receipt from',
|
'delivery receipt from',
|
||||||
source,
|
source,
|
||||||
sourceUuid,
|
sourceUuid,
|
||||||
|
@ -3783,7 +3754,7 @@ export async function startApp(): Promise<void> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!sourceConversationId) {
|
if (!sourceConversationId) {
|
||||||
window.log.info('no conversation for', source, sourceUuid);
|
log.info('no conversation for', source, sourceUuid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { isOlderThan } from './util/timestamp';
|
||||||
import { parseRetryAfter } from './util/parseRetryAfter';
|
import { parseRetryAfter } from './util/parseRetryAfter';
|
||||||
import { getEnvironment, Environment } from './environment';
|
import { getEnvironment, Environment } from './environment';
|
||||||
import { StorageInterface } from './types/Storage.d';
|
import { StorageInterface } from './types/Storage.d';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
export type ChallengeResponse = {
|
export type ChallengeResponse = {
|
||||||
readonly captcha: string;
|
readonly captcha: string;
|
||||||
|
@ -143,7 +144,7 @@ export class ChallengeHandler {
|
||||||
const stored: ReadonlyArray<StoredEntity> =
|
const stored: ReadonlyArray<StoredEntity> =
|
||||||
this.options.storage.get('challenge:retry-message-ids') || [];
|
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>();
|
const entityMap = new Map<string, StoredEntity>();
|
||||||
for (const entity of stored) {
|
for (const entity of stored) {
|
||||||
|
@ -162,13 +163,13 @@ export class ChallengeHandler {
|
||||||
|
|
||||||
const messages: Array<MinimalMessage> = maybeMessages.filter(isNotNil);
|
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(
|
await Promise.all(
|
||||||
messages.map(async message => {
|
messages.map(async message => {
|
||||||
const entity = entityMap.get(message.id);
|
const entity = entityMap.get(message.id);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'challenge: unexpected missing entity ' +
|
'challenge: unexpected missing entity ' +
|
||||||
`for ${message.idForLogging()}`
|
`for ${message.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
@ -177,9 +178,7 @@ export class ChallengeHandler {
|
||||||
|
|
||||||
const expireAfter = this.options.expireAfter || DEFAULT_EXPIRE_AFTER;
|
const expireAfter = this.options.expireAfter || DEFAULT_EXPIRE_AFTER;
|
||||||
if (isOlderThan(entity.createdAt, expireAfter)) {
|
if (isOlderThan(entity.createdAt, expireAfter)) {
|
||||||
window.log.info(
|
log.info(`challenge: expired entity for ${message.idForLogging()}`);
|
||||||
`challenge: expired entity for ${message.idForLogging()}`
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +197,7 @@ export class ChallengeHandler {
|
||||||
public async onOffline(): Promise<void> {
|
public async onOffline(): Promise<void> {
|
||||||
this.isOnline = false;
|
this.isOnline = false;
|
||||||
|
|
||||||
window.log.info('challenge: offline');
|
log.info('challenge: offline');
|
||||||
}
|
}
|
||||||
|
|
||||||
public async onOnline(): Promise<void> {
|
public async onOnline(): Promise<void> {
|
||||||
|
@ -207,7 +206,7 @@ export class ChallengeHandler {
|
||||||
const pending = Array.from(this.pendingRetries.values());
|
const pending = Array.from(this.pendingRetries.values());
|
||||||
this.pendingRetries.clear();
|
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
|
// Retry messages that matured while we were offline
|
||||||
await Promise.all(pending.map(message => this.retryOne(message)));
|
await Promise.all(pending.map(message => this.retryOne(message)));
|
||||||
|
@ -221,7 +220,7 @@ export class ChallengeHandler {
|
||||||
entity?: StoredEntity
|
entity?: StoredEntity
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (this.isRegistered(message)) {
|
if (this.isRegistered(message)) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`challenge: message already registered ${message.idForLogging()}`
|
`challenge: message already registered ${message.idForLogging()}`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -235,7 +234,7 @@ export class ChallengeHandler {
|
||||||
|
|
||||||
// Message is already retryable - initiate new send
|
// Message is already retryable - initiate new send
|
||||||
if (retry === RetryMode.Retry && shouldRetrySend(message)) {
|
if (retry === RetryMode.Retry && shouldRetrySend(message)) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`challenge: sending message immediately ${message.idForLogging()}`
|
`challenge: sending message immediately ${message.idForLogging()}`
|
||||||
);
|
);
|
||||||
await this.retryOne(message);
|
await this.retryOne(message);
|
||||||
|
@ -244,7 +243,7 @@ export class ChallengeHandler {
|
||||||
|
|
||||||
const error = message.getLastChallengeError();
|
const error = message.getLastChallengeError();
|
||||||
if (!error) {
|
if (!error) {
|
||||||
window.log.error('Unexpected message without challenge error');
|
log.error('Unexpected message without challenge error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,19 +261,19 @@ export class ChallengeHandler {
|
||||||
}, waitTime)
|
}, waitTime)
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`challenge: tracking ${message.idForLogging()} ` +
|
`challenge: tracking ${message.idForLogging()} ` +
|
||||||
`with waitTime=${waitTime}`
|
`with waitTime=${waitTime}`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!error.data.options || !error.data.options.includes('recaptcha')) {
|
if (!error.data.options || !error.data.options.includes('recaptcha')) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`challenge: unexpected options ${JSON.stringify(error.data.options)}`
|
`challenge: unexpected options ${JSON.stringify(error.data.options)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error.data.token) {
|
if (!error.data.token) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`challenge: no token in challenge error ${JSON.stringify(error.data)}`
|
`challenge: no token in challenge error ${JSON.stringify(error.data)}`
|
||||||
);
|
);
|
||||||
} else if (message.isNormalBubble()) {
|
} else if (message.isNormalBubble()) {
|
||||||
|
@ -285,9 +284,7 @@ export class ChallengeHandler {
|
||||||
// challenge to be fully completed.
|
// challenge to be fully completed.
|
||||||
this.solve(error.data.token);
|
this.solve(error.data.token);
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info(`challenge: not a bubble message ${message.idForLogging()}`);
|
||||||
`challenge: not a bubble message ${message.idForLogging()}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +299,7 @@ export class ChallengeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async unregister(message: MinimalMessage): Promise<void> {
|
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.trackedMessages.delete(message.id);
|
||||||
this.pendingRetries.delete(message);
|
this.pendingRetries.delete(message);
|
||||||
|
|
||||||
|
@ -335,7 +332,7 @@ export class ChallengeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async retrySend(force = false): Promise<void> {
|
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())
|
const retries = Array.from(this.trackedMessages.values())
|
||||||
.map(({ message }) => message)
|
.map(({ message }) => message)
|
||||||
|
@ -360,13 +357,13 @@ export class ChallengeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
const retryCount = this.retryCountById.get(message.id) || 0;
|
const retryCount = this.retryCountById.get(message.id) || 0;
|
||||||
window.log.info(
|
log.info(
|
||||||
`challenge: retrying sending ${message.idForLogging()}, ` +
|
`challenge: retrying sending ${message.idForLogging()}, ` +
|
||||||
`retry count: ${retryCount}`
|
`retry count: ${retryCount}`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (retryCount === MAX_RETRIES) {
|
if (retryCount === MAX_RETRIES) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`challenge: dropping message ${message.idForLogging()}, ` +
|
`challenge: dropping message ${message.idForLogging()}, ` +
|
||||||
'too many failed retries'
|
'too many failed retries'
|
||||||
);
|
);
|
||||||
|
@ -387,7 +384,7 @@ export class ChallengeHandler {
|
||||||
try {
|
try {
|
||||||
await message.retrySend();
|
await message.retrySend();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`challenge: failed to send ${message.idForLogging()} due to ` +
|
`challenge: failed to send ${message.idForLogging()} due to ` +
|
||||||
`error: ${error && error.stack}`
|
`error: ${error && error.stack}`
|
||||||
);
|
);
|
||||||
|
@ -396,13 +393,13 @@ export class ChallengeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sent) {
|
if (sent) {
|
||||||
window.log.info(`challenge: message ${message.idForLogging()} sent`);
|
log.info(`challenge: message ${message.idForLogging()} sent`);
|
||||||
this.retryCountById.delete(message.id);
|
this.retryCountById.delete(message.id);
|
||||||
if (this.trackedMessages.size === 0) {
|
if (this.trackedMessages.size === 0) {
|
||||||
this.options.setChallengeStatus('idle');
|
this.options.setChallengeStatus('idle');
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
this.retryCountById.set(message.id, retryCount + 1);
|
||||||
await this.register(message, RetryMode.NoImmediateRetry);
|
await this.register(message, RetryMode.NoImmediateRetry);
|
||||||
|
@ -431,7 +428,7 @@ export class ChallengeHandler {
|
||||||
|
|
||||||
this.options.setChallengeStatus('pending');
|
this.options.setChallengeStatus('pending');
|
||||||
|
|
||||||
window.log.info('challenge: sending challenge to server');
|
log.info('challenge: sending challenge to server');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.sendChallengeResponse({
|
await this.sendChallengeResponse({
|
||||||
|
@ -440,14 +437,12 @@ export class ChallengeHandler {
|
||||||
captcha: response.captcha,
|
captcha: response.captcha,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(`challenge: challenge failure, error: ${error && error.stack}`);
|
||||||
`challenge: challenge failure, error: ${error && error.stack}`
|
|
||||||
);
|
|
||||||
this.options.setChallengeStatus('required');
|
this.options.setChallengeStatus('required');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('challenge: challenge success. force sending');
|
log.info('challenge: challenge success. force sending');
|
||||||
|
|
||||||
this.options.setChallengeStatus('idle');
|
this.options.setChallengeStatus('idle');
|
||||||
|
|
||||||
|
@ -470,7 +465,7 @@ export class ChallengeHandler {
|
||||||
|
|
||||||
const retryAfter = parseRetryAfter(error.responseHeaders['retry-after']);
|
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);
|
this.options.onChallengeFailed(retryAfter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import {
|
||||||
import { SignalClipboard } from '../quill/signal-clipboard';
|
import { SignalClipboard } from '../quill/signal-clipboard';
|
||||||
import { DirectionalBlot } from '../quill/block/blot';
|
import { DirectionalBlot } from '../quill/block/blot';
|
||||||
import { getClassNamesFor } from '../util/getClassNamesFor';
|
import { getClassNamesFor } from '../util/getClassNamesFor';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
Quill.register('formats/emoji', EmojiBlot);
|
Quill.register('formats/emoji', EmojiBlot);
|
||||||
Quill.register('formats/mention', MentionBlot);
|
Quill.register('formats/mention', MentionBlot);
|
||||||
|
@ -231,7 +232,7 @@ export function CompositionInput(props: Props): React.ReactElement {
|
||||||
|
|
||||||
const [text, mentions] = getTextAndMentions();
|
const [text, mentions] = getTextAndMentions();
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`CompositionInput: Submitting message ${timestamp} with ${mentions.length} mentions`
|
`CompositionInput: Submitting message ${timestamp} with ${mentions.length} mentions`
|
||||||
);
|
);
|
||||||
onSubmit(text, mentions, timestamp);
|
onSubmit(text, mentions, timestamp);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import PQueue from 'p-queue';
|
||||||
import LRU from 'lru-cache';
|
import LRU from 'lru-cache';
|
||||||
|
|
||||||
import { WaveformCache } from '../types/Audio';
|
import { WaveformCache } from '../types/Audio';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
const MAX_WAVEFORM_COUNT = 1000;
|
const MAX_WAVEFORM_COUNT = 1000;
|
||||||
const MAX_PARALLEL_COMPUTE = 8;
|
const MAX_PARALLEL_COMPUTE = 8;
|
||||||
|
@ -84,11 +85,11 @@ async function doComputePeaks(
|
||||||
): Promise<ComputePeaksResult> {
|
): Promise<ComputePeaksResult> {
|
||||||
const existing = waveformCache.get(url);
|
const existing = waveformCache.get(url);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
window.log.info('GlobalAudioContext: waveform cache hit', url);
|
log.info('GlobalAudioContext: waveform cache hit', url);
|
||||||
return Promise.resolve(existing);
|
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
|
// Load and decode `url` into a raw PCM
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
|
@ -98,7 +99,7 @@ async function doComputePeaks(
|
||||||
|
|
||||||
const peaks = new Array(barCount).fill(0);
|
const peaks = new Array(barCount).fill(0);
|
||||||
if (duration > MAX_AUDIO_DURATION) {
|
if (duration > MAX_AUDIO_DURATION) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`GlobalAudioContext: audio ${url} duration ${duration}s is too long`
|
`GlobalAudioContext: audio ${url} duration ${duration}s is too long`
|
||||||
);
|
);
|
||||||
const emptyResult = { peaks, duration };
|
const emptyResult = { peaks, duration };
|
||||||
|
@ -151,14 +152,11 @@ export async function computePeaks(
|
||||||
|
|
||||||
const pending = inProgressMap.get(computeKey);
|
const pending = inProgressMap.get(computeKey);
|
||||||
if (pending) {
|
if (pending) {
|
||||||
window.log.info(
|
log.info('GlobalAudioContext: already computing peaks for', computeKey);
|
||||||
'GlobalAudioContext: already computing peaks for',
|
|
||||||
computeKey
|
|
||||||
);
|
|
||||||
return pending;
|
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));
|
const promise = computeQueue.add(() => doComputePeaks(url, barCount));
|
||||||
|
|
||||||
inProgressMap.set(computeKey, promise);
|
inProgressMap.set(computeKey, promise);
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { useGetCallingFrameBuffer } from '../calling/useGetCallingFrameBuffer';
|
||||||
import { LocalizerType } from '../types/Util';
|
import { LocalizerType } from '../types/Util';
|
||||||
import { usePageVisibility } from '../util/hooks';
|
import { usePageVisibility } from '../util/hooks';
|
||||||
import { nonRenderedRemoteParticipant } from '../util/ringrtc/nonRenderedRemoteParticipant';
|
import { nonRenderedRemoteParticipant } from '../util/ringrtc/nonRenderedRemoteParticipant';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
const MIN_RENDERED_HEIGHT = 180;
|
const MIN_RENDERED_HEIGHT = 180;
|
||||||
const PARTICIPANT_MARGIN = 10;
|
const PARTICIPANT_MARGIN = 10;
|
||||||
|
@ -197,9 +198,7 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
|
||||||
// the LARGER of the two could cause overflow.)
|
// the LARGER of the two could cause overflow.)
|
||||||
const widestRow = maxBy(rows, totalRemoteParticipantWidthAtMinHeight);
|
const widestRow = maxBy(rows, totalRemoteParticipantWidthAtMinHeight);
|
||||||
if (!widestRow) {
|
if (!widestRow) {
|
||||||
window.log.error(
|
log.error('Unable to find the widest row, which should be impossible');
|
||||||
'Unable to find the widest row, which should be impossible'
|
|
||||||
);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const widthScalar =
|
const widthScalar =
|
||||||
|
@ -331,7 +330,7 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
|
||||||
bounds
|
bounds
|
||||||
onResize={({ bounds }) => {
|
onResize={({ bounds }) => {
|
||||||
if (!bounds) {
|
if (!bounds) {
|
||||||
window.log.error('We should be measuring the bounds');
|
log.error('We should be measuring the bounds');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setContainerDimensions(bounds);
|
setContainerDimensions(bounds);
|
||||||
|
@ -346,7 +345,7 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
|
||||||
bounds
|
bounds
|
||||||
onResize={({ bounds }) => {
|
onResize={({ bounds }) => {
|
||||||
if (!bounds) {
|
if (!bounds) {
|
||||||
window.log.error('We should be measuring the bounds');
|
log.error('We should be measuring the bounds');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setGridDimensions(bounds);
|
setGridDimensions(bounds);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import React from 'react';
|
||||||
|
|
||||||
import { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
import { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
||||||
import { ReplacementValuesType } from '../types/I18N';
|
import { ReplacementValuesType } from '../types/I18N';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
export type FullJSXType = Array<JSX.Element | string> | JSX.Element | string;
|
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;
|
const { id, components } = this.props;
|
||||||
|
|
||||||
if (!components) {
|
if (!components) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`Error: Intl component prop not provided; Metadata: id '${id}', index ${index}, placeholder '${placeholderName}'`
|
`Error: Intl component prop not provided; Metadata: id '${id}', index ${index}, placeholder '${placeholderName}'`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -39,7 +40,7 @@ export class Intl extends React.Component<Props> {
|
||||||
|
|
||||||
if (Array.isArray(components)) {
|
if (Array.isArray(components)) {
|
||||||
if (!components || !components.length || components.length <= index) {
|
if (!components || !components.length || components.length <= index) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`Error: Intl missing provided component for id '${id}', index ${index}`
|
`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];
|
const value = components[placeholderName];
|
||||||
if (!value) {
|
if (!value) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`Error: Intl missing provided component for id '${id}', placeholder '${placeholderName}'`
|
`Error: Intl missing provided component for id '${id}', placeholder '${placeholderName}'`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { LocalizerType } from '../types/Util';
|
||||||
import { MediaItemType, MessageAttributesType } from '../types/MediaItem';
|
import { MediaItemType, MessageAttributesType } from '../types/MediaItem';
|
||||||
import { formatDuration } from '../util/formatDuration';
|
import { formatDuration } from '../util/formatDuration';
|
||||||
import { useRestoreFocus } from '../util/hooks/useRestoreFocus';
|
import { useRestoreFocus } from '../util/hooks/useRestoreFocus';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
export type PropsType = {
|
export type PropsType = {
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
|
@ -294,7 +295,7 @@ export function Lightbox({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
window.log.info('Lightbox: Unexpected content type', { contentType });
|
log.info('Lightbox: Unexpected content type', { contentType });
|
||||||
|
|
||||||
content = (
|
content = (
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React, { ReactNode } from 'react';
|
import React, { ReactNode } from 'react';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
type InternalPropsType = Readonly<{
|
type InternalPropsType = Readonly<{
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -39,7 +40,7 @@ const onRender: InternalPropsType['onRender'] = (
|
||||||
start,
|
start,
|
||||||
commit
|
commit
|
||||||
) => {
|
) => {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Profiler.tsx(${id}): actual=${actual.toFixed(1)}ms phase=${phase} ` +
|
`Profiler.tsx(${id}): actual=${actual.toFixed(1)}ms phase=${phase} ` +
|
||||||
`base=${base.toFixed(1)}ms start=${start.toFixed(1)}ms ` +
|
`base=${base.toFixed(1)}ms start=${start.toFixed(1)}ms ` +
|
||||||
`commit=${commit.toFixed(1)}ms`
|
`commit=${commit.toFixed(1)}ms`
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { usePrevious } from '../../util/hooks';
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
import { Tooltip, TooltipPlacement } from '../Tooltip';
|
import { Tooltip, TooltipPlacement } from '../Tooltip';
|
||||||
import type { TimelineItemType } from './TimelineItem';
|
import type { TimelineItemType } from './TimelineItem';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export type PropsActionsType = {
|
export type PropsActionsType = {
|
||||||
messageSizeChanged: (messageId: string, conversationId: string) => void;
|
messageSizeChanged: (messageId: string, conversationId: string) => void;
|
||||||
|
@ -66,9 +67,7 @@ export const CallingNotification: React.FC<PropsType> = React.memo(props => {
|
||||||
timestamp = props.startedTime;
|
timestamp = props.startedTime;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
window.log.error(
|
log.error(`CallingNotification missing case: ${missingCaseError(props)}`);
|
||||||
`CallingNotification missing case: ${missingCaseError(props)}`
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ export const CallingNotification: React.FC<PropsType> = React.memo(props => {
|
||||||
bounds
|
bounds
|
||||||
onResize={({ bounds }) => {
|
onResize={({ bounds }) => {
|
||||||
if (!bounds) {
|
if (!bounds) {
|
||||||
window.log.error('We should be measuring the bounds');
|
log.error('We should be measuring the bounds');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setHeight(bounds.height);
|
setHeight(bounds.height);
|
||||||
|
@ -173,7 +172,7 @@ function renderCallingNotificationButton(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
window.log.error(missingCaseError(props));
|
log.error(missingCaseError(props));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { LocalizerType } from '../../types/Util';
|
||||||
import { ConfirmationDialog } from '../ConfirmationDialog';
|
import { ConfirmationDialog } from '../ConfirmationDialog';
|
||||||
import { Button, ButtonSize, ButtonVariant } from '../Button';
|
import { Button, ButtonSize, ButtonVariant } from '../Button';
|
||||||
import { shouldBlurAvatar } from '../../util/shouldBlurAvatar';
|
import { shouldBlurAvatar } from '../../util/shouldBlurAvatar';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
about?: string;
|
about?: string;
|
||||||
|
@ -133,7 +134,7 @@ export const ConversationHero = ({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('ConversationHero: calling onHeightChange');
|
log.info('ConversationHero: calling onHeightChange');
|
||||||
onHeightChange();
|
onHeightChange();
|
||||||
}, [
|
}, [
|
||||||
about,
|
about,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import React, { ReactNode } from 'react';
|
||||||
|
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
import * as Errors from '../../types/errors';
|
import * as Errors from '../../types/errors';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
@ -27,7 +28,7 @@ export class ErrorBoundary extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getDerivedStateFromError(error: Error): State {
|
public static getDerivedStateFromError(error: Error): State {
|
||||||
window.log.error(
|
log.error(
|
||||||
'ErrorBoundary: captured rendering error',
|
'ErrorBoundary: captured rendering error',
|
||||||
Errors.toLogFormat(error)
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
getImageDimensions,
|
getImageDimensions,
|
||||||
defaultBlurHash,
|
defaultBlurHash,
|
||||||
} from '../../types/Attachment';
|
} from '../../types/Attachment';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
const MAX_GIF_REPEAT = 4;
|
const MAX_GIF_REPEAT = 4;
|
||||||
const MAX_GIF_TIME = 8;
|
const MAX_GIF_TIME = 8;
|
||||||
|
@ -87,7 +88,7 @@ export const GIF: React.FC<Props> = props => {
|
||||||
|
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
video.play().catch(error => {
|
video.play().catch(error => {
|
||||||
window.log.info(
|
log.info(
|
||||||
"Failed to match GIF playback to window's state",
|
"Failed to match GIF playback to window's state",
|
||||||
(error && error.stack) || error
|
(error && error.stack) || error
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { ConversationType } from '../../state/ducks/conversations';
|
||||||
import { Intl } from '../Intl';
|
import { Intl } from '../Intl';
|
||||||
import { ContactName } from './ContactName';
|
import { ContactName } from './ContactName';
|
||||||
import { GroupV1MigrationDialog } from '../GroupV1MigrationDialog';
|
import { GroupV1MigrationDialog } from '../GroupV1MigrationDialog';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export type PropsDataType = {
|
export type PropsDataType = {
|
||||||
areWeInvited: boolean;
|
areWeInvited: boolean;
|
||||||
|
@ -79,9 +80,7 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
|
||||||
hasMigrated
|
hasMigrated
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
invitedMembers={invitedMembers}
|
invitedMembers={invitedMembers}
|
||||||
migrate={() =>
|
migrate={() => log.warn('GroupV1Migration: Modal called migrate()')}
|
||||||
window.log.warn('GroupV1Migration: Modal called migrate()')
|
|
||||||
}
|
|
||||||
onClose={dismissDialog}
|
onClose={dismissDialog}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import { Emoji } from '../emoji/Emoji';
|
||||||
import { LinkPreviewDate } from './LinkPreviewDate';
|
import { LinkPreviewDate } from './LinkPreviewDate';
|
||||||
import { LinkPreviewType } from '../../types/message/LinkPreviews';
|
import { LinkPreviewType } from '../../types/message/LinkPreviews';
|
||||||
import { shouldUseFullSizeLinkPreviewImage } from '../../linkPreviews/shouldUseFullSizeLinkPreviewImage';
|
import { shouldUseFullSizeLinkPreviewImage } from '../../linkPreviews/shouldUseFullSizeLinkPreviewImage';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AttachmentType,
|
AttachmentType,
|
||||||
|
@ -386,7 +387,7 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
public handleImageError = (): void => {
|
public handleImageError = (): void => {
|
||||||
const { id } = this.props;
|
const { id } = this.props;
|
||||||
window.log.info(
|
log.info(
|
||||||
`Message ${id}: Image failed to load; failing over to placeholder`
|
`Message ${id}: Image failed to load; failing over to placeholder`
|
||||||
);
|
);
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -492,7 +493,7 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
timestamp,
|
timestamp,
|
||||||
delta,
|
delta,
|
||||||
});
|
});
|
||||||
window.log.info(
|
log.info(
|
||||||
`Message.tsx: Rendered 'send complete' for message ${timestamp}; took ${delta}ms`
|
`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;
|
played = readStatus === ReadStatus.Viewed;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
window.log.error(missingCaseError(direction));
|
log.error(missingCaseError(direction));
|
||||||
played = false;
|
played = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2131,7 +2132,7 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
if (isTapToView) {
|
if (isTapToView) {
|
||||||
if (isAttachmentPending) {
|
if (isAttachmentPending) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'<Message> handleOpen: tap-to-view attachment is pending; not showing the lightbox'
|
'<Message> handleOpen: tap-to-view attachment is pending; not showing the lightbox'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import type { DirectionType, MessageStatusType } from './Message';
|
||||||
|
|
||||||
import { ComputePeaksResult } from '../GlobalAudioContext';
|
import { ComputePeaksResult } from '../GlobalAudioContext';
|
||||||
import { MessageMetadata } from './MessageMetadata';
|
import { MessageMetadata } from './MessageMetadata';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
renderingContext: string;
|
renderingContext: string;
|
||||||
|
@ -214,7 +215,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||||
return noop;
|
return noop;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('MessageAudio: loading audio and computing waveform');
|
log.info('MessageAudio: loading audio and computing waveform');
|
||||||
|
|
||||||
let canceled = false;
|
let canceled = false;
|
||||||
|
|
||||||
|
@ -238,7 +239,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||||
setHasPeaks(true);
|
setHasPeaks(true);
|
||||||
setDuration(Math.max(newDuration, 1e-23));
|
setDuration(Math.max(newDuration, 1e-23));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'MessageAudio: computePeaks error, marking as corrupted',
|
'MessageAudio: computePeaks error, marking as corrupted',
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
@ -271,7 +272,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Owner of Audio instance changed
|
// Owner of Audio instance changed
|
||||||
if (!isActive) {
|
if (!isActive) {
|
||||||
window.log.info('MessageAudio: pausing old owner', id);
|
log.info('MessageAudio: pausing old owner', id);
|
||||||
setIsPlaying(false);
|
setIsPlaying(false);
|
||||||
setCurrentTime(0);
|
setCurrentTime(0);
|
||||||
return noop;
|
return noop;
|
||||||
|
@ -285,7 +286,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEnded = () => {
|
const onEnded = () => {
|
||||||
window.log.info('MessageAudio: ended, changing UI', id);
|
log.info('MessageAudio: ended, changing UI', id);
|
||||||
setIsPlaying(false);
|
setIsPlaying(false);
|
||||||
setCurrentTime(0);
|
setCurrentTime(0);
|
||||||
};
|
};
|
||||||
|
@ -296,7 +297,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||||
'Audio should have definite duration on `loadedmetadata` event'
|
'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
|
// Sync-up audio's time in case if <audio/> loaded its source after
|
||||||
// user clicked on waveform
|
// user clicked on waveform
|
||||||
|
@ -304,7 +305,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDurationChange = () => {
|
const onDurationChange = () => {
|
||||||
window.log.info('MessageAudio: `durationchange` event', id);
|
log.info('MessageAudio: `durationchange` event', id);
|
||||||
|
|
||||||
if (!Number.isNaN(audio.duration)) {
|
if (!Number.isNaN(audio.duration)) {
|
||||||
setDuration(Math.max(audio.duration, 1e-23));
|
setDuration(Math.max(audio.duration, 1e-23));
|
||||||
|
@ -336,13 +337,13 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('MessageAudio: resuming playback for', id);
|
log.info('MessageAudio: resuming playback for', id);
|
||||||
audio.currentTime = currentTime;
|
audio.currentTime = currentTime;
|
||||||
audio.play().catch(error => {
|
audio.play().catch(error => {
|
||||||
window.log.info('MessageAudio: resume error', id, error.stack || error);
|
log.info('MessageAudio: resume error', id, error.stack || error);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.log.info('MessageAudio: pausing playback for', id);
|
log.info('MessageAudio: pausing playback for', id);
|
||||||
audio.pause();
|
audio.pause();
|
||||||
}
|
}
|
||||||
}, [id, audio, isActive, isPlaying, currentTime]);
|
}, [id, audio, isActive, isPlaying, currentTime]);
|
||||||
|
@ -351,7 +352,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
|
||||||
setIsPlaying(!isPlaying);
|
setIsPlaying(!isPlaying);
|
||||||
|
|
||||||
if (!isActive && !isPlaying) {
|
if (!isActive && !isPlaying) {
|
||||||
window.log.info('MessageAudio: changing owner', id);
|
log.info('MessageAudio: changing owner', id);
|
||||||
setActiveAudioID(id, renderingContext);
|
setActiveAudioID(id, renderingContext);
|
||||||
|
|
||||||
// Pause old audio
|
// Pause old audio
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { ConversationType } from '../../state/ducks/conversations';
|
||||||
import { groupBy } from '../../util/mapUtil';
|
import { groupBy } from '../../util/mapUtil';
|
||||||
import { ContactNameColorType } from '../../types/Colors';
|
import { ContactNameColorType } from '../../types/Colors';
|
||||||
import { SendStatus } from '../../messages/MessageSendState';
|
import { SendStatus } from '../../messages/MessageSendState';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export type Contact = Pick<
|
export type Contact = Pick<
|
||||||
ConversationType,
|
ConversationType,
|
||||||
|
@ -292,16 +293,16 @@ export class MessageDetail extends React.Component<Props> {
|
||||||
contactNameColor={contactNameColor}
|
contactNameColor={contactNameColor}
|
||||||
containerElementRef={this.messageContainerRef}
|
containerElementRef={this.messageContainerRef}
|
||||||
deleteMessage={() =>
|
deleteMessage={() =>
|
||||||
window.log.warn('MessageDetail: deleteMessage called!')
|
log.warn('MessageDetail: deleteMessage called!')
|
||||||
}
|
}
|
||||||
deleteMessageForEveryone={() =>
|
deleteMessageForEveryone={() =>
|
||||||
window.log.warn('MessageDetail: deleteMessageForEveryone called!')
|
log.warn('MessageDetail: deleteMessageForEveryone called!')
|
||||||
}
|
}
|
||||||
disableMenu
|
disableMenu
|
||||||
disableScroll
|
disableScroll
|
||||||
displayTapToViewMessage={displayTapToViewMessage}
|
displayTapToViewMessage={displayTapToViewMessage}
|
||||||
downloadAttachment={() =>
|
downloadAttachment={() =>
|
||||||
window.log.warn('MessageDetail: deleteMessageForEveryone called!')
|
log.warn('MessageDetail: deleteMessageForEveryone called!')
|
||||||
}
|
}
|
||||||
doubleCheckMissingQuoteReference={doubleCheckMissingQuoteReference}
|
doubleCheckMissingQuoteReference={doubleCheckMissingQuoteReference}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
|
@ -320,7 +321,7 @@ export class MessageDetail extends React.Component<Props> {
|
||||||
retrySend={retrySend}
|
retrySend={retrySend}
|
||||||
showForwardMessageModal={showForwardMessageModal}
|
showForwardMessageModal={showForwardMessageModal}
|
||||||
scrollToQuotedMessage={() => {
|
scrollToQuotedMessage={() => {
|
||||||
window.log.warn('MessageDetail: scrollToQuotedMessage called!');
|
log.warn('MessageDetail: scrollToQuotedMessage called!');
|
||||||
}}
|
}}
|
||||||
showContactDetail={showContactDetail}
|
showContactDetail={showContactDetail}
|
||||||
showContactModal={showContactModal}
|
showContactModal={showContactModal}
|
||||||
|
@ -331,9 +332,7 @@ export class MessageDetail extends React.Component<Props> {
|
||||||
showExpiredOutgoingTapToViewToast
|
showExpiredOutgoingTapToViewToast
|
||||||
}
|
}
|
||||||
showMessageDetail={() => {
|
showMessageDetail={() => {
|
||||||
window.log.warn(
|
log.warn('MessageDetail: deleteMessageForEveryone called!');
|
||||||
'MessageDetail: deleteMessageForEveryone called!'
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
showVisualAttachment={showVisualAttachment}
|
showVisualAttachment={showVisualAttachment}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -69,6 +69,7 @@ import {
|
||||||
ProfileChangeNotification,
|
ProfileChangeNotification,
|
||||||
PropsType as ProfileChangeNotificationPropsType,
|
PropsType as ProfileChangeNotificationPropsType,
|
||||||
} from './ProfileChangeNotification';
|
} from './ProfileChangeNotification';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
type CallHistoryType = {
|
type CallHistoryType = {
|
||||||
type: 'callHistory';
|
type: 'callHistory';
|
||||||
|
@ -203,7 +204,7 @@ export class TimelineItem extends React.PureComponent<PropsType> {
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
window.log.warn(`TimelineItem: item ${id} provided was falsey`);
|
log.warn(`TimelineItem: item ${id} provided was falsey`);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { SystemMessage } from './SystemMessage';
|
||||||
import { Intl } from '../Intl';
|
import { Intl } from '../Intl';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
import * as expirationTimer from '../../util/expirationTimer';
|
import * as expirationTimer from '../../util/expirationTimer';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export type TimerNotificationType =
|
export type TimerNotificationType =
|
||||||
| 'fromOther'
|
| 'fromOther'
|
||||||
|
@ -78,7 +79,7 @@ export const TimerNotification: FunctionComponent<Props> = props => {
|
||||||
: i18n('timerSetByMember', [timespan]);
|
: i18n('timerSetByMember', [timespan]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
window.log.warn('TimerNotification: unsupported type provided:', type);
|
log.warn('TimerNotification: unsupported type provided:', type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
} from '../../../util/GoogleChrome';
|
} from '../../../util/GoogleChrome';
|
||||||
import { LocalizerType } from '../../../types/Util';
|
import { LocalizerType } from '../../../types/Util';
|
||||||
import { MediaItemType } from '../../../types/MediaItem';
|
import { MediaItemType } from '../../../types/MediaItem';
|
||||||
|
import * as log from '../../../logging/log';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
mediaItem: MediaItemType;
|
mediaItem: MediaItemType;
|
||||||
|
@ -35,7 +36,7 @@ export class MediaGridItem extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public onImageError(): void {
|
public onImageError(): void {
|
||||||
window.log.info(
|
log.info(
|
||||||
'MediaGridItem: Image failed to load; failing over to placeholder'
|
'MediaGridItem: Image failed to load; failing over to placeholder'
|
||||||
);
|
);
|
||||||
this.setState({
|
this.setState({
|
||||||
|
|
|
@ -21,6 +21,7 @@ import Fuse from 'fuse.js';
|
||||||
import PQueue from 'p-queue';
|
import PQueue from 'p-queue';
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
import { getOwn } from '../../util/getOwn';
|
import { getOwn } from '../../util/getOwn';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF'];
|
export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF'];
|
||||||
|
|
||||||
|
@ -108,7 +109,7 @@ export const preloadImages = async (): Promise<void> => {
|
||||||
setTimeout(reject, 5000);
|
setTimeout(reject, 5000);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.info('Preloading emoji images');
|
log.info('Preloading emoji images');
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
|
||||||
data.forEach(emoji => {
|
data.forEach(emoji => {
|
||||||
|
@ -124,7 +125,7 @@ export const preloadImages = async (): Promise<void> => {
|
||||||
await imageQueue.onEmpty();
|
await imageQueue.onEmpty();
|
||||||
|
|
||||||
const end = Date.now();
|
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');
|
const dataByShortName = keyBy(data, 'short_name');
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { missingCaseError } from './util/missingCaseError';
|
||||||
|
|
||||||
import { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups';
|
import { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups';
|
||||||
import { SignalService as Proto } from './protobuf';
|
import { SignalService as Proto } from './protobuf';
|
||||||
|
import * as log from './logging/log';
|
||||||
|
|
||||||
export type SmartContactRendererType = (conversationId: string) => FullJSXType;
|
export type SmartContactRendererType = (conversationId: string) => FullJSXType;
|
||||||
export type StringRendererType = (
|
export type StringRendererType = (
|
||||||
|
@ -137,7 +138,7 @@ export function renderChangeDetail(
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--access-attributes--all--unknown', i18n);
|
return renderString('GroupV2--access-attributes--all--unknown', i18n);
|
||||||
}
|
}
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`access-attributes change type, privilege ${newPrivilege} is unknown`
|
`access-attributes change type, privilege ${newPrivilege} is unknown`
|
||||||
);
|
);
|
||||||
return '';
|
return '';
|
||||||
|
@ -167,7 +168,7 @@ export function renderChangeDetail(
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--access-members--all--unknown', i18n);
|
return renderString('GroupV2--access-members--all--unknown', i18n);
|
||||||
}
|
}
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`access-members change type, privilege ${newPrivilege} is unknown`
|
`access-members change type, privilege ${newPrivilege} is unknown`
|
||||||
);
|
);
|
||||||
return '';
|
return '';
|
||||||
|
@ -207,7 +208,7 @@ export function renderChangeDetail(
|
||||||
i18n
|
i18n
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`access-invite-link change type, privilege ${newPrivilege} is unknown`
|
`access-invite-link change type, privilege ${newPrivilege} is unknown`
|
||||||
);
|
);
|
||||||
return '';
|
return '';
|
||||||
|
@ -318,7 +319,7 @@ export function renderChangeDetail(
|
||||||
|
|
||||||
// Note: this shouldn't happen, because we only capture 'add-from-link' status
|
// Note: this shouldn't happen, because we only capture 'add-from-link' status
|
||||||
// from group change events, which always have a sender.
|
// 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, [
|
return renderString('GroupV2--member-add--other--unknown', i18n, [
|
||||||
renderContact(conversationId),
|
renderContact(conversationId),
|
||||||
]);
|
]);
|
||||||
|
@ -338,7 +339,7 @@ export function renderChangeDetail(
|
||||||
|
|
||||||
// Note: this shouldn't happen, because we only capture 'add-from-admin-approval'
|
// Note: this shouldn't happen, because we only capture 'add-from-admin-approval'
|
||||||
// status from group change events, which always have a sender.
|
// 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!'
|
'member-add-from-admin-approval change type; we have no from, and we are joiner!'
|
||||||
);
|
);
|
||||||
return renderString(
|
return renderString(
|
||||||
|
@ -367,9 +368,7 @@ export function renderChangeDetail(
|
||||||
|
|
||||||
// Note: this shouldn't happen, because we only capture 'add-from-admin-approval'
|
// Note: this shouldn't happen, because we only capture 'add-from-admin-approval'
|
||||||
// status from group change events, which always have a sender.
|
// 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');
|
||||||
'member-add-from-admin-approval change type; we have no from'
|
|
||||||
);
|
|
||||||
return renderString(
|
return renderString(
|
||||||
'GroupV2--member-add-from-admin-approval--other--unknown',
|
'GroupV2--member-add-from-admin-approval--other--unknown',
|
||||||
i18n,
|
i18n,
|
||||||
|
@ -493,7 +492,7 @@ export function renderChangeDetail(
|
||||||
[renderContact(conversationId)]
|
[renderContact(conversationId)]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`member-privilege change type, privilege ${newPrivilege} is unknown`
|
`member-privilege change type, privilege ${newPrivilege} is unknown`
|
||||||
);
|
);
|
||||||
return '';
|
return '';
|
||||||
|
@ -800,9 +799,7 @@ export function renderChangeDetail(
|
||||||
}
|
}
|
||||||
return renderString('GroupV2--group-link-add--disabled--unknown', i18n);
|
return renderString('GroupV2--group-link-add--disabled--unknown', i18n);
|
||||||
}
|
}
|
||||||
window.log.warn(
|
log.warn(`group-link-add change type, privilege ${privilege} is unknown`);
|
||||||
`group-link-add change type, privilege ${privilege} is unknown`
|
|
||||||
);
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (detail.type === 'group-link-reset') {
|
if (detail.type === 'group-link-reset') {
|
||||||
|
|
226
ts/groups.ts
226
ts/groups.ts
|
@ -13,6 +13,7 @@ import {
|
||||||
import { ClientZkGroupCipher } from 'zkgroup';
|
import { ClientZkGroupCipher } from 'zkgroup';
|
||||||
import { v4 as getGuid } from 'uuid';
|
import { v4 as getGuid } from 'uuid';
|
||||||
import LRU from 'lru-cache';
|
import LRU from 'lru-cache';
|
||||||
|
import * as log from './logging/log';
|
||||||
import {
|
import {
|
||||||
getCredentialsForToday,
|
getCredentialsForToday,
|
||||||
GROUP_CREDENTIALS_KEY,
|
GROUP_CREDENTIALS_KEY,
|
||||||
|
@ -400,10 +401,7 @@ async function uploadAvatar(
|
||||||
key,
|
key,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(`uploadAvatar/${logId} Failed to upload avatar`, error.stack);
|
||||||
`uploadAvatar/${logId} Failed to upload avatar`,
|
|
||||||
error.stack
|
|
||||||
);
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1248,20 +1246,20 @@ export async function modifyGroupV2({
|
||||||
const MAX_ATTEMPTS = 5;
|
const MAX_ATTEMPTS = 5;
|
||||||
|
|
||||||
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {
|
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 {
|
try {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await window.waitForEmptyEventQueue();
|
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
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await conversation.queueJob('modifyGroupV2', async () => {
|
await conversation.queueJob('modifyGroupV2', async () => {
|
||||||
window.log.info(`modifyGroupV2/${idLog}: Running attempt ${attempt}`);
|
log.info(`modifyGroupV2/${idLog}: Running attempt ${attempt}`);
|
||||||
|
|
||||||
const actions = await createGroupChange();
|
const actions = await createGroupChange();
|
||||||
if (!actions) {
|
if (!actions) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`modifyGroupV2/${idLog}: No change actions. Returning early.`
|
`modifyGroupV2/${idLog}: No change actions. Returning early.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -1346,20 +1344,20 @@ export async function modifyGroupV2({
|
||||||
});
|
});
|
||||||
|
|
||||||
// If we've gotten here with no error, we exit!
|
// If we've gotten here with no error, we exit!
|
||||||
window.log.info(
|
log.info(
|
||||||
`modifyGroupV2/${idLog}: Update complete, with attempt ${attempt}!`
|
`modifyGroupV2/${idLog}: Update complete, with attempt ${attempt}!`
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === 409 && Date.now() <= timeoutTime) {
|
if (error.code === 409 && Date.now() <= timeoutTime) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`modifyGroupV2/${idLog}: Conflict while updating. Trying again...`
|
`modifyGroupV2/${idLog}: Conflict while updating. Trying again...`
|
||||||
);
|
);
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await conversation.fetchLatestGroupV2Data({ force: true });
|
await conversation.fetchLatestGroupV2Data({ force: true });
|
||||||
} else if (error.code === 409) {
|
} else if (error.code === 409) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`modifyGroupV2/${idLog}: Conflict while updating. Timed out; not retrying.`
|
`modifyGroupV2/${idLog}: Conflict while updating. Timed out; not retrying.`
|
||||||
);
|
);
|
||||||
// We don't wait here because we're breaking out of the loop immediately.
|
// We don't wait here because we're breaking out of the loop immediately.
|
||||||
|
@ -1367,9 +1365,7 @@ export async function modifyGroupV2({
|
||||||
throw error;
|
throw error;
|
||||||
} else {
|
} else {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = error && error.stack ? error.stack : error;
|
||||||
window.log.error(
|
log.error(`modifyGroupV2/${idLog}: Error updating: ${errorString}`);
|
||||||
`modifyGroupV2/${idLog}: Error updating: ${errorString}`
|
|
||||||
);
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1396,7 +1392,7 @@ export function deriveGroupFields(masterKey: Uint8Array): GroupFields {
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('deriveGroupFields: cache miss');
|
log.info('deriveGroupFields: cache miss');
|
||||||
|
|
||||||
const secretParams = deriveGroupSecretParams(masterKey);
|
const secretParams = deriveGroupSecretParams(masterKey);
|
||||||
const publicParams = deriveGroupPublicParams(secretParams);
|
const publicParams = deriveGroupPublicParams(secretParams);
|
||||||
|
@ -1448,7 +1444,7 @@ async function makeRequestWithTemporalRetry<T>({
|
||||||
return await request(sender, todayOptions);
|
return await request(sender, todayOptions);
|
||||||
} catch (todayError) {
|
} catch (todayError) {
|
||||||
if (todayError.code === TEMPORAL_AUTH_REJECTED_CODE) {
|
if (todayError.code === TEMPORAL_AUTH_REJECTED_CODE) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`makeRequestWithTemporalRetry/${logId}: Trying again with tomorrow's credentials`
|
`makeRequestWithTemporalRetry/${logId}: Trying again with tomorrow's credentials`
|
||||||
);
|
);
|
||||||
const tomorrowOptions = getGroupCredentials({
|
const tomorrowOptions = getGroupCredentials({
|
||||||
|
@ -1657,7 +1653,7 @@ export async function createGroupV2({
|
||||||
hash: uploadedAvatar.hash,
|
hash: uploadedAvatar.hash,
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`createGroupV2/${logId}: avatar failed to save to disk. Continuing on`
|
`createGroupV2/${logId}: avatar failed to save to disk. Continuing on`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1753,7 +1749,7 @@ export async function hasV1GroupBeenMigrated(
|
||||||
const logId = conversation.idForLogging();
|
const logId = conversation.idForLogging();
|
||||||
const isGroupV1 = getIsGroupV1(conversation.attributes);
|
const isGroupV1 = getIsGroupV1(conversation.attributes);
|
||||||
if (!isGroupV1) {
|
if (!isGroupV1) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`checkForGV2Existence/${logId}: Called for non-GroupV1 conversation!`
|
`checkForGV2Existence/${logId}: Called for non-GroupV1 conversation!`
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1887,21 +1883,21 @@ export async function getGroupMigrationMembers(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!isMe(contact.attributes) && window.GV2_MIGRATION_DISABLE_ADD) {
|
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`
|
`getGroupMigrationMembers/${logId}: membersV2 - skipping ${e164} due to GV2_MIGRATION_DISABLE_ADD flag`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contact.get('uuid')) {
|
if (!contact.get('uuid')) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: membersV2 - missing uuid for ${e164}, skipping.`
|
`getGroupMigrationMembers/${logId}: membersV2 - missing uuid for ${e164}, skipping.`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contact.get('profileKey')) {
|
if (!contact.get('profileKey')) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: membersV2 - missing profileKey for member ${e164}, skipping.`
|
`getGroupMigrationMembers/${logId}: membersV2 - missing profileKey for member ${e164}, skipping.`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -1921,19 +1917,19 @@ export async function getGroupMigrationMembers(
|
||||||
|
|
||||||
capabilities = contact.get('capabilities');
|
capabilities = contact.get('capabilities');
|
||||||
if (!capabilities || !capabilities.gv2) {
|
if (!capabilities || !capabilities.gv2) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv2 capability, skipping.`
|
`getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv2 capability, skipping.`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!capabilities || !capabilities['gv1-migration']) {
|
if (!capabilities || !capabilities['gv1-migration']) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv1-migration capability, skipping.`
|
`getGroupMigrationMembers/${logId}: membersV2 - member ${e164} is missing gv1-migration capability, skipping.`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!contact.get('profileKeyCredential')) {
|
if (!contact.get('profileKeyCredential')) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: membersV2 - no profileKeyCredential for ${e164}, skipping.`
|
`getGroupMigrationMembers/${logId}: membersV2 - no profileKeyCredential for ${e164}, skipping.`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -1974,7 +1970,7 @@ export async function getGroupMigrationMembers(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMe(contact.attributes) && window.GV2_MIGRATION_DISABLE_INVITE) {
|
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`
|
`getGroupMigrationMembers/${logId}: pendingMembersV2 - skipping ${e164} due to GV2_MIGRATION_DISABLE_INVITE flag`
|
||||||
);
|
);
|
||||||
droppedGV2MemberIds.push(conversationId);
|
droppedGV2MemberIds.push(conversationId);
|
||||||
|
@ -1982,7 +1978,7 @@ export async function getGroupMigrationMembers(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contact.get('uuid')) {
|
if (!contact.get('uuid')) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: pendingMembersV2 - missing uuid for ${e164}, skipping.`
|
`getGroupMigrationMembers/${logId}: pendingMembersV2 - missing uuid for ${e164}, skipping.`
|
||||||
);
|
);
|
||||||
droppedGV2MemberIds.push(conversationId);
|
droppedGV2MemberIds.push(conversationId);
|
||||||
|
@ -1991,14 +1987,14 @@ export async function getGroupMigrationMembers(
|
||||||
|
|
||||||
const capabilities = contact.get('capabilities');
|
const capabilities = contact.get('capabilities');
|
||||||
if (!capabilities || !capabilities.gv2) {
|
if (!capabilities || !capabilities.gv2) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv2 capability, skipping.`
|
`getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv2 capability, skipping.`
|
||||||
);
|
);
|
||||||
droppedGV2MemberIds.push(conversationId);
|
droppedGV2MemberIds.push(conversationId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!capabilities || !capabilities['gv1-migration']) {
|
if (!capabilities || !capabilities['gv1-migration']) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv1-migration capability, skipping.`
|
`getGroupMigrationMembers/${logId}: pendingMembersV2 - member ${e164} is missing gv1-migration capability, skipping.`
|
||||||
);
|
);
|
||||||
droppedGV2MemberIds.push(conversationId);
|
droppedGV2MemberIds.push(conversationId);
|
||||||
|
@ -2062,7 +2058,7 @@ export async function initiateMigrationToGroupV2(
|
||||||
|
|
||||||
const groupId = Bytes.toBase64(fields.id);
|
const groupId = Bytes.toBase64(fields.id);
|
||||||
const logId = `groupv2(${groupId})`;
|
const logId = `groupv2(${groupId})`;
|
||||||
window.log.info(
|
log.info(
|
||||||
`initiateMigrationToGroupV2/${logId}: Migrating from ${conversation.idForLogging()}`
|
`initiateMigrationToGroupV2/${logId}: Migrating from ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2166,7 +2162,7 @@ export async function initiateMigrationToGroupV2(
|
||||||
request: (sender, options) => sender.createGroup(groupProto, options),
|
request: (sender, options) => sender.createGroup(groupProto, options),
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`initiateMigrationToGroupV2/${logId}: Error creating group:`,
|
`initiateMigrationToGroupV2/${logId}: Error creating group:`,
|
||||||
error.stack
|
error.stack
|
||||||
);
|
);
|
||||||
|
@ -2206,7 +2202,7 @@ export async function initiateMigrationToGroupV2(
|
||||||
|
|
||||||
const alreadyMigrated = await hasV1GroupBeenMigrated(conversation);
|
const alreadyMigrated = await hasV1GroupBeenMigrated(conversation);
|
||||||
if (!alreadyMigrated) {
|
if (!alreadyMigrated) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`initiateMigrationToGroupV2/${logId}: Group has not already been migrated, re-throwing error`
|
`initiateMigrationToGroupV2/${logId}: Group has not already been migrated, re-throwing error`
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -2315,7 +2311,7 @@ export async function wrapWithSyncMessageSend({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`wrapWithSyncMessageSend/${logId}: We are primary device; not sync message`
|
`wrapWithSyncMessageSend/${logId}: We are primary device; not sync message`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -2349,7 +2345,7 @@ export async function waitThenRespondToGroupV2Migration(
|
||||||
// And finally try to migrate the group
|
// And finally try to migrate the group
|
||||||
await respondToGroupV2Migration(options);
|
await respondToGroupV2Migration(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`waitThenRespondToGroupV2Migration/${conversation.idForLogging()}: respondToGroupV2Migration failure:`,
|
`waitThenRespondToGroupV2Migration/${conversation.idForLogging()}: respondToGroupV2Migration failure:`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -2420,7 +2416,7 @@ export async function joinGroupV2ViaLinkAndMigrate({
|
||||||
|
|
||||||
const groupId = Bytes.toBase64(fields.id);
|
const groupId = Bytes.toBase64(fields.id);
|
||||||
const logId = idForLogging(groupId);
|
const logId = idForLogging(groupId);
|
||||||
window.log.info(
|
log.info(
|
||||||
`joinGroupV2ViaLinkAndMigrate/${logId}: Migrating from ${conversation.idForLogging()}`
|
`joinGroupV2ViaLinkAndMigrate/${logId}: Migrating from ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2518,7 +2514,7 @@ export async function respondToGroupV2Migration({
|
||||||
|
|
||||||
const groupId = Bytes.toBase64(fields.id);
|
const groupId = Bytes.toBase64(fields.id);
|
||||||
const logId = idForLogging(groupId);
|
const logId = idForLogging(groupId);
|
||||||
window.log.info(
|
log.info(
|
||||||
`respondToGroupV2Migration/${logId}: Migrating from ${conversation.idForLogging()}`
|
`respondToGroupV2Migration/${logId}: Migrating from ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2567,7 +2563,7 @@ export async function respondToGroupV2Migration({
|
||||||
firstGroupState = response?.changes?.groupChanges?.[0]?.groupState;
|
firstGroupState = response?.changes?.groupChanges?.[0]?.groupState;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === GROUP_ACCESS_DENIED_CODE) {
|
if (error.code === GROUP_ACCESS_DENIED_CODE) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`respondToGroupV2Migration/${logId}: Failed to access log endpoint; fetching full group state`
|
`respondToGroupV2Migration/${logId}: Failed to access log endpoint; fetching full group state`
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
|
@ -2579,7 +2575,7 @@ export async function respondToGroupV2Migration({
|
||||||
});
|
});
|
||||||
} catch (secondError) {
|
} catch (secondError) {
|
||||||
if (secondError.code === GROUP_ACCESS_DENIED_CODE) {
|
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`
|
`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;
|
const { conversation } = options;
|
||||||
|
|
||||||
if (conversation.isBlocked()) {
|
if (conversation.isBlocked()) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`waitThenMaybeUpdateGroup: Group ${conversation.idForLogging()} is blocked, returning early`
|
`waitThenMaybeUpdateGroup: Group ${conversation.idForLogging()} is blocked, returning early`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -2739,7 +2735,7 @@ export async function waitThenMaybeUpdateGroup(
|
||||||
isMoreRecentThan(lastSuccessfulGroupFetch, FIVE_MINUTES)
|
isMoreRecentThan(lastSuccessfulGroupFetch, FIVE_MINUTES)
|
||||||
) {
|
) {
|
||||||
const waitTime = lastSuccessfulGroupFetch + FIVE_MINUTES - Date.now();
|
const waitTime = lastSuccessfulGroupFetch + FIVE_MINUTES - Date.now();
|
||||||
window.log.info(
|
log.info(
|
||||||
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: group update ` +
|
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: group update ` +
|
||||||
`was fetched recently, skipping for ${waitTime}ms`
|
`was fetched recently, skipping for ${waitTime}ms`
|
||||||
);
|
);
|
||||||
|
@ -2754,7 +2750,7 @@ export async function waitThenMaybeUpdateGroup(
|
||||||
|
|
||||||
conversation.lastSuccessfulGroupFetch = Date.now();
|
conversation.lastSuccessfulGroupFetch = Date.now();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: maybeUpdateGroup failure:`,
|
`waitThenMaybeUpdateGroup/${conversation.idForLogging()}: maybeUpdateGroup failure:`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -2792,7 +2788,7 @@ export async function maybeUpdateGroup(
|
||||||
{ viaSync }
|
{ viaSync }
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`maybeUpdateGroup/${logId}: Failed to update group:`,
|
`maybeUpdateGroup/${logId}: Failed to update group:`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -2915,7 +2911,7 @@ async function getGroupUpdates({
|
||||||
}): Promise<UpdatesResultType> {
|
}): Promise<UpdatesResultType> {
|
||||||
const logId = idForLogging(group.groupId);
|
const logId = idForLogging(group.groupId);
|
||||||
|
|
||||||
window.log.info(`getGroupUpdates/${logId}: Starting...`);
|
log.info(`getGroupUpdates/${logId}: Starting...`);
|
||||||
|
|
||||||
const currentRevision = group.revision;
|
const currentRevision = group.revision;
|
||||||
const isFirstFetch = !isNumber(group.revision);
|
const isFirstFetch = !isNumber(group.revision);
|
||||||
|
@ -2936,7 +2932,7 @@ async function getGroupUpdates({
|
||||||
isNumber(newRevision) &&
|
isNumber(newRevision) &&
|
||||||
(isInitialCreationMessage || weAreAwaitingApproval || isOneVersionUp)
|
(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 groupChangeBuffer = Bytes.fromBase64(groupChangeBase64);
|
||||||
const groupChange = Proto.GroupChange.decode(groupChangeBuffer);
|
const groupChange = Proto.GroupChange.decode(groupChangeBuffer);
|
||||||
const isChangeSupported =
|
const isChangeSupported =
|
||||||
|
@ -2952,7 +2948,7 @@ async function getGroupUpdates({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`getGroupUpdates/${logId}: Failing over; group change unsupported`
|
`getGroupUpdates/${logId}: Failing over; group change unsupported`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2969,12 +2965,12 @@ async function getGroupUpdates({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
|
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
|
||||||
// We will fail over to the updateGroupViaState call below
|
// We will fail over to the updateGroupViaState call below
|
||||||
window.log.info(
|
log.info(
|
||||||
`getGroupUpdates/${logId}: Temporal credential failure, now fetching full group state`
|
`getGroupUpdates/${logId}: Temporal credential failure, now fetching full group state`
|
||||||
);
|
);
|
||||||
} else if (error.code === GROUP_ACCESS_DENIED_CODE) {
|
} else if (error.code === GROUP_ACCESS_DENIED_CODE) {
|
||||||
// We will fail over to the updateGroupViaState call below
|
// We will fail over to the updateGroupViaState call below
|
||||||
window.log.info(
|
log.info(
|
||||||
`getGroupUpdates/${logId}: Log access denied, now fetching full group state`
|
`getGroupUpdates/${logId}: Log access denied, now fetching full group state`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2991,7 +2987,7 @@ async function getGroupUpdates({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`getGroupUpdates/${logId}: No processing was legal! Returning empty changeset.`
|
`getGroupUpdates/${logId}: No processing was legal! Returning empty changeset.`
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
|
@ -3025,9 +3021,7 @@ async function updateGroupViaState({
|
||||||
authCredentialBase64: groupCredentials.today.credential,
|
authCredentialBase64: groupCredentials.today.credential,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
window.log.info(
|
log.info(`updateGroupViaState/${logId}: Getting full group state...`);
|
||||||
`updateGroupViaState/${logId}: Getting full group state...`
|
|
||||||
);
|
|
||||||
// We await this here so our try/catch below takes effect
|
// We await this here so our try/catch below takes effect
|
||||||
const result = await getCurrentGroupState(stateOptions);
|
const result = await getCurrentGroupState(stateOptions);
|
||||||
|
|
||||||
|
@ -3037,7 +3031,7 @@ async function updateGroupViaState({
|
||||||
return generateLeftGroupChanges(group);
|
return generateLeftGroupChanges(group);
|
||||||
}
|
}
|
||||||
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
|
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`updateGroupViaState/${logId}: Credential for today failed, failing over to tomorrow...`
|
`updateGroupViaState/${logId}: Credential for today failed, failing over to tomorrow...`
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
|
@ -3120,7 +3114,7 @@ async function updateGroupViaLogs({
|
||||||
authCredentialBase64: groupCredentials.today.credential,
|
authCredentialBase64: groupCredentials.today.credential,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
window.log.info(
|
log.info(
|
||||||
`updateGroupViaLogs/${logId}: Getting group delta from ${group.revision} to ${newRevision} for group groupv2(${group.groupId})...`
|
`updateGroupViaLogs/${logId}: Getting group delta from ${group.revision} to ${newRevision} for group groupv2(${group.groupId})...`
|
||||||
);
|
);
|
||||||
const result = await getGroupDelta(deltaOptions);
|
const result = await getGroupDelta(deltaOptions);
|
||||||
|
@ -3128,7 +3122,7 @@ async function updateGroupViaLogs({
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
|
if (error.code === TEMPORAL_AUTH_REJECTED_CODE) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`updateGroupViaLogs/${logId}: Credential for today failed, failing over to tomorrow...`
|
`updateGroupViaLogs/${logId}: Credential for today failed, failing over to tomorrow...`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3153,7 +3147,7 @@ async function generateLeftGroupChanges(
|
||||||
group: ConversationAttributesType
|
group: ConversationAttributesType
|
||||||
): Promise<UpdatesResultType> {
|
): Promise<UpdatesResultType> {
|
||||||
const logId = idForLogging(group.groupId);
|
const logId = idForLogging(group.groupId);
|
||||||
window.log.info(`generateLeftGroupChanges/${logId}: Starting...`);
|
log.info(`generateLeftGroupChanges/${logId}: Starting...`);
|
||||||
const ourConversationId = window.ConversationController.getOurConversationId();
|
const ourConversationId = window.ConversationController.getOurConversationId();
|
||||||
if (!ourConversationId) {
|
if (!ourConversationId) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -3166,7 +3160,7 @@ async function generateLeftGroupChanges(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (masterKey && groupInviteLinkPassword) {
|
if (masterKey && groupInviteLinkPassword) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`generateLeftGroupChanges/${logId}: Have invite link. Attempting to fetch latest revision with it.`
|
`generateLeftGroupChanges/${logId}: Have invite link. Attempting to fetch latest revision with it.`
|
||||||
);
|
);
|
||||||
const preJoinInfo = await getPreJoinGroupInfo(
|
const preJoinInfo = await getPreJoinGroupInfo(
|
||||||
|
@ -3177,7 +3171,7 @@ async function generateLeftGroupChanges(
|
||||||
revision = preJoinInfo.version;
|
revision = preJoinInfo.version;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'generateLeftGroupChanges: Failed to fetch latest revision via group link. Code:',
|
'generateLeftGroupChanges: Failed to fetch latest revision via group link. Code:',
|
||||||
error.code
|
error.code
|
||||||
);
|
);
|
||||||
|
@ -3323,7 +3317,7 @@ async function integrateGroupChanges({
|
||||||
const { groupChange, groupState } = changeState;
|
const { groupChange, groupState } = changeState;
|
||||||
|
|
||||||
if (!groupChange && !groupState) {
|
if (!groupChange && !groupState) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'integrateGroupChanges: item had neither groupState nor groupChange. Skipping.'
|
'integrateGroupChanges: item had neither groupState nor groupChange. Skipping.'
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -3346,7 +3340,7 @@ async function integrateGroupChanges({
|
||||||
finalMessages.push(groupChangeMessages);
|
finalMessages.push(groupChangeMessages);
|
||||||
finalMembers.push(members);
|
finalMembers.push(members);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`integrateGroupChanges/${logId}: Failed to apply change log, continuing to apply remaining change logs.`,
|
`integrateGroupChanges/${logId}: Failed to apply change log, continuing to apply remaining change logs.`,
|
||||||
error && error.stack ? error.stack : error
|
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}`,
|
`integrateGroupChange/${logId}: Applying full group state, from version ${group.revision} to ${groupState.version}`,
|
||||||
{
|
{
|
||||||
isChangePresent: Boolean(groupChange),
|
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}`
|
`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 oldVersion = group.revision;
|
||||||
const newVersion = decryptedGroupState.version;
|
const newVersion = decryptedGroupState.version;
|
||||||
window.log.info(
|
log.info(
|
||||||
`getCurrentGroupState/${logId}: Applying full group state, from version ${oldVersion} to ${newVersion}.`
|
`getCurrentGroupState/${logId}: Applying full group state, from version ${oldVersion} to ${newVersion}.`
|
||||||
);
|
);
|
||||||
const { newAttributes, newProfileKeys } = await applyGroupState({
|
const { newAttributes, newProfileKeys } = await applyGroupState({
|
||||||
|
@ -3831,7 +3825,7 @@ function extractDiffs({
|
||||||
conversationId: lastPendingConversationId,
|
conversationId: lastPendingConversationId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`extractDiffs/${logId}: pendingCount was 1, no last conversationId available`
|
`extractDiffs/${logId}: pendingCount was 1, no last conversationId available`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4016,7 +4010,7 @@ function extractDiffs({
|
||||||
|
|
||||||
const result = compact([message, timerNotification]);
|
const result = compact([message, timerNotification]);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`extractDiffs/${logId} complete, generated ${result.length} change messages`
|
`extractDiffs/${logId} complete, generated ${result.length} change messages`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -4090,7 +4084,7 @@ async function applyGroupChange({
|
||||||
);
|
);
|
||||||
|
|
||||||
if (members[conversation.id]) {
|
if (members[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to add member failed; already in members.`
|
`applyGroupChange/${logId}: Attempt to add member failed; already in members.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -4104,7 +4098,7 @@ async function applyGroupChange({
|
||||||
};
|
};
|
||||||
|
|
||||||
if (pendingMembers[conversation.id]) {
|
if (pendingMembers[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Removing newly-added member from pendingMembers.`
|
`applyGroupChange/${logId}: Removing newly-added member from pendingMembers.`
|
||||||
);
|
);
|
||||||
delete pendingMembers[conversation.id];
|
delete pendingMembers[conversation.id];
|
||||||
|
@ -4144,7 +4138,7 @@ async function applyGroupChange({
|
||||||
if (members[conversation.id]) {
|
if (members[conversation.id]) {
|
||||||
delete members[conversation.id];
|
delete members[conversation.id];
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to remove member failed; was not in members.`
|
`applyGroupChange/${logId}: Attempt to remove member failed; was not in members.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4207,13 +4201,13 @@ async function applyGroupChange({
|
||||||
);
|
);
|
||||||
|
|
||||||
if (members[conversation.id]) {
|
if (members[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to add pendingMember failed; was already in members.`
|
`applyGroupChange/${logId}: Attempt to add pendingMember failed; was already in members.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pendingMembers[conversation.id]) {
|
if (pendingMembers[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to add pendingMember failed; was already in pendingMembers.`
|
`applyGroupChange/${logId}: Attempt to add pendingMember failed; was already in pendingMembers.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -4253,7 +4247,7 @@ async function applyGroupChange({
|
||||||
if (pendingMembers[conversation.id]) {
|
if (pendingMembers[conversation.id]) {
|
||||||
delete pendingMembers[conversation.id];
|
delete pendingMembers[conversation.id];
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to remove pendingMember failed; was not in pendingMembers.`
|
`applyGroupChange/${logId}: Attempt to remove pendingMember failed; was not in pendingMembers.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4280,13 +4274,13 @@ async function applyGroupChange({
|
||||||
if (pendingMembers[conversation.id]) {
|
if (pendingMembers[conversation.id]) {
|
||||||
delete pendingMembers[conversation.id];
|
delete pendingMembers[conversation.id];
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was not in pendingMembers.`
|
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was not in pendingMembers.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (members[conversation.id]) {
|
if (members[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was already in members.`
|
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was already in members.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -4310,7 +4304,7 @@ async function applyGroupChange({
|
||||||
if (title && title.content === 'title') {
|
if (title && title.content === 'title') {
|
||||||
result.name = title.title;
|
result.name = title.title;
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Clearing group title due to missing data.`
|
`applyGroupChange/${logId}: Clearing group title due to missing data.`
|
||||||
);
|
);
|
||||||
result.name = undefined;
|
result.name = undefined;
|
||||||
|
@ -4335,7 +4329,7 @@ async function applyGroupChange({
|
||||||
result.expireTimer =
|
result.expireTimer =
|
||||||
disappearingMessagesTimer.disappearingMessagesDuration;
|
disappearingMessagesTimer.disappearingMessagesDuration;
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Clearing group expireTimer due to missing data.`
|
`applyGroupChange/${logId}: Clearing group expireTimer due to missing data.`
|
||||||
);
|
);
|
||||||
result.expireTimer = undefined;
|
result.expireTimer = undefined;
|
||||||
|
@ -4395,19 +4389,19 @@ async function applyGroupChange({
|
||||||
);
|
);
|
||||||
|
|
||||||
if (members[conversation.id]) {
|
if (members[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in members.`
|
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in members.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pendingMembers[conversation.id]) {
|
if (pendingMembers[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in pendingMembers.`
|
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in pendingMembers.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pendingAdminApprovalMembers[conversation.id]) {
|
if (pendingAdminApprovalMembers[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in pendingAdminApprovalMembers.`
|
`applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in pendingAdminApprovalMembers.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -4447,7 +4441,7 @@ async function applyGroupChange({
|
||||||
if (pendingAdminApprovalMembers[conversation.id]) {
|
if (pendingAdminApprovalMembers[conversation.id]) {
|
||||||
delete pendingAdminApprovalMembers[conversation.id];
|
delete pendingAdminApprovalMembers[conversation.id];
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to remove pendingAdminApproval failed; was not in pendingAdminApprovalMembers.`
|
`applyGroupChange/${logId}: Attempt to remove pendingAdminApproval failed; was not in pendingAdminApprovalMembers.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4474,19 +4468,19 @@ async function applyGroupChange({
|
||||||
if (pendingAdminApprovalMembers[conversation.id]) {
|
if (pendingAdminApprovalMembers[conversation.id]) {
|
||||||
delete pendingAdminApprovalMembers[conversation.id];
|
delete pendingAdminApprovalMembers[conversation.id];
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to promote pendingAdminApproval failed; was not in pendingAdminApprovalMembers.`
|
`applyGroupChange/${logId}: Attempt to promote pendingAdminApproval failed; was not in pendingAdminApprovalMembers.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (pendingMembers[conversation.id]) {
|
if (pendingMembers[conversation.id]) {
|
||||||
delete pendingAdminApprovalMembers[conversation.id];
|
delete pendingAdminApprovalMembers[conversation.id];
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Deleted pendingAdminApproval from pendingMembers.`
|
`applyGroupChange/${logId}: Deleted pendingAdminApproval from pendingMembers.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (members[conversation.id]) {
|
if (members[conversation.id]) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was already in members.`
|
`applyGroupChange/${logId}: Attempt to promote pendingMember failed; was already in members.`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -4517,7 +4511,7 @@ async function applyGroupChange({
|
||||||
if (descriptionBytes && descriptionBytes.content === 'descriptionText') {
|
if (descriptionBytes && descriptionBytes.content === 'descriptionText') {
|
||||||
result.description = descriptionBytes.descriptionText;
|
result.description = descriptionBytes.descriptionText;
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyGroupChange/${logId}: Clearing group description due to missing data.`
|
`applyGroupChange/${logId}: Clearing group description due to missing data.`
|
||||||
);
|
);
|
||||||
result.description = undefined;
|
result.description = undefined;
|
||||||
|
@ -4608,7 +4602,7 @@ export async function applyNewAvatar(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`applyNewAvatar/${logId} Failed to handle avatar, clearing it`,
|
`applyNewAvatar/${logId} Failed to handle avatar, clearing it`,
|
||||||
error.stack
|
error.stack
|
||||||
);
|
);
|
||||||
|
@ -4952,14 +4946,14 @@ function decryptGroupChange(
|
||||||
'actions.sourceUuid'
|
'actions.sourceUuid'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt sourceUuid.`,
|
`decryptGroupChange/${logId}: Unable to decrypt sourceUuid.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(result.sourceUuid)) {
|
if (!window.isValidGuid(result.sourceUuid)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Invalid sourceUuid. Clearing sourceUuid.`
|
`decryptGroupChange/${logId}: Invalid sourceUuid. Clearing sourceUuid.`
|
||||||
);
|
);
|
||||||
result.sourceUuid = undefined;
|
result.sourceUuid = undefined;
|
||||||
|
@ -5007,7 +5001,7 @@ function decryptGroupChange(
|
||||||
'actions.deleteMembers.deletedUserId'
|
'actions.deleteMembers.deletedUserId'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt deleteMembers.deletedUserId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt deleteMembers.deletedUserId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5015,7 +5009,7 @@ function decryptGroupChange(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(userId)) {
|
if (!window.isValidGuid(userId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Dropping deleteMember due to invalid userId`
|
`decryptGroupChange/${logId}: Dropping deleteMember due to invalid userId`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5041,7 +5035,7 @@ function decryptGroupChange(
|
||||||
'actions.modifyMemberRoles.userId'
|
'actions.modifyMemberRoles.userId'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt modifyMemberRole.userId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt modifyMemberRole.userId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5049,7 +5043,7 @@ function decryptGroupChange(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(userId)) {
|
if (!window.isValidGuid(userId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Dropping modifyMemberRole due to invalid userId`
|
`decryptGroupChange/${logId}: Dropping modifyMemberRole due to invalid userId`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5093,7 +5087,7 @@ function decryptGroupChange(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(decryptedPresentation.uuid)) {
|
if (!window.isValidGuid(decryptedPresentation.uuid)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Dropping modifyMemberProfileKey due to invalid userId`
|
`decryptGroupChange/${logId}: Dropping modifyMemberProfileKey due to invalid userId`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5151,7 +5145,7 @@ function decryptGroupChange(
|
||||||
'actions.deletePendingMembers.deletedUserId'
|
'actions.deletePendingMembers.deletedUserId'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt deletePendingMembers.deletedUserId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt deletePendingMembers.deletedUserId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5159,7 +5153,7 @@ function decryptGroupChange(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(userId)) {
|
if (!window.isValidGuid(userId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Dropping deletePendingMember due to invalid deletedUserId`
|
`decryptGroupChange/${logId}: Dropping deletePendingMember due to invalid deletedUserId`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5194,7 +5188,7 @@ function decryptGroupChange(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(decryptedPresentation.uuid)) {
|
if (!window.isValidGuid(decryptedPresentation.uuid)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Dropping modifyMemberProfileKey due to invalid userId`
|
`decryptGroupChange/${logId}: Dropping modifyMemberProfileKey due to invalid userId`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5223,7 +5217,7 @@ function decryptGroupChange(
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt modifyTitle.title`,
|
`decryptGroupChange/${logId}: Unable to decrypt modifyTitle.title`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5250,7 +5244,7 @@ function decryptGroupChange(
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt modifyDisappearingMessagesTimer.timer`,
|
`decryptGroupChange/${logId}: Unable to decrypt modifyDisappearingMessagesTimer.timer`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5323,7 +5317,7 @@ function decryptGroupChange(
|
||||||
logId
|
logId
|
||||||
);
|
);
|
||||||
if (!decrypted) {
|
if (!decrypted) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt addPendingAdminApproval.added. Dropping member.`
|
`decryptGroupChange/${logId}: Unable to decrypt addPendingAdminApproval.added. Dropping member.`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -5353,14 +5347,14 @@ function decryptGroupChange(
|
||||||
'actions.deleteMemberPendingAdminApprovals'
|
'actions.deleteMemberPendingAdminApprovals'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt deletePendingApproval.deletedUserId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt deletePendingApproval.deletedUserId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!window.isValidGuid(userId)) {
|
if (!window.isValidGuid(userId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Dropping deletePendingApproval due to invalid deletedUserId`
|
`decryptGroupChange/${logId}: Dropping deletePendingApproval due to invalid deletedUserId`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5391,7 +5385,7 @@ function decryptGroupChange(
|
||||||
'actions.promoteMemberPendingAdminApprovals.userId'
|
'actions.promoteMemberPendingAdminApprovals.userId'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt promoteAdminApproval.userId. Dropping member.`,
|
`decryptGroupChange/${logId}: Unable to decrypt promoteAdminApproval.userId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5433,7 +5427,7 @@ function decryptGroupChange(
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupChange/${logId}: Unable to decrypt modifyDescription.descriptionBytes`,
|
`decryptGroupChange/${logId}: Unable to decrypt modifyDescription.descriptionBytes`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5526,7 +5520,7 @@ function decryptGroupState(
|
||||||
decryptGroupBlob(clientZkGroupCipher, groupState.title)
|
decryptGroupBlob(clientZkGroupCipher, groupState.title)
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupState/${logId}: Unable to decrypt title. Clearing it.`,
|
`decryptGroupState/${logId}: Unable to decrypt title. Clearing it.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5549,7 +5543,7 @@ function decryptGroupState(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupState/${logId}: Unable to decrypt disappearing message timer. Clearing it.`,
|
`decryptGroupState/${logId}: Unable to decrypt disappearing message timer. Clearing it.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5633,7 +5627,7 @@ function decryptGroupState(
|
||||||
decryptGroupBlob(clientZkGroupCipher, groupState.descriptionBytes)
|
decryptGroupBlob(clientZkGroupCipher, groupState.descriptionBytes)
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptGroupState/${logId}: Unable to decrypt descriptionBytes. Clearing it.`,
|
`decryptGroupState/${logId}: Unable to decrypt descriptionBytes. Clearing it.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5674,7 +5668,7 @@ function decryptMember(
|
||||||
'decryptMember.userId'
|
'decryptMember.userId'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMember/${logId}: Unable to decrypt member userid. Dropping member.`,
|
`decryptMember/${logId}: Unable to decrypt member userid. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5682,9 +5676,7 @@ function decryptMember(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(userId)) {
|
if (!window.isValidGuid(userId)) {
|
||||||
window.log.warn(
|
log.warn(`decryptMember/${logId}: Dropping member due to invalid userId`);
|
||||||
`decryptMember/${logId}: Dropping member due to invalid userId`
|
|
||||||
);
|
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -5747,7 +5739,7 @@ function decryptMemberPendingProfileKey(
|
||||||
'decryptMemberPendingProfileKey.addedByUserId'
|
'decryptMemberPendingProfileKey.addedByUserId'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member addedByUserId. Dropping member.`,
|
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member addedByUserId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5755,7 +5747,7 @@ function decryptMemberPendingProfileKey(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(addedByUserId)) {
|
if (!window.isValidGuid(addedByUserId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to invalid addedByUserId`
|
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to invalid addedByUserId`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -5765,7 +5757,7 @@ function decryptMemberPendingProfileKey(
|
||||||
const timestamp = normalizeTimestamp(member.timestamp);
|
const timestamp = normalizeTimestamp(member.timestamp);
|
||||||
|
|
||||||
if (!member.member) {
|
if (!member.member) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to missing member details`
|
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to missing member details`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5787,7 +5779,7 @@ function decryptMemberPendingProfileKey(
|
||||||
'decryptMemberPendingProfileKey.member.userId'
|
'decryptMemberPendingProfileKey.member.userId'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member userId. Dropping member.`,
|
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member userId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5795,7 +5787,7 @@ function decryptMemberPendingProfileKey(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(decryptedUserId)) {
|
if (!window.isValidGuid(decryptedUserId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to invalid member.userId`
|
`decryptMemberPendingProfileKey/${logId}: Dropping pending member due to invalid member.userId`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5812,14 +5804,14 @@ function decryptMemberPendingProfileKey(
|
||||||
decryptedUserId
|
decryptedUserId
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member profileKey. Dropping profileKey.`,
|
`decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member profileKey. Dropping profileKey.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidProfileKey(decryptedProfileKey)) {
|
if (!isValidProfileKey(decryptedProfileKey)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingProfileKey/${logId}: Dropping profileKey, since it was invalid`
|
`decryptMemberPendingProfileKey/${logId}: Dropping profileKey, since it was invalid`
|
||||||
);
|
);
|
||||||
decryptedProfileKey = undefined;
|
decryptedProfileKey = undefined;
|
||||||
|
@ -5874,7 +5866,7 @@ function decryptMemberPendingAdminApproval(
|
||||||
'decryptMemberPendingAdminApproval.userId'
|
'decryptMemberPendingAdminApproval.userId'
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt pending member userId. Dropping member.`,
|
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt pending member userId. Dropping member.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -5882,7 +5874,7 @@ function decryptMemberPendingAdminApproval(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isValidGuid(decryptedUserId)) {
|
if (!window.isValidGuid(decryptedUserId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingAdminApproval/${logId}: Invalid userId. Dropping member.`
|
`decryptMemberPendingAdminApproval/${logId}: Invalid userId. Dropping member.`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5899,14 +5891,14 @@ function decryptMemberPendingAdminApproval(
|
||||||
decryptedUserId
|
decryptedUserId
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt profileKey. Dropping profileKey.`,
|
`decryptMemberPendingAdminApproval/${logId}: Unable to decrypt profileKey. Dropping profileKey.`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidProfileKey(decryptedProfileKey)) {
|
if (!isValidProfileKey(decryptedProfileKey)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`decryptMemberPendingAdminApproval/${logId}: Dropping profileKey, since it was invalid`
|
`decryptMemberPendingAdminApproval/${logId}: Dropping profileKey, since it was invalid`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import type { ConversationAttributesType } from '../model-types.d';
|
||||||
import type { ConversationModel } from '../models/conversations';
|
import type { ConversationModel } from '../models/conversations';
|
||||||
import type { PreJoinConversationType } from '../state/ducks/conversations';
|
import type { PreJoinConversationType } from '../state/ducks/conversations';
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
export async function joinViaLink(hash: string): Promise<void> {
|
export async function joinViaLink(hash: string): Promise<void> {
|
||||||
let inviteLinkPassword: string;
|
let inviteLinkPassword: string;
|
||||||
|
@ -28,7 +29,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
||||||
({ inviteLinkPassword, masterKey } = parseGroupLink(hash));
|
({ inviteLinkPassword, masterKey } = parseGroupLink(hash));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : 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) {
|
if (error && error.name === LINK_VERSION_ERROR) {
|
||||||
showErrorDialog(
|
showErrorDialog(
|
||||||
window.i18n('GroupV2--join--unknown-link-version'),
|
window.i18n('GroupV2--join--unknown-link-version'),
|
||||||
|
@ -58,7 +59,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
||||||
existingConversation &&
|
existingConversation &&
|
||||||
existingConversation.hasMember(ourConversationId)
|
existingConversation.hasMember(ourConversationId)
|
||||||
) {
|
) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`joinViaLink/${logId}: Already a member of group, opening conversation`
|
`joinViaLink/${logId}: Already a member of group, opening conversation`
|
||||||
);
|
);
|
||||||
window.reduxActions.conversations.openConversationInternal({
|
window.reduxActions.conversations.openConversationInternal({
|
||||||
|
@ -84,7 +85,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorString = error && error.stack ? error.stack : error;
|
const errorString = error && error.stack ? error.stack : error;
|
||||||
window.log.error(
|
log.error(
|
||||||
`joinViaLink/${logId}: Failed to fetch group info - ${errorString}`
|
`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.ADMINISTRATOR &&
|
||||||
result.addFromInviteLink !== ACCESS_ENUM.ANY
|
result.addFromInviteLink !== ACCESS_ENUM.ANY
|
||||||
) {
|
) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`joinViaLink/${logId}: addFromInviteLink value of ${result.addFromInviteLink} is invalid`
|
`joinViaLink/${logId}: addFromInviteLink value of ${result.addFromInviteLink} is invalid`
|
||||||
);
|
);
|
||||||
showErrorDialog(
|
showErrorDialog(
|
||||||
|
@ -136,7 +137,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
||||||
existingConversation &&
|
existingConversation &&
|
||||||
existingConversation.isMemberAwaitingApproval(ourConversationId)
|
existingConversation.isMemberAwaitingApproval(ourConversationId)
|
||||||
) {
|
) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`joinViaLink/${logId}: Already awaiting approval, opening conversation`
|
`joinViaLink/${logId}: Already awaiting approval, opening conversation`
|
||||||
);
|
);
|
||||||
window.reduxActions.conversations.openConversationInternal({
|
window.reduxActions.conversations.openConversationInternal({
|
||||||
|
@ -226,7 +227,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
||||||
(approvalRequired &&
|
(approvalRequired &&
|
||||||
targetConversation.isMemberAwaitingApproval(ourConversationId)))
|
targetConversation.isMemberAwaitingApproval(ourConversationId)))
|
||||||
) {
|
) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`joinViaLink/${logId}: User is part of group on second check, opening conversation`
|
`joinViaLink/${logId}: User is part of group on second check, opening conversation`
|
||||||
);
|
);
|
||||||
window.reduxActions.conversations.openConversationInternal({
|
window.reduxActions.conversations.openConversationInternal({
|
||||||
|
@ -339,7 +340,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
||||||
getPreJoinConversation()
|
getPreJoinConversation()
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(`joinViaLink/${logId}: Showing modal`);
|
log.info(`joinViaLink/${logId}: Showing modal`);
|
||||||
|
|
||||||
let groupV2InfoDialog:
|
let groupV2InfoDialog:
|
||||||
| Backbone.View
|
| Backbone.View
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { LoggerType } from '../logging/log';
|
import type { LoggerType } from '../types/Logging';
|
||||||
import type { ParsedJob } from './types';
|
import type { ParsedJob } from './types';
|
||||||
|
|
||||||
export class JobLogger implements LoggerType {
|
export class JobLogger implements LoggerType {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { assert } from '../util/assert';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
import { JobLogger } from './JobLogger';
|
import { JobLogger } from './JobLogger';
|
||||||
import * as Errors from '../types/errors';
|
import * as Errors from '../types/errors';
|
||||||
|
import type { LoggerType } from '../types/Logging';
|
||||||
|
|
||||||
const noopOnCompleteCallbacks = {
|
const noopOnCompleteCallbacks = {
|
||||||
resolve: noop,
|
resolve: noop,
|
||||||
|
@ -39,7 +40,7 @@ type JobQueueOptions = {
|
||||||
/**
|
/**
|
||||||
* A custom logger. Might be overwritten in test.
|
* A custom logger. Might be overwritten in test.
|
||||||
*/
|
*/
|
||||||
logger?: log.LoggerType;
|
logger?: LoggerType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export abstract class JobQueue<T> {
|
export abstract class JobQueue<T> {
|
||||||
|
@ -49,7 +50,7 @@ export abstract class JobQueue<T> {
|
||||||
|
|
||||||
private readonly store: JobQueueStore;
|
private readonly store: JobQueueStore;
|
||||||
|
|
||||||
private readonly logger: log.LoggerType;
|
private readonly logger: LoggerType;
|
||||||
|
|
||||||
private readonly logPrefix: string;
|
private readonly logPrefix: string;
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ export abstract class JobQueue<T> {
|
||||||
*/
|
*/
|
||||||
protected abstract run(
|
protected abstract run(
|
||||||
job: Readonly<ParsedJob<T>>,
|
job: Readonly<ParsedJob<T>>,
|
||||||
extra?: Readonly<{ attempt?: number; log?: log.LoggerType }>
|
extra?: Readonly<{ attempt?: number; log?: LoggerType }>
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// 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 { waitForOnline } from '../../util/waitForOnline';
|
||||||
import { sleep } from '../../util/sleep';
|
import { sleep } from '../../util/sleep';
|
||||||
import { exponentialBackoffSleepTime } from '../../util/exponentialBackoff';
|
import { exponentialBackoffSleepTime } from '../../util/exponentialBackoff';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// 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 { parseIntWithFallback } from '../../util/parseIntWithFallback';
|
||||||
import { sleepFor413RetryAfterTimeIfApplicable } from './sleepFor413RetryAfterTimeIfApplicable';
|
import { sleepFor413RetryAfterTimeIfApplicable } from './sleepFor413RetryAfterTimeIfApplicable';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { chunk } from 'lodash';
|
import { chunk } from 'lodash';
|
||||||
import type { LoggerType } from '../../logging/log';
|
import type { LoggerType } from '../../types/Logging';
|
||||||
import { getSendOptions } from '../../util/getSendOptions';
|
import { getSendOptions } from '../../util/getSendOptions';
|
||||||
import { handleMessageSend, SendTypesType } from '../../util/handleMessageSend';
|
import { handleMessageSend, SendTypesType } from '../../util/handleMessageSend';
|
||||||
import { isNotNil } from '../../util/isNotNil';
|
import { isNotNil } from '../../util/isNotNil';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// 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 { sleep } from '../../util/sleep';
|
||||||
import { parseRetryAfter } from '../../util/parseRetryAfter';
|
import { parseRetryAfter } from '../../util/parseRetryAfter';
|
||||||
import { isRecord } from '../../util/isRecord';
|
import { isRecord } from '../../util/isRecord';
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
|
|
||||||
import PQueue from 'p-queue';
|
import PQueue from 'p-queue';
|
||||||
import type { LoggerType } from '../logging/log';
|
import type { LoggerType } from '../types/Logging';
|
||||||
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
|
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
|
||||||
import { commonShouldJobContinue } from './helpers/commonShouldJobContinue';
|
import { commonShouldJobContinue } from './helpers/commonShouldJobContinue';
|
||||||
import { sleepFor413RetryAfterTimeIfApplicable } from './helpers/sleepFor413RetryAfterTimeIfApplicable';
|
import { sleepFor413RetryAfterTimeIfApplicable } from './helpers/sleepFor413RetryAfterTimeIfApplicable';
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
|
|
||||||
import * as durations from '../util/durations';
|
import * as durations from '../util/durations';
|
||||||
import type { LoggerType } from '../logging/log';
|
import type { LoggerType } from '../types/Logging';
|
||||||
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
|
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
|
||||||
import {
|
import {
|
||||||
SyncType,
|
SyncType,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import * as durations from '../util/durations';
|
||||||
import { strictAssert } from '../util/assert';
|
import { strictAssert } from '../util/assert';
|
||||||
import { waitForOnline } from '../util/waitForOnline';
|
import { waitForOnline } from '../util/waitForOnline';
|
||||||
import { isDone as isDeviceLinked } from '../util/registration';
|
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 { map } from '../util/iterables';
|
||||||
import { sleep } from '../util/sleep';
|
import { sleep } from '../util/sleep';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
|
|
||||||
import * as durations from '../util/durations';
|
import * as durations from '../util/durations';
|
||||||
import type { LoggerType } from '../logging/log';
|
import type { LoggerType } from '../types/Logging';
|
||||||
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
|
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
|
||||||
import {
|
import {
|
||||||
SyncType,
|
SyncType,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import * as durations from '../util/durations';
|
import * as durations from '../util/durations';
|
||||||
import type { LoggerType } from '../logging/log';
|
import type { LoggerType } from '../types/Logging';
|
||||||
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
|
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
|
||||||
import { commonShouldJobContinue } from './helpers/commonShouldJobContinue';
|
import { commonShouldJobContinue } from './helpers/commonShouldJobContinue';
|
||||||
import { sendViewedReceipt } from '../util/sendViewedReceipt';
|
import { sendViewedReceipt } from '../util/sendViewedReceipt';
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
MIMEType,
|
MIMEType,
|
||||||
stringToMIMEType,
|
stringToMIMEType,
|
||||||
} from '../types/MIME';
|
} from '../types/MIME';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
const USER_AGENT = 'WhatsApp/2';
|
const USER_AGENT = 'WhatsApp/2';
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ async function fetchWithRedirects(
|
||||||
let nextHrefToLoad = href;
|
let nextHrefToLoad = href;
|
||||||
for (let i = 0; i < MAX_REQUEST_COUNT_WITH_REDIRECTS; i += 1) {
|
for (let i = 0; i < MAX_REQUEST_COUNT_WITH_REDIRECTS; i += 1) {
|
||||||
if (urlsSeen.has(nextHrefToLoad)) {
|
if (urlsSeen.has(nextHrefToLoad)) {
|
||||||
window.log.warn('fetchWithRedirects: found a redirect loop');
|
log.warn('fetchWithRedirects: found a redirect loop');
|
||||||
throw new Error('redirect loop');
|
throw new Error('redirect loop');
|
||||||
}
|
}
|
||||||
urlsSeen.add(nextHrefToLoad);
|
urlsSeen.add(nextHrefToLoad);
|
||||||
|
@ -100,7 +101,7 @@ async function fetchWithRedirects(
|
||||||
|
|
||||||
const location = response.headers.get('location');
|
const location = response.headers.get('location');
|
||||||
if (!location) {
|
if (!location) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'fetchWithRedirects: got a redirect status code but no Location header; bailing'
|
'fetchWithRedirects: got a redirect status code but no Location header; bailing'
|
||||||
);
|
);
|
||||||
throw new Error('no location with redirect');
|
throw new Error('no location with redirect');
|
||||||
|
@ -108,7 +109,7 @@ async function fetchWithRedirects(
|
||||||
|
|
||||||
const newUrl = maybeParseUrl(location, nextHrefToLoad);
|
const newUrl = maybeParseUrl(location, nextHrefToLoad);
|
||||||
if (newUrl?.protocol !== 'https:') {
|
if (newUrl?.protocol !== 'https:') {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'fetchWithRedirects: got a redirect status code and an invalid Location header'
|
'fetchWithRedirects: got a redirect status code and an invalid Location header'
|
||||||
);
|
);
|
||||||
throw new Error('invalid location');
|
throw new Error('invalid location');
|
||||||
|
@ -117,7 +118,7 @@ async function fetchWithRedirects(
|
||||||
nextHrefToLoad = newUrl.href;
|
nextHrefToLoad = newUrl.href;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.warn('fetchWithRedirects: too many redirects');
|
log.warn('fetchWithRedirects: too many redirects');
|
||||||
throw new Error('too many redirects');
|
throw new Error('too many redirects');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +322,7 @@ const getHtmlDocument = async (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'getHtmlDocument: error when reading body; continuing with what we got'
|
'getHtmlDocument: error when reading body; continuing with what we got'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -370,9 +371,7 @@ const parseMetadata = (
|
||||||
const title =
|
const title =
|
||||||
getOpenGraphContent(document, ['og:title']) || document.title.trim();
|
getOpenGraphContent(document, ['og:title']) || document.title.trim();
|
||||||
if (!title) {
|
if (!title) {
|
||||||
window.log.warn(
|
log.warn("parseMetadata: HTML document doesn't have a title; bailing");
|
||||||
"parseMetadata: HTML document doesn't have a title; bailing"
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,28 +448,28 @@ export async function fetchLinkPreviewMetadata(
|
||||||
signal: abortSignal as AbortSignalForNodeFetch,
|
signal: abortSignal as AbortSignalForNodeFetch,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'fetchLinkPreviewMetadata: failed to fetch link preview HTML; bailing'
|
'fetchLinkPreviewMetadata: failed to fetch link preview HTML; bailing'
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`fetchLinkPreviewMetadata: got a ${response.status} status code; bailing`
|
`fetchLinkPreviewMetadata: got a ${response.status} status code; bailing`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.body) {
|
if (!response.body) {
|
||||||
window.log.warn('fetchLinkPreviewMetadata: no response body; bailing');
|
log.warn('fetchLinkPreviewMetadata: no response body; bailing');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!isInlineContentDisposition(response.headers.get('Content-Disposition'))
|
!isInlineContentDisposition(response.headers.get('Content-Disposition'))
|
||||||
) {
|
) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'fetchLinkPreviewMetadata: Content-Disposition header is not inline; bailing'
|
'fetchLinkPreviewMetadata: Content-Disposition header is not inline; bailing'
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -484,17 +483,13 @@ export async function fetchLinkPreviewMetadata(
|
||||||
response.headers.get('Content-Length')
|
response.headers.get('Content-Length')
|
||||||
);
|
);
|
||||||
if (contentLength < MIN_HTML_CONTENT_LENGTH) {
|
if (contentLength < MIN_HTML_CONTENT_LENGTH) {
|
||||||
window.log.warn(
|
log.warn('fetchLinkPreviewMetadata: Content-Length is too short; bailing');
|
||||||
'fetchLinkPreviewMetadata: Content-Length is too short; bailing'
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentType = parseContentType(response.headers.get('Content-Type'));
|
const contentType = parseContentType(response.headers.get('Content-Type'));
|
||||||
if (contentType.type !== 'text/html') {
|
if (contentType.type !== 'text/html') {
|
||||||
window.log.warn(
|
log.warn('fetchLinkPreviewMetadata: Content-Type is not HTML; bailing');
|
||||||
'fetchLinkPreviewMetadata: Content-Type is not HTML; bailing'
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +541,7 @@ export async function fetchLinkPreviewImage(
|
||||||
signal: abortSignal as AbortSignalForNodeFetch,
|
signal: abortSignal as AbortSignalForNodeFetch,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.warn('fetchLinkPreviewImage: failed to fetch image; bailing');
|
log.warn('fetchLinkPreviewImage: failed to fetch image; bailing');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,7 +550,7 @@ export async function fetchLinkPreviewImage(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`fetchLinkPreviewImage: got a ${response.status} status code; bailing`
|
`fetchLinkPreviewImage: got a ${response.status} status code; bailing`
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -565,13 +560,11 @@ export async function fetchLinkPreviewImage(
|
||||||
response.headers.get('Content-Length')
|
response.headers.get('Content-Length')
|
||||||
);
|
);
|
||||||
if (contentLength < MIN_IMAGE_CONTENT_LENGTH) {
|
if (contentLength < MIN_IMAGE_CONTENT_LENGTH) {
|
||||||
window.log.warn(
|
log.warn('fetchLinkPreviewImage: Content-Length is too short; bailing');
|
||||||
'fetchLinkPreviewImage: Content-Length is too short; bailing'
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (contentLength > MAX_IMAGE_CONTENT_LENGTH) {
|
if (contentLength > MAX_IMAGE_CONTENT_LENGTH) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'fetchLinkPreviewImage: Content-Length is too large or is unset; bailing'
|
'fetchLinkPreviewImage: Content-Length is too large or is unset; bailing'
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -581,9 +574,7 @@ export async function fetchLinkPreviewImage(
|
||||||
response.headers.get('Content-Type')
|
response.headers.get('Content-Type')
|
||||||
);
|
);
|
||||||
if (!contentType || !VALID_IMAGE_MIME_TYPES.has(contentType)) {
|
if (!contentType || !VALID_IMAGE_MIME_TYPES.has(contentType)) {
|
||||||
window.log.warn(
|
log.warn('fetchLinkPreviewImage: Content-Type is not an image; bailing');
|
||||||
'fetchLinkPreviewImage: Content-Type is not an image; bailing'
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,7 +582,7 @@ export async function fetchLinkPreviewImage(
|
||||||
try {
|
try {
|
||||||
data = await response.arrayBuffer();
|
data = await response.arrayBuffer();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.warn('fetchLinkPreviewImage: failed to read body; bailing');
|
log.warn('fetchLinkPreviewImage: failed to read body; bailing');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright 2018-2021 Signal Messenger, LLC
|
// Copyright 2018-2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { memoize, sortBy } from 'lodash';
|
||||||
|
import { ipcRenderer as ipc } from 'electron';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
import { gzip } from 'zlib';
|
import { gzip } from 'zlib';
|
||||||
|
@ -8,6 +10,19 @@ import pify from 'pify';
|
||||||
import got, { Response } from 'got';
|
import got, { Response } from 'got';
|
||||||
import { getUserAgent } from '../util/getUserAgent';
|
import { getUserAgent } from '../util/getUserAgent';
|
||||||
import { maybeParseUrl } from '../util/url';
|
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';
|
const BASE_URL = 'https://debuglogs.org';
|
||||||
|
|
||||||
|
@ -34,7 +49,7 @@ const parseTokenBody = (
|
||||||
return body;
|
return body;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const uploadDebugLogs = async (
|
export const upload = async (
|
||||||
content: string,
|
content: string,
|
||||||
appVersion: string
|
appVersion: string
|
||||||
): Promise<string> => {
|
): Promise<string> => {
|
||||||
|
@ -62,7 +77,7 @@ export const uploadDebugLogs = async (
|
||||||
filename: `signal-desktop-debug-log-${appVersion}.txt.gz`,
|
filename: `signal-desktop-debug-log-${appVersion}.txt.gz`,
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.info('Debug log upload starting...');
|
log.info('Debug log upload starting...');
|
||||||
try {
|
try {
|
||||||
const { statusCode, body } = await got.post(url, { headers, body: form });
|
const { statusCode, body } = await got.post(url, { headers, body: form });
|
||||||
if (statusCode !== 204) {
|
if (statusCode !== 204) {
|
||||||
|
@ -76,7 +91,92 @@ export const uploadDebugLogs = async (
|
||||||
`Got threw on upload to S3, got status ${response?.statusCode}, body '${response?.body}' `
|
`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}`;
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import { noop } from 'lodash';
|
import { noop } from 'lodash';
|
||||||
import { LogLevel } from './shared';
|
import { LogLevel } from './shared';
|
||||||
|
import { LogFunction } from '../types/Logging';
|
||||||
|
|
||||||
type LogAtLevelFnType = (
|
type LogAtLevelFnType = (
|
||||||
level: LogLevel,
|
level: LogLevel,
|
||||||
|
@ -12,23 +13,18 @@ type LogAtLevelFnType = (
|
||||||
let logAtLevel: LogAtLevelFnType = noop;
|
let logAtLevel: LogAtLevelFnType = noop;
|
||||||
let hasInitialized = false;
|
let hasInitialized = false;
|
||||||
|
|
||||||
type LogFn = (...args: ReadonlyArray<unknown>) => void;
|
export const fatal: LogFunction = (...args) =>
|
||||||
|
logAtLevel(LogLevel.Fatal, ...args);
|
||||||
export type LoggerType = {
|
export const error: LogFunction = (...args) =>
|
||||||
fatal: LogFn;
|
logAtLevel(LogLevel.Error, ...args);
|
||||||
error: LogFn;
|
export const warn: LogFunction = (...args) =>
|
||||||
warn: LogFn;
|
logAtLevel(LogLevel.Warn, ...args);
|
||||||
info: LogFn;
|
export const info: LogFunction = (...args) =>
|
||||||
debug: LogFn;
|
logAtLevel(LogLevel.Info, ...args);
|
||||||
trace: LogFn;
|
export const debug: LogFunction = (...args) =>
|
||||||
};
|
logAtLevel(LogLevel.Debug, ...args);
|
||||||
|
export const trace: LogFunction = (...args) =>
|
||||||
export const fatal: LogFn = (...args) => logAtLevel(LogLevel.Fatal, ...args);
|
logAtLevel(LogLevel.Trace, ...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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the low-level logging interface. Should be called early in a process's life, and
|
* Sets the low-level logging interface. Should be called early in a process's life, and
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
import { ipcRenderer as ipc } from 'electron';
|
import { ipcRenderer as ipc } from 'electron';
|
||||||
import _ from 'lodash';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import pino from 'pino';
|
import pino from 'pino';
|
||||||
import { createStream } from 'rotating-file-stream';
|
import { createStream } from 'rotating-file-stream';
|
||||||
|
@ -16,28 +15,15 @@ import {
|
||||||
LogLevel as SignalClientLogLevel,
|
LogLevel as SignalClientLogLevel,
|
||||||
} from '@signalapp/signal-client';
|
} from '@signalapp/signal-client';
|
||||||
|
|
||||||
import { uploadDebugLogs } from './debuglogs';
|
|
||||||
import { redactAll } from '../util/privacy';
|
|
||||||
import {
|
import {
|
||||||
FetchLogIpcData,
|
|
||||||
LogEntryType,
|
|
||||||
LogLevel,
|
LogLevel,
|
||||||
cleanArgs,
|
cleanArgs,
|
||||||
getLogLevelString,
|
getLogLevelString,
|
||||||
isFetchLogIpcData,
|
levelMaxLength,
|
||||||
isLogEntry,
|
|
||||||
} from './shared';
|
} from './shared';
|
||||||
import * as log from './log';
|
import * as log from './log';
|
||||||
import { reallyJsonStringify } from '../util/reallyJsonStringify';
|
|
||||||
import { Environment, getEnvironment } from '../environment';
|
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)
|
// Backwards-compatible logging, simple strings and no level (defaulted to INFO)
|
||||||
function now() {
|
function now() {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
@ -53,91 +39,6 @@ if (window.console) {
|
||||||
console.log = consoleLog;
|
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 globalLogger: undefined | pino.Logger;
|
||||||
let shouldRestart = false;
|
let shouldRestart = false;
|
||||||
|
|
||||||
|
@ -176,8 +77,6 @@ export function initialize(): void {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const publish = uploadDebugLogs;
|
|
||||||
|
|
||||||
// A modern logging interface for the browser
|
// A modern logging interface for the browser
|
||||||
|
|
||||||
function logAtLevel(level: LogLevel, ...args: ReadonlyArray<unknown>): void {
|
function logAtLevel(level: LogLevel, ...args: ReadonlyArray<unknown>): void {
|
||||||
|
@ -201,27 +100,26 @@ function logAtLevel(level: LogLevel, ...args: ReadonlyArray<unknown>): void {
|
||||||
|
|
||||||
log.setLogAtLevel(logAtLevel);
|
log.setLogAtLevel(logAtLevel);
|
||||||
|
|
||||||
window.log = {
|
window.SignalWindow = window.SignalWindow || {};
|
||||||
|
window.SignalWindow.log = {
|
||||||
fatal: log.fatal,
|
fatal: log.fatal,
|
||||||
error: log.error,
|
error: log.error,
|
||||||
warn: log.warn,
|
warn: log.warn,
|
||||||
info: log.info,
|
info: log.info,
|
||||||
debug: log.debug,
|
debug: log.debug,
|
||||||
trace: log.trace,
|
trace: log.trace,
|
||||||
fetch,
|
|
||||||
publish,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.onerror = (_message, _script, _line, _col, error) => {
|
window.onerror = (_message, _script, _line, _col, error) => {
|
||||||
const errorInfo = error && error.stack ? error.stack : JSON.stringify(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 => {
|
window.addEventListener('unhandledrejection', rejectionEvent => {
|
||||||
const error = rejectionEvent.reason;
|
const error = rejectionEvent.reason;
|
||||||
const errorString =
|
const errorString =
|
||||||
error && error.stack ? error.stack : JSON.stringify(error);
|
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(
|
initLogger(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import * as pino from 'pino';
|
import pino from 'pino';
|
||||||
import { isRecord } from '../util/isRecord';
|
import { isRecord } from '../util/isRecord';
|
||||||
import { redactAll } from '../util/privacy';
|
import { redactAll } from '../util/privacy';
|
||||||
import { missingCaseError } from '../util/missingCaseError';
|
import { missingCaseError } from '../util/missingCaseError';
|
||||||
|
@ -106,3 +106,10 @@ export function cleanArgs(args: ReadonlyArray<unknown>): string {
|
||||||
.join(' ')
|
.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
|
||||||
|
);
|
||||||
|
|
|
@ -15,7 +15,8 @@ import {
|
||||||
|
|
||||||
import { MessageModel } from '../models/messages';
|
import { MessageModel } from '../models/messages';
|
||||||
import { AttachmentType } from '../types/Attachment';
|
import { AttachmentType } from '../types/Attachment';
|
||||||
import { LoggerType } from '../window.d';
|
import { LoggerType } from '../types/Logging';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getMessageById,
|
getMessageById,
|
||||||
|
@ -179,7 +180,7 @@ async function _maybeStartJob(): Promise<void> {
|
||||||
|
|
||||||
async function _runJob(job?: AttachmentDownloadJobType): Promise<void> {
|
async function _runJob(job?: AttachmentDownloadJobType): Promise<void> {
|
||||||
if (!job) {
|
if (!job) {
|
||||||
window.log.warn('_runJob: Job was missing!');
|
log.warn('_runJob: Job was missing!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import { Collection, Model } from 'backbone';
|
import { Collection, Model } from 'backbone';
|
||||||
import { MessageModel } from '../models/messages';
|
import { MessageModel } from '../models/messages';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
type DeleteAttributesType = {
|
type DeleteAttributesType = {
|
||||||
targetSentTimestamp: number;
|
targetSentTimestamp: number;
|
||||||
|
@ -34,7 +35,7 @@ export class Deletes extends Collection<DeleteModel> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (matchingDeletes.length > 0) {
|
if (matchingDeletes.length > 0) {
|
||||||
window.log.info('Found early DOE for message');
|
log.info('Found early DOE for message');
|
||||||
this.remove(matchingDeletes);
|
this.remove(matchingDeletes);
|
||||||
return matchingDeletes;
|
return matchingDeletes;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +53,7 @@ export class Deletes extends Collection<DeleteModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!targetConversation) {
|
if (!targetConversation) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'No target conversation for DOE',
|
'No target conversation for DOE',
|
||||||
del.get('fromId'),
|
del.get('fromId'),
|
||||||
del.get('targetSentTimestamp')
|
del.get('targetSentTimestamp')
|
||||||
|
@ -63,7 +64,7 @@ export class Deletes extends Collection<DeleteModel> {
|
||||||
|
|
||||||
// Do not await, since this can deadlock the queue
|
// Do not await, since this can deadlock the queue
|
||||||
targetConversation.queueJob('Deletes.onDelete', async () => {
|
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(
|
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||||
del.get('targetSentTimestamp'),
|
del.get('targetSentTimestamp'),
|
||||||
|
@ -77,7 +78,7 @@ export class Deletes extends Collection<DeleteModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!targetMessage) {
|
if (!targetMessage) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'No message for DOE',
|
'No message for DOE',
|
||||||
del.get('fromId'),
|
del.get('fromId'),
|
||||||
del.get('targetSentTimestamp')
|
del.get('targetSentTimestamp')
|
||||||
|
@ -96,7 +97,7 @@ export class Deletes extends Collection<DeleteModel> {
|
||||||
this.remove(del);
|
this.remove(del);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Deletes.onDelete error:',
|
'Deletes.onDelete error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
} from '../messages/MessageSendState';
|
} from '../messages/MessageSendState';
|
||||||
import type { DeleteSentProtoRecipientOptionsType } from '../sql/Interface';
|
import type { DeleteSentProtoRecipientOptionsType } from '../sql/Interface';
|
||||||
import dataInterface from '../sql/Client';
|
import dataInterface from '../sql/Client';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
const { deleteSentProtoRecipient } = dataInterface;
|
const { deleteSentProtoRecipient } = dataInterface;
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ const deleteSentProtoBatcher = createWaitBatcher({
|
||||||
wait: 250,
|
wait: 250,
|
||||||
maxSize: 30,
|
maxSize: 30,
|
||||||
async processBatch(items: Array<DeleteSentProtoRecipientOptionsType>) {
|
async processBatch(items: Array<DeleteSentProtoRecipientOptionsType>) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`MessageReceipts: Batching ${items.length} sent proto recipients deletes`
|
`MessageReceipts: Batching ${items.length} sent proto recipients deletes`
|
||||||
);
|
);
|
||||||
await deleteSentProtoRecipient(items);
|
await deleteSentProtoRecipient(items);
|
||||||
|
@ -125,7 +126,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
|
||||||
ids.includes(receipt.get('sourceConversationId'))
|
ids.includes(receipt.get('sourceConversationId'))
|
||||||
);
|
);
|
||||||
if (receipts.length) {
|
if (receipts.length) {
|
||||||
window.log.info('Found early receipts for message');
|
log.info('Found early receipts for message');
|
||||||
this.remove(receipts);
|
this.remove(receipts);
|
||||||
}
|
}
|
||||||
return receipts;
|
return receipts;
|
||||||
|
@ -146,7 +147,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
|
||||||
|
|
||||||
const message = await getTargetMessage(sourceConversationId, messages);
|
const message = await getTargetMessage(sourceConversationId, messages);
|
||||||
if (!message) {
|
if (!message) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'No message for receipt',
|
'No message for receipt',
|
||||||
type,
|
type,
|
||||||
sourceConversationId,
|
sourceConversationId,
|
||||||
|
@ -222,7 +223,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
|
||||||
deviceId,
|
deviceId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`MessageReceipts.onReceipt: Missing uuid or deviceId for deliveredTo ${sourceConversationId}`
|
`MessageReceipts.onReceipt: Missing uuid or deviceId for deliveredTo ${sourceConversationId}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -230,7 +231,7 @@ export class MessageReceipts extends Collection<MessageReceiptModel> {
|
||||||
|
|
||||||
this.remove(receipt);
|
this.remove(receipt);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'MessageReceipts.onReceipt error:',
|
'MessageReceipts.onReceipt error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import { Collection, Model } from 'backbone';
|
import { Collection, Model } from 'backbone';
|
||||||
import { ConversationModel } from '../models/conversations';
|
import { ConversationModel } from '../models/conversations';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
type MessageRequestAttributesType = {
|
type MessageRequestAttributesType = {
|
||||||
threadE164?: string;
|
threadE164?: string;
|
||||||
|
@ -33,7 +34,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
|
||||||
threadE164: conversation.get('e164'),
|
threadE164: conversation.get('e164'),
|
||||||
});
|
});
|
||||||
if (syncByE164) {
|
if (syncByE164) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Found early message request response for E164 ${conversation.idForLogging()}`
|
`Found early message request response for E164 ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
this.remove(syncByE164);
|
this.remove(syncByE164);
|
||||||
|
@ -46,7 +47,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
|
||||||
threadUuid: conversation.get('uuid'),
|
threadUuid: conversation.get('uuid'),
|
||||||
});
|
});
|
||||||
if (syncByUuid) {
|
if (syncByUuid) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Found early message request response for UUID ${conversation.idForLogging()}`
|
`Found early message request response for UUID ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
this.remove(syncByUuid);
|
this.remove(syncByUuid);
|
||||||
|
@ -60,7 +61,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
|
||||||
groupId: conversation.get('groupId'),
|
groupId: conversation.get('groupId'),
|
||||||
});
|
});
|
||||||
if (syncByGroupId) {
|
if (syncByGroupId) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Found early message request response for group v1 ID ${conversation.idForLogging()}`
|
`Found early message request response for group v1 ID ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
this.remove(syncByGroupId);
|
this.remove(syncByGroupId);
|
||||||
|
@ -74,7 +75,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
|
||||||
groupV2Id: conversation.get('groupId'),
|
groupV2Id: conversation.get('groupId'),
|
||||||
});
|
});
|
||||||
if (syncByGroupId) {
|
if (syncByGroupId) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Found early message request response for group v2 ID ${conversation.idForLogging()}`
|
`Found early message request response for group v2 ID ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
this.remove(syncByGroupId);
|
this.remove(syncByGroupId);
|
||||||
|
@ -111,7 +112,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`Received message request response for unknown conversation: groupv2(${groupV2Id}) group(${groupId}) ${threadUuid} ${threadE164}`
|
`Received message request response for unknown conversation: groupv2(${groupV2Id}) group(${groupId}) ${threadUuid} ${threadE164}`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -123,7 +124,7 @@ export class MessageRequests extends Collection<MessageRequestModel> {
|
||||||
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'MessageRequests.onResponse error:',
|
'MessageRequests.onResponse error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { Collection, Model } from 'backbone';
|
||||||
import { MessageModel } from '../models/messages';
|
import { MessageModel } from '../models/messages';
|
||||||
import { isOutgoing } from '../state/selectors/message';
|
import { isOutgoing } from '../state/selectors/message';
|
||||||
import { ReactionAttributesType } from '../model-types.d';
|
import { ReactionAttributesType } from '../model-types.d';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
export class ReactionModel extends Model<ReactionAttributesType> {}
|
export class ReactionModel extends Model<ReactionAttributesType> {}
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ export class Reactions extends Collection {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (outgoingReactions.length > 0) {
|
if (outgoingReactions.length > 0) {
|
||||||
window.log.info('Found early reaction for outgoing message');
|
log.info('Found early reaction for outgoing message');
|
||||||
this.remove(outgoingReactions);
|
this.remove(outgoingReactions);
|
||||||
return outgoingReactions;
|
return outgoingReactions;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ export class Reactions extends Collection {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (reactionsBySource.length > 0) {
|
if (reactionsBySource.length > 0) {
|
||||||
window.log.info('Found early reaction for message');
|
log.info('Found early reaction for message');
|
||||||
this.remove(reactionsBySource);
|
this.remove(reactionsBySource);
|
||||||
return reactionsBySource;
|
return reactionsBySource;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +76,7 @@ export class Reactions extends Collection {
|
||||||
reaction.get('targetTimestamp')
|
reaction.get('targetTimestamp')
|
||||||
);
|
);
|
||||||
if (!targetConversation) {
|
if (!targetConversation) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'No target conversation for reaction',
|
'No target conversation for reaction',
|
||||||
reaction.get('targetAuthorUuid'),
|
reaction.get('targetAuthorUuid'),
|
||||||
reaction.get('targetTimestamp')
|
reaction.get('targetTimestamp')
|
||||||
|
@ -87,10 +88,7 @@ export class Reactions extends Collection {
|
||||||
return await targetConversation.queueJob(
|
return await targetConversation.queueJob(
|
||||||
'Reactions.onReaction',
|
'Reactions.onReaction',
|
||||||
async () => {
|
async () => {
|
||||||
window.log.info(
|
log.info('Handling reaction for', reaction.get('targetTimestamp'));
|
||||||
'Handling reaction for',
|
|
||||||
reaction.get('targetTimestamp')
|
|
||||||
);
|
|
||||||
|
|
||||||
const messages = await window.Signal.Data.getMessagesBySentAt(
|
const messages = await window.Signal.Data.getMessagesBySentAt(
|
||||||
reaction.get('targetTimestamp'),
|
reaction.get('targetTimestamp'),
|
||||||
|
@ -115,7 +113,7 @@ export class Reactions extends Collection {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!targetMessage) {
|
if (!targetMessage) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'No message for reaction',
|
'No message for reaction',
|
||||||
reaction.get('targetAuthorUuid'),
|
reaction.get('targetAuthorUuid'),
|
||||||
reaction.get('targetTimestamp')
|
reaction.get('targetTimestamp')
|
||||||
|
@ -149,7 +147,7 @@ export class Reactions extends Collection {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Reactions.onReaction error:',
|
'Reactions.onReaction error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { Collection, Model } from 'backbone';
|
||||||
import { MessageModel } from '../models/messages';
|
import { MessageModel } from '../models/messages';
|
||||||
import { isIncoming } from '../state/selectors/message';
|
import { isIncoming } from '../state/selectors/message';
|
||||||
import { isMessageUnread } from '../util/isMessageUnread';
|
import { isMessageUnread } from '../util/isMessageUnread';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
type ReadSyncAttributesType = {
|
type ReadSyncAttributesType = {
|
||||||
senderId: string;
|
senderId: string;
|
||||||
|
@ -28,7 +29,7 @@ async function maybeItIsAReactionReadSync(sync: ReadSyncModel): Promise<void> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!readReaction) {
|
if (!readReaction) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'Nothing found for read sync',
|
'Nothing found for read sync',
|
||||||
sync.get('senderId'),
|
sync.get('senderId'),
|
||||||
sync.get('sender'),
|
sync.get('sender'),
|
||||||
|
@ -67,9 +68,7 @@ export class ReadSyncs extends Collection {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
if (sync) {
|
if (sync) {
|
||||||
window.log.info(
|
log.info(`Found early read sync for message ${sync.get('timestamp')}`);
|
||||||
`Found early read sync for message ${sync.get('timestamp')}`
|
|
||||||
);
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
return sync;
|
return sync;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +144,7 @@ export class ReadSyncs extends Collection {
|
||||||
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'ReadSyncs.onSync error:',
|
'ReadSyncs.onSync error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import { Collection, Model } from 'backbone';
|
import { Collection, Model } from 'backbone';
|
||||||
import { MessageModel } from '../models/messages';
|
import { MessageModel } from '../models/messages';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
type ViewOnceOpenSyncAttributesType = {
|
type ViewOnceOpenSyncAttributesType = {
|
||||||
source?: string;
|
source?: string;
|
||||||
|
@ -33,7 +34,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
if (syncBySourceUuid) {
|
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);
|
this.remove(syncBySourceUuid);
|
||||||
return syncBySourceUuid;
|
return syncBySourceUuid;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
if (syncBySource) {
|
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);
|
this.remove(syncBySource);
|
||||||
return syncBySource;
|
return syncBySource;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +81,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
|
||||||
const syncSourceUuid = sync.get('sourceUuid');
|
const syncSourceUuid = sync.get('sourceUuid');
|
||||||
const syncTimestamp = sync.get('timestamp');
|
const syncTimestamp = sync.get('timestamp');
|
||||||
const wasMessageFound = Boolean(found);
|
const wasMessageFound = Boolean(found);
|
||||||
window.log.info('Receive view once open sync:', {
|
log.info('Receive view once open sync:', {
|
||||||
syncSource,
|
syncSource,
|
||||||
syncSourceUuid,
|
syncSourceUuid,
|
||||||
syncTimestamp,
|
syncTimestamp,
|
||||||
|
@ -96,7 +97,7 @@ export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
|
||||||
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'ViewOnceOpenSyncs.onSync error:',
|
'ViewOnceOpenSyncs.onSync error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { MessageModel } from '../models/messages';
|
||||||
import { ReadStatus } from '../messages/MessageReadStatus';
|
import { ReadStatus } from '../messages/MessageReadStatus';
|
||||||
import { markViewed } from '../services/MessageUpdater';
|
import { markViewed } from '../services/MessageUpdater';
|
||||||
import { isIncoming } from '../state/selectors/message';
|
import { isIncoming } from '../state/selectors/message';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
type ViewSyncAttributesType = {
|
type ViewSyncAttributesType = {
|
||||||
senderId: string;
|
senderId: string;
|
||||||
|
@ -43,7 +44,7 @@ export class ViewSyncs extends Collection {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
if (syncs.length) {
|
if (syncs.length) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Found ${syncs.length} early view sync(s) for message ${message.get(
|
`Found ${syncs.length} early view sync(s) for message ${message.get(
|
||||||
'sent_at'
|
'sent_at'
|
||||||
)}`
|
)}`
|
||||||
|
@ -72,7 +73,7 @@ export class ViewSyncs extends Collection {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'Nothing found for view sync',
|
'Nothing found for view sync',
|
||||||
sync.get('senderId'),
|
sync.get('senderId'),
|
||||||
sync.get('senderE164'),
|
sync.get('senderE164'),
|
||||||
|
@ -92,7 +93,7 @@ export class ViewSyncs extends Collection {
|
||||||
|
|
||||||
this.remove(sync);
|
this.remove(sync);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'ViewSyncs.onSync error:',
|
'ViewSyncs.onSync error:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -92,6 +92,7 @@ import { getProfile } from '../util/getProfile';
|
||||||
import { SEALED_SENDER } from '../types/SealedSender';
|
import { SEALED_SENDER } from '../types/SealedSender';
|
||||||
import { getAvatarData } from '../util/getAvatarData';
|
import { getAvatarData } from '../util/getAvatarData';
|
||||||
import { createIdenticon } from '../util/createIdenticon';
|
import { createIdenticon } from '../util/createIdenticon';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
// TODO: remove once we move away from ArrayBuffers
|
// TODO: remove once we move away from ArrayBuffers
|
||||||
const FIXMEU8 = Uint8Array;
|
const FIXMEU8 = Uint8Array;
|
||||||
|
@ -399,7 +400,7 @@ export class ConversationModel extends window.Backbone
|
||||||
const bothFalsey = Boolean(current) === false && Boolean(seconds) === false;
|
const bothFalsey = Boolean(current) === false && Boolean(seconds) === false;
|
||||||
|
|
||||||
if (current === seconds || bothFalsey) {
|
if (current === seconds || bothFalsey) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`updateExpirationTimerInGroupV2/${idLog}: Requested timer ${seconds} is unchanged from existing ${current}.`
|
`updateExpirationTimerInGroupV2/${idLog}: Requested timer ${seconds} is unchanged from existing ${current}.`
|
||||||
);
|
);
|
||||||
return undefined;
|
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
|
// button press and when we get here. It's especially important to check here
|
||||||
// in conflict/retry cases.
|
// in conflict/retry cases.
|
||||||
if (!this.isMemberPending(conversationId)) {
|
if (!this.isMemberPending(conversationId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`promotePendingMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
|
`promotePendingMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
|
||||||
);
|
);
|
||||||
return undefined;
|
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
|
// button press and when we get here. It's especially important to check here
|
||||||
// in conflict/retry cases.
|
// in conflict/retry cases.
|
||||||
if (!this.isMemberRequestingToJoin(conversationId)) {
|
if (!this.isMemberRequestingToJoin(conversationId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`approvePendingApprovalRequest/${idLog}: ${conversationId} is not requesting to join the group. Returning early.`
|
`approvePendingApprovalRequest/${idLog}: ${conversationId} is not requesting to join the group. Returning early.`
|
||||||
);
|
);
|
||||||
return undefined;
|
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
|
// button press and when we get here. It's especially important to check here
|
||||||
// in conflict/retry cases.
|
// in conflict/retry cases.
|
||||||
if (!this.isMemberRequestingToJoin(conversationId)) {
|
if (!this.isMemberRequestingToJoin(conversationId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`denyPendingApprovalRequest/${idLog}: ${conversationId} is not requesting to join the group. Returning early.`
|
`denyPendingApprovalRequest/${idLog}: ${conversationId} is not requesting to join the group. Returning early.`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -544,9 +545,7 @@ export class ConversationModel extends window.Backbone
|
||||||
this.get('announcementsOnly') &&
|
this.get('announcementsOnly') &&
|
||||||
!toRequest.get('capabilities')?.announcementGroup
|
!toRequest.get('capabilities')?.announcementGroup
|
||||||
) {
|
) {
|
||||||
window.log.warn(
|
log.warn(`addPendingApprovalRequest/${idLog}: member needs to upgrade.`);
|
||||||
`addPendingApprovalRequest/${idLog}: member needs to upgrade.`
|
|
||||||
);
|
|
||||||
return undefined;
|
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
|
// button press and when we get here. It's especially important to check here
|
||||||
// in conflict/retry cases.
|
// in conflict/retry cases.
|
||||||
if (this.isMemberAwaitingApproval(conversationId)) {
|
if (this.isMemberAwaitingApproval(conversationId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`addPendingApprovalRequest/${idLog}: ${conversationId} already in pending approval.`
|
`addPendingApprovalRequest/${idLog}: ${conversationId} already in pending approval.`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -598,9 +597,7 @@ export class ConversationModel extends window.Backbone
|
||||||
this.get('announcementsOnly') &&
|
this.get('announcementsOnly') &&
|
||||||
!toRequest.get('capabilities')?.announcementGroup
|
!toRequest.get('capabilities')?.announcementGroup
|
||||||
) {
|
) {
|
||||||
window.log.warn(
|
log.warn(`addMember/${idLog}: ${conversationId} needs to upgrade.`);
|
||||||
`addMember/${idLog}: ${conversationId} needs to upgrade.`
|
|
||||||
);
|
|
||||||
return undefined;
|
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
|
// button press and when we get here. It's especially important to check here
|
||||||
// in conflict/retry cases.
|
// in conflict/retry cases.
|
||||||
if (this.isMember(conversationId)) {
|
if (this.isMember(conversationId)) {
|
||||||
window.log.warn(
|
log.warn(`addMember/${idLog}: ${conversationId} already a member.`);
|
||||||
`addMember/${idLog}: ${conversationId} already a member.`
|
|
||||||
);
|
|
||||||
return undefined;
|
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
|
// button press and when we get here. It's especially important to check here
|
||||||
// in conflict/retry cases.
|
// in conflict/retry cases.
|
||||||
if (!this.isMemberPending(conversationId)) {
|
if (!this.isMemberPending(conversationId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`removePendingMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
|
`removePendingMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -655,7 +650,7 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
const pendingMember = window.ConversationController.get(conversationId);
|
const pendingMember = window.ConversationController.get(conversationId);
|
||||||
if (!pendingMember) {
|
if (!pendingMember) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`removePendingMember/${idLog}: No conversation found for conversation ${conversationId}`
|
`removePendingMember/${idLog}: No conversation found for conversation ${conversationId}`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -663,7 +658,7 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
const uuid = pendingMember.get('uuid');
|
const uuid = pendingMember.get('uuid');
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`removePendingMember/${idLog}: Missing uuid for conversation ${pendingMember.idForLogging()}`
|
`removePendingMember/${idLog}: Missing uuid for conversation ${pendingMember.idForLogging()}`
|
||||||
);
|
);
|
||||||
return undefined;
|
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
|
// button press and when we get here. It's especially important to check here
|
||||||
// in conflict/retry cases.
|
// in conflict/retry cases.
|
||||||
if (!this.isMember(conversationId)) {
|
if (!this.isMember(conversationId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`removeMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
|
`removeMember/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -727,7 +722,7 @@ export class ConversationModel extends window.Backbone
|
||||||
const idLog = this.idForLogging();
|
const idLog = this.idForLogging();
|
||||||
|
|
||||||
if (!this.isMember(conversationId)) {
|
if (!this.isMember(conversationId)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`toggleAdminChange/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
|
`toggleAdminChange/${idLog}: ${conversationId} is not a pending member of group. Returning early.`
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -796,7 +791,7 @@ export class ConversationModel extends window.Backbone
|
||||||
}
|
}
|
||||||
|
|
||||||
setUnregistered(): void {
|
setUnregistered(): void {
|
||||||
window.log.info(`Conversation ${this.idForLogging()} is now unregistered`);
|
log.info(`Conversation ${this.idForLogging()} is now unregistered`);
|
||||||
this.set({
|
this.set({
|
||||||
discoveredUnregisteredAt: Date.now(),
|
discoveredUnregisteredAt: Date.now(),
|
||||||
});
|
});
|
||||||
|
@ -808,9 +803,7 @@ export class ConversationModel extends window.Backbone
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(`Conversation ${this.idForLogging()} is registered once again`);
|
||||||
`Conversation ${this.idForLogging()} is registered once again`
|
|
||||||
);
|
|
||||||
this.set({
|
this.set({
|
||||||
discoveredUnregisteredAt: undefined,
|
discoveredUnregisteredAt: undefined,
|
||||||
});
|
});
|
||||||
|
@ -900,7 +893,7 @@ export class ConversationModel extends window.Backbone
|
||||||
}
|
}
|
||||||
|
|
||||||
enableProfileSharing({ viaStorageServiceSync = false } = {}): void {
|
enableProfileSharing({ viaStorageServiceSync = false } = {}): void {
|
||||||
window.log.info(
|
log.info(
|
||||||
`enableProfileSharing: ${this.idForLogging()} storage? ${viaStorageServiceSync}`
|
`enableProfileSharing: ${this.idForLogging()} storage? ${viaStorageServiceSync}`
|
||||||
);
|
);
|
||||||
const before = this.get('profileSharing');
|
const before = this.get('profileSharing');
|
||||||
|
@ -915,7 +908,7 @@ export class ConversationModel extends window.Backbone
|
||||||
}
|
}
|
||||||
|
|
||||||
disableProfileSharing({ viaStorageServiceSync = false } = {}): void {
|
disableProfileSharing({ viaStorageServiceSync = false } = {}): void {
|
||||||
window.log.info(
|
log.info(
|
||||||
`disableProfileSharing: ${this.idForLogging()} storage? ${viaStorageServiceSync}`
|
`disableProfileSharing: ${this.idForLogging()} storage? ${viaStorageServiceSync}`
|
||||||
);
|
);
|
||||||
const before = this.get('profileSharing');
|
const before = this.get('profileSharing');
|
||||||
|
@ -1041,7 +1034,7 @@ export class ConversationModel extends window.Backbone
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`Fetching uuid for a sms-only conversation ${this.idForLogging()}`
|
`Fetching uuid for a sms-only conversation ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1060,7 +1053,7 @@ export class ConversationModel extends window.Backbone
|
||||||
this.isFetchingUUID = false;
|
this.isFetchingUUID = false;
|
||||||
this.trigger('change', this);
|
this.trigger('change', this);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`Done fetching uuid for a sms-only conversation ${this.idForLogging()}`
|
`Done fetching uuid for a sms-only conversation ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1110,7 +1103,7 @@ export class ConversationModel extends window.Backbone
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(`Repairing GroupV2 conversation ${this.idForLogging()}`);
|
log.info(`Repairing GroupV2 conversation ${this.idForLogging()}`);
|
||||||
const { masterKey, secretParams, publicParams } = data;
|
const { masterKey, secretParams, publicParams } = data;
|
||||||
|
|
||||||
this.set({ masterKey, secretParams, publicParams, groupVersion: 2 });
|
this.set({ masterKey, secretParams, publicParams, groupVersion: 2 });
|
||||||
|
@ -1325,7 +1318,7 @@ export class ConversationModel extends window.Backbone
|
||||||
}
|
}
|
||||||
|
|
||||||
const { stack } = new Error('for stack');
|
const { stack } = new Error('for stack');
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`Conversation.format()/${this.idForLogging()} reentrant call! ${stack}`
|
`Conversation.format()/${this.idForLogging()} reentrant call! ${stack}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1701,11 +1694,11 @@ export class ConversationModel extends window.Backbone
|
||||||
isGroupV2(this.attributes) &&
|
isGroupV2(this.attributes) &&
|
||||||
this.isMember(ourConversationId)
|
this.isMember(ourConversationId)
|
||||||
) {
|
) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'applyMessageRequestResponse/accept: Already a member of v2 group'
|
'applyMessageRequestResponse/accept: Already a member of v2 group'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
window.log.error(
|
log.error(
|
||||||
'applyMessageRequestResponse/accept: Neither member nor pending member of v2 group'
|
'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) {
|
if (errorDetails !== ALREADY_REQUESTED_TO_JOIN) {
|
||||||
throw error;
|
throw error;
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info(
|
||||||
'joinGroupV2ViaLink: Got 400, but server is telling us we have already requested to join. Forcing that local state'
|
'joinGroupV2ViaLink: Got 400, but server is telling us we have already requested to join. Forcing that local state'
|
||||||
);
|
);
|
||||||
this.set({
|
this.set({
|
||||||
|
@ -1938,7 +1931,7 @@ export class ConversationModel extends window.Backbone
|
||||||
createGroupChange: () => this.removeMember(ourConversationId),
|
createGroupChange: () => this.removeMember(ourConversationId),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.log.error(
|
log.error(
|
||||||
'leaveGroupV2: We were neither a member nor a pending member of the group'
|
'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)) {
|
if (!this.isMember(conversationId)) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`toggleAdmin: Member ${conversationId} is not a member of the group`
|
`toggleAdmin: Member ${conversationId} is not a member of the group`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -2036,7 +2029,7 @@ export class ConversationModel extends window.Backbone
|
||||||
extraConversationsForSend: [conversationId],
|
extraConversationsForSend: [conversationId],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.log.error(
|
log.error(
|
||||||
`removeFromGroupV2: Member ${conversationId} is neither a member nor a pending member of the group`
|
`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();
|
const groupId = this.getGroupIdBuffer();
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'syncMessageRequestResponse: We are primary device; not sending message request sync'
|
'syncMessageRequestResponse: We are primary device; not sending message request sync'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -2209,9 +2202,7 @@ export class ConversationModel extends window.Backbone
|
||||||
verified
|
verified
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn(`_setVerified(${this.id}): no uuid to update protocol storage`);
|
||||||
`_setVerified(${this.id}): no uuid to update protocol storage`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set({ verified });
|
this.set({ verified });
|
||||||
|
@ -2262,7 +2253,7 @@ export class ConversationModel extends window.Backbone
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'sendVerifySyncMessage: We are primary device; not sending sync'
|
'sendVerifySyncMessage: We are primary device; not sending sync'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -2366,7 +2357,7 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
const uuid = this.get('uuid');
|
const uuid = this.get('uuid');
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
window.log.warn(`setApproved(${this.id}): no uuid, ignoring`);
|
log.warn(`setApproved(${this.id}): no uuid, ignoring`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2475,10 +2466,9 @@ export class ConversationModel extends window.Backbone
|
||||||
receivedAt: number;
|
receivedAt: number;
|
||||||
receivedAtCounter: number;
|
receivedAtCounter: number;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
window.log.info(
|
log.info(`addChatSessionRefreshed: adding for ${this.idForLogging()}`, {
|
||||||
`addChatSessionRefreshed: adding for ${this.idForLogging()}`,
|
receivedAt,
|
||||||
{ receivedAt }
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const message = ({
|
const message = ({
|
||||||
conversationId: this.id,
|
conversationId: this.id,
|
||||||
|
@ -2514,7 +2504,7 @@ export class ConversationModel extends window.Backbone
|
||||||
senderUuid: string;
|
senderUuid: string;
|
||||||
sentAt: number;
|
sentAt: number;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
window.log.info(`addDeliveryIssue: adding for ${this.idForLogging()}`, {
|
log.info(`addDeliveryIssue: adding for ${this.idForLogging()}`, {
|
||||||
sentAt,
|
sentAt,
|
||||||
senderUuid,
|
senderUuid,
|
||||||
});
|
});
|
||||||
|
@ -2546,7 +2536,7 @@ export class ConversationModel extends window.Backbone
|
||||||
}
|
}
|
||||||
|
|
||||||
async addKeyChange(keyChangedId: UUID): Promise<void> {
|
async addKeyChange(keyChangedId: UUID): Promise<void> {
|
||||||
window.log.info(
|
log.info(
|
||||||
'adding key change advisory for',
|
'adding key change advisory for',
|
||||||
this.idForLogging(),
|
this.idForLogging(),
|
||||||
keyChangedId.toString(),
|
keyChangedId.toString(),
|
||||||
|
@ -2596,15 +2586,13 @@ export class ConversationModel extends window.Backbone
|
||||||
window._.defaults(options, { local: true });
|
window._.defaults(options, { local: true });
|
||||||
|
|
||||||
if (isMe(this.attributes)) {
|
if (isMe(this.attributes)) {
|
||||||
window.log.info(
|
log.info('refusing to add verified change advisory for our own number');
|
||||||
'refusing to add verified change advisory for our own number'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastMessage = this.get('timestamp') || Date.now();
|
const lastMessage = this.get('timestamp') || Date.now();
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'adding verified change advisory for',
|
'adding verified change advisory for',
|
||||||
this.idForLogging(),
|
this.idForLogging(),
|
||||||
verifiedChangeId,
|
verifiedChangeId,
|
||||||
|
@ -2851,7 +2839,7 @@ export class ConversationModel extends window.Backbone
|
||||||
}
|
}
|
||||||
|
|
||||||
async addChangeNumberNotification(): Promise<void> {
|
async addChangeNumberNotification(): Promise<void> {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Conversation ${this.idForLogging()}: adding change number notification`
|
`Conversation ${this.idForLogging()}: adding change number notification`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2981,9 +2969,7 @@ export class ConversationModel extends window.Backbone
|
||||||
const waitTime = startedAt - queuedAt;
|
const waitTime = startedAt - queuedAt;
|
||||||
|
|
||||||
if (waitTime > JOB_REPORTING_THRESHOLD_MS) {
|
if (waitTime > JOB_REPORTING_THRESHOLD_MS) {
|
||||||
window.log.info(
|
log.info(`Conversation job ${name} was blocked for ${waitTime}ms`);
|
||||||
`Conversation job ${name} was blocked for ${waitTime}ms`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -2992,7 +2978,7 @@ export class ConversationModel extends window.Backbone
|
||||||
const duration = Date.now() - startedAt;
|
const duration = Date.now() - startedAt;
|
||||||
|
|
||||||
if (duration > JOB_REPORTING_THRESHOLD_MS) {
|
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 packData = Stickers.getStickerPack(packId);
|
||||||
const stickerData = Stickers.getSticker(packId, stickerId);
|
const stickerData = Stickers.getSticker(packId, stickerId);
|
||||||
if (!stickerData || !packData) {
|
if (!stickerData || !packData) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`Attempted to send nonexistent (${packId}, ${stickerId}) sticker!`
|
`Attempted to send nonexistent (${packId}, ${stickerId}) sticker!`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -3262,9 +3248,7 @@ export class ConversationModel extends window.Backbone
|
||||||
if (sniffedMimeType) {
|
if (sniffedMimeType) {
|
||||||
contentType = sniffedMimeType;
|
contentType = sniffedMimeType;
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
log.warn('Unable to sniff sticker MIME type; falling back to WebP');
|
||||||
'Unable to sniff sticker MIME type; falling back to WebP'
|
|
||||||
);
|
|
||||||
contentType = IMAGE_WEBP;
|
contentType = IMAGE_WEBP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3305,7 +3289,7 @@ export class ConversationModel extends window.Backbone
|
||||||
const destination = this.getSendTarget()!;
|
const destination = this.getSendTarget()!;
|
||||||
|
|
||||||
await this.queueJob('sendDeleteForEveryone', async () => {
|
await this.queueJob('sendDeleteForEveryone', async () => {
|
||||||
window.log.info(
|
log.info(
|
||||||
'Sending deleteForEveryone to conversation',
|
'Sending deleteForEveryone to conversation',
|
||||||
this.idForLogging(),
|
this.idForLogging(),
|
||||||
'with timestamp',
|
'with timestamp',
|
||||||
|
@ -3395,7 +3379,7 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Error sending deleteForEveryone',
|
'Error sending deleteForEveryone',
|
||||||
deleteModel,
|
deleteModel,
|
||||||
targetTimestamp,
|
targetTimestamp,
|
||||||
|
@ -3434,7 +3418,7 @@ export class ConversationModel extends window.Backbone
|
||||||
const destination = this.getSendTarget()!;
|
const destination = this.getSendTarget()!;
|
||||||
|
|
||||||
return this.queueJob('sendReactionMessage', async () => {
|
return this.queueJob('sendReactionMessage', async () => {
|
||||||
window.log.info(
|
log.info(
|
||||||
'Sending reaction to conversation',
|
'Sending reaction to conversation',
|
||||||
this.idForLogging(),
|
this.idForLogging(),
|
||||||
'with timestamp',
|
'with timestamp',
|
||||||
|
@ -3570,17 +3554,17 @@ export class ConversationModel extends window.Backbone
|
||||||
const id = this.get('id');
|
const id = this.get('id');
|
||||||
const recipients = this.getRecipients();
|
const recipients = this.getRecipients();
|
||||||
if (!this.get('profileSharing')) {
|
if (!this.get('profileSharing')) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Attempted to send profileKeyUpdate to conversation without profileSharing enabled',
|
'Attempted to send profileKeyUpdate to conversation without profileSharing enabled',
|
||||||
id,
|
id,
|
||||||
recipients
|
recipients
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
window.log.info('Sending profileKeyUpdate to conversation', id, recipients);
|
log.info('Sending profileKeyUpdate to conversation', id, recipients);
|
||||||
const profileKey = await ourProfileKeyService.get();
|
const profileKey = await ourProfileKeyService.get();
|
||||||
if (!profileKey) {
|
if (!profileKey) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Attempted to send profileKeyUpdate but our profile key was not found'
|
'Attempted to send profileKeyUpdate but our profile key was not found'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -3640,7 +3624,7 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
const expireTimer = this.get('expireTimer');
|
const expireTimer = this.get('expireTimer');
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'Sending message to conversation',
|
'Sending message to conversation',
|
||||||
this.idForLogging(),
|
this.idForLogging(),
|
||||||
'with timestamp',
|
'with timestamp',
|
||||||
|
@ -3709,7 +3693,7 @@ export class ConversationModel extends window.Backbone
|
||||||
await normalMessageSendJobQueue.add(
|
await normalMessageSendJobQueue.add(
|
||||||
{ messageId: message.id, conversationId: this.id },
|
{ messageId: message.id, conversationId: this.id },
|
||||||
async jobToInsert => {
|
async jobToInsert => {
|
||||||
window.log.info(
|
log.info(
|
||||||
`enqueueMessageForSend: saving message ${message.id} and job ${jobToInsert.id}`
|
`enqueueMessageForSend: saving message ${message.id} and job ${jobToInsert.id}`
|
||||||
);
|
);
|
||||||
await window.Signal.Data.saveMessage(message.attributes, {
|
await window.Signal.Data.saveMessage(message.attributes, {
|
||||||
|
@ -3721,7 +3705,7 @@ export class ConversationModel extends window.Backbone
|
||||||
|
|
||||||
const dbDuration = Date.now() - dbStart;
|
const dbDuration = Date.now() - dbStart;
|
||||||
if (dbDuration > SEND_REPORTING_THRESHOLD_MS) {
|
if (dbDuration > SEND_REPORTING_THRESHOLD_MS) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`ConversationModel(${this.idForLogging()}.sendMessage(${now}): ` +
|
`ConversationModel(${this.idForLogging()}.sendMessage(${now}): ` +
|
||||||
`db save took ${dbDuration}ms`
|
`db save took ${dbDuration}ms`
|
||||||
);
|
);
|
||||||
|
@ -3755,7 +3739,7 @@ export class ConversationModel extends window.Backbone
|
||||||
const renderDuration = Date.now() - renderStart;
|
const renderDuration = Date.now() - renderStart;
|
||||||
|
|
||||||
if (renderDuration > SEND_REPORTING_THRESHOLD_MS) {
|
if (renderDuration > SEND_REPORTING_THRESHOLD_MS) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`ConversationModel(${this.idForLogging()}.sendMessage(${now}): ` +
|
`ConversationModel(${this.idForLogging()}.sendMessage(${now}): ` +
|
||||||
`render save took ${renderDuration}ms`
|
`render save took ${renderDuration}ms`
|
||||||
);
|
);
|
||||||
|
@ -3902,7 +3886,7 @@ export class ConversationModel extends window.Backbone
|
||||||
window.Signal.Groups.generateGroupInviteLinkPassword()
|
window.Signal.Groups.generateGroupInviteLinkPassword()
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info('refreshGroupLink for conversation', this.idForLogging());
|
log.info('refreshGroupLink for conversation', this.idForLogging());
|
||||||
|
|
||||||
await this.modifyGroupV2({
|
await this.modifyGroupV2({
|
||||||
name: 'updateInviteLinkPassword',
|
name: 'updateInviteLinkPassword',
|
||||||
|
@ -3929,11 +3913,7 @@ export class ConversationModel extends window.Backbone
|
||||||
window.Signal.Groups.generateGroupInviteLinkPassword()
|
window.Signal.Groups.generateGroupInviteLinkPassword()
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info('toggleGroupLink for conversation', this.idForLogging(), value);
|
||||||
'toggleGroupLink for conversation',
|
|
||||||
this.idForLogging(),
|
|
||||||
value
|
|
||||||
);
|
|
||||||
|
|
||||||
const ACCESS_ENUM = Proto.AccessControl.AccessRequired;
|
const ACCESS_ENUM = Proto.AccessControl.AccessRequired;
|
||||||
const addFromInviteLink = value
|
const addFromInviteLink = value
|
||||||
|
@ -4108,7 +4088,7 @@ export class ConversationModel extends window.Backbone
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info("Update conversation 'expireTimer'", {
|
log.info("Update conversation 'expireTimer'", {
|
||||||
id: this.idForLogging(),
|
id: this.idForLogging(),
|
||||||
expireTimer,
|
expireTimer,
|
||||||
source,
|
source,
|
||||||
|
@ -4223,7 +4203,7 @@ export class ConversationModel extends window.Backbone
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
|
|
||||||
if (this.hasAddedHistoryDisclaimer) {
|
if (this.hasAddedHistoryDisclaimer) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`addMessageHistoryDisclaimer/${this.idForLogging()}: Refusing to add another this session`
|
`addMessageHistoryDisclaimer/${this.idForLogging()}: Refusing to add another this session`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -4489,7 +4469,7 @@ export class ConversationModel extends window.Backbone
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// profileKey is a string so we can compare it directly
|
// profileKey is a string so we can compare it directly
|
||||||
if (this.get('profileKey') !== profileKey) {
|
if (this.get('profileKey') !== profileKey) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Setting sealedSender to UNKNOWN for conversation ${this.idForLogging()}`
|
`Setting sealedSender to UNKNOWN for conversation ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
this.set({
|
this.set({
|
||||||
|
@ -4780,18 +4760,14 @@ export class ConversationModel extends window.Backbone
|
||||||
// [X] dontNotifyForMentionsIfMuted
|
// [X] dontNotifyForMentionsIfMuted
|
||||||
captureChange(logMessage: string): void {
|
captureChange(logMessage: string): void {
|
||||||
if (!window.Signal.RemoteConfig.isEnabled('desktop.storageWrite3')) {
|
if (!window.Signal.RemoteConfig.isEnabled('desktop.storageWrite3')) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'conversation.captureChange: Returning early; desktop.storageWrite3 is falsey'
|
'conversation.captureChange: Returning early; desktop.storageWrite3 is falsey'
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info('storageService[captureChange]', logMessage, this.idForLogging());
|
||||||
'storageService[captureChange]',
|
|
||||||
logMessage,
|
|
||||||
this.idForLogging()
|
|
||||||
);
|
|
||||||
this.set({ needsStorageServiceSync: true });
|
this.set({ needsStorageServiceSync: true });
|
||||||
|
|
||||||
this.queueJob('captureChange', async () => {
|
this.queueJob('captureChange', async () => {
|
||||||
|
@ -5003,7 +4979,7 @@ export class ConversationModel extends window.Backbone
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('pinning', this.idForLogging());
|
log.info('pinning', this.idForLogging());
|
||||||
const pinnedConversationIds = new Set(
|
const pinnedConversationIds = new Set(
|
||||||
window.storage.get('pinnedConversationIds', new Array<string>())
|
window.storage.get('pinnedConversationIds', new Array<string>())
|
||||||
);
|
);
|
||||||
|
@ -5025,7 +5001,7 @@ export class ConversationModel extends window.Backbone
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('un-pinning', this.idForLogging());
|
log.info('un-pinning', this.idForLogging());
|
||||||
|
|
||||||
const pinnedConversationIds = new Set(
|
const pinnedConversationIds = new Set(
|
||||||
window.storage.get('pinnedConversationIds', new Array<string>())
|
window.storage.get('pinnedConversationIds', new Array<string>())
|
||||||
|
|
|
@ -113,6 +113,7 @@ import * as LinkPreview from '../types/LinkPreview';
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
import { normalMessageSendJobQueue } from '../jobs/normalMessageSendJobQueue';
|
import { normalMessageSendJobQueue } from '../jobs/normalMessageSendJobQueue';
|
||||||
import type { PreviewType as OutgoingPreviewType } from '../textsecure/SendMessage';
|
import type { PreviewType as OutgoingPreviewType } from '../textsecure/SendMessage';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
/* eslint-disable more/no-then */
|
/* eslint-disable more/no-then */
|
||||||
|
@ -198,7 +199,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
this.set(
|
this.set(
|
||||||
TypedMessage.initializeSchemaVersion({
|
TypedMessage.initializeSchemaVersion({
|
||||||
message: attributes,
|
message: attributes,
|
||||||
logger: window.log,
|
logger: log,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -630,7 +631,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
const { emoji } = sticker || {};
|
const { emoji } = sticker || {};
|
||||||
if (!emoji) {
|
if (!emoji) {
|
||||||
window.log.warn('Unable to get emoji for sticker');
|
log.warn('Unable to get emoji for sticker');
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
text: window.i18n('message--getNotificationText--stickers'),
|
text: window.i18n('message--getNotificationText--stickers'),
|
||||||
|
@ -651,9 +652,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.error(
|
log.error("This call history message doesn't have valid call history");
|
||||||
"This call history message doesn't have valid call history"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (isExpirationTimerUpdate(attributes)) {
|
if (isExpirationTimerUpdate(attributes)) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// 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 required = ['conversationId', 'received_at', 'sent_at'];
|
||||||
const missing = _.filter(required, attr => !attributes[attr]);
|
const missing = _.filter(required, attr => !attributes[attr]);
|
||||||
if (missing.length) {
|
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 || {};
|
const { fromSync } = options || {};
|
||||||
|
|
||||||
if (!this.isValidTapToView()) {
|
if (!this.isValidTapToView()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`markViewOnceMessageViewed: Message ${this.idForLogging()} is not a valid tap to view message!`
|
`markViewOnceMessageViewed: Message ${this.idForLogging()} is not a valid tap to view message!`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.isErased()) {
|
if (this.isErased()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`markViewOnceMessageViewed: Message ${this.idForLogging()} is already erased!`
|
`markViewOnceMessageViewed: Message ${this.idForLogging()} is already erased!`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -879,7 +878,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'markViewOnceMessageViewed: We are primary device; not sending view once open sync'
|
'markViewOnceMessageViewed: We are primary device; not sending view once open sync'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -901,9 +900,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
const logId = this.idForLogging();
|
const logId = this.idForLogging();
|
||||||
const quote = this.get('quote');
|
const quote = this.get('quote');
|
||||||
if (!quote) {
|
if (!quote) {
|
||||||
window.log.warn(
|
log.warn(`doubleCheckMissingQuoteReference/${logId}: Missing quote!`);
|
||||||
`doubleCheckMissingQuoteReference/${logId}: Missing quote!`
|
|
||||||
);
|
|
||||||
return;
|
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
|
// Is the quote really without a reference? Check with our in memory store
|
||||||
// first to make sure it's not there.
|
// first to make sure it's not there.
|
||||||
if (referencedMessageNotFound && contact) {
|
if (referencedMessageNotFound && contact) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`doubleCheckMissingQuoteReference/${logId}: Verifying reference to ${sentAt}`
|
`doubleCheckMissingQuoteReference/${logId}: Verifying reference to ${sentAt}`
|
||||||
);
|
);
|
||||||
const inMemoryMessages = window.MessageController.filterBySentAt(
|
const inMemoryMessages = window.MessageController.filterBySentAt(
|
||||||
|
@ -923,7 +920,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
isQuoteAMatch(message, this.get('conversationId'), quote)
|
isQuoteAMatch(message, this.get('conversationId'), quote)
|
||||||
);
|
);
|
||||||
if (!matchingMessage) {
|
if (!matchingMessage) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`doubleCheckMissingQuoteReference/${logId}: No match for ${sentAt}.`
|
`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.`
|
`doubleCheckMissingQuoteReference/${logId}: Found match for ${sentAt}, updating.`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -960,7 +957,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
additionalProperties = {},
|
additionalProperties = {},
|
||||||
shouldPersist = true
|
shouldPersist = true
|
||||||
): Promise<void> {
|
): 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
|
// 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.
|
// a viewed (or outgoing) View-Once message is deleted for everyone.
|
||||||
|
@ -968,7 +965,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
try {
|
try {
|
||||||
await this.deleteData();
|
await this.deleteData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`Error erasing data for message ${this.idForLogging()}:`,
|
`Error erasing data for message ${this.idForLogging()}:`,
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
@ -1075,7 +1072,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
return this.get('source');
|
return this.get('source');
|
||||||
}
|
}
|
||||||
if (!isOutgoing(this.attributes)) {
|
if (!isOutgoing(this.attributes)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'Message.getSource: Called for non-incoming/non-outoing message'
|
'Message.getSource: Called for non-incoming/non-outoing message'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1090,7 +1087,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
return sourceDevice;
|
return sourceDevice;
|
||||||
}
|
}
|
||||||
if (!isOutgoing(this.attributes)) {
|
if (!isOutgoing(this.attributes)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'Message.getSourceDevice: Called for non-incoming/non-outoing message'
|
'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');
|
return this.get('sourceUuid');
|
||||||
}
|
}
|
||||||
if (!isOutgoing(this.attributes)) {
|
if (!isOutgoing(this.attributes)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'Message.getSourceUuid: Called for non-incoming/non-outoing message'
|
'Message.getSourceUuid: Called for non-incoming/non-outoing message'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1145,7 +1142,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
errors.forEach(e => {
|
errors.forEach(e => {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Message.saveErrors:',
|
'Message.saveErrors:',
|
||||||
e && e.reason ? e.reason : null,
|
e && e.reason ? e.reason : null,
|
||||||
e && e.stack ? e.stack : e
|
e && e.stack ? e.stack : e
|
||||||
|
@ -1207,7 +1204,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
const retryOptions = this.get('retryOptions');
|
const retryOptions = this.get('retryOptions');
|
||||||
if (retryOptions) {
|
if (retryOptions) {
|
||||||
if (!window.textsecure.messaging) {
|
if (!window.textsecure.messaging) {
|
||||||
window.log.error('retrySend: Cannot retry since we are offline!');
|
log.error('retrySend: Cannot retry since we are offline!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.unset('errors');
|
this.unset('errors');
|
||||||
|
@ -1611,7 +1608,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'sendSyncMessage: We are primary device; not sending sync message'
|
'sendSyncMessage: We are primary device; not sending sync message'
|
||||||
);
|
);
|
||||||
this.set({ dataMessage: undefined });
|
this.set({ dataMessage: undefined });
|
||||||
|
@ -1832,7 +1829,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let bodyPending;
|
let bodyPending;
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`Queueing ${
|
`Queueing ${
|
||||||
attachmentsToQueue.length
|
attachmentsToQueue.length
|
||||||
} attachment downloads for message ${this.idForLogging()}`
|
} attachment downloads for message ${this.idForLogging()}`
|
||||||
|
@ -1846,12 +1843,12 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (longMessageAttachments.length > 1) {
|
if (longMessageAttachments.length > 1) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`Received more than one long message attachment in message ${this.idForLogging()}`
|
`Received more than one long message attachment in message ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`Queueing ${
|
`Queueing ${
|
||||||
longMessageAttachments.length
|
longMessageAttachments.length
|
||||||
} long message attachment downloads for message ${this.idForLogging()}`
|
} 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 ${
|
`Queueing ${
|
||||||
normalAttachments.length
|
normalAttachments.length
|
||||||
} normal attachment downloads for message ${this.idForLogging()}`
|
} normal attachment downloads for message ${this.idForLogging()}`
|
||||||
|
@ -1879,7 +1876,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
// We've already downloaded this!
|
// We've already downloaded this!
|
||||||
if (attachment.path) {
|
if (attachment.path) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Normal attachment already downloaded for message ${this.idForLogging()}`
|
`Normal attachment already downloaded for message ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
return attachment;
|
return attachment;
|
||||||
|
@ -1896,7 +1893,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
|
|
||||||
const previewsToQueue = this.get('preview') || [];
|
const previewsToQueue = this.get('preview') || [];
|
||||||
window.log.info(
|
log.info(
|
||||||
`Queueing ${
|
`Queueing ${
|
||||||
previewsToQueue.length
|
previewsToQueue.length
|
||||||
} preview attachment downloads for message ${this.idForLogging()}`
|
} preview attachment downloads for message ${this.idForLogging()}`
|
||||||
|
@ -1908,7 +1905,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
// We've already downloaded this!
|
// We've already downloaded this!
|
||||||
if (item.image.path) {
|
if (item.image.path) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Preview attachment already downloaded for message ${this.idForLogging()}`
|
`Preview attachment already downloaded for message ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
return item;
|
return item;
|
||||||
|
@ -1927,7 +1924,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
|
|
||||||
const contactsToQueue = this.get('contact') || [];
|
const contactsToQueue = this.get('contact') || [];
|
||||||
window.log.info(
|
log.info(
|
||||||
`Queueing ${
|
`Queueing ${
|
||||||
contactsToQueue.length
|
contactsToQueue.length
|
||||||
} contact attachment downloads for message ${this.idForLogging()}`
|
} contact attachment downloads for message ${this.idForLogging()}`
|
||||||
|
@ -1939,7 +1936,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
// We've already downloaded this!
|
// We've already downloaded this!
|
||||||
if (item.avatar.avatar.path) {
|
if (item.avatar.avatar.path) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Contact attachment already downloaded for message ${this.idForLogging()}`
|
`Contact attachment already downloaded for message ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
return item;
|
return item;
|
||||||
|
@ -1964,7 +1961,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
let quote = this.get('quote')!;
|
let quote = this.get('quote')!;
|
||||||
const quoteAttachmentsToQueue =
|
const quoteAttachmentsToQueue =
|
||||||
quote && quote.attachments ? quote.attachments : [];
|
quote && quote.attachments ? quote.attachments : [];
|
||||||
window.log.info(
|
log.info(
|
||||||
`Queueing ${
|
`Queueing ${
|
||||||
quoteAttachmentsToQueue.length
|
quoteAttachmentsToQueue.length
|
||||||
} quote attachment downloads for message ${this.idForLogging()}`
|
} quote attachment downloads for message ${this.idForLogging()}`
|
||||||
|
@ -1979,7 +1976,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
// We've already downloaded this!
|
// We've already downloaded this!
|
||||||
if (item.thumbnail.path) {
|
if (item.thumbnail.path) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Quote attachment already downloaded for message ${this.idForLogging()}`
|
`Quote attachment already downloaded for message ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
return item;
|
return item;
|
||||||
|
@ -2002,13 +1999,11 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
let sticker = this.get('sticker')!;
|
let sticker = this.get('sticker')!;
|
||||||
if (sticker && sticker.data && sticker.data.path) {
|
if (sticker && sticker.data && sticker.data.path) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Sticker attachment already downloaded for message ${this.idForLogging()}`
|
`Sticker attachment already downloaded for message ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
} else if (sticker) {
|
} else if (sticker) {
|
||||||
window.log.info(
|
log.info(`Queueing sticker download for message ${this.idForLogging()}`);
|
||||||
`Queueing sticker download for message ${this.idForLogging()}`
|
|
||||||
);
|
|
||||||
count += 1;
|
count += 1;
|
||||||
const { packId, stickerId, packKey } = sticker;
|
const { packId, stickerId, packKey } = sticker;
|
||||||
|
|
||||||
|
@ -2026,7 +2021,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
contentType: IMAGE_WEBP,
|
contentType: IMAGE_WEBP,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`Problem copying sticker (${packId}, ${stickerId}) to attachments:`,
|
`Problem copying sticker (${packId}, ${stickerId}) to attachments:`,
|
||||||
error && error.stack ? error.stack : error
|
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()}`
|
`Queued ${count} total attachment downloads for message ${this.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2111,9 +2106,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info('markAttachmentAsCorrupted: marking an attachment as corrupted');
|
||||||
'markAttachmentAsCorrupted: marking an attachment as corrupted'
|
|
||||||
);
|
|
||||||
|
|
||||||
this.set({
|
this.set({
|
||||||
attachments: newAttachments,
|
attachments: newAttachments,
|
||||||
|
@ -2171,7 +2164,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
if (matchingMessage) {
|
if (matchingMessage) {
|
||||||
queryMessage = matchingMessage;
|
queryMessage = matchingMessage;
|
||||||
} else {
|
} else {
|
||||||
window.log.info('copyFromQuotedMessage: db lookup needed', id);
|
log.info('copyFromQuotedMessage: db lookup needed', id);
|
||||||
const collection = await window.Signal.Data.getMessagesBySentAt(id, {
|
const collection = await window.Signal.Data.getMessagesBySentAt(id, {
|
||||||
MessageCollection: window.Whisper.MessageCollection,
|
MessageCollection: window.Whisper.MessageCollection,
|
||||||
});
|
});
|
||||||
|
@ -2252,7 +2245,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
await window.Signal.Data.saveMessage(upgradedMessage);
|
await window.Signal.Data.saveMessage(upgradedMessage);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Problem upgrading message quoted message from database',
|
'Problem upgrading message quoted message from database',
|
||||||
Errors.toLogFormat(error)
|
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
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
const conversation = window.ConversationController.get(conversationId)!;
|
const conversation = window.ConversationController.get(conversationId)!;
|
||||||
return conversation.queueJob('handleDataMessage', async () => {
|
return conversation.queueJob('handleDataMessage', async () => {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Starting handleDataMessage for message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
|
`Starting handleDataMessage for message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2331,12 +2324,9 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
this.getSenderIdentifier()
|
this.getSenderIdentifier()
|
||||||
);
|
);
|
||||||
if (inMemoryMessage) {
|
if (inMemoryMessage) {
|
||||||
window.log.info(
|
log.info('handleDataMessage: cache hit', this.getSenderIdentifier());
|
||||||
'handleDataMessage: cache hit',
|
|
||||||
this.getSenderIdentifier()
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info(
|
||||||
'handleDataMessage: duplicate check db lookup needed',
|
'handleDataMessage: duplicate check db lookup needed',
|
||||||
this.getSenderIdentifier()
|
this.getSenderIdentifier()
|
||||||
);
|
);
|
||||||
|
@ -2349,13 +2339,13 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
const isUpdate = Boolean(data && data.isRecipientUpdate);
|
const isUpdate = Boolean(data && data.isRecipientUpdate);
|
||||||
|
|
||||||
if (existingMessage && type === 'incoming') {
|
if (existingMessage && type === 'incoming') {
|
||||||
window.log.warn('Received duplicate message', this.idForLogging());
|
log.warn('Received duplicate message', this.idForLogging());
|
||||||
confirm();
|
confirm();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type === 'outgoing') {
|
if (type === 'outgoing') {
|
||||||
if (isUpdate && existingMessage) {
|
if (isUpdate && existingMessage) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`handleDataMessage: Updating message ${message.idForLogging()} with received transcript`
|
`handleDataMessage: Updating message ${message.idForLogging()} with received transcript`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2431,7 +2421,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isUpdate) {
|
if (isUpdate) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`handleDataMessage: Received update transcript, but no existing entry for message ${message.idForLogging()}. Dropping.`
|
`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;
|
return;
|
||||||
}
|
}
|
||||||
if (existingMessage) {
|
if (existingMessage) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`handleDataMessage: Received duplicate transcript for message ${message.idForLogging()}, but it was not an update transcript. Dropping.`
|
`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) {
|
} catch (error) {
|
||||||
const errorText = error && error.stack ? error.stack : 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}`
|
`handleDataMessage: Failed to process group update for ${conversation.idForLogging()} as part of message ${message.idForLogging()}: ${errorText}`
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -2525,7 +2515,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
!conversation.hasMember(ourConversationId) ||
|
!conversation.hasMember(ourConversationId) ||
|
||||||
!conversation.hasMember(senderId))
|
!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.`
|
`Received message destined for group ${conversation.idForLogging()}, which we or the sender are not a part of. Dropping.`
|
||||||
);
|
);
|
||||||
confirm();
|
confirm();
|
||||||
|
@ -2545,7 +2535,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
conversation.get('members') &&
|
conversation.get('members') &&
|
||||||
(conversation.get('left') || !conversation.hasMember(ourConversationId))
|
(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.`
|
`Received message destined for group ${conversation.idForLogging()}, which we're not a part of. Dropping.`
|
||||||
);
|
);
|
||||||
confirm();
|
confirm();
|
||||||
|
@ -2555,7 +2545,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
// Because GroupV1 messages can now be multiplexed into GroupV2 conversations, we
|
// Because GroupV1 messages can now be multiplexed into GroupV2 conversations, we
|
||||||
// drop GroupV1 updates in GroupV2 groups.
|
// drop GroupV1 updates in GroupV2 groups.
|
||||||
if (isV1GroupUpdate && isGroupV2(conversation.attributes)) {
|
if (isV1GroupUpdate && isGroupV2(conversation.attributes)) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`Received GroupV1 update in GroupV2 conversation ${conversation.idForLogging()}. Dropping.`
|
`Received GroupV1 update in GroupV2 conversation ${conversation.idForLogging()}. Dropping.`
|
||||||
);
|
);
|
||||||
confirm();
|
confirm();
|
||||||
|
@ -2615,7 +2605,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
LinkPreview.isLinkSafeToPreview(item.url)
|
LinkPreview.isLinkSafeToPreview(item.url)
|
||||||
);
|
);
|
||||||
if (preview.length < incomingPreview.length) {
|
if (preview.length < incomingPreview.length) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`${message.idForLogging()}: Eliminated ${
|
`${message.idForLogging()}: Eliminated ${
|
||||||
preview.length - incomingPreview.length
|
preview.length - incomingPreview.length
|
||||||
} previews with invalid urls'`
|
} previews with invalid urls'`
|
||||||
|
@ -2705,9 +2695,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.info(
|
log.info('handleDataMessage: group avatar download failed');
|
||||||
'handleDataMessage: group avatar download failed'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2747,7 +2735,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
|
|
||||||
pendingGroupUpdate.avatarUpdated = true;
|
pendingGroupUpdate.avatarUpdated = true;
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info(
|
||||||
'handleDataMessage: Group avatar hash matched; not replacing group avatar'
|
'handleDataMessage: Group avatar hash matched; not replacing group avatar'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2766,7 +2754,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
pendingGroupUpdate.joined = [...e164s];
|
pendingGroupUpdate.joined = [...e164s];
|
||||||
}
|
}
|
||||||
if (conversation.get('left')) {
|
if (conversation.get('left')) {
|
||||||
window.log.warn('re-added to a left group');
|
log.warn('re-added to a left group');
|
||||||
attributes.left = false;
|
attributes.left = false;
|
||||||
conversation.set({ addedBy: message.getContactId() });
|
conversation.set({ addedBy: message.getContactId() });
|
||||||
}
|
}
|
||||||
|
@ -2779,7 +2767,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
if (!inGroup) {
|
if (!inGroup) {
|
||||||
const senderString = sender ? sender.idForLogging() : null;
|
const senderString = sender ? sender.idForLogging() : null;
|
||||||
window.log.info(
|
log.info(
|
||||||
`Got 'left' message from someone not in group: ${senderString}. Dropping.`
|
`Got 'left' message from someone not in group: ${senderString}. Dropping.`
|
||||||
);
|
);
|
||||||
return;
|
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
|
// message.set call and after GroupV1 processing to make sure all possible
|
||||||
// properties are set before we determine that a message is empty.
|
// properties are set before we determine that a message is empty.
|
||||||
if (message.isEmpty()) {
|
if (message.isEmpty()) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`handleDataMessage: Dropping empty message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
|
`handleDataMessage: Dropping empty message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
confirm();
|
confirm();
|
||||||
|
@ -2840,7 +2828,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
const shouldLogExpireTimerChange =
|
const shouldLogExpireTimerChange =
|
||||||
isExpirationTimerUpdate(message.attributes) || expireTimer;
|
isExpirationTimerUpdate(message.attributes) || expireTimer;
|
||||||
if (shouldLogExpireTimerChange) {
|
if (shouldLogExpireTimerChange) {
|
||||||
window.log.info("Update conversation 'expireTimer'", {
|
log.info("Update conversation 'expireTimer'", {
|
||||||
id: conversation.idForLogging(),
|
id: conversation.idForLogging(),
|
||||||
expireTimer,
|
expireTimer,
|
||||||
source: 'handleDataMessage',
|
source: 'handleDataMessage',
|
||||||
|
@ -2908,7 +2896,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
isTapToView(message.attributes) &&
|
isTapToView(message.attributes) &&
|
||||||
!message.isValidTapToView()
|
!message.isValidTapToView()
|
||||||
) {
|
) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`Received tap to view message ${message.idForLogging()} with invalid data. Erasing contents.`
|
`Received tap to view message ${message.idForLogging()} with invalid data. Erasing contents.`
|
||||||
);
|
);
|
||||||
message.set({
|
message.set({
|
||||||
|
@ -2949,7 +2937,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
) {
|
) {
|
||||||
if (window.attachmentDownloadQueue) {
|
if (window.attachmentDownloadQueue) {
|
||||||
window.attachmentDownloadQueue.unshift(message);
|
window.attachmentDownloadQueue.unshift(message);
|
||||||
window.log.info(
|
log.info(
|
||||||
'Adding to attachmentDownloadQueue',
|
'Adding to attachmentDownloadQueue',
|
||||||
message.get('sent_at')
|
message.get('sent_at')
|
||||||
);
|
);
|
||||||
|
@ -2961,14 +2949,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
const isFirstRun = true;
|
const isFirstRun = true;
|
||||||
await this.modifyTargetMessage(conversation, isFirstRun);
|
await this.modifyTargetMessage(conversation, isFirstRun);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'handleDataMessage: Batching save for',
|
'handleDataMessage: Batching save for',
|
||||||
message.get('sent_at')
|
message.get('sent_at')
|
||||||
);
|
);
|
||||||
this.saveAndNotify(conversation, confirm);
|
this.saveAndNotify(conversation, confirm);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorForLog = error && error.stack ? error.stack : error;
|
const errorForLog = error && error.stack ? error.stack : error;
|
||||||
window.log.error(
|
log.error(
|
||||||
'handleDataMessage',
|
'handleDataMessage',
|
||||||
message.idForLogging(),
|
message.idForLogging(),
|
||||||
'error:',
|
'error:',
|
||||||
|
@ -2985,7 +2973,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await window.Signal.Util.saveNewMessageBatcher.add(this.attributes);
|
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);
|
conversation.trigger('newmessage', this);
|
||||||
|
|
||||||
|
@ -3057,7 +3045,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
) => {
|
) => {
|
||||||
const oldSendState = getOwn(result, destinationConversationId);
|
const oldSendState = getOwn(result, destinationConversationId);
|
||||||
if (!oldSendState) {
|
if (!oldSendState) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
`Got a receipt for a conversation (${destinationConversationId}), but we have no record of sending to them`
|
`Got a receipt for a conversation (${destinationConversationId}), but we have no record of sending to them`
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
|
@ -3177,7 +3165,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (changed && !isFirstRun) {
|
if (changed && !isFirstRun) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`modifyTargetMessage/${this.idForLogging()}: Changes in second run; saving.`
|
`modifyTargetMessage/${this.idForLogging()}: Changes in second run; saving.`
|
||||||
);
|
);
|
||||||
await window.Signal.Data.saveMessage(this.attributes);
|
await window.Signal.Data.saveMessage(this.attributes);
|
||||||
|
@ -3219,7 +3207,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
|
|
||||||
let oldReaction: ReactionAttributesType | undefined;
|
let oldReaction: ReactionAttributesType | undefined;
|
||||||
if (reaction.get('remove')) {
|
if (reaction.get('remove')) {
|
||||||
window.log.info('Removing reaction for message', messageId);
|
log.info('Removing reaction for message', messageId);
|
||||||
const newReactions = reactions.filter(
|
const newReactions = reactions.filter(
|
||||||
re =>
|
re =>
|
||||||
re.emoji !== reaction.get('emoji') ||
|
re.emoji !== reaction.get('emoji') ||
|
||||||
|
@ -3240,7 +3228,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
targetTimestamp: reaction.get('targetTimestamp'),
|
targetTimestamp: reaction.get('targetTimestamp'),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.log.info('Adding reaction for message', messageId);
|
log.info('Adding reaction for message', messageId);
|
||||||
const newReactions = reactions.filter(
|
const newReactions = reactions.filter(
|
||||||
re => re.fromId !== reaction.get('fromId')
|
re => re.fromId !== reaction.get('fromId')
|
||||||
);
|
);
|
||||||
|
@ -3281,7 +3269,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const newCount = (this.get('reactions') || []).length;
|
const newCount = (this.get('reactions') || []).length;
|
||||||
window.log.info(
|
log.info(
|
||||||
`Done processing reaction for message ${messageId}. Went from ${count} to ${newCount} reactions.`
|
`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,
|
del: typeof window.WhatIsThis,
|
||||||
shouldPersist = true
|
shouldPersist = true
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
window.log.info('Handling DOE.', {
|
log.info('Handling DOE.', {
|
||||||
fromId: del.get('fromId'),
|
fromId: del.get('fromId'),
|
||||||
targetSentTimestamp: del.get('targetSentTimestamp'),
|
targetSentTimestamp: del.get('targetSentTimestamp'),
|
||||||
messageServerTimestamp: this.get('serverTimestamp'),
|
messageServerTimestamp: this.get('serverTimestamp'),
|
||||||
|
|
|
@ -53,7 +53,7 @@ export async function routineProfileRefresh({
|
||||||
async function refreshConversation(
|
async function refreshConversation(
|
||||||
conversation: ConversationModel
|
conversation: ConversationModel
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
window.log.info(
|
log.info(
|
||||||
`routineProfileRefresh: refreshing profile for ${conversation.idForLogging()}`
|
`routineProfileRefresh: refreshing profile for ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -63,12 +63,12 @@ export async function routineProfileRefresh({
|
||||||
conversation.get('uuid'),
|
conversation.get('uuid'),
|
||||||
conversation.get('e164')
|
conversation.get('e164')
|
||||||
);
|
);
|
||||||
window.log.info(
|
log.info(
|
||||||
`routineProfileRefresh: refreshed profile for ${conversation.idForLogging()}`
|
`routineProfileRefresh: refreshed profile for ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
successCount += 1;
|
successCount += 1;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error(
|
||||||
`routineProfileRefresh: refreshed profile for ${conversation.idForLogging()}`,
|
`routineProfileRefresh: refreshed profile for ${conversation.idForLogging()}`,
|
||||||
err?.stack || err
|
err?.stack || err
|
||||||
);
|
);
|
||||||
|
|
|
@ -83,6 +83,7 @@ import { notify } from './notify';
|
||||||
import { getSendOptions } from '../util/getSendOptions';
|
import { getSendOptions } from '../util/getSendOptions';
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
import dataInterface from '../sql/Client';
|
import dataInterface from '../sql/Client';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
processGroupCallRingRequest,
|
processGroupCallRingRequest,
|
||||||
|
@ -275,11 +276,11 @@ export class CallingClass {
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
isVideoCall: boolean
|
isVideoCall: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
window.log.info('CallingClass.startCallingLobby()');
|
log.info('CallingClass.startCallingLobby()');
|
||||||
|
|
||||||
const conversation = window.ConversationController.get(conversationId);
|
const conversation = window.ConversationController.get(conversationId);
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error('Could not find conversation, cannot start call lobby');
|
log.error('Could not find conversation, cannot start call lobby');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,15 +288,11 @@ export class CallingClass {
|
||||||
const callMode = getConversationCallMode(conversationProps);
|
const callMode = getConversationCallMode(conversationProps);
|
||||||
switch (callMode) {
|
switch (callMode) {
|
||||||
case CallMode.None:
|
case CallMode.None:
|
||||||
window.log.error(
|
log.error('Conversation does not support calls, new call not allowed.');
|
||||||
'Conversation does not support calls, new call not allowed.'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
case CallMode.Direct:
|
case CallMode.Direct:
|
||||||
if (!this.getRemoteUserIdFromConversation(conversation)) {
|
if (!this.getRemoteUserIdFromConversation(conversation)) {
|
||||||
window.log.error(
|
log.error('Missing remote user identifier, new call not allowed.');
|
||||||
'Missing remote user identifier, new call not allowed.'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -306,24 +303,22 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.uxActions) {
|
if (!this.uxActions) {
|
||||||
window.log.error('Missing uxActions, new call not allowed.');
|
log.error('Missing uxActions, new call not allowed.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.localDeviceId) {
|
if (!this.localDeviceId) {
|
||||||
window.log.error(
|
log.error('Missing local device identifier, new call not allowed.');
|
||||||
'Missing local device identifier, new call not allowed.'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const haveMediaPermissions = await this.requestPermissions(isVideoCall);
|
const haveMediaPermissions = await this.requestPermissions(isVideoCall);
|
||||||
if (!haveMediaPermissions) {
|
if (!haveMediaPermissions) {
|
||||||
window.log.info('Permissions were denied, new call not allowed.');
|
log.info('Permissions were denied, new call not allowed.');
|
||||||
return;
|
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
|
// It's important that this function comes before any calls to
|
||||||
// `videoCapturer.enableCapture` or `videoCapturer.enableCaptureAndSend` because of
|
// `videoCapturer.enableCapture` or `videoCapturer.enableCaptureAndSend` because of
|
||||||
|
@ -358,7 +353,7 @@ export class CallingClass {
|
||||||
!conversationProps.publicParams ||
|
!conversationProps.publicParams ||
|
||||||
!conversationProps.secretParams
|
!conversationProps.secretParams
|
||||||
) {
|
) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Conversation is missing required parameters. Cannot connect group call'
|
'Conversation is missing required parameters. Cannot connect group call'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -406,7 +401,7 @@ export class CallingClass {
|
||||||
hasLocalAudio: boolean,
|
hasLocalAudio: boolean,
|
||||||
hasLocalVideo: boolean
|
hasLocalVideo: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
window.log.info('CallingClass.startOutgoingDirectCall()');
|
log.info('CallingClass.startOutgoingDirectCall()');
|
||||||
|
|
||||||
if (!this.uxActions) {
|
if (!this.uxActions) {
|
||||||
throw new Error('Redux actions not available');
|
throw new Error('Redux actions not available');
|
||||||
|
@ -415,41 +410,37 @@ export class CallingClass {
|
||||||
const conversation = window.ConversationController.get(conversationId);
|
const conversation = window.ConversationController.get(conversationId);
|
||||||
|
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error('Could not find conversation, cannot start call');
|
log.error('Could not find conversation, cannot start call');
|
||||||
this.stopCallingLobby();
|
this.stopCallingLobby();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const remoteUserId = this.getRemoteUserIdFromConversation(conversation);
|
const remoteUserId = this.getRemoteUserIdFromConversation(conversation);
|
||||||
if (!remoteUserId || !this.localDeviceId) {
|
if (!remoteUserId || !this.localDeviceId) {
|
||||||
window.log.error('Missing identifier, new call not allowed.');
|
log.error('Missing identifier, new call not allowed.');
|
||||||
this.stopCallingLobby();
|
this.stopCallingLobby();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const haveMediaPermissions = await this.requestPermissions(hasLocalVideo);
|
const haveMediaPermissions = await this.requestPermissions(hasLocalVideo);
|
||||||
if (!haveMediaPermissions) {
|
if (!haveMediaPermissions) {
|
||||||
window.log.info('Permissions were denied, new call not allowed.');
|
log.info('Permissions were denied, new call not allowed.');
|
||||||
this.stopCallingLobby();
|
this.stopCallingLobby();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info('CallingClass.startOutgoingDirectCall(): Getting call settings');
|
||||||
'CallingClass.startOutgoingDirectCall(): Getting call settings'
|
|
||||||
);
|
|
||||||
|
|
||||||
const callSettings = await this.getCallSettings(conversation);
|
const callSettings = await this.getCallSettings(conversation);
|
||||||
|
|
||||||
// Check state after awaiting to debounce call button.
|
// Check state after awaiting to debounce call button.
|
||||||
if (RingRTC.call && RingRTC.call.state !== CallState.Ended) {
|
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();
|
this.stopCallingLobby();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info('CallingClass.startOutgoingDirectCall(): Starting in RingRTC');
|
||||||
'CallingClass.startOutgoingDirectCall(): Starting in RingRTC'
|
|
||||||
);
|
|
||||||
|
|
||||||
// We could make this faster by getting the call object
|
// We could make this faster by getting the call object
|
||||||
// from the RingRTC before we lookup the ICE servers.
|
// from the RingRTC before we lookup the ICE servers.
|
||||||
|
@ -655,7 +646,7 @@ export class CallingClass {
|
||||||
groupCall.setMembershipProof(Buffer.from(Bytes.fromString(proof)));
|
groupCall.setMembershipProof(Buffer.from(Bytes.fromString(proof)));
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error('Failed to fetch membership proof', err);
|
log.error('Failed to fetch membership proof', err);
|
||||||
} finally {
|
} finally {
|
||||||
isRequestingMembershipProof = false;
|
isRequestingMembershipProof = false;
|
||||||
}
|
}
|
||||||
|
@ -689,7 +680,7 @@ export class CallingClass {
|
||||||
conversationId
|
conversationId
|
||||||
)?.format();
|
)?.format();
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error('Missing conversation; not joining group call');
|
log.error('Missing conversation; not joining group call');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +689,7 @@ export class CallingClass {
|
||||||
!conversation.publicParams ||
|
!conversation.publicParams ||
|
||||||
!conversation.secretParams
|
!conversation.secretParams
|
||||||
) {
|
) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Conversation is missing required parameters. Cannot join group call'
|
'Conversation is missing required parameters. Cannot join group call'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -782,7 +773,7 @@ export class CallingClass {
|
||||||
uuids: peekInfo.joinedMembers.map(uuidBuffer => {
|
uuids: peekInfo.joinedMembers.map(uuidBuffer => {
|
||||||
let uuid = arrayBufferToUuid(typedArrayToArrayBuffer(uuidBuffer));
|
let uuid = arrayBufferToUuid(typedArrayToArrayBuffer(uuidBuffer));
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Calling.formatGroupCallPeekInfoForRedux: could not convert peek UUID ArrayBuffer to string; using fallback UUID'
|
'Calling.formatGroupCallPeekInfoForRedux: could not convert peek UUID ArrayBuffer to string; using fallback UUID'
|
||||||
);
|
);
|
||||||
uuid = '00000000-0000-0000-0000-000000000000';
|
uuid = '00000000-0000-0000-0000-000000000000';
|
||||||
|
@ -832,7 +823,7 @@ export class CallingClass {
|
||||||
typedArrayToArrayBuffer(remoteDeviceState.userId)
|
typedArrayToArrayBuffer(remoteDeviceState.userId)
|
||||||
);
|
);
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Calling.formatGroupCallForRedux: could not convert remote participant UUID ArrayBuffer to string; using fallback UUID'
|
'Calling.formatGroupCallForRedux: could not convert remote participant UUID ArrayBuffer to string; using fallback UUID'
|
||||||
);
|
);
|
||||||
uuid = '00000000-0000-0000-0000-000000000000';
|
uuid = '00000000-0000-0000-0000-000000000000';
|
||||||
|
@ -891,7 +882,7 @@ export class CallingClass {
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const conversation = window.ConversationController.get(conversationId);
|
const conversation = window.ConversationController.get(conversationId);
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Unable to send group call update message for non-existent conversation'
|
'Unable to send group call update message for non-existent conversation'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -900,7 +891,7 @@ export class CallingClass {
|
||||||
const groupV2 = conversation.getGroupV2Info();
|
const groupV2 = conversation.getGroupV2Info();
|
||||||
const sendOptions = await getSendOptions(conversation.attributes);
|
const sendOptions = await getSendOptions(conversation.attributes);
|
||||||
if (!groupV2) {
|
if (!groupV2) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Unable to send group call update message for conversation that lacks groupV2 info'
|
'Unable to send group call update message for conversation that lacks groupV2 info'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -926,7 +917,7 @@ export class CallingClass {
|
||||||
sendType: 'callingMessage',
|
sendType: 'callingMessage',
|
||||||
timestamp,
|
timestamp,
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Failed to send group call update:',
|
'Failed to send group call update:',
|
||||||
err && err.stack ? err.stack : err
|
err && err.stack ? err.stack : err
|
||||||
);
|
);
|
||||||
|
@ -937,11 +928,11 @@ export class CallingClass {
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
asVideoCall: boolean
|
asVideoCall: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
window.log.info('CallingClass.acceptDirectCall()');
|
log.info('CallingClass.acceptDirectCall()');
|
||||||
|
|
||||||
const callId = this.getCallIdForConversation(conversationId);
|
const callId = this.getCallIdForConversation(conversationId);
|
||||||
if (!callId) {
|
if (!callId) {
|
||||||
window.log.warn('Trying to accept a non-existent call');
|
log.warn('Trying to accept a non-existent call');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,19 +943,17 @@ export class CallingClass {
|
||||||
RingRTC.setVideoRenderer(callId, this.videoRenderer);
|
RingRTC.setVideoRenderer(callId, this.videoRenderer);
|
||||||
RingRTC.accept(callId, asVideoCall);
|
RingRTC.accept(callId, asVideoCall);
|
||||||
} else {
|
} 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);
|
RingRTC.hangup(callId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declineDirectCall(conversationId: string): void {
|
declineDirectCall(conversationId: string): void {
|
||||||
window.log.info('CallingClass.declineDirectCall()');
|
log.info('CallingClass.declineDirectCall()');
|
||||||
|
|
||||||
const callId = this.getCallIdForConversation(conversationId);
|
const callId = this.getCallIdForConversation(conversationId);
|
||||||
if (!callId) {
|
if (!callId) {
|
||||||
window.log.warn(
|
log.warn('declineDirectCall: Trying to decline a non-existent call');
|
||||||
'declineDirectCall: Trying to decline a non-existent call'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -972,13 +961,13 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
declineGroupCall(conversationId: string, ringId: bigint): void {
|
declineGroupCall(conversationId: string, ringId: bigint): void {
|
||||||
window.log.info('CallingClass.declineGroupCall()');
|
log.info('CallingClass.declineGroupCall()');
|
||||||
|
|
||||||
const groupId = window.ConversationController.get(conversationId)?.get(
|
const groupId = window.ConversationController.get(conversationId)?.get(
|
||||||
'groupId'
|
'groupId'
|
||||||
);
|
);
|
||||||
if (!groupId) {
|
if (!groupId) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'declineGroupCall: could not find the group ID for that conversation'
|
'declineGroupCall: could not find the group ID for that conversation'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -993,11 +982,11 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
hangup(conversationId: string): void {
|
hangup(conversationId: string): void {
|
||||||
window.log.info('CallingClass.hangup()');
|
log.info('CallingClass.hangup()');
|
||||||
|
|
||||||
const call = getOwn(this.callsByConversation, conversationId);
|
const call = getOwn(this.callsByConversation, conversationId);
|
||||||
if (!call) {
|
if (!call) {
|
||||||
window.log.warn('Trying to hang up a non-existent call');
|
log.warn('Trying to hang up a non-existent call');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1018,7 +1007,7 @@ export class CallingClass {
|
||||||
setOutgoingAudio(conversationId: string, enabled: boolean): void {
|
setOutgoingAudio(conversationId: string, enabled: boolean): void {
|
||||||
const call = getOwn(this.callsByConversation, conversationId);
|
const call = getOwn(this.callsByConversation, conversationId);
|
||||||
if (!call) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,7 +1023,7 @@ export class CallingClass {
|
||||||
setOutgoingVideo(conversationId: string, enabled: boolean): void {
|
setOutgoingVideo(conversationId: string, enabled: boolean): void {
|
||||||
const call = getOwn(this.callsByConversation, conversationId);
|
const call = getOwn(this.callsByConversation, conversationId);
|
||||||
if (!call) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,7 +1088,7 @@ export class CallingClass {
|
||||||
): void {
|
): void {
|
||||||
const call = getOwn(this.callsByConversation, conversationId);
|
const call = getOwn(this.callsByConversation, conversationId);
|
||||||
if (!call) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,7 +1232,7 @@ export class CallingClass {
|
||||||
if (
|
if (
|
||||||
!this.mediaDeviceSettingsEqual(this.lastMediaDeviceSettings, newSettings)
|
!this.mediaDeviceSettingsEqual(this.lastMediaDeviceSettings, newSettings)
|
||||||
) {
|
) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'MediaDevice: available devices changed (from->to)',
|
'MediaDevice: available devices changed (from->to)',
|
||||||
this.lastMediaDeviceSettings,
|
this.lastMediaDeviceSettings,
|
||||||
newSettings
|
newSettings
|
||||||
|
@ -1354,13 +1343,13 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
setPreferredMicrophone(device: AudioDevice): void {
|
setPreferredMicrophone(device: AudioDevice): void {
|
||||||
window.log.info('MediaDevice: setPreferredMicrophone', device);
|
log.info('MediaDevice: setPreferredMicrophone', device);
|
||||||
window.Events.setPreferredAudioInputDevice(device);
|
window.Events.setPreferredAudioInputDevice(device);
|
||||||
RingRTC.setAudioInput(device.index);
|
RingRTC.setAudioInput(device.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
setPreferredSpeaker(device: AudioDevice): void {
|
setPreferredSpeaker(device: AudioDevice): void {
|
||||||
window.log.info('MediaDevice: setPreferredSpeaker', device);
|
log.info('MediaDevice: setPreferredSpeaker', device);
|
||||||
window.Events.setPreferredAudioOutputDevice(device);
|
window.Events.setPreferredAudioOutputDevice(device);
|
||||||
RingRTC.setAudioOutput(device.index);
|
RingRTC.setAudioOutput(device.index);
|
||||||
}
|
}
|
||||||
|
@ -1374,7 +1363,7 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setPreferredCamera(device: string): Promise<void> {
|
async setPreferredCamera(device: string): Promise<void> {
|
||||||
window.log.info('MediaDevice: setPreferredCamera', device);
|
log.info('MediaDevice: setPreferredCamera', device);
|
||||||
window.Events.setPreferredVideoInputDevice(device);
|
window.Events.setPreferredVideoInputDevice(device);
|
||||||
await this.videoCapturer.setPreferredDevice(device);
|
await this.videoCapturer.setPreferredDevice(device);
|
||||||
}
|
}
|
||||||
|
@ -1383,19 +1372,19 @@ export class CallingClass {
|
||||||
envelope: ProcessedEnvelope,
|
envelope: ProcessedEnvelope,
|
||||||
callingMessage: Proto.ICallingMessage
|
callingMessage: Proto.ICallingMessage
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
window.log.info('CallingClass.handleCallingMessage()');
|
log.info('CallingClass.handleCallingMessage()');
|
||||||
|
|
||||||
const enableIncomingCalls = window.Events.getIncomingCallNotification();
|
const enableIncomingCalls = window.Events.getIncomingCallNotification();
|
||||||
if (callingMessage.offer && !enableIncomingCalls) {
|
if (callingMessage.offer && !enableIncomingCalls) {
|
||||||
// Drop offers silently if incoming call notifications are disabled.
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const remoteUserId = envelope.sourceUuid;
|
const remoteUserId = envelope.sourceUuid;
|
||||||
const remoteDeviceId = this.parseDeviceId(envelope.sourceDevice);
|
const remoteDeviceId = this.parseDeviceId(envelope.sourceDevice);
|
||||||
if (!remoteUserId || !remoteDeviceId || !this.localDeviceId) {
|
if (!remoteUserId || !remoteDeviceId || !this.localDeviceId) {
|
||||||
window.log.error('Missing identifier, ignoring call message.');
|
log.error('Missing identifier, ignoring call message.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1405,9 +1394,7 @@ export class CallingClass {
|
||||||
new UUID(remoteUserId)
|
new UUID(remoteUserId)
|
||||||
);
|
);
|
||||||
if (!senderIdentityRecord) {
|
if (!senderIdentityRecord) {
|
||||||
window.log.error(
|
log.error('Missing sender identity record; ignoring call message.');
|
||||||
'Missing sender identity record; ignoring call message.'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const senderIdentityKey = senderIdentityRecord.publicKey.slice(1); // Ignore the type header, it is not used.
|
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);
|
const receiverIdentityRecord = storage.protocol.getIdentityRecord(ourUuid);
|
||||||
if (!receiverIdentityRecord) {
|
if (!receiverIdentityRecord) {
|
||||||
window.log.error(
|
log.error('Missing receiver identity record; ignoring call message.');
|
||||||
'Missing receiver identity record; ignoring call message.'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const receiverIdentityKey = receiverIdentityRecord.publicKey.slice(1); // Ignore the type header, it is not used.
|
const receiverIdentityKey = receiverIdentityRecord.publicKey.slice(1); // Ignore the type header, it is not used.
|
||||||
|
|
||||||
const conversation = window.ConversationController.get(remoteUserId);
|
const conversation = window.ConversationController.get(remoteUserId);
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error('Missing conversation; ignoring call message.');
|
log.error('Missing conversation; ignoring call message.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callingMessage.offer && !conversation.getAccepted()) {
|
if (callingMessage.offer && !conversation.getAccepted()) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'Conversation was not approved by user; rejecting call message.'
|
'Conversation was not approved by user; rejecting call message.'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1460,7 +1445,7 @@ export class CallingClass {
|
||||||
|
|
||||||
const messageAgeSec = envelope.messageAgeSec ? envelope.messageAgeSec : 0;
|
const messageAgeSec = envelope.messageAgeSec ? envelope.messageAgeSec : 0;
|
||||||
|
|
||||||
window.log.info('CallingClass.handleCallingMessage(): Handling in RingRTC');
|
log.info('CallingClass.handleCallingMessage(): Handling in RingRTC');
|
||||||
|
|
||||||
RingRTC.handleCallingMessage(
|
RingRTC.handleCallingMessage(
|
||||||
remoteUserId,
|
remoteUserId,
|
||||||
|
@ -1483,14 +1468,14 @@ export class CallingClass {
|
||||||
settings.selectedCamera &&
|
settings.selectedCamera &&
|
||||||
this.lastMediaDeviceSettings.selectedCamera !== 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);
|
await this.videoCapturer.setPreferredDevice(settings.selectedCamera);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume that the MediaDeviceSettings have been obtained very recently and
|
// Assume that the MediaDeviceSettings have been obtained very recently and
|
||||||
// the index is still valid (no devices have been plugged in in between).
|
// the index is still valid (no devices have been plugged in in between).
|
||||||
if (settings.selectedMicrophone) {
|
if (settings.selectedMicrophone) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'MediaDevice: selecting microphone',
|
'MediaDevice: selecting microphone',
|
||||||
settings.selectedMicrophone
|
settings.selectedMicrophone
|
||||||
);
|
);
|
||||||
|
@ -1498,10 +1483,7 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.selectedSpeaker) {
|
if (settings.selectedSpeaker) {
|
||||||
window.log.info(
|
log.info('MediaDevice: selecting speaker', settings.selectedSpeaker);
|
||||||
'MediaDevice: selecting speaker',
|
|
||||||
settings.selectedSpeaker
|
|
||||||
);
|
|
||||||
RingRTC.setAudioOutput(settings.selectedSpeaker.index);
|
RingRTC.setAudioOutput(settings.selectedSpeaker.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1550,7 +1532,7 @@ export class CallingClass {
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const userId = arrayBufferToUuid(typedArrayToArrayBuffer(recipient));
|
const userId = arrayBufferToUuid(typedArrayToArrayBuffer(recipient));
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
window.log.error('handleSendCallMessage(): bad recipient UUID');
|
log.error('handleSendCallMessage(): bad recipient UUID');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const message = new CallingMessage();
|
const message = new CallingMessage();
|
||||||
|
@ -1567,9 +1549,7 @@ export class CallingClass {
|
||||||
const groupId = groupIdBytes.toString('base64');
|
const groupId = groupIdBytes.toString('base64');
|
||||||
const conversation = window.ConversationController.get(groupId);
|
const conversation = window.ConversationController.get(groupId);
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error(
|
log.error('handleSendCallMessageToGroup(): could not find conversation');
|
||||||
'handleSendCallMessageToGroup(): could not find conversation'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1609,21 +1589,19 @@ export class CallingClass {
|
||||||
ringerBytes: Buffer,
|
ringerBytes: Buffer,
|
||||||
update: RingUpdate
|
update: RingUpdate
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
window.log.info(`handleGroupCallRingUpdate(): got ring update ${update}`);
|
log.info(`handleGroupCallRingUpdate(): got ring update ${update}`);
|
||||||
|
|
||||||
const groupId = groupIdBytes.toString('base64');
|
const groupId = groupIdBytes.toString('base64');
|
||||||
|
|
||||||
const ringerUuid = arrayBufferToUuid(typedArrayToArrayBuffer(ringerBytes));
|
const ringerUuid = arrayBufferToUuid(typedArrayToArrayBuffer(ringerBytes));
|
||||||
if (!ringerUuid) {
|
if (!ringerUuid) {
|
||||||
window.log.error('handleGroupCallRingUpdate(): ringerUuid was invalid');
|
log.error('handleGroupCallRingUpdate(): ringerUuid was invalid');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const conversation = window.ConversationController.get(groupId);
|
const conversation = window.ConversationController.get(groupId);
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error(
|
log.error('handleGroupCallRingUpdate(): could not find conversation');
|
||||||
'handleGroupCallRingUpdate(): could not find conversation'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const conversationId = conversation.id;
|
const conversationId = conversation.id;
|
||||||
|
@ -1650,14 +1628,14 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldRing) {
|
if (shouldRing) {
|
||||||
window.log.info('handleGroupCallRingUpdate: ringing');
|
log.info('handleGroupCallRingUpdate: ringing');
|
||||||
this.uxActions?.receiveIncomingGroupCall({
|
this.uxActions?.receiveIncomingGroupCall({
|
||||||
conversationId,
|
conversationId,
|
||||||
ringId,
|
ringId,
|
||||||
ringerUuid,
|
ringerUuid,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.log.info('handleGroupCallRingUpdate: canceling any existing ring');
|
log.info('handleGroupCallRingUpdate: canceling any existing ring');
|
||||||
this.uxActions?.cancelIncomingGroupCallRing({
|
this.uxActions?.cancelIncomingGroupCallRing({
|
||||||
conversationId,
|
conversationId,
|
||||||
ringId,
|
ringId,
|
||||||
|
@ -1676,7 +1654,7 @@ export class CallingClass {
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
if (!window.textsecure.messaging) {
|
if (!window.textsecure.messaging) {
|
||||||
window.log.warn('handleOutgoingSignaling() returning false; offline');
|
log.warn('handleOutgoingSignaling() returning false; offline');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1694,15 +1672,13 @@ export class CallingClass {
|
||||||
throw result.errors[0];
|
throw result.errors[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('handleOutgoingSignaling() completed successfully');
|
log.info('handleOutgoingSignaling() completed successfully');
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err && err.errors && err.errors.length > 0) {
|
if (err && err.errors && err.errors.length > 0) {
|
||||||
window.log.error(
|
log.error(`handleOutgoingSignaling() failed: ${err.errors[0].reason}`);
|
||||||
`handleOutgoingSignaling() failed: ${err.errors[0].reason}`
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
window.log.error('handleOutgoingSignaling() failed');
|
log.error('handleOutgoingSignaling() failed');
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1710,16 +1686,16 @@ export class CallingClass {
|
||||||
|
|
||||||
// If we return null here, we hang up the call.
|
// If we return null here, we hang up the call.
|
||||||
private async handleIncomingCall(call: Call): Promise<CallSettings | null> {
|
private async handleIncomingCall(call: Call): Promise<CallSettings | null> {
|
||||||
window.log.info('CallingClass.handleIncomingCall()');
|
log.info('CallingClass.handleIncomingCall()');
|
||||||
|
|
||||||
if (!this.uxActions || !this.localDeviceId) {
|
if (!this.uxActions || !this.localDeviceId) {
|
||||||
window.log.error('Missing required objects, ignoring incoming call.');
|
log.error('Missing required objects, ignoring incoming call.');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const conversation = window.ConversationController.get(call.remoteUserId);
|
const conversation = window.ConversationController.get(call.remoteUserId);
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error('Missing conversation, ignoring incoming call.');
|
log.error('Missing conversation, ignoring incoming call.');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1732,7 +1708,7 @@ export class CallingClass {
|
||||||
verifiedEnum ===
|
verifiedEnum ===
|
||||||
window.textsecure.storage.protocol.VerifiedStatus.UNVERIFIED
|
window.textsecure.storage.protocol.VerifiedStatus.UNVERIFIED
|
||||||
) {
|
) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Peer is not trusted, ignoring incoming call for conversation: ${conversation.idForLogging()}`
|
`Peer is not trusted, ignoring incoming call for conversation: ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
this.addCallHistoryForFailedIncomingCall(
|
this.addCallHistoryForFailedIncomingCall(
|
||||||
|
@ -1750,11 +1726,11 @@ export class CallingClass {
|
||||||
isVideoCall: call.isVideoCall,
|
isVideoCall: call.isVideoCall,
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.info('CallingClass.handleIncomingCall(): Proceeding');
|
log.info('CallingClass.handleIncomingCall(): Proceeding');
|
||||||
|
|
||||||
return await this.getCallSettings(conversation);
|
return await this.getCallSettings(conversation);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(`Ignoring incoming call: ${err.stack}`);
|
log.error(`Ignoring incoming call: ${err.stack}`);
|
||||||
this.addCallHistoryForFailedIncomingCall(
|
this.addCallHistoryForFailedIncomingCall(
|
||||||
conversation,
|
conversation,
|
||||||
call.isVideoCall,
|
call.isVideoCall,
|
||||||
|
@ -1831,13 +1807,13 @@ export class CallingClass {
|
||||||
) {
|
) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case CallLogLevel.Info:
|
case CallLogLevel.Info:
|
||||||
window.log.info(`${fileName}:${line} ${message}`);
|
log.info(`${fileName}:${line} ${message}`);
|
||||||
break;
|
break;
|
||||||
case CallLogLevel.Warn:
|
case CallLogLevel.Warn:
|
||||||
window.log.warn(`${fileName}:${line} ${message}`);
|
log.warn(`${fileName}:${line} ${message}`);
|
||||||
break;
|
break;
|
||||||
case CallLogLevel.Error:
|
case CallLogLevel.Error:
|
||||||
window.log.error(`${fileName}:${line} ${message}`);
|
log.error(`${fileName}:${line} ${message}`);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1880,7 +1856,7 @@ export class CallingClass {
|
||||||
// it an empty one.
|
// it an empty one.
|
||||||
RingRTC.receivedHttpResponse(requestId, err.code, Buffer.alloc(0));
|
RingRTC.receivedHttpResponse(requestId, err.code, Buffer.alloc(0));
|
||||||
} else {
|
} else {
|
||||||
window.log.error('handleSendHttpRequest: fetch failed with error', err);
|
log.error('handleSendHttpRequest: fetch failed with error', err);
|
||||||
RingRTC.httpRequestFailed(requestId, String(err));
|
RingRTC.httpRequestFailed(requestId, String(err));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -2017,15 +1993,13 @@ export class CallingClass {
|
||||||
typedArrayToArrayBuffer(peekInfo.creator)
|
typedArrayToArrayBuffer(peekInfo.creator)
|
||||||
);
|
);
|
||||||
if (!creatorUuid) {
|
if (!creatorUuid) {
|
||||||
window.log.error('updateCallHistoryForGroupCall(): bad creator UUID');
|
log.error('updateCallHistoryForGroupCall(): bad creator UUID');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const conversation = window.ConversationController.get(conversationId);
|
const conversation = window.ConversationController.get(conversationId);
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
window.log.error(
|
log.error('updateCallHistoryForGroupCall(): could not find conversation');
|
||||||
'updateCallHistoryForGroupCall(): could not find conversation'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { GroupCredentialType } from '../textsecure/WebAPI';
|
||||||
import * as durations from '../util/durations';
|
import * as durations from '../util/durations';
|
||||||
import { BackOff } from '../util/BackOff';
|
import { BackOff } from '../util/BackOff';
|
||||||
import { sleep } from '../util/sleep';
|
import { sleep } from '../util/sleep';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
export const GROUP_CREDENTIALS_KEY = 'groupCredentials';
|
export const GROUP_CREDENTIALS_KEY = 'groupCredentials';
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ export async function initializeGroupCredentialFetcher(): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info('initializeGroupCredentialFetcher: starting...');
|
log.info('initializeGroupCredentialFetcher: starting...');
|
||||||
started = true;
|
started = true;
|
||||||
|
|
||||||
// Because we fetch eight days of credentials at a time, we really only need to run
|
// 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;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const wait = backOff.getAndIncrement();
|
const wait = backOff.getAndIncrement();
|
||||||
window.log.info(
|
log.info(
|
||||||
`runWithRetry: ${fn.name} failed. Waiting ${wait}ms for retry. Error: ${error.stack}`
|
`runWithRetry: ${fn.name} failed. Waiting ${wait}ms for retry. Error: ${error.stack}`
|
||||||
);
|
);
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
@ -83,7 +84,7 @@ export async function runWithRetry(
|
||||||
// could end up with multiple endlessly-retrying runs.
|
// could end up with multiple endlessly-retrying runs.
|
||||||
const duration = options.scheduleAnother;
|
const duration = options.scheduleAnother;
|
||||||
if (duration) {
|
if (duration) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`runWithRetry: scheduling another run with a setTimeout duration of ${duration}ms`
|
`runWithRetry: scheduling another run with a setTimeout duration of ${duration}ms`
|
||||||
);
|
);
|
||||||
setTimeout(async () => runWithRetry(fn, options), duration);
|
setTimeout(async () => runWithRetry(fn, options), duration);
|
||||||
|
@ -117,7 +118,7 @@ export function getCredentialsForToday(
|
||||||
export async function maybeFetchNewCredentials(): Promise<void> {
|
export async function maybeFetchNewCredentials(): Promise<void> {
|
||||||
const uuid = window.textsecure.storage.user.getUuid()?.toString();
|
const uuid = window.textsecure.storage.user.getUuid()?.toString();
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
window.log.info('maybeFetchCredentials: no UUID, returning early');
|
log.info('maybeFetchCredentials: no UUID, returning early');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const previous: CredentialsDataType | undefined = window.storage.get(
|
const previous: CredentialsDataType | undefined = window.storage.get(
|
||||||
|
@ -125,18 +126,18 @@ export async function maybeFetchNewCredentials(): Promise<void> {
|
||||||
);
|
);
|
||||||
const requestDates = getDatesForRequest(previous);
|
const requestDates = getDatesForRequest(previous);
|
||||||
if (!requestDates) {
|
if (!requestDates) {
|
||||||
window.log.info('maybeFetchCredentials: no new credentials needed');
|
log.info('maybeFetchCredentials: no new credentials needed');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountManager = window.getAccountManager();
|
const accountManager = window.getAccountManager();
|
||||||
if (!accountManager) {
|
if (!accountManager) {
|
||||||
window.log.info('maybeFetchCredentials: unable to get AccountManager');
|
log.info('maybeFetchCredentials: unable to get AccountManager');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { startDay, endDay } = requestDates;
|
const { startDay, endDay } = requestDates;
|
||||||
window.log.info(
|
log.info(
|
||||||
`maybeFetchCredentials: fetching credentials for ${startDay} through ${endDay}`
|
`maybeFetchCredentials: fetching credentials for ${startDay} through ${endDay}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -168,10 +169,10 @@ export async function maybeFetchNewCredentials(): Promise<void> {
|
||||||
: [];
|
: [];
|
||||||
const finalCredentials = [...previousCleaned, ...newCredentials];
|
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
|
// Note: we don't wait for this to finish
|
||||||
window.storage.put(GROUP_CREDENTIALS_KEY, finalCredentials);
|
window.storage.put(GROUP_CREDENTIALS_KEY, finalCredentials);
|
||||||
window.log.info('maybeFetchCredentials: Save complete.');
|
log.info('maybeFetchCredentials: Save complete.');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDatesForRequest(
|
export function getDatesForRequest(
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
NetworkActionType,
|
NetworkActionType,
|
||||||
} from '../state/ducks/network';
|
} from '../state/ducks/network';
|
||||||
import { getSocketStatus } from '../shims/socketStatus';
|
import { getSocketStatus } from '../shims/socketStatus';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
type NetworkActions = {
|
type NetworkActions = {
|
||||||
checkNetworkStatus: (x: CheckNetworkStatusPayloadType) => NetworkActionType;
|
checkNetworkStatus: (x: CheckNetworkStatusPayloadType) => NetworkActionType;
|
||||||
|
@ -17,7 +18,6 @@ const REFRESH_INTERVAL = 5000;
|
||||||
export function initializeNetworkObserver(
|
export function initializeNetworkObserver(
|
||||||
networkActions: NetworkActions
|
networkActions: NetworkActions
|
||||||
): void {
|
): void {
|
||||||
const { log } = window;
|
|
||||||
log.info(`Initializing network observer every ${REFRESH_INTERVAL}ms`);
|
log.info(`Initializing network observer every ${REFRESH_INTERVAL}ms`);
|
||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
|
|
|
@ -40,6 +40,7 @@ import {
|
||||||
typeofConversation,
|
typeofConversation,
|
||||||
} from '../util/whatTypeOfConversation';
|
} from '../util/whatTypeOfConversation';
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
type IManifestRecordIdentifier = Proto.ManifestRecord.IIdentifier;
|
type IManifestRecordIdentifier = Proto.ManifestRecord.IIdentifier;
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ async function generateManifest(
|
||||||
previousManifest?: Proto.IManifestRecord,
|
previousManifest?: Proto.IManifestRecord,
|
||||||
isNewManifest = false
|
isNewManifest = false
|
||||||
): Promise<GeneratedManifestType> {
|
): Promise<GeneratedManifestType> {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: generating manifest',
|
'storageService.generateManifest: generating manifest',
|
||||||
version,
|
version,
|
||||||
isNewManifest
|
isNewManifest
|
||||||
|
@ -186,7 +187,7 @@ async function generateManifest(
|
||||||
storageRecord.groupV1 = await toGroupV1Record(conversation);
|
storageRecord.groupV1 = await toGroupV1Record(conversation);
|
||||||
identifier.type = ITEM_TYPE.GROUPV1;
|
identifier.type = ITEM_TYPE.GROUPV1;
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: unknown conversation',
|
'storageService.generateManifest: unknown conversation',
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
);
|
);
|
||||||
|
@ -209,7 +210,7 @@ async function generateManifest(
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
storageItem = await encryptRecord(storageID, storageRecord);
|
storageItem = await encryptRecord(storageID, storageRecord);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.generateManifest: encrypt record failed:',
|
'storageService.generateManifest: encrypt record failed:',
|
||||||
err && err.stack ? err.stack : String(err)
|
err && err.stack ? err.stack : String(err)
|
||||||
);
|
);
|
||||||
|
@ -224,13 +225,13 @@ async function generateManifest(
|
||||||
|
|
||||||
if (storageID) {
|
if (storageID) {
|
||||||
insertKeys.push(storageID);
|
insertKeys.push(storageID);
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: new key',
|
'storageService.generateManifest: new key',
|
||||||
conversation.idForLogging(),
|
conversation.idForLogging(),
|
||||||
redactStorageID(storageID)
|
redactStorageID(storageID)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: no storage id',
|
'storageService.generateManifest: no storage id',
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
);
|
);
|
||||||
|
@ -238,7 +239,7 @@ async function generateManifest(
|
||||||
|
|
||||||
const oldStorageID = conversation.get('storageID');
|
const oldStorageID = conversation.get('storageID');
|
||||||
if (oldStorageID) {
|
if (oldStorageID) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: deleting key',
|
'storageService.generateManifest: deleting key',
|
||||||
redactStorageID(oldStorageID)
|
redactStorageID(oldStorageID)
|
||||||
);
|
);
|
||||||
|
@ -259,7 +260,7 @@ async function generateManifest(
|
||||||
window.storage.get('storage-service-unknown-records') || []
|
window.storage.get('storage-service-unknown-records') || []
|
||||||
).filter((record: UnknownRecord) => !validRecordTypes.has(record.itemType));
|
).filter((record: UnknownRecord) => !validRecordTypes.has(record.itemType));
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: adding unknown records:',
|
'storageService.generateManifest: adding unknown records:',
|
||||||
unknownRecordsArray.length
|
unknownRecordsArray.length
|
||||||
);
|
);
|
||||||
|
@ -279,7 +280,7 @@ async function generateManifest(
|
||||||
new Array<UnknownRecord>()
|
new Array<UnknownRecord>()
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: adding records that had errors in the previous merge',
|
'storageService.generateManifest: adding records that had errors in the previous merge',
|
||||||
recordsWithErrors.length
|
recordsWithErrors.length
|
||||||
);
|
);
|
||||||
|
@ -311,7 +312,7 @@ async function generateManifest(
|
||||||
rawDuplicates.has(identifier.raw) ||
|
rawDuplicates.has(identifier.raw) ||
|
||||||
typeRawDuplicates.has(typeAndRaw)
|
typeRawDuplicates.has(typeAndRaw)
|
||||||
) {
|
) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: removing duplicate identifier from manifest',
|
'storageService.generateManifest: removing duplicate identifier from manifest',
|
||||||
identifier.type
|
identifier.type
|
||||||
);
|
);
|
||||||
|
@ -325,7 +326,7 @@ async function generateManifest(
|
||||||
key => arrayBufferToBase64(key) === storageID
|
key => arrayBufferToBase64(key) === storageID
|
||||||
);
|
);
|
||||||
if (hasDeleteKey) {
|
if (hasDeleteKey) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: removing key which has been deleted',
|
'storageService.generateManifest: removing key which has been deleted',
|
||||||
identifier.type
|
identifier.type
|
||||||
);
|
);
|
||||||
|
@ -335,9 +336,7 @@ async function generateManifest(
|
||||||
// Ensure that there is *exactly* one Account type in the manifest
|
// Ensure that there is *exactly* one Account type in the manifest
|
||||||
if (identifier.type === ITEM_TYPE.ACCOUNT) {
|
if (identifier.type === ITEM_TYPE.ACCOUNT) {
|
||||||
if (hasAccountType) {
|
if (hasAccountType) {
|
||||||
window.log.info(
|
log.info('storageService.generateManifest: removing duplicate account');
|
||||||
'storageService.generateManifest: removing duplicate account'
|
|
||||||
);
|
|
||||||
manifestRecordKeys.delete(identifier);
|
manifestRecordKeys.delete(identifier);
|
||||||
}
|
}
|
||||||
hasAccountType = true;
|
hasAccountType = true;
|
||||||
|
@ -355,7 +354,7 @@ async function generateManifest(
|
||||||
|
|
||||||
const storageID = Bytes.toBase64(storageItem.key);
|
const storageID = Bytes.toBase64(storageItem.key);
|
||||||
if (storageKeyDuplicates.has(storageID)) {
|
if (storageKeyDuplicates.has(storageID)) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.generateManifest: removing duplicate identifier from inserts',
|
'storageService.generateManifest: removing duplicate identifier from inserts',
|
||||||
redactStorageID(storageID)
|
redactStorageID(storageID)
|
||||||
);
|
);
|
||||||
|
@ -405,7 +404,7 @@ async function generateManifest(
|
||||||
);
|
);
|
||||||
const remoteDeletes: Array<string> = [];
|
const remoteDeletes: Array<string> = [];
|
||||||
pendingDeletes.forEach(id => remoteDeletes.push(redactStorageID(id)));
|
pendingDeletes.forEach(id => remoteDeletes.push(redactStorageID(id)));
|
||||||
window.log.error(
|
log.error(
|
||||||
'Delete key sizes do not match',
|
'Delete key sizes do not match',
|
||||||
'local',
|
'local',
|
||||||
localDeletes.join(','),
|
localDeletes.join(','),
|
||||||
|
@ -480,13 +479,13 @@ async function uploadManifest(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newItems.size === 0 && deleteKeys.length === 0) {
|
if (newItems.size === 0 && deleteKeys.length === 0) {
|
||||||
window.log.info('storageService.uploadManifest: nothing to upload');
|
log.info('storageService.uploadManifest: nothing to upload');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const credentials = window.storage.get('storageCredentials');
|
const credentials = window.storage.get('storageCredentials');
|
||||||
try {
|
try {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.uploadManifest: keys inserting, deleting:',
|
'storageService.uploadManifest: keys inserting, deleting:',
|
||||||
newItems.size,
|
newItems.size,
|
||||||
deleteKeys.length
|
deleteKeys.length
|
||||||
|
@ -497,7 +496,7 @@ async function uploadManifest(
|
||||||
writeOperation.insertItem = Array.from(newItems);
|
writeOperation.insertItem = Array.from(newItems);
|
||||||
writeOperation.deleteKey = deleteKeys.map(key => new FIXMEU8(key));
|
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(
|
await window.textsecure.messaging.modifyStorageRecords(
|
||||||
typedArrayToArrayBuffer(
|
typedArrayToArrayBuffer(
|
||||||
Proto.WriteOperation.encode(writeOperation).finish()
|
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:',
|
'storageService.uploadManifest: upload done, updating conversation(s) with new storageIDs:',
|
||||||
conversationsToUpdate.length
|
conversationsToUpdate.length
|
||||||
);
|
);
|
||||||
|
@ -521,20 +520,20 @@ async function uploadManifest(
|
||||||
updateConversation(conversation.attributes);
|
updateConversation(conversation.attributes);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.uploadManifest: failed!',
|
'storageService.uploadManifest: failed!',
|
||||||
err && err.stack ? err.stack : String(err)
|
err && err.stack ? err.stack : String(err)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (err.code === 409) {
|
if (err.code === 409) {
|
||||||
if (conflictBackOff.isFull()) {
|
if (conflictBackOff.isFull()) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.uploadManifest: Exceeded maximum consecutive conflicts'
|
'storageService.uploadManifest: Exceeded maximum consecutive conflicts'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`storageService.uploadManifest: Conflict found with v${version}, running sync job times(${conflictBackOff.getIndex()})`
|
`storageService.uploadManifest: Conflict found with v${version}, running sync job times(${conflictBackOff.getIndex()})`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -544,7 +543,7 @@ async function uploadManifest(
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.uploadManifest: setting new manifestVersion',
|
'storageService.uploadManifest: setting new manifestVersion',
|
||||||
version
|
version
|
||||||
);
|
);
|
||||||
|
@ -553,7 +552,7 @@ async function uploadManifest(
|
||||||
backOff.reset();
|
backOff.reset();
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'uploadManifest: We are primary device; not sending sync manifest'
|
'uploadManifest: We are primary device; not sending sync manifest'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -566,26 +565,26 @@ async function uploadManifest(
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stopStorageServiceSync() {
|
async function stopStorageServiceSync() {
|
||||||
window.log.info('storageService.stopStorageServiceSync');
|
log.info('storageService.stopStorageServiceSync');
|
||||||
|
|
||||||
await window.storage.remove('storageKey');
|
await window.storage.remove('storageKey');
|
||||||
|
|
||||||
if (backOff.isFull()) {
|
if (backOff.isFull()) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.stopStorageServiceSync: too many consecutive stops'
|
'storageService.stopStorageServiceSync: too many consecutive stops'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await sleep(backOff.getAndIncrement());
|
await sleep(backOff.getAndIncrement());
|
||||||
window.log.info('storageService.stopStorageServiceSync: requesting new keys');
|
log.info('storageService.stopStorageServiceSync: requesting new keys');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!window.textsecure.messaging) {
|
if (!window.textsecure.messaging) {
|
||||||
throw new Error('storageService.stopStorageServiceSync: We are offline!');
|
throw new Error('storageService.stopStorageServiceSync: We are offline!');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'stopStorageServiceSync: We are primary device; not sending key sync request'
|
'stopStorageServiceSync: We are primary device; not sending key sync request'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -599,7 +598,7 @@ async function stopStorageServiceSync() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createNewManifest() {
|
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);
|
const version = window.storage.get('manifestVersion', 0);
|
||||||
|
|
||||||
|
@ -645,7 +644,7 @@ async function decryptManifest(
|
||||||
async function fetchManifest(
|
async function fetchManifest(
|
||||||
manifestVersion: number
|
manifestVersion: number
|
||||||
): Promise<Proto.ManifestRecord | undefined> {
|
): Promise<Proto.ManifestRecord | undefined> {
|
||||||
window.log.info('storageService.fetchManifest');
|
log.info('storageService.fetchManifest');
|
||||||
|
|
||||||
if (!window.textsecure.messaging) {
|
if (!window.textsecure.messaging) {
|
||||||
throw new Error('storageService.fetchManifest: We are offline!');
|
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 we don't get a value we're assuming that there's no newer manifest
|
||||||
if (!encryptedManifest.value || !encryptedManifest.version) {
|
if (!encryptedManifest.value || !encryptedManifest.version) {
|
||||||
window.log.info('storageService.fetchManifest: nothing changed');
|
log.info('storageService.fetchManifest: nothing changed');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,7 +677,7 @@ async function fetchManifest(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.fetchManifest: failed!',
|
'storageService.fetchManifest: failed!',
|
||||||
err && err.stack ? err.stack : String(err)
|
err && err.stack ? err.stack : String(err)
|
||||||
);
|
);
|
||||||
|
@ -721,10 +720,7 @@ async function mergeRecord(
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (itemType === ITEM_TYPE.UNKNOWN) {
|
if (itemType === ITEM_TYPE.UNKNOWN) {
|
||||||
window.log.info(
|
log.info('storageService.mergeRecord: Unknown item type', storageID);
|
||||||
'storageService.mergeRecord: Unknown item type',
|
|
||||||
storageID
|
|
||||||
);
|
|
||||||
} else if (itemType === ITEM_TYPE.CONTACT && storageRecord.contact) {
|
} else if (itemType === ITEM_TYPE.CONTACT && storageRecord.contact) {
|
||||||
hasConflict = await mergeContactRecord(storageID, storageRecord.contact);
|
hasConflict = await mergeContactRecord(storageID, storageRecord.contact);
|
||||||
} else if (itemType === ITEM_TYPE.GROUPV1 && storageRecord.groupV1) {
|
} else if (itemType === ITEM_TYPE.GROUPV1 && storageRecord.groupV1) {
|
||||||
|
@ -735,9 +731,9 @@ async function mergeRecord(
|
||||||
hasConflict = await mergeAccountRecord(storageID, storageRecord.account);
|
hasConflict = await mergeAccountRecord(storageID, storageRecord.account);
|
||||||
} else {
|
} else {
|
||||||
isUnsupported = true;
|
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',
|
'storageService.mergeRecord: merged',
|
||||||
redactStorageID(storageID),
|
redactStorageID(storageID),
|
||||||
itemType,
|
itemType,
|
||||||
|
@ -745,7 +741,7 @@ async function mergeRecord(
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.mergeRecord: Error with',
|
'storageService.mergeRecord: Error with',
|
||||||
redactStorageID(storageID),
|
redactStorageID(storageID),
|
||||||
itemType,
|
itemType,
|
||||||
|
@ -798,22 +794,16 @@ async function processManifest(
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.processManifest: local records:',
|
'storageService.processManifest: local records:',
|
||||||
conversations.length
|
conversations.length
|
||||||
);
|
);
|
||||||
window.log.info(
|
log.info('storageService.processManifest: local keys:', localKeys.size);
|
||||||
'storageService.processManifest: local keys:',
|
log.info(
|
||||||
localKeys.size
|
|
||||||
);
|
|
||||||
window.log.info(
|
|
||||||
'storageService.processManifest: unknown records:',
|
'storageService.processManifest: unknown records:',
|
||||||
stillUnknown.length
|
stillUnknown.length
|
||||||
);
|
);
|
||||||
window.log.info(
|
log.info('storageService.processManifest: remote keys:', remoteKeys.size);
|
||||||
'storageService.processManifest: remote keys:',
|
|
||||||
remoteKeys.size
|
|
||||||
);
|
|
||||||
|
|
||||||
const remoteOnlySet: Set<string> = new Set();
|
const remoteOnlySet: Set<string> = new Set();
|
||||||
remoteKeys.forEach((key: string) => {
|
remoteKeys.forEach((key: string) => {
|
||||||
|
@ -822,7 +812,7 @@ async function processManifest(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.processManifest: remote ids:',
|
'storageService.processManifest: remote ids:',
|
||||||
Array.from(remoteOnlySet).map(redactStorageID).join(',')
|
Array.from(remoteOnlySet).map(redactStorageID).join(',')
|
||||||
);
|
);
|
||||||
|
@ -845,7 +835,7 @@ async function processManifest(
|
||||||
window.getConversations().forEach((conversation: ConversationModel) => {
|
window.getConversations().forEach((conversation: ConversationModel) => {
|
||||||
const storageID = conversation.get('storageID');
|
const storageID = conversation.get('storageID');
|
||||||
if (storageID && !remoteKeys.has(storageID)) {
|
if (storageID && !remoteKeys.has(storageID)) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.processManifest: local key was not in remote manifest',
|
'storageService.processManifest: local key was not in remote manifest',
|
||||||
redactStorageID(storageID),
|
redactStorageID(storageID),
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
|
@ -867,7 +857,7 @@ async function processRemoteRecords(
|
||||||
}
|
}
|
||||||
const storageKey = base64ToArrayBuffer(storageKeyBase64);
|
const storageKey = base64ToArrayBuffer(storageKeyBase64);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.processRemoteRecords: remote only keys',
|
'storageService.processRemoteRecords: remote only keys',
|
||||||
remoteOnlyRecords.size
|
remoteOnlyRecords.size
|
||||||
);
|
);
|
||||||
|
@ -890,9 +880,7 @@ async function processRemoteRecords(
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!storageItems.items) {
|
if (!storageItems.items) {
|
||||||
window.log.info(
|
log.info('storageService.processRemoteRecords: No storage items retrieved');
|
||||||
'storageService.processRemoteRecords: No storage items retrieved'
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,7 +892,7 @@ async function processRemoteRecords(
|
||||||
const { key, value: storageItemCiphertext } = storageRecordWrapper;
|
const { key, value: storageItemCiphertext } = storageRecordWrapper;
|
||||||
|
|
||||||
if (!key || !storageItemCiphertext) {
|
if (!key || !storageItemCiphertext) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.processRemoteRecords: No key or Ciphertext available'
|
'storageService.processRemoteRecords: No key or Ciphertext available'
|
||||||
);
|
);
|
||||||
await stopStorageServiceSync();
|
await stopStorageServiceSync();
|
||||||
|
@ -927,7 +915,7 @@ async function processRemoteRecords(
|
||||||
storageItemKey
|
storageItemKey
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.processRemoteRecords: Error decrypting storage item'
|
'storageService.processRemoteRecords: Error decrypting storage item'
|
||||||
);
|
);
|
||||||
await stopStorageServiceSync();
|
await stopStorageServiceSync();
|
||||||
|
@ -964,13 +952,13 @@ async function processRemoteRecords(
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
window.log.info(
|
log.info(
|
||||||
`storageService.processRemoteRecords: Attempting to merge ${sortedStorageItems.length} records`
|
`storageService.processRemoteRecords: Attempting to merge ${sortedStorageItems.length} records`
|
||||||
);
|
);
|
||||||
const mergedRecords = await pMap(sortedStorageItems, mergeRecord, {
|
const mergedRecords = await pMap(sortedStorageItems, mergeRecord, {
|
||||||
concurrency: 5,
|
concurrency: 5,
|
||||||
});
|
});
|
||||||
window.log.info(
|
log.info(
|
||||||
`storageService.processRemoteRecords: Processed ${mergedRecords.length} records`
|
`storageService.processRemoteRecords: Processed ${mergedRecords.length} records`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1012,13 +1000,13 @@ async function processRemoteRecords(
|
||||||
(record: UnknownRecord) => !validRecordTypes.has(record.itemType)
|
(record: UnknownRecord) => !validRecordTypes.has(record.itemType)
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.processRemoteRecords: Unknown records found:',
|
'storageService.processRemoteRecords: Unknown records found:',
|
||||||
newUnknownRecords.length
|
newUnknownRecords.length
|
||||||
);
|
);
|
||||||
window.storage.put('storage-service-unknown-records', newUnknownRecords);
|
window.storage.put('storage-service-unknown-records', newUnknownRecords);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.processRemoteRecords: Records with errors:',
|
'storageService.processRemoteRecords: Records with errors:',
|
||||||
newRecordsWithErrors.length
|
newRecordsWithErrors.length
|
||||||
);
|
);
|
||||||
|
@ -1028,7 +1016,7 @@ async function processRemoteRecords(
|
||||||
window.storage.put('storage-service-error-records', newRecordsWithErrors);
|
window.storage.put('storage-service-error-records', newRecordsWithErrors);
|
||||||
|
|
||||||
if (conflictCount !== 0) {
|
if (conflictCount !== 0) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.processRemoteRecords: ' +
|
'storageService.processRemoteRecords: ' +
|
||||||
`${conflictCount} conflicts found, uploading changes`
|
`${conflictCount} conflicts found, uploading changes`
|
||||||
);
|
);
|
||||||
|
@ -1038,7 +1026,7 @@ async function processRemoteRecords(
|
||||||
|
|
||||||
conflictBackOff.reset();
|
conflictBackOff.reset();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.processRemoteRecords: failed!',
|
'storageService.processRemoteRecords: failed!',
|
||||||
err && err.stack ? err.stack : String(err)
|
err && err.stack ? err.stack : String(err)
|
||||||
);
|
);
|
||||||
|
@ -1051,9 +1039,7 @@ async function sync(
|
||||||
ignoreConflicts = false
|
ignoreConflicts = false
|
||||||
): Promise<Proto.ManifestRecord | undefined> {
|
): Promise<Proto.ManifestRecord | undefined> {
|
||||||
if (!isStorageWriteFeatureEnabled()) {
|
if (!isStorageWriteFeatureEnabled()) {
|
||||||
window.log.info(
|
log.info('storageService.sync: Not starting desktop.storage is falsey');
|
||||||
'storageService.sync: Not starting desktop.storage is falsey'
|
|
||||||
);
|
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -1062,7 +1048,7 @@ async function sync(
|
||||||
throw new Error('storageService.sync: Cannot start; no storage key!');
|
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;
|
let manifest: Proto.ManifestRecord | undefined;
|
||||||
try {
|
try {
|
||||||
|
@ -1078,7 +1064,7 @@ async function sync(
|
||||||
|
|
||||||
// Guarding against no manifests being returned, everything should be ok
|
// Guarding against no manifests being returned, everything should be ok
|
||||||
if (!manifest) {
|
if (!manifest) {
|
||||||
window.log.info('storageService.sync: no new manifest');
|
log.info('storageService.sync: no new manifest');
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,7 +1074,7 @@ async function sync(
|
||||||
);
|
);
|
||||||
const version = normalizeNumber(manifest.version);
|
const version = normalizeNumber(manifest.version);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
`storageService.sync: manifest versions - previous: ${localManifestVersion}, current: ${version}`
|
`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
|
// We now know that we've successfully completed a storage service fetch
|
||||||
window.storage.put('storageFetchComplete', true);
|
window.storage.put('storageFetchComplete', true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.sync: error processing manifest',
|
'storageService.sync: error processing manifest',
|
||||||
err && err.stack ? err.stack : String(err)
|
err && err.stack ? err.stack : String(err)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.Signal.Util.postLinkExperience.stop();
|
window.Signal.Util.postLinkExperience.stop();
|
||||||
window.log.info('storageService.sync: complete');
|
log.info('storageService.sync: complete');
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function upload(fromSync = false): Promise<void> {
|
async function upload(fromSync = false): Promise<void> {
|
||||||
if (!isStorageWriteFeatureEnabled()) {
|
if (!isStorageWriteFeatureEnabled()) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.upload: Not starting because the feature is not enabled'
|
'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')) {
|
if (!window.storage.get('storageKey')) {
|
||||||
// requesting new keys runs the sync job which will detect the conflict
|
// 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.
|
// and re-run the upload job once we're merged and up-to-date.
|
||||||
window.log.info(
|
log.info('storageService.upload: no storageKey, requesting new keys');
|
||||||
'storageService.upload: no storageKey, requesting new keys'
|
|
||||||
);
|
|
||||||
backOff.reset();
|
backOff.reset();
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn('upload: We are primary device; not sending key sync request');
|
||||||
'upload: We are primary device; not sending key sync request'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1178,10 +1160,7 @@ async function upload(fromSync = false): Promise<void> {
|
||||||
const localManifestVersion = window.storage.get('manifestVersion', 0);
|
const localManifestVersion = window.storage.get('manifestVersion', 0);
|
||||||
const version = Number(localManifestVersion) + 1;
|
const version = Number(localManifestVersion) + 1;
|
||||||
|
|
||||||
window.log.info(
|
log.info('storageService.upload: will update to manifest version', version);
|
||||||
'storageService.upload: will update to manifest version',
|
|
||||||
version
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const generatedManifest = await generateManifest(version, previousManifest);
|
const generatedManifest = await generateManifest(version, previousManifest);
|
||||||
|
@ -1189,14 +1168,14 @@ async function upload(fromSync = false): Promise<void> {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code === 409) {
|
if (err.code === 409) {
|
||||||
await sleep(conflictBackOff.getAndIncrement());
|
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
|
// 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
|
// check if an item needs sync and doesn't match with the remote record
|
||||||
// it'll kick off another upload.
|
// it'll kick off another upload.
|
||||||
setTimeout(runStorageServiceSyncJob);
|
setTimeout(runStorageServiceSyncJob);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.upload',
|
'storageService.upload',
|
||||||
err && err.stack ? err.stack : String(err)
|
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.
|
// 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.
|
// It goes directly to the database, so in-memory conversations will be out of date.
|
||||||
export async function eraseAllStorageServiceState(): Promise<void> {
|
export async function eraseAllStorageServiceState(): Promise<void> {
|
||||||
window.log.info('storageService.eraseAllStorageServiceState: starting...');
|
log.info('storageService.eraseAllStorageServiceState: starting...');
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
window.storage.remove('manifestVersion'),
|
window.storage.remove('manifestVersion'),
|
||||||
window.storage.remove('storage-service-unknown-records'),
|
window.storage.remove('storage-service-unknown-records'),
|
||||||
window.storage.remove('storageCredentials'),
|
window.storage.remove('storageCredentials'),
|
||||||
]);
|
]);
|
||||||
await eraseStorageServiceStateFromConversations();
|
await eraseStorageServiceStateFromConversations();
|
||||||
window.log.info('storageService.eraseAllStorageServiceState: complete');
|
log.info('storageService.eraseAllStorageServiceState: complete');
|
||||||
}
|
}
|
||||||
|
|
||||||
export const storageServiceUploadJob = debounce(() => {
|
export const storageServiceUploadJob = debounce(() => {
|
||||||
if (!storageServiceEnabled) {
|
if (!storageServiceEnabled) {
|
||||||
window.log.info(
|
log.info('storageService.storageServiceUploadJob: called before enabled');
|
||||||
'storageService.storageServiceUploadJob: called before enabled'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,9 +1214,7 @@ export const storageServiceUploadJob = debounce(() => {
|
||||||
|
|
||||||
export const runStorageServiceSyncJob = debounce(() => {
|
export const runStorageServiceSyncJob = debounce(() => {
|
||||||
if (!storageServiceEnabled) {
|
if (!storageServiceEnabled) {
|
||||||
window.log.info(
|
log.info('storageService.runStorageServiceSyncJob: called before enabled');
|
||||||
'storageService.runStorageServiceSyncJob: called before enabled'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ import * as preferredReactionEmoji from '../reactions/preferredReactionEmoji';
|
||||||
import { UUID } from '../types/UUID';
|
import { UUID } from '../types/UUID';
|
||||||
import * as Errors from '../types/errors';
|
import * as Errors from '../types/errors';
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
const { updateConversation } = dataInterface;
|
const { updateConversation } = dataInterface;
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ function addUnknownFields(
|
||||||
conversation: ConversationModel
|
conversation: ConversationModel
|
||||||
): void {
|
): void {
|
||||||
if (record.__unknownFields) {
|
if (record.__unknownFields) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.addUnknownFields: Unknown fields found for',
|
'storageService.addUnknownFields: Unknown fields found for',
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
);
|
);
|
||||||
|
@ -82,7 +83,7 @@ function addUnknownFields(
|
||||||
} else if (conversation.get('storageUnknownFields')) {
|
} else if (conversation.get('storageUnknownFields')) {
|
||||||
// If the record doesn't have unknown fields attached but we have them
|
// If the record doesn't have unknown fields attached but we have them
|
||||||
// saved locally then we need to clear it out
|
// saved locally then we need to clear it out
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.addUnknownFields: Clearing unknown fields for',
|
'storageService.addUnknownFields: Clearing unknown fields for',
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
);
|
);
|
||||||
|
@ -96,7 +97,7 @@ function applyUnknownFields(
|
||||||
): void {
|
): void {
|
||||||
const storageUnknownFields = conversation.get('storageUnknownFields');
|
const storageUnknownFields = conversation.get('storageUnknownFields');
|
||||||
if (storageUnknownFields) {
|
if (storageUnknownFields) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.applyUnknownFields: Applying unknown fields for',
|
'storageService.applyUnknownFields: Applying unknown fields for',
|
||||||
conversation.get('id')
|
conversation.get('id')
|
||||||
);
|
);
|
||||||
|
@ -126,9 +127,7 @@ export async function toContactRecord(
|
||||||
try {
|
try {
|
||||||
maybeUuid = uuid ? new UUID(uuid) : undefined;
|
maybeUuid = uuid ? new UUID(uuid) : undefined;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.warn(
|
log.warn(`Invalid uuid in contact record: ${Errors.toLogFormat(error)}`);
|
||||||
`Invalid uuid in contact record: ${Errors.toLogFormat(error)}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const identityKey = maybeUuid
|
const identityKey = maybeUuid
|
||||||
|
@ -296,7 +295,7 @@ export async function toAccountRecord(
|
||||||
pinnedConversationClass !== undefined
|
pinnedConversationClass !== undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.toAccountRecord: pinnedConversations',
|
'storageService.toAccountRecord: pinnedConversations',
|
||||||
pinnedConversations.length
|
pinnedConversations.length
|
||||||
);
|
);
|
||||||
|
@ -403,7 +402,7 @@ function doRecordsConflict(
|
||||||
if (localValue instanceof Uint8Array) {
|
if (localValue instanceof Uint8Array) {
|
||||||
const areEqual = Bytes.areEqual(localValue, remoteValue);
|
const areEqual = Bytes.areEqual(localValue, remoteValue);
|
||||||
if (!areEqual) {
|
if (!areEqual) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.doRecordsConflict: Conflict found for ArrayBuffer',
|
'storageService.doRecordsConflict: Conflict found for ArrayBuffer',
|
||||||
key,
|
key,
|
||||||
idForLogging
|
idForLogging
|
||||||
|
@ -422,7 +421,7 @@ function doRecordsConflict(
|
||||||
Long.fromValue(remoteValue)
|
Long.fromValue(remoteValue)
|
||||||
);
|
);
|
||||||
if (!areEqual) {
|
if (!areEqual) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.doRecordsConflict: Conflict found for Long',
|
'storageService.doRecordsConflict: Conflict found for Long',
|
||||||
key,
|
key,
|
||||||
idForLogging
|
idForLogging
|
||||||
|
@ -434,7 +433,7 @@ function doRecordsConflict(
|
||||||
if (key === 'pinnedConversations') {
|
if (key === 'pinnedConversations') {
|
||||||
const areEqual = arePinnedConversationsEqual(localValue, remoteValue);
|
const areEqual = arePinnedConversationsEqual(localValue, remoteValue);
|
||||||
if (!areEqual) {
|
if (!areEqual) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.doRecordsConflict: Conflict found for pinnedConversations',
|
'storageService.doRecordsConflict: Conflict found for pinnedConversations',
|
||||||
idForLogging
|
idForLogging
|
||||||
);
|
);
|
||||||
|
@ -462,7 +461,7 @@ function doRecordsConflict(
|
||||||
const areEqual = isEqual(localValue, remoteValue);
|
const areEqual = isEqual(localValue, remoteValue);
|
||||||
|
|
||||||
if (!areEqual) {
|
if (!areEqual) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.doRecordsConflict: Conflict found for',
|
'storageService.doRecordsConflict: Conflict found for',
|
||||||
key,
|
key,
|
||||||
idForLogging
|
idForLogging
|
||||||
|
@ -532,14 +531,14 @@ export async function mergeGroupV1Record(
|
||||||
const fields = deriveGroupFields(new FIXMEU8(masterKeyBuffer));
|
const fields = deriveGroupFields(new FIXMEU8(masterKeyBuffer));
|
||||||
const derivedGroupV2Id = Bytes.toBase64(fields.id);
|
const derivedGroupV2Id = Bytes.toBase64(fields.id);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.mergeGroupV1Record: failed to find group by v1 id ' +
|
'storageService.mergeGroupV1Record: failed to find group by v1 id ' +
|
||||||
`attempting lookup by v2 groupv2(${derivedGroupV2Id})`
|
`attempting lookup by v2 groupv2(${derivedGroupV2Id})`
|
||||||
);
|
);
|
||||||
conversation = window.ConversationController.get(derivedGroupV2Id);
|
conversation = window.ConversationController.get(derivedGroupV2Id);
|
||||||
}
|
}
|
||||||
if (conversation) {
|
if (conversation) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.mergeGroupV1Record: found existing group',
|
'storageService.mergeGroupV1Record: found existing group',
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
);
|
);
|
||||||
|
@ -552,7 +551,7 @@ export async function mergeGroupV1Record(
|
||||||
groupId,
|
groupId,
|
||||||
'group'
|
'group'
|
||||||
);
|
);
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.mergeGroupV1Record: created a new group locally',
|
'storageService.mergeGroupV1Record: created a new group locally',
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
);
|
);
|
||||||
|
@ -587,7 +586,7 @@ export async function mergeGroupV1Record(
|
||||||
// We cannot preserve unknown fields if local group is V2 and the remote is
|
// 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
|
// still V1, because the storageItem that we'll put into manifest will have
|
||||||
// a different record type.
|
// a different record type.
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.mergeGroupV1Record marking v1' +
|
'storageService.mergeGroupV1Record marking v1' +
|
||||||
' group for an update to v2',
|
' group for an update to v2',
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
|
@ -660,10 +659,7 @@ export async function mergeGroupV2Record(
|
||||||
const masterKeyBuffer = groupV2Record.masterKey;
|
const masterKeyBuffer = groupV2Record.masterKey;
|
||||||
const conversation = await getGroupV2Conversation(masterKeyBuffer);
|
const conversation = await getGroupV2Conversation(masterKeyBuffer);
|
||||||
|
|
||||||
window.log.info(
|
log.info('storageService.mergeGroupV2Record:', conversation.idForLogging());
|
||||||
'storageService.mergeGroupV2Record:',
|
|
||||||
conversation.idForLogging()
|
|
||||||
);
|
|
||||||
|
|
||||||
conversation.set({
|
conversation.set({
|
||||||
isArchived: Boolean(groupV2Record.archived),
|
isArchived: Boolean(groupV2Record.archived),
|
||||||
|
@ -763,10 +759,7 @@ export async function mergeContactRecord(
|
||||||
'private'
|
'private'
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info('storageService.mergeContactRecord:', conversation.idForLogging());
|
||||||
'storageService.mergeContactRecord:',
|
|
||||||
conversation.idForLogging()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (contactRecord.profileKey) {
|
if (contactRecord.profileKey) {
|
||||||
await conversation.setProfileKey(Bytes.toBase64(contactRecord.profileKey), {
|
await conversation.setProfileKey(Bytes.toBase64(contactRecord.profileKey), {
|
||||||
|
@ -924,7 +917,7 @@ export async function mergeAccountRecord(
|
||||||
.filter(id => !modelPinnedConversationIds.includes(id));
|
.filter(id => !modelPinnedConversationIds.includes(id));
|
||||||
|
|
||||||
if (missingStoragePinnedConversationIds.length !== 0) {
|
if (missingStoragePinnedConversationIds.length !== 0) {
|
||||||
window.log.info(
|
log.info(
|
||||||
'mergeAccountRecord: pinnedConversationIds in storage does not match pinned Conversation models'
|
'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',
|
'storageService.mergeAccountRecord: Local pinned',
|
||||||
locallyPinnedConversations.length
|
locallyPinnedConversations.length
|
||||||
);
|
);
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.mergeAccountRecord: Remote pinned',
|
'storageService.mergeAccountRecord: Remote pinned',
|
||||||
pinnedConversations.length
|
pinnedConversations.length
|
||||||
);
|
);
|
||||||
|
@ -965,13 +958,13 @@ export async function mergeAccountRecord(
|
||||||
|
|
||||||
conversationId = groupId;
|
conversationId = groupId;
|
||||||
} else {
|
} else {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.mergeAccountRecord: Invalid identifier received'
|
'storageService.mergeAccountRecord: Invalid identifier received'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conversationId) {
|
if (!conversationId) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'storageService.mergeAccountRecord: missing conversation id.'
|
'storageService.mergeAccountRecord: missing conversation id.'
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -996,12 +989,12 @@ export async function mergeAccountRecord(
|
||||||
({ id }) => !remotelyPinnedConversationIds.includes(id)
|
({ id }) => !remotelyPinnedConversationIds.includes(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.mergeAccountRecord: unpinning',
|
'storageService.mergeAccountRecord: unpinning',
|
||||||
conversationsToUnpin.length
|
conversationsToUnpin.length
|
||||||
);
|
);
|
||||||
|
|
||||||
window.log.info(
|
log.info(
|
||||||
'storageService.mergeAccountRecord: pinning',
|
'storageService.mergeAccountRecord: pinning',
|
||||||
remotelyPinnedConversations.length
|
remotelyPinnedConversations.length
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,29 +1,31 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
export async function deleteAllData(): Promise<void> {
|
export async function deleteAllData(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await window.Signal.Logs.deleteAll();
|
await window.Signal.Logs.deleteAll();
|
||||||
|
|
||||||
window.log.info('deleteAllData: deleted all logs');
|
log.info('deleteAllData: deleted all logs');
|
||||||
|
|
||||||
await window.Signal.Data.removeAll();
|
await window.Signal.Data.removeAll();
|
||||||
|
|
||||||
window.log.info('deleteAllData: emptied database');
|
log.info('deleteAllData: emptied database');
|
||||||
|
|
||||||
await window.Signal.Data.close();
|
await window.Signal.Data.close();
|
||||||
|
|
||||||
window.log.info('deleteAllData: closed database');
|
log.info('deleteAllData: closed database');
|
||||||
|
|
||||||
await window.Signal.Data.removeDB();
|
await window.Signal.Data.removeDB();
|
||||||
|
|
||||||
window.log.info('deleteAllData: removed database');
|
log.info('deleteAllData: removed database');
|
||||||
|
|
||||||
await window.Signal.Data.removeOtherData();
|
await window.Signal.Data.removeOtherData();
|
||||||
|
|
||||||
window.log.info('deleteAllData: removed all other data');
|
log.info('deleteAllData: removed all other data');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Something went wrong deleting all data:',
|
'Something went wrong deleting all data:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
|
|
||||||
import { handleMessageSend } from '../util/handleMessageSend';
|
import { handleMessageSend } from '../util/handleMessageSend';
|
||||||
import { getSendOptions } from '../util/getSendOptions';
|
import { getSendOptions } from '../util/getSendOptions';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
export async function sendStickerPackSync(
|
export async function sendStickerPackSync(
|
||||||
packId: string,
|
packId: string,
|
||||||
packKey: string,
|
packKey: string,
|
||||||
installed: boolean
|
installed: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { ConversationController, textsecure, log } = window;
|
const { ConversationController, textsecure } = window;
|
||||||
const ourConversation = ConversationController.getOurConversationOrThrow();
|
const ourConversation = ConversationController.getOurConversationOrThrow();
|
||||||
const sendOptions = await getSendOptions(ourConversation.attributes, {
|
const sendOptions = await getSendOptions(ourConversation.attributes, {
|
||||||
syncMessage: true,
|
syncMessage: true,
|
||||||
|
@ -24,7 +25,7 @@ export async function sendStickerPackSync(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.ConversationController.areWePrimaryDevice()) {
|
if (window.ConversationController.areWePrimaryDevice()) {
|
||||||
window.log.warn(
|
log.warn(
|
||||||
'shims/sendStickerPackSync: We are primary device; not sending sync'
|
'shims/sendStickerPackSync: We are primary device; not sending sync'
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -34,6 +34,7 @@ import { ReactionType } from '../types/Reactions';
|
||||||
import { ConversationColorType, CustomColorType } from '../types/Colors';
|
import { ConversationColorType, CustomColorType } from '../types/Colors';
|
||||||
import type { ProcessGroupCallRingRequestResult } from '../types/Calling';
|
import type { ProcessGroupCallRingRequestResult } from '../types/Calling';
|
||||||
import type { RemoveAllConfiguration } from '../types/RemoveAllConfiguration';
|
import type { RemoveAllConfiguration } from '../types/RemoveAllConfiguration';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ConversationModelCollectionType,
|
ConversationModelCollectionType,
|
||||||
|
@ -88,7 +89,7 @@ import { ConversationModel } from '../models/conversations';
|
||||||
if (ipcRenderer && ipcRenderer.setMaxListeners) {
|
if (ipcRenderer && ipcRenderer.setMaxListeners) {
|
||||||
ipcRenderer.setMaxListeners(0);
|
ipcRenderer.setMaxListeners(0);
|
||||||
} else {
|
} 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;
|
const DATABASE_UPDATE_TIMEOUT = 2 * durations.MINUTE;
|
||||||
|
@ -305,14 +306,12 @@ export default dataInterface;
|
||||||
|
|
||||||
async function goBackToMainProcess(): Promise<void> {
|
async function goBackToMainProcess(): Promise<void> {
|
||||||
if (!shouldUseRendererProcess) {
|
if (!shouldUseRendererProcess) {
|
||||||
window.log.info(
|
log.info('data.goBackToMainProcess: already switched to main process');
|
||||||
'data.goBackToMainProcess: already switched to main process'
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't need to wait for pending queries since they are synchronous.
|
// 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.
|
// Close the database in the renderer process.
|
||||||
const closePromise = close();
|
const closePromise = close();
|
||||||
|
@ -331,7 +330,7 @@ async function goBackToMainProcess(): Promise<void> {
|
||||||
.sort((a, b) => b[1] - a[1])
|
.sort((a, b) => b[1] - a[1])
|
||||||
.filter(([_, duration]) => duration > MIN_TRACE_DURATION)
|
.filter(([_, duration]) => duration > MIN_TRACE_DURATION)
|
||||||
.forEach(([query, 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);
|
const { cleaned, pathsChanged } = cleanDataForIpc(data);
|
||||||
|
|
||||||
if (pathsChanged.length) {
|
if (pathsChanged.length) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`_cleanData cleaned the following paths: ${pathsChanged.join(', ')}`
|
`_cleanData cleaned the following paths: ${pathsChanged.join(', ')}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -374,7 +373,7 @@ function _cleanMessageData(data: MessageType): MessageType {
|
||||||
|
|
||||||
async function _shutdown() {
|
async function _shutdown() {
|
||||||
const jobKeys = Object.keys(_jobs);
|
const jobKeys = Object.keys(_jobs);
|
||||||
window.log.info(
|
log.info(
|
||||||
`data.shutdown: shutdown requested. ${jobKeys.length} jobs outstanding`
|
`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
|
// Outstanding jobs; we need to wait until the last one is done
|
||||||
_shutdownPromise = new Promise<void>((resolve, reject) => {
|
_shutdownPromise = new Promise<void>((resolve, reject) => {
|
||||||
_shutdownCallback = (error: Error) => {
|
_shutdownCallback = (error: Error) => {
|
||||||
window.log.info('data.shutdown: process complete');
|
log.info('data.shutdown: process complete');
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
|
|
||||||
|
@ -419,7 +418,7 @@ function _makeJob(fnName: string) {
|
||||||
const id = _jobCounter;
|
const id = _jobCounter;
|
||||||
|
|
||||||
if (_DEBUG) {
|
if (_DEBUG) {
|
||||||
window.log.info(`SQL channel job ${id} (${fnName}) started`);
|
log.info(`SQL channel job ${id} (${fnName}) started`);
|
||||||
}
|
}
|
||||||
_jobs[id] = {
|
_jobs[id] = {
|
||||||
fnName,
|
fnName,
|
||||||
|
@ -440,7 +439,7 @@ function _updateJob(id: number, data: ClientJobUpdateType) {
|
||||||
_removeJob(id);
|
_removeJob(id);
|
||||||
const end = Date.now();
|
const end = Date.now();
|
||||||
if (_DEBUG) {
|
if (_DEBUG) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`SQL channel job ${id} (${fnName}) succeeded in ${end - start}ms`
|
`SQL channel job ${id} (${fnName}) succeeded in ${end - start}ms`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -450,9 +449,7 @@ function _updateJob(id: number, data: ClientJobUpdateType) {
|
||||||
reject: (error: Error) => {
|
reject: (error: Error) => {
|
||||||
_removeJob(id);
|
_removeJob(id);
|
||||||
const end = Date.now();
|
const end = Date.now();
|
||||||
window.log.info(
|
log.info(`SQL channel job ${id} (${fnName}) failed in ${end - start}ms`);
|
||||||
`SQL channel job ${id} (${fnName}) failed in ${end - start}ms`
|
|
||||||
);
|
|
||||||
|
|
||||||
return reject(error);
|
return reject(error);
|
||||||
},
|
},
|
||||||
|
@ -511,7 +508,7 @@ if (ipcRenderer && ipcRenderer.on) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
window.log.warn('sql/Client: ipcRenderer.on is not available!');
|
log.warn('sql/Client: ipcRenderer.on is not available!');
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeChannel(fnName: string) {
|
function makeChannel(fnName: string) {
|
||||||
|
@ -531,13 +528,13 @@ function makeChannel(fnName: string) {
|
||||||
return await Server[serverFnName](...args);
|
return await Server[serverFnName](...args);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (isCorruptionError(error)) {
|
if (isCorruptionError(error)) {
|
||||||
window.log.error(
|
log.error(
|
||||||
'Detected sql corruption in renderer process. ' +
|
'Detected sql corruption in renderer process. ' +
|
||||||
`Restarting the application immediately. Error: ${error.message}`
|
`Restarting the application immediately. Error: ${error.message}`
|
||||||
);
|
);
|
||||||
ipcRenderer?.send('database-error', error.stack);
|
ipcRenderer?.send('database-error', error.stack);
|
||||||
}
|
}
|
||||||
window.log.error(
|
log.error(
|
||||||
`Renderer SQL channel job (${fnName}) error ${error.message}`
|
`Renderer SQL channel job (${fnName}) error ${error.message}`
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -550,7 +547,7 @@ function makeChannel(fnName: string) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (duration > MIN_TRACE_DURATION || _DEBUG) {
|
if (duration > MIN_TRACE_DURATION || _DEBUG) {
|
||||||
window.log.info(
|
log.info(
|
||||||
`Renderer SQL channel job (${fnName}) completed in ${duration}ms`
|
`Renderer SQL channel job (${fnName}) completed in ${duration}ms`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1339,7 +1336,7 @@ async function removeAllMessagesInConversation(
|
||||||
let messages;
|
let messages;
|
||||||
do {
|
do {
|
||||||
const chunkSize = 20;
|
const chunkSize = 20;
|
||||||
window.log.info(
|
log.info(
|
||||||
`removeAllMessagesInConversation/${logId}: Fetching chunk of ${chunkSize} messages`
|
`removeAllMessagesInConversation/${logId}: Fetching chunk of ${chunkSize} messages`
|
||||||
);
|
);
|
||||||
// Yes, we really want the await in the loop. We're deleting a chunk at a
|
// 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);
|
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
|
// 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.
|
// 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 });
|
const queue = new window.PQueue({ concurrency: 3, timeout: 1000 * 60 * 2 });
|
||||||
|
@ -1364,7 +1361,7 @@ async function removeAllMessagesInConversation(
|
||||||
);
|
);
|
||||||
await queue.onIdle();
|
await queue.onIdle();
|
||||||
|
|
||||||
window.log.info(`removeAllMessagesInConversation/${logId}: Deleting...`);
|
log.info(`removeAllMessagesInConversation/${logId}: Deleting...`);
|
||||||
await channels.removeMessages(ids);
|
await channels.removeMessages(ids);
|
||||||
} while (messages.length > 0);
|
} while (messages.length > 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ import { ConversationColorType, CustomColorType } from '../types/Colors';
|
||||||
import { ProcessGroupCallRingRequestResult } from '../types/Calling';
|
import { ProcessGroupCallRingRequestResult } from '../types/Calling';
|
||||||
import { RemoveAllConfiguration } from '../types/RemoveAllConfiguration';
|
import { RemoveAllConfiguration } from '../types/RemoveAllConfiguration';
|
||||||
import type { LoggerType } from '../types/Logging';
|
import type { LoggerType } from '../types/Logging';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AllItemsType,
|
AllItemsType,
|
||||||
|
@ -2742,7 +2743,7 @@ async function initializeRenderer({
|
||||||
// test database
|
// test database
|
||||||
await getMessageCount();
|
await getMessageCount();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error('Database startup error:', error.stack);
|
log.error('Database startup error:', error.stack);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import { ThunkAction } from 'redux-thunk';
|
import { ThunkAction } from 'redux-thunk';
|
||||||
import { StateType as RootStateType } from '../reducer';
|
import { StateType as RootStateType } from '../reducer';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ function openInbox(): ThunkAction<
|
||||||
OpenInboxActionType
|
OpenInboxActionType
|
||||||
> {
|
> {
|
||||||
return async dispatch => {
|
return async dispatch => {
|
||||||
window.log.info('open inbox');
|
log.info('open inbox');
|
||||||
|
|
||||||
await window.ConversationController.loadPromise();
|
await window.ConversationController.loadPromise();
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import { isGroupCallOutboundRingEnabled } from '../../util/isGroupCallOutboundRi
|
||||||
import { sleep } from '../../util/sleep';
|
import { sleep } from '../../util/sleep';
|
||||||
import { LatestQueue } from '../../util/LatestQueue';
|
import { LatestQueue } from '../../util/LatestQueue';
|
||||||
import type { ConversationChangedActionType } from './conversations';
|
import type { ConversationChangedActionType } from './conversations';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
|
||||||
|
@ -506,7 +507,7 @@ function acceptCall(
|
||||||
|
|
||||||
const call = getOwn(getState().calling.callsByConversation, conversationId);
|
const call = getOwn(getState().calling.callsByConversation, conversationId);
|
||||||
if (!call) {
|
if (!call) {
|
||||||
window.log.error('Trying to accept a non-existent call');
|
log.error('Trying to accept a non-existent call');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +612,7 @@ function declineCall(
|
||||||
|
|
||||||
const call = getOwn(getState().calling.callsByConversation, conversationId);
|
const call = getOwn(getState().calling.callsByConversation, conversationId);
|
||||||
if (!call) {
|
if (!call) {
|
||||||
window.log.error('Trying to decline a non-existent call');
|
log.error('Trying to decline a non-existent call');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,7 +627,7 @@ function declineCall(
|
||||||
case CallMode.Group: {
|
case CallMode.Group: {
|
||||||
const { ringId } = call;
|
const { ringId } = call;
|
||||||
if (ringId === undefined) {
|
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 {
|
} else {
|
||||||
calling.declineGroupCall(conversationId, ringId);
|
calling.declineGroupCall(conversationId, ringId);
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -861,7 +862,7 @@ function peekNotConnectedGroupCall(
|
||||||
try {
|
try {
|
||||||
peekInfo = await calling.peekGroupCall(conversationId);
|
peekInfo = await calling.peekGroupCall(conversationId);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error('Group call peeking failed', err);
|
log.error('Group call peeking failed', err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,7 +939,7 @@ function setLocalAudio(
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const activeCall = getActiveCall(getState().calling);
|
const activeCall = getActiveCall(getState().calling);
|
||||||
if (!activeCall) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -957,7 +958,7 @@ function setLocalVideo(
|
||||||
return async (dispatch, getState) => {
|
return async (dispatch, getState) => {
|
||||||
const activeCall = getActiveCall(getState().calling);
|
const activeCall = getActiveCall(getState().calling);
|
||||||
if (!activeCall) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,7 +1013,7 @@ function setPresenting(
|
||||||
const { activeCallState } = callingState;
|
const { activeCallState } = callingState;
|
||||||
const activeCall = getActiveCall(callingState);
|
const activeCall = getActiveCall(callingState);
|
||||||
if (!activeCall || !activeCallState) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1314,7 +1315,7 @@ export function reducer(
|
||||||
|
|
||||||
if (action.type === ACCEPT_CALL_PENDING) {
|
if (action.type === ACCEPT_CALL_PENDING) {
|
||||||
if (!has(state.callsByConversation, action.payload.conversationId)) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1341,7 +1342,7 @@ export function reducer(
|
||||||
) {
|
) {
|
||||||
const activeCall = getActiveCall(state);
|
const activeCall = getActiveCall(state);
|
||||||
if (!activeCall) {
|
if (!activeCall) {
|
||||||
window.log.warn('No active call to remove');
|
log.warn('No active call to remove');
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
switch (activeCall.callMode) {
|
switch (activeCall.callMode) {
|
||||||
|
@ -1421,11 +1422,11 @@ export function reducer(
|
||||||
const existingGroupCall = getGroupCall(conversationId, state);
|
const existingGroupCall = getGroupCall(conversationId, state);
|
||||||
if (existingGroupCall) {
|
if (existingGroupCall) {
|
||||||
if (existingGroupCall.ringerUuid) {
|
if (existingGroupCall.ringerUuid) {
|
||||||
window.log.info('Group call was already ringing');
|
log.info('Group call was already ringing');
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
if (existingGroupCall.joinState !== GroupCallJoinState.NotJoined) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1503,7 +1504,7 @@ export function reducer(
|
||||||
action.payload.conversationId
|
action.payload.conversationId
|
||||||
);
|
);
|
||||||
if (call?.callMode !== CallMode.Direct) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1676,7 +1677,7 @@ export function reducer(
|
||||||
const { conversationId, isSharingScreen } = action.payload;
|
const { conversationId, isSharingScreen } = action.payload;
|
||||||
const call = getOwn(state.callsByConversation, conversationId);
|
const call = getOwn(state.callsByConversation, conversationId);
|
||||||
if (call?.callMode !== CallMode.Direct) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1696,7 +1697,7 @@ export function reducer(
|
||||||
const { conversationId, hasVideo } = action.payload;
|
const { conversationId, hasVideo } = action.payload;
|
||||||
const call = getOwn(state.callsByConversation, conversationId);
|
const call = getOwn(state.callsByConversation, conversationId);
|
||||||
if (call?.callMode !== CallMode.Direct) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1715,9 +1716,7 @@ export function reducer(
|
||||||
if (action.type === RETURN_TO_ACTIVE_CALL) {
|
if (action.type === RETURN_TO_ACTIVE_CALL) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
if (!activeCallState) {
|
||||||
window.log.warn(
|
log.warn('Cannot return to active call if there is no active call');
|
||||||
'Cannot return to active call if there is no active call'
|
|
||||||
);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1732,7 +1731,7 @@ export function reducer(
|
||||||
|
|
||||||
if (action.type === SET_LOCAL_AUDIO_FULFILLED) {
|
if (action.type === SET_LOCAL_AUDIO_FULFILLED) {
|
||||||
if (!state.activeCallState) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1747,7 +1746,7 @@ export function reducer(
|
||||||
|
|
||||||
if (action.type === SET_LOCAL_VIDEO_FULFILLED) {
|
if (action.type === SET_LOCAL_VIDEO_FULFILLED) {
|
||||||
if (!state.activeCallState) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1802,7 +1801,7 @@ export function reducer(
|
||||||
if (action.type === TOGGLE_SETTINGS) {
|
if (action.type === TOGGLE_SETTINGS) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1818,9 +1817,7 @@ export function reducer(
|
||||||
if (action.type === TOGGLE_PARTICIPANTS) {
|
if (action.type === TOGGLE_PARTICIPANTS) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
if (!activeCallState) {
|
||||||
window.log.warn(
|
log.warn('Cannot toggle participants list when there is no active call');
|
||||||
'Cannot toggle participants list when there is no active call'
|
|
||||||
);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1836,7 +1833,7 @@ export function reducer(
|
||||||
if (action.type === TOGGLE_PIP) {
|
if (action.type === TOGGLE_PIP) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1852,7 +1849,7 @@ export function reducer(
|
||||||
if (action.type === SET_PRESENTING) {
|
if (action.type === SET_PRESENTING) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1869,9 +1866,7 @@ export function reducer(
|
||||||
if (action.type === SET_PRESENTING_SOURCES) {
|
if (action.type === SET_PRESENTING_SOURCES) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
if (!activeCallState) {
|
||||||
window.log.warn(
|
log.warn('Cannot set presenting sources when there is no active call');
|
||||||
'Cannot set presenting sources when there is no active call'
|
|
||||||
);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1887,7 +1882,7 @@ export function reducer(
|
||||||
if (action.type === SET_OUTGOING_RING) {
|
if (action.type === SET_OUTGOING_RING) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1903,9 +1898,7 @@ export function reducer(
|
||||||
if (action.type === TOGGLE_NEEDS_SCREEN_RECORDING_PERMISSIONS) {
|
if (action.type === TOGGLE_NEEDS_SCREEN_RECORDING_PERMISSIONS) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
if (!activeCallState) {
|
||||||
window.log.warn(
|
log.warn('Cannot set presenting sources when there is no active call');
|
||||||
'Cannot set presenting sources when there is no active call'
|
|
||||||
);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1921,9 +1914,7 @@ export function reducer(
|
||||||
if (action.type === TOGGLE_SPEAKER_VIEW) {
|
if (action.type === TOGGLE_SPEAKER_VIEW) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
if (!activeCallState) {
|
||||||
window.log.warn(
|
log.warn('Cannot toggle speaker view when there is no active call');
|
||||||
'Cannot toggle speaker view when there is no active call'
|
|
||||||
);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1939,9 +1930,7 @@ export function reducer(
|
||||||
if (action.type === MARK_CALL_UNTRUSTED) {
|
if (action.type === MARK_CALL_UNTRUSTED) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
if (!activeCallState) {
|
||||||
window.log.warn(
|
log.warn('Cannot mark call as untrusted when there is no active call');
|
||||||
'Cannot mark call as untrusted when there is no active call'
|
|
||||||
);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1962,9 +1951,7 @@ export function reducer(
|
||||||
if (action.type === MARK_CALL_TRUSTED) {
|
if (action.type === MARK_CALL_TRUSTED) {
|
||||||
const { activeCallState } = state;
|
const { activeCallState } = state;
|
||||||
if (!activeCallState) {
|
if (!activeCallState) {
|
||||||
window.log.warn(
|
log.warn('Cannot mark call as trusted when there is no active call');
|
||||||
'Cannot mark call as trusted when there is no active call'
|
|
||||||
);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -861,7 +861,7 @@ function deleteAvatarFromDisk(
|
||||||
if (avatarData.imagePath) {
|
if (avatarData.imagePath) {
|
||||||
await window.Signal.Migrations.deleteAvatar(avatarData.imagePath);
|
await window.Signal.Migrations.deleteAvatar(avatarData.imagePath);
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info(
|
||||||
'No imagePath for avatarData. Removing from userAvatarData, but not disk'
|
'No imagePath for avatarData. Removing from userAvatarData, but not disk'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1155,7 +1155,7 @@ function composeDeleteAvatarFromDisk(
|
||||||
if (avatarData.imagePath) {
|
if (avatarData.imagePath) {
|
||||||
await window.Signal.Migrations.deleteAvatar(avatarData.imagePath);
|
await window.Signal.Migrations.deleteAvatar(avatarData.imagePath);
|
||||||
} else {
|
} else {
|
||||||
window.log.info(
|
log.info(
|
||||||
'No imagePath for avatarData. Removing from userAvatarData, but not disk'
|
'No imagePath for avatarData. Removing from userAvatarData, but not disk'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1325,10 +1325,7 @@ function createGroup(): ThunkAction<
|
||||||
switchToAssociatedView: true,
|
switchToAssociatedView: true,
|
||||||
})(dispatch, getState, ...args);
|
})(dispatch, getState, ...args);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
window.log.error(
|
log.error('Failed to create group', err && err.stack ? err.stack : err);
|
||||||
'Failed to create group',
|
|
||||||
err && err.stack ? err.stack : err
|
|
||||||
);
|
|
||||||
dispatch({ type: 'CREATE_GROUP_REJECTED' });
|
dispatch({ type: 'CREATE_GROUP_REJECTED' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
reloadProfiles,
|
reloadProfiles,
|
||||||
toggleVerification,
|
toggleVerification,
|
||||||
} from '../../shims/contactVerification';
|
} from '../../shims/contactVerification';
|
||||||
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
export type SafetyNumberContactType = {
|
export type SafetyNumberContactType = {
|
||||||
safetyNumber: string;
|
safetyNumber: string;
|
||||||
|
@ -107,7 +108,7 @@ async function alterVerification(contact: ConversationType): Promise<void> {
|
||||||
if (result.name === 'OutgoingIdentityKeyError') {
|
if (result.name === 'OutgoingIdentityKeyError') {
|
||||||
throw result;
|
throw result;
|
||||||
} else {
|
} else {
|
||||||
window.log.error(
|
log.error(
|
||||||
'failed to toggle verified:',
|
'failed to toggle verified:',
|
||||||
result && result.stack ? result.stack : result
|
result && result.stack ? result.stack : result
|
||||||
);
|
);
|
||||||
|
@ -120,7 +121,7 @@ async function alterVerification(contact: ConversationType): Promise<void> {
|
||||||
throw keyError;
|
throw keyError;
|
||||||
} else {
|
} else {
|
||||||
result.errors.forEach((error: Error) => {
|
result.errors.forEach((error: Error) => {
|
||||||
window.log.error(
|
log.error(
|
||||||
'failed to toggle verified:',
|
'failed to toggle verified:',
|
||||||
error && error.stack ? error.stack : error
|
error && error.stack ? error.stack : error
|
||||||
);
|
);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue