Use window.log in browser context, turn on console eslint rule

This commit is contained in:
Scott Nonnenberg 2018-07-21 12:00:08 -07:00
parent 4320b125dd
commit 5933a34a18
71 changed files with 816 additions and 559 deletions

View file

@ -26,10 +26,11 @@
// Implicitly used in `indexeddb-backbonejs-adapter`:
// https://github.com/signalapp/Signal-Desktop/blob/4033a9f8137e62ed286170ed5d4941982b1d3a64/components/indexeddb-backbonejs-adapter/backbone-indexeddb.js#L569
window.onInvalidStateError = e => console.log(e);
window.onInvalidStateError = error =>
window.log.error(error && error.stack ? error.stack : error);
console.log('background page reloaded');
console.log('environment:', window.getEnvironment());
window.log.info('background page reloaded');
window.log.info('environment:', window.getEnvironment());
let initialLoadComplete = false;
window.owsDesktopApp = {};
@ -58,7 +59,7 @@
accountManager = new textsecure.AccountManager(USERNAME, PASSWORD);
accountManager.addEventListener('registration', () => {
Whisper.Registration.markDone();
console.log('dispatching registration event');
window.log.info('dispatching registration event');
Whisper.events.trigger('registration_done');
});
}
@ -66,19 +67,22 @@
};
const cancelInitializationMessage = Views.Initialization.setMessage();
console.log('Start IndexedDB migrations');
window.log.info('Start IndexedDB migrations');
console.log('Run migrations on database with attachment data');
await Migrations0DatabaseWithAttachmentData.run({ Backbone });
window.log.info('Run migrations on database with attachment data');
await Migrations0DatabaseWithAttachmentData.run({
Backbone,
logger: window.log,
});
console.log('Storage fetch');
window.log.info('Storage fetch');
storage.fetch();
const idleDetector = new IdleDetector();
let isMigrationWithIndexComplete = false;
let isMigrationWithoutIndexComplete = false;
idleDetector.on('idle', async () => {
console.log('Idle processing started');
window.log.info('Idle processing started');
const NUM_MESSAGES_PER_BATCH = 1;
if (!isMigrationWithIndexComplete) {
@ -88,7 +92,7 @@
numMessagesPerBatch: NUM_MESSAGES_PER_BATCH,
upgradeMessageSchema,
});
console.log('Upgrade message schema (with index):', batchWithIndex);
window.log.info('Upgrade message schema (with index):', batchWithIndex);
isMigrationWithIndexComplete = batchWithIndex.done;
}
@ -102,14 +106,17 @@
upgradeMessageSchema,
}
);
console.log('Upgrade message schema (without index):', batchWithoutIndex);
window.log.info(
'Upgrade message schema (without index):',
batchWithoutIndex
);
isMigrationWithoutIndexComplete = batchWithoutIndex.done;
}
const areAllMigrationsComplete =
isMigrationWithIndexComplete && isMigrationWithoutIndexComplete;
if (areAllMigrationsComplete) {
console.log('All migrations are complete. Stopping idle detector.');
window.log.info('All migrations are complete. Stopping idle detector.');
idleDetector.stop();
}
});
@ -254,22 +261,22 @@
if (newVersion) {
if (
lastVersion &&
window.isBeforeVersion(lastVersion, 'v1.15.0-beta.4')
window.isBeforeVersion(lastVersion, 'v1.15.0-beta.5')
) {
await window.Signal.Logs.deleteAll();
window.restart();
}
console.log(
window.log.info(
`New version detected: ${currentVersion}; previous: ${lastVersion}`
);
}
window.dispatchEvent(new Event('storage_ready'));
console.log('listening for registration events');
window.log.info('listening for registration events');
Whisper.events.on('registration_done', () => {
console.log('handling registration event');
window.log.info('handling registration event');
Whisper.RotateSignedPreKeyListener.init(Whisper.events, newVersion);
connect(true);
});
@ -284,7 +291,7 @@
Whisper.ExpiringMessagesListener.init(Whisper.events);
if (Whisper.Import.isIncomplete()) {
console.log('Import was interrupted, showing import error screen');
window.log.info('Import was interrupted, showing import error screen');
appView.openImporter();
} else if (Whisper.Registration.everDone()) {
Whisper.RotateSignedPreKeyListener.init(Whisper.events, newVersion);
@ -346,7 +353,7 @@
let disconnectTimer = null;
function onOffline() {
console.log('offline');
window.log.info('offline');
window.removeEventListener('offline', onOffline);
window.addEventListener('online', onOnline);
@ -358,13 +365,13 @@
}
function onOnline() {
console.log('online');
window.log.info('online');
window.removeEventListener('online', onOnline);
window.addEventListener('offline', onOffline);
if (disconnectTimer && isSocketOnline()) {
console.log('Already online. Had a blip in online/offline status.');
window.log.warn('Already online. Had a blip in online/offline status.');
clearTimeout(disconnectTimer);
disconnectTimer = null;
return;
@ -385,7 +392,7 @@
}
function disconnect() {
console.log('disconnect');
window.log.info('disconnect');
// Clear timer, since we're only called when the timer is expired
disconnectTimer = null;
@ -397,14 +404,14 @@
let connectCount = 0;
async function connect(firstRun) {
console.log('connect');
window.log.info('connect');
// Bootstrap our online/offline detection, only the first time we connect
if (connectCount === 0 && navigator.onLine) {
window.addEventListener('offline', onOffline);
}
if (connectCount === 0 && !navigator.onLine) {
console.log(
window.log.warn(
'Starting up offline; will connect when we have network access'
);
window.addEventListener('online', onOnline);
@ -480,7 +487,7 @@
sendRequestConfigurationSyncMessage,
storage,
});
console.log('Sync read receipt configuration status:', status);
window.log.info('Sync read receipt configuration status:', status);
if (firstRun === true && deviceId !== '1') {
const hasThemeSetting = Boolean(storage.get('theme-setting'));
@ -494,19 +501,24 @@
);
Whisper.events.trigger('contactsync:begin');
syncRequest.addEventListener('success', () => {
console.log('sync successful');
window.log.info('sync successful');
storage.put('synced_at', Date.now());
Whisper.events.trigger('contactsync');
});
syncRequest.addEventListener('timeout', () => {
console.log('sync timed out');
window.log.error('sync timed out');
Whisper.events.trigger('contactsync');
});
if (Whisper.Import.isComplete()) {
textsecure.messaging.sendRequestConfigurationSyncMessage().catch(e => {
console.log(e);
});
textsecure.messaging
.sendRequestConfigurationSyncMessage()
.catch(error => {
window.log.error(
'Import complete, but failed to send sync message',
error && error.stack ? error.stack : error
);
});
}
}
@ -571,7 +583,7 @@
if (id === textsecure.storage.user.getNumber()) {
// special case for syncing details about ourselves
if (details.profileKey) {
console.log('Got sync message with our own profile key');
window.log.info('Got sync message with our own profile key');
storage.put('profileKey', details.profileKey);
}
}
@ -581,7 +593,7 @@
});
const validationError = c.validateNumber();
if (validationError) {
console.log(
window.log.error(
'Invalid contact received:',
Errors.toLogFormat(validationError)
);
@ -651,7 +663,7 @@
ev.confirm();
} catch (error) {
console.log('onContactReceived error:', Errors.toLogFormat(error));
window.log.error('onContactReceived error:', Errors.toLogFormat(error));
}
}
@ -686,7 +698,7 @@
const { expireTimer } = details;
const isValidExpireTimer = typeof expireTimer === 'number';
if (!isValidExpireTimer) {
console.log(
window.log.error(
'Ignore invalid expire timer.',
'Expected numeric `expireTimer`, got:',
expireTimer
@ -741,7 +753,7 @@
const message = createMessage(data);
const isDuplicate = await isMessageDuplicate(message);
if (isDuplicate) {
console.log('Received duplicate message', message.idForLogging());
window.log.warn('Received duplicate message', message.idForLogging());
return event.confirm();
}
@ -835,7 +847,7 @@
return resolve(false);
});
}).catch(error => {
console.log('isMessageDuplicate error:', Errors.toLogFormat(error));
window.log.error('isMessageDuplicate error:', Errors.toLogFormat(error));
return false;
});
}
@ -856,7 +868,7 @@
async function onError(ev) {
const { error } = ev;
console.log('background onError:', Errors.toLogFormat(error));
window.log.error('background onError:', Errors.toLogFormat(error));
if (
error &&
@ -865,7 +877,7 @@
) {
Whisper.events.trigger('unauthorized');
console.log(
window.log.warn(
'Client is no longer authorized; deleting local configuration'
);
Whisper.Registration.remove();
@ -877,9 +889,9 @@
// the conversation list, instead of showing just the QR code screen.
Whisper.Registration.markEverDone();
textsecure.storage.put('number_id', previousNumberId);
console.log('Successfully cleared local configuration');
window.log.info('Successfully cleared local configuration');
} catch (eraseError) {
console.log(
window.log.error(
'Something went wrong clearing local configuration',
eraseError && eraseError.stack ? eraseError.stack : eraseError
);
@ -891,7 +903,7 @@
if (error && error.name === 'HTTPError' && error.code === -1) {
// Failed to connect to server
if (navigator.onLine) {
console.log('retrying in 1 minute');
window.log.info('retrying in 1 minute');
setTimeout(connect, 60000);
Whisper.events.trigger('reconnectTimer');
@ -945,7 +957,7 @@
const readAt = ev.timestamp;
const { timestamp } = ev.read;
const { reader } = ev.read;
console.log('read receipt', reader, timestamp);
window.log.info('read receipt', reader, timestamp);
if (!storage.get('read-receipt-setting')) {
return ev.confirm();
@ -967,7 +979,7 @@
const readAt = ev.timestamp;
const { timestamp } = ev.read;
const { sender } = ev.read;
console.log('read sync', sender, timestamp);
window.log.info('read sync', sender, timestamp);
const receipt = Whisper.ReadSyncs.add({
sender,
@ -991,7 +1003,10 @@
});
const error = c.validateNumber();
if (error) {
console.log('Invalid verified sync received:', Errors.toLogFormat(error));
window.log.error(
'Invalid verified sync received:',
Errors.toLogFormat(error)
);
return;
}
@ -1006,10 +1021,10 @@
state = 'UNVERIFIED';
break;
default:
console.log(`Got unexpected verified state: ${ev.verified.state}`);
window.log.error(`Got unexpected verified state: ${ev.verified.state}`);
}
console.log(
window.log.info(
'got verified sync for',
number,
state,
@ -1041,7 +1056,7 @@
function onDeliveryReceipt(ev) {
const { deliveryReceipt } = ev;
console.log(
window.log.info(
'delivery receipt from',
`${deliveryReceipt.source}.${deliveryReceipt.sourceDevice}`,
deliveryReceipt.timestamp

View file

@ -135,7 +135,7 @@
conversation.initialPromise = new Promise((resolve, reject) => {
if (!conversation.isValid()) {
const validationError = conversation.validationError || {};
console.log(
window.log.error(
'Contact is not valid. Not saving, but adding to collection:',
conversation.idForLogging(),
validationError.stack
@ -146,7 +146,7 @@
const deferred = conversation.save();
if (!deferred) {
console.log('Conversation save failed! ', id, type);
window.log.error('Conversation save failed! ', id, type);
return reject(new Error('getOrCreate: Conversation save failed'));
}
@ -184,17 +184,17 @@
conversations.reset([]);
},
load() {
console.log('ConversationController: starting initial fetch');
window.log.info('ConversationController: starting initial fetch');
this._initialPromise = new Promise((resolve, reject) => {
conversations.fetch().then(
() => {
console.log('ConversationController: done with initial fetch');
window.log.info('ConversationController: done with initial fetch');
this._initialFetchComplete = true;
resolve();
},
error => {
console.log(
window.log.error(
'ConversationController: initial fetch failed',
error && error.stack ? error.stack : error
);

View file

@ -15,7 +15,7 @@
window.Whisper.Database.nolog = true;
Whisper.Database.handleDOMException = (prefix, error, reject) => {
console.log(
window.log.error(
`${prefix}:`,
error && error.name,
error && error.message,
@ -27,12 +27,12 @@
function clearStores(db, names) {
return new Promise((resolve, reject) => {
const storeNames = names || db.objectStoreNames;
console.log('Clearing these indexeddb stores:', storeNames);
window.log.info('Clearing these indexeddb stores:', storeNames);
const transaction = db.transaction(storeNames, 'readwrite');
let finished = false;
const finish = via => {
console.log('clearing all stores done via', via);
window.log.info('clearing all stores done via', via);
if (finished) {
resolve();
}
@ -57,10 +57,10 @@
request.onsuccess = () => {
count += 1;
console.log('Done clearing store', storeName);
window.log.info('Done clearing store', storeName);
if (count >= storeNames.length) {
console.log('Done clearing indexeddb stores');
window.log.info('Done clearing indexeddb stores');
finish('clears complete');
}
};

View file

@ -81,7 +81,7 @@
// TODO: consider keeping a list of numbers we've
// successfully delivered to?
}
console.log(
window.log.info(
'No message for delivery receipt',
receipt.get('source'),
receipt.get('timestamp')
@ -90,7 +90,7 @@
return null;
})
.catch(error => {
console.log(
window.log.error(
'DeliveryReceipts.onReceipt error:',
error && error.stack ? error.stack : error
);

View file

@ -6,7 +6,10 @@
try {
BUILD_EXPIRATION = parseInt(window.getExpiration(), 10);
if (BUILD_EXPIRATION) {
console.log('Build expires: ', new Date(BUILD_EXPIRATION).toISOString());
window.log.info(
'Build expires: ',
new Date(BUILD_EXPIRATION).toISOString()
);
}
} catch (e) {
// nothing

View file

@ -15,7 +15,7 @@
// Load messages that have expired and destroy them
const expired = new Whisper.MessageCollection();
expired.on('add', async message => {
console.log('Message expired', {
window.log.info('Message expired', {
sentAt: message.get('sent_at'),
});
const conversation = message.getConversation();
@ -41,7 +41,10 @@
const expiring = new Whisper.MessageCollection();
expiring.once('add', next => {
const expiresAt = next.get('expires_at');
console.log('next message expires', new Date(expiresAt).toISOString());
window.log.info(
'next message expires',
new Date(expiresAt).toISOString()
);
let wait = expiresAt - Date.now();

View file

@ -1,9 +1,9 @@
/* eslint-env node */
/* eslint strict: ['error', 'never'] */
/* eslint-disable no-console */
const electron = require('electron');
const bunyan = require('bunyan');
const _ = require('lodash');
const debuglogs = require('./modules/debuglogs');
@ -29,11 +29,8 @@ function now() {
return date.toJSON();
}
function log(...args) {
const consoleArgs = ['INFO ', now()].concat(args);
console._log(...consoleArgs);
// To avoid [Object object] in our log since console.log handles non-strings smoothly
// To avoid [Object object] in our log since console.log handles non-strings smoothly
function cleanArgsForIPC(args) {
const str = args.map(item => {
if (typeof item !== 'string') {
try {
@ -46,8 +43,11 @@ function log(...args) {
return item;
});
const logText = Privacy.redactAll(str.join(' '));
ipc.send('log-info', logText);
return str.join(' ');
}
function log(...args) {
logAtLevel('info', 'INFO ', ...args);
}
if (window.console) {
@ -98,37 +98,22 @@ const publish = debuglogs.upload;
// A modern logging interface for the browser
// We create our own stream because we don't want to output JSON to the devtools console.
// Anyway, the default process.stdout stream goes to the command-line, not the devtools.
const logger = bunyan.createLogger({
name: 'log',
streams: [
{
level: 'debug',
stream: {
write(entry) {
console._log(formatLine(JSON.parse(entry)));
},
},
},
],
});
// The Bunyan API: https://github.com/trentm/node-bunyan#log-method-api
function logAtLevel(level, ...args) {
const ipcArgs = [`log-${level}`].concat(args);
ipc.send(...ipcArgs);
function logAtLevel(level, prefix, ...args) {
console._log(prefix, now(), ...args);
logger[level](...args);
const str = cleanArgsForIPC(args);
const logText = Privacy.redactAll(str);
ipc.send(`log-${level}`, logText);
}
window.log = {
fatal: _.partial(logAtLevel, 'fatal'),
error: _.partial(logAtLevel, 'error'),
warn: _.partial(logAtLevel, 'warn'),
info: _.partial(logAtLevel, 'info'),
debug: _.partial(logAtLevel, 'debug'),
trace: _.partial(logAtLevel, 'trace'),
fatal: _.partial(logAtLevel, 'fatal', 'FATAL'),
error: _.partial(logAtLevel, 'error', 'ERROR'),
warn: _.partial(logAtLevel, 'warn', 'WARN '),
info: _.partial(logAtLevel, 'info', 'INFO '),
debug: _.partial(logAtLevel, 'debug', 'DEBUG'),
trace: _.partial(logAtLevel, 'trace', 'TRACE'),
fetch,
publish,
};

View file

@ -15,7 +15,7 @@
return;
}
console.log('adding', number, 'to blocked list');
window.log.info('adding', number, 'to blocked list');
storage.put('blocked', numbers.concat(number));
};
storage.removeBlockedNumber = number => {
@ -24,7 +24,7 @@
return;
}
console.log('removing', number, 'from blocked list');
window.log.info('removing', number, 'from blocked list');
storage.put('blocked', _.without(numbers, number));
};
})();

View file

@ -156,7 +156,7 @@
async onExpiredCollection(message) {
const removeMessage = () => {
console.log('Remove expired message from collection', {
window.log.info('Remove expired message from collection', {
sentAt: message.get('sent_at'),
});
this.messageCollection.remove(message.id);
@ -347,7 +347,7 @@
return lookup;
})
.catch(error => {
console.log(
window.log.error(
'getIdentityKeys error for conversation',
this.idForLogging(),
error && error.stack ? error.stack : error
@ -361,7 +361,7 @@
lookup[contact.id] = key;
},
error => {
console.log(
window.log.error(
'getIdentityKeys error for group member',
contact.idForLogging(),
error && error.stack ? error.stack : error
@ -375,7 +375,7 @@
replay(error, message) {
const replayable = new textsecure.ReplayableError(error);
return replayable.replay(message.attributes).catch(e => {
console.log('replay error:', e && e.stack ? e.stack : e);
window.log.error('replay error:', e && e.stack ? e.stack : e);
});
},
decryptOldIncomingKeyErrors() {
@ -383,7 +383,10 @@
if (this.get('decryptedOldIncomingKeyErrors')) {
return Promise.resolve();
}
console.log('decryptOldIncomingKeyErrors start for', this.idForLogging());
window.log.info(
'decryptOldIncomingKeyErrors start for',
this.idForLogging()
);
const messages = this.messageCollection.filter(message => {
const errors = message.get('errors');
@ -399,7 +402,7 @@
});
const markComplete = () => {
console.log(
window.log.info(
'decryptOldIncomingKeyErrors complete for',
this.idForLogging()
);
@ -412,7 +415,7 @@
return markComplete();
}
console.log(
window.log.info(
'decryptOldIncomingKeyErrors found',
messages.length,
'messages to process'
@ -449,7 +452,7 @@
)
)
.catch(error => {
console.log(
window.log.error(
'decryptOldIncomingKeyErrors error:',
error && error.stack ? error.stack : error
);
@ -583,7 +586,7 @@
},
addKeyChange(id) {
console.log(
window.log.info(
'adding key change advisory for',
this.idForLogging(),
id,
@ -606,7 +609,7 @@
_.defaults(options, { local: true });
if (this.isMe()) {
console.log(
window.log.info(
'refusing to add verified change advisory for our own number'
);
return;
@ -614,7 +617,7 @@
const lastMessage = this.get('timestamp') || Date.now();
console.log(
window.log.info(
'adding verified change advisory for',
this.idForLogging(),
id,
@ -823,7 +826,7 @@
this.queueJob(async () => {
const now = Date.now();
console.log(
window.log.info(
'Sending message to conversation',
this.idForLogging(),
'with timestamp',
@ -933,7 +936,7 @@
return Promise.resolve();
}
console.log("Update conversation 'expireTimer'", {
window.log.info("Update conversation 'expireTimer'", {
id: this.idForLogging(),
expireTimer,
source,
@ -1085,7 +1088,7 @@
if (this.messageCollection.get(m.id)) {
m = this.messageCollection.get(m.id);
} else {
console.log(
window.log.warn(
'Marked a message as read in the database, but ' +
'it was not in messageCollection.'
);
@ -1117,7 +1120,7 @@
read = read.filter(item => !item.hasErrors);
if (read.length && options.sendReadReceipts) {
console.log('Sending', read.length, 'read receipts');
window.log.info('Sending', read.length, 'read receipts');
promises.push(textsecure.messaging.syncReadMessages(read));
if (storage.get('read-receipt-setting')) {
@ -1173,7 +1176,7 @@
// save identity will close all sessions except for .1, so we
// must close that one manually.
const address = new libsignal.SignalProtocolAddress(id, 1);
console.log('closing session for', address.toString());
window.log.info('closing session for', address.toString());
const sessionCipher = new libsignal.SessionCipher(
textsecure.storage.protocol,
address
@ -1197,7 +1200,7 @@
e => {
if (e.name === 'ProfileDecryptError') {
// probably the profile key has changed.
console.log(
window.log.error(
'decryptProfile error:',
id,
profile,
@ -1209,7 +1212,7 @@
});
})
.catch(error => {
console.log(
window.log.error(
'getProfile error:',
error && error.stack ? error.stack : error
);
@ -1365,7 +1368,7 @@
await wrapDeferred(message.save());
}
} catch (error) {
console.log(
window.log.error(
'Problem upgrading message quoted message from database',
Errors.toLogFormat(error)
);
@ -1532,7 +1535,7 @@
throw new Error('This conversation has no id!');
}
if (this.inProgressFetch) {
console.log('Attempting to start a parallel fetchMessages() call');
window.log.warn('Attempting to start a parallel fetchMessages() call');
return;
}
@ -1550,7 +1553,7 @@
// one-time hit. We do this so we have guarantees about message structure.
await this.upgradeMessages(this.messageCollection);
} catch (error) {
console.log(
window.log.error(
'fetchMessages: failed to upgrade messages',
Errors.toLogFormat(error)
);
@ -1758,7 +1761,7 @@
const messageId = message.id;
const isExpiringMessage = Message.hasExpiration(messageJSON);
console.log('Add notification', {
window.log.info('Add notification', {
conversationId: this.idForLogging(),
isExpiringMessage,
messageSentAt,

View file

@ -59,7 +59,12 @@
storeName: 'messages',
initialize(attributes) {
if (_.isObject(attributes)) {
this.set(TypedMessage.initializeSchemaVersion(attributes));
this.set(
TypedMessage.initializeSchemaVersion({
message: attributes,
logger: window.log,
})
);
}
this.OUR_NUMBER = textsecure.storage.user.getNumber();
@ -86,7 +91,7 @@
const required = ['conversationId', 'received_at', 'sent_at'];
const missing = _.filter(required, attr => !attributes[attr]);
if (missing.length) {
console.log(`Message missing attributes: ${missing}`);
window.log.warn(`Message missing attributes: ${missing}`);
}
},
isEndSession() {
@ -860,7 +865,7 @@
errors = [errors];
}
errors.forEach(e => {
console.log(
window.log.error(
'Message.saveErrors:',
e && e.reason ? e.reason : null,
e && e.stack ? e.stack : e
@ -972,7 +977,7 @@
groupUpdate.joined = difference;
}
if (conversation.get('left')) {
console.log('re-added to a left group');
window.log.warn('re-added to a left group');
attributes.left = false;
}
} else if (dataMessage.group.type === GROUP_TYPES.QUIT) {
@ -1038,7 +1043,7 @@
const shouldLogExpireTimerChange =
message.isExpirationTimerUpdate() || expireTimer;
if (shouldLogExpireTimerChange) {
console.log("Update conversation 'expireTimer'", {
window.log.info("Update conversation 'expireTimer'", {
id: conversation.idForLogging(),
expireTimer,
source: 'handleDataMessage',
@ -1142,7 +1147,7 @@
const handleError = error => {
const errorForLog = error && error.stack ? error.stack : error;
console.log(
window.log.error(
'handleDataMessage',
message.idForLogging(),
'error:',
@ -1167,7 +1172,7 @@
() => {
try {
if (previousUnread !== message.get('unread')) {
console.log(
window.log.warn(
'Caught race condition on new message read state! ' +
'Manually starting timers.'
);
@ -1192,7 +1197,7 @@
},
() => {
try {
console.log(
window.log.warn(
'handleDataMessage: Message',
message.idForLogging(),
'was deleted'
@ -1257,7 +1262,7 @@
}
Whisper.ExpiringMessagesListener.update();
console.log('Set message expiration', {
window.log.info('Set message expiration', {
expiresAt,
sentAt: this.get('sent_at'),
});
@ -1364,7 +1369,9 @@
return Promise.resolve();
}
console.log('fetchConversation: doing another fetch to get all unread');
window.log.info(
'fetchConversation: doing another fetch to get all unread'
);
return this.fetchConversation(conversationId, limit, unreadCount);
});
},
@ -1374,7 +1381,7 @@
},
fetchExpired() {
console.log('Load expired messages');
window.log.info('Load expired messages');
this.fetch({
conditions: { expires_at: { $lte: Date.now() } },
addIndividually: true,

View file

@ -134,7 +134,7 @@ function exportContactsAndGroups(db, fileWriter) {
if (storeNames.length === 0) {
throw new Error('No stores to export');
}
console.log('Exporting from these stores:', storeNames.join(', '));
window.log.info('Exporting from these stores:', storeNames.join(', '));
const stream = createOutputStream(fileWriter);
@ -153,7 +153,7 @@ function exportContactsAndGroups(db, fileWriter) {
);
};
transaction.oncomplete = () => {
console.log('transaction complete');
window.log.info('transaction complete');
};
const store = transaction.objectStore(storeName);
@ -168,7 +168,7 @@ function exportContactsAndGroups(db, fileWriter) {
};
request.onsuccess = async event => {
if (count === 0) {
console.log('cursor opened');
window.log.info('cursor opened');
stream.write(`"${storeName}": [`);
}
@ -188,17 +188,17 @@ function exportContactsAndGroups(db, fileWriter) {
} else {
// no more
stream.write(']');
console.log('Exported', count, 'items from store', storeName);
window.log.info('Exported', count, 'items from store', storeName);
exportedStoreNames.push(storeName);
if (exportedStoreNames.length < storeNames.length) {
stream.write(',');
} else {
console.log('Exported all stores');
window.log.info('Exported all stores');
stream.write('}');
await stream.close();
console.log('Finished writing all stores to disk');
window.log.info('Finished writing all stores to disk');
resolve();
}
}
@ -215,11 +215,11 @@ async function importNonMessages(db, parent, options) {
function eliminateClientConfigInBackup(data, targetPath) {
const cleaned = _.pick(data, 'conversations', 'groups');
console.log('Writing configuration-free backup file back to disk');
window.log.info('Writing configuration-free backup file back to disk');
try {
fs.writeFileSync(targetPath, JSON.stringify(cleaned));
} catch (error) {
console.log('Error writing cleaned-up backup to disk: ', error.stack);
window.log.error('Error writing cleaned-up backup to disk: ', error.stack);
}
}
@ -250,7 +250,9 @@ function importFromJsonString(db, jsonString, targetPath, options) {
delete importObject.sessions;
delete importObject.unprocessed;
console.log('This is a light import; contacts, groups and messages only');
window.log.info(
'This is a light import; contacts, groups and messages only'
);
}
// We mutate the on-disk backup to prevent the user from importing client
@ -259,11 +261,11 @@ function importFromJsonString(db, jsonString, targetPath, options) {
eliminateClientConfigInBackup(importObject, targetPath);
const storeNames = _.keys(importObject);
console.log('Importing to these stores:', storeNames.join(', '));
window.log.info('Importing to these stores:', storeNames.join(', '));
let finished = false;
const finish = via => {
console.log('non-messages import done via', via);
window.log.info('non-messages import done via', via);
if (finished) {
resolve(result);
}
@ -281,7 +283,7 @@ function importFromJsonString(db, jsonString, targetPath, options) {
transaction.oncomplete = finish.bind(null, 'transaction complete');
_.each(storeNames, storeName => {
console.log('Importing items for store', storeName);
window.log.info('Importing items for store', storeName);
if (!importObject[storeName].length) {
delete importObject[storeName];
@ -294,7 +296,7 @@ function importFromJsonString(db, jsonString, targetPath, options) {
const finishStore = () => {
// added all objects for this store
delete importObject[storeName];
console.log(
window.log.info(
'Done importing to store',
storeName,
'Total count:',
@ -304,7 +306,7 @@ function importFromJsonString(db, jsonString, targetPath, options) {
);
if (_.keys(importObject).length === 0) {
// added all object stores
console.log('DB import complete');
window.log.info('DB import complete');
finish('puts scheduled');
}
};
@ -455,7 +457,7 @@ async function readAttachment(dir, attachment, name, options) {
const targetPath = path.join(dir, sanitizedName);
if (!fs.existsSync(targetPath)) {
console.log(`Warning: attachment ${sanitizedName} not found`);
window.log.warn(`Warning: attachment ${sanitizedName} not found`);
return;
}
@ -518,7 +520,7 @@ async function writeThumbnails(rawQuotedAttachments, options) {
)
);
} catch (error) {
console.log(
window.log.error(
'writeThumbnails: error exporting conversation',
name,
':',
@ -560,7 +562,7 @@ async function writeAttachments(rawAttachments, options) {
try {
await Promise.all(promises);
} catch (error) {
console.log(
window.log.error(
'writeAttachments: error exporting conversation',
name,
':',
@ -571,7 +573,6 @@ async function writeAttachments(rawAttachments, options) {
}
async function writeAvatar(avatar, options) {
console.log('writeAvatar', { avatar, options });
const { dir, message, index, key, newKey } = options;
const name = _getAnonymousAttachmentFileName(message, index);
const filename = `${name}-contact-avatar`;
@ -618,7 +619,7 @@ async function writeContactAvatars(contact, options) {
)
);
} catch (error) {
console.log(
window.log.error(
'writeContactAvatars: error exporting conversation',
name,
':',
@ -633,10 +634,10 @@ async function writeEncryptedAttachment(target, data, options = {}) {
if (fs.existsSync(target)) {
if (newKey) {
console.log(`Deleting attachment ${filename}; key has changed`);
window.log.info(`Deleting attachment ${filename}; key has changed`);
fs.unlinkSync(target);
} else {
console.log(`Skipping attachment ${filename}; already exists`);
window.log.info(`Skipping attachment ${filename}; already exists`);
return;
}
}
@ -669,7 +670,7 @@ async function exportConversation(db, conversation, options) {
throw new Error('Need a key to encrypt with!');
}
console.log('exporting conversation', name);
window.log.info('exporting conversation', name);
const writer = await createFileAndWriter(dir, 'messages.json');
return new Promise(async (resolve, reject) => {
@ -792,7 +793,7 @@ async function exportConversation(db, conversation, options) {
try {
await Promise.all([stream.write(']}'), promiseChain, stream.close()]);
} catch (error) {
console.log(
window.log.error(
'exportConversation: error exporting conversation',
name,
':',
@ -802,7 +803,7 @@ async function exportConversation(db, conversation, options) {
return;
}
console.log('done exporting conversation', name);
window.log.info('done exporting conversation', name);
resolve();
}
};
@ -888,12 +889,12 @@ function exportConversations(db, options) {
});
};
console.log('scheduling export for conversation', name);
window.log.info('scheduling export for conversation', name);
// eslint-disable-next-line more/no-then
promiseChain = promiseChain.then(process);
cursor.continue();
} else {
console.log('Done scheduling conversation exports');
window.log.info('Done scheduling conversation exports');
try {
await promiseChain;
} catch (error) {
@ -979,7 +980,7 @@ async function loadAttachments(dir, getName, options) {
})
);
console.log('loadAttachments', { message });
window.log.info('loadAttachments', { message });
}
function saveMessage(db, message) {
@ -1000,7 +1001,7 @@ async function saveAllMessages(db, rawMessages) {
return new Promise((resolve, reject) => {
let finished = false;
const finish = via => {
console.log('messages done saving via', via);
window.log.info('messages done saving via', via);
if (finished) {
resolve();
}
@ -1026,7 +1027,7 @@ async function saveAllMessages(db, rawMessages) {
request.onsuccess = () => {
count += 1;
if (count === messages.length) {
console.log(
window.log.info(
'Saved',
messages.length,
'messages for conversation',
@ -1066,7 +1067,9 @@ async function importConversation(db, dir, options) {
try {
contents = await readFileAsText(dir, 'messages.json');
} catch (error) {
console.log(`Warning: could not access messages.json in directory: ${dir}`);
window.log.error(
`Warning: could not access messages.json in directory: ${dir}`
);
}
let promiseChain = Promise.resolve();
@ -1120,7 +1123,7 @@ async function importConversation(db, dir, options) {
await saveAllMessages(db, messages);
await promiseChain;
console.log(
window.log.info(
'Finished importing conversation',
conversationId,
'Total:',
@ -1208,7 +1211,7 @@ function assembleLookup(db, storeName, keyFunction) {
lookup[keyFunction(cursor.value)] = true;
cursor.continue();
} else {
console.log(`Done creating ${storeName} lookup`);
window.log.info(`Done creating ${storeName} lookup`);
resolve(lookup);
}
};
@ -1236,7 +1239,7 @@ function createZip(zipDir, targetDir) {
});
archive.on('warning', error => {
console.log(`Archive generation warning: ${error.stack}`);
window.log.warn(`Archive generation warning: ${error.stack}`);
});
archive.on('error', reject);
@ -1286,7 +1289,7 @@ function createTempDir() {
}
function deleteAll(pattern) {
console.log(`Deleting ${pattern}`);
window.log.info(`Deleting ${pattern}`);
return pify(rimraf)(pattern);
}
@ -1320,10 +1323,10 @@ async function exportToDirectory(directory, options) {
const zip = await createZip(encryptionDir, stagingDir);
await encryptFile(zip, path.join(directory, 'messages.zip'), options);
console.log('done backing up!');
window.log.info('done backing up!');
return directory;
} catch (error) {
console.log(
window.log.error(
'The backup went wrong!',
error && error.stack ? error.stack : error
);
@ -1392,7 +1395,7 @@ async function importFromDirectory(directory, options) {
const result = await importNonMessages(db, stagingDir, options);
await importConversations(db, stagingDir, Object.assign({}, options));
console.log('Done importing from backup!');
window.log.info('Done importing from backup!');
return result;
} finally {
if (stagingDir) {
@ -1407,10 +1410,10 @@ async function importFromDirectory(directory, options) {
const result = await importNonMessages(db, directory, options);
await importConversations(db, directory, options);
console.log('Done importing!');
window.log.info('Done importing!');
return result;
} catch (error) {
console.log(
window.log.error(
'The import went wrong!',
error && error.stack ? error.stack : error
);

View file

@ -1,4 +1,5 @@
/* eslint-env node */
/* global log */
const fs = require('fs-extra');
const path = require('path');
@ -56,7 +57,7 @@ exports.createConversation = async ({
await Promise.all(
range(0, numMessages).map(async index => {
await sleep(index * 100);
console.log(`Create message ${index + 1}`);
log.info(`Create message ${index + 1}`);
const messageAttributes = await createRandomMessage({ conversationId });
const message = new WhisperMessage(messageAttributes);
return deferredToPromise(message.save());
@ -107,7 +108,7 @@ const createRandomMessage = async ({ conversationId } = {}) => {
};
const message = _createMessage({ commonProperties, conversationId, type });
return Message.initializeSchemaVersion(message);
return Message.initializeSchemaVersion({ message, logger: log });
};
const _createMessage = ({ commonProperties, conversationId, type } = {}) => {

View file

@ -1,16 +0,0 @@
const addUnhandledErrorHandler = require('electron-unhandled');
const Errors = require('./types/errors');
// addHandler :: Unit -> Unit
exports.addHandler = () => {
addUnhandledErrorHandler({
logger: error => {
console.error(
'Uncaught error or unhandled promise rejection:',
Errors.toLogFormat(error)
);
},
showDialog: false,
});
};

View file

@ -1,4 +1,5 @@
/* eslint-env node */
/* global log */
exports.setup = (locale, messages) => {
if (!locale) {
@ -11,7 +12,7 @@ exports.setup = (locale, messages) => {
function getMessage(key, substitutions) {
const entry = messages[key];
if (!entry) {
console.error(
log.error(
`i18n: Attempted to get translation for nonexistent key '${key}'`
);
return '';

View file

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

View file

@ -82,6 +82,7 @@ exports.dangerouslyProcessAllWithoutIndex = async ({
minDatabaseVersion,
numMessagesPerBatch,
upgradeMessageSchema,
logger,
} = {}) => {
if (!isString(databaseName)) {
throw new TypeError("'databaseName' must be a string");
@ -102,7 +103,7 @@ exports.dangerouslyProcessAllWithoutIndex = async ({
const connection = await database.open(databaseName);
const databaseVersion = connection.version;
const isValidDatabaseVersion = databaseVersion >= minDatabaseVersion;
console.log('Database status', {
logger.info('Database status', {
databaseVersion,
isValidDatabaseVersion,
minDatabaseVersion,
@ -133,7 +134,7 @@ exports.dangerouslyProcessAllWithoutIndex = async ({
break;
}
numCumulativeMessagesProcessed += status.numMessagesProcessed;
console.log(
logger.info(
'Upgrade message schema:',
Object.assign({}, status, {
numTotalMessages,
@ -142,11 +143,11 @@ exports.dangerouslyProcessAllWithoutIndex = async ({
);
}
console.log('Close database connection');
logger.info('Close database connection');
connection.close();
const totalDuration = Date.now() - migrationStartTime;
console.log('Attachment migration complete:', {
logger.info('Attachment migration complete:', {
totalDuration,
totalMessagesProcessed: numCumulativeMessagesProcessed,
});

View file

@ -1,7 +1,7 @@
exports.run = transaction => {
exports.run = ({ transaction, logger }) => {
const messagesStore = transaction.objectStore('messages');
console.log("Create message attachment metadata index: 'hasAttachments'");
logger.info("Create message attachment metadata index: 'hasAttachments'");
messagesStore.createIndex(
'hasAttachments',
['conversationId', 'hasAttachments', 'received_at'],
@ -9,7 +9,7 @@ exports.run = transaction => {
);
['hasVisualMediaAttachments', 'hasFileAttachments'].forEach(name => {
console.log(`Create message attachment metadata index: '${name}'`);
logger.info(`Create message attachment metadata index: '${name}'`);
messagesStore.createIndex(name, ['conversationId', 'received_at', name], {
unique: false,
});

View file

@ -1,3 +1,5 @@
/* global window */
const { isString, last } = require('lodash');
const { runMigrations } = require('./run_migrations');
@ -12,8 +14,8 @@ const migrations = [
{
version: '12.0',
migrate(transaction, next) {
console.log('Migration 12');
console.log('creating object stores');
window.log.info('Migration 12');
window.log.info('creating object stores');
const messages = transaction.db.createObjectStore('messages');
messages.createIndex('conversation', ['conversationId', 'received_at'], {
unique: false,
@ -46,7 +48,7 @@ const migrations = [
transaction.db.createObjectStore('signedPreKeys');
transaction.db.createObjectStore('items');
console.log('creating debug log');
window.log.info('creating debug log');
transaction.db.createObjectStore('debug');
next();
@ -55,8 +57,8 @@ const migrations = [
{
version: '13.0',
migrate(transaction, next) {
console.log('Migration 13');
console.log('Adding fields to identity keys');
window.log.info('Migration 13');
window.log.info('Adding fields to identity keys');
const identityKeys = transaction.objectStore('identityKeys');
const request = identityKeys.openCursor();
const promises = [];
@ -72,9 +74,9 @@ const migrations = [
new Promise((resolve, reject) => {
const putRequest = identityKeys.put(attributes, attributes.id);
putRequest.onsuccess = resolve;
putRequest.onerror = e => {
console.log(e);
reject(e);
putRequest.onerror = error => {
window.log.error(error && error.stack ? error.stack : error);
reject(error);
};
})
);
@ -88,15 +90,15 @@ const migrations = [
}
};
request.onerror = event => {
console.log(event);
window.log.error(event);
};
},
},
{
version: '14.0',
migrate(transaction, next) {
console.log('Migration 14');
console.log('Adding unprocessed message store');
window.log.info('Migration 14');
window.log.info('Adding unprocessed message store');
const unprocessed = transaction.db.createObjectStore('unprocessed');
unprocessed.createIndex('received', 'timestamp', { unique: false });
next();
@ -105,8 +107,8 @@ const migrations = [
{
version: '15.0',
migrate(transaction, next) {
console.log('Migration 15');
console.log('Adding messages index for de-duplication');
window.log.info('Migration 15');
window.log.info('Adding messages index for de-duplication');
const messages = transaction.objectStore('messages');
messages.createIndex('unique', ['source', 'sourceDevice', 'sent_at'], {
unique: true,
@ -117,8 +119,8 @@ const migrations = [
{
version: '16.0',
migrate(transaction, next) {
console.log('Migration 16');
console.log('Dropping log table, since we now log to disk');
window.log.info('Migration 16');
window.log.info('Dropping log table, since we now log to disk');
transaction.db.deleteObjectStore('debug');
next();
},
@ -126,19 +128,21 @@ const migrations = [
{
version: 17,
async migrate(transaction, next) {
console.log('Migration 17');
window.log.info('Migration 17');
const start = Date.now();
const messagesStore = transaction.objectStore('messages');
console.log('Create index from attachment schema version to attachment');
window.log.info(
'Create index from attachment schema version to attachment'
);
messagesStore.createIndex('schemaVersion', 'schemaVersion', {
unique: false,
});
const duration = Date.now() - start;
console.log(
window.log.info(
'Complete migration to database version 17',
`Duration: ${duration}ms`
);
@ -148,13 +152,13 @@ const migrations = [
{
version: 18,
migrate(transaction, next) {
console.log('Migration 18');
window.log.info('Migration 18');
const start = Date.now();
Migration18.run(transaction);
Migration18.run({ transaction, logger: window.log });
const duration = Date.now() - start;
console.log(
window.log.info(
'Complete migration to database version 18',
`Duration: ${duration}ms`
);
@ -169,9 +173,10 @@ const database = {
migrations,
};
exports.run = ({ Backbone, databaseName } = {}) =>
exports.run = ({ Backbone, databaseName, logger } = {}) =>
runMigrations({
Backbone,
logger,
database: Object.assign(
{},
database,

View file

@ -16,7 +16,7 @@ const migrations = [
// },
];
exports.run = async ({ Backbone, database } = {}) => {
exports.run = async ({ Backbone, database, logger } = {}) => {
const { canRun } = await exports.getStatus({ database });
if (!canRun) {
throw new Error(
@ -24,7 +24,7 @@ exports.run = async ({ Backbone, database } = {}) => {
);
}
await runMigrations({ Backbone, database });
await runMigrations({ Backbone, database, logger });
};
exports.getStatus = async ({ database } = {}) => {

View file

@ -8,13 +8,13 @@ const { deferredToPromise } = require('../deferred_to_promise');
const closeDatabaseConnection = ({ Backbone } = {}) =>
deferredToPromise(Backbone.sync('closeall'));
exports.runMigrations = async ({ Backbone, database } = {}) => {
exports.runMigrations = async ({ Backbone, database, logger } = {}) => {
if (
!isObject(Backbone) ||
!isObject(Backbone.Collection) ||
!isFunction(Backbone.Collection.extend)
) {
throw new TypeError("'Backbone' is required");
throw new TypeError('runMigrations: Backbone is required');
}
if (
@ -22,7 +22,10 @@ exports.runMigrations = async ({ Backbone, database } = {}) => {
!isString(database.id) ||
!Array.isArray(database.migrations)
) {
throw new TypeError("'database' is required");
throw new TypeError('runMigrations: database is required');
}
if (!isObject(logger)) {
throw new TypeError('runMigrations: logger is required');
}
const {
@ -33,7 +36,7 @@ exports.runMigrations = async ({ Backbone, database } = {}) => {
const databaseVersion = await db.getVersion(database.id);
const isAlreadyUpgraded = databaseVersion >= lastMigrationVersion;
console.log('Database status', {
logger.info('Database status', {
firstMigrationVersion,
lastMigrationVersion,
databaseVersion,
@ -50,7 +53,7 @@ exports.runMigrations = async ({ Backbone, database } = {}) => {
}))();
await deferredToPromise(migrationCollection.fetch({ limit: 1 }));
console.log('Close database connection');
logger.info('Close database connection');
await closeDatabaseConnection({ Backbone });
};

View file

@ -86,6 +86,7 @@ function initializeMigrations({
Attachments,
Type,
VisualType,
logger,
}) {
if (!Attachments) {
return null;
@ -131,15 +132,17 @@ function initializeMigrations({
getImageDimensions,
makeImageThumbnail,
makeVideoScreenshot,
logger,
}),
writeMessageAttachments: MessageType.createAttachmentDataWriter(
createWriterForExisting(attachmentsPath)
),
writeMessageAttachments: MessageType.createAttachmentDataWriter({
writeExistingAttachmentData: createWriterForExisting(attachmentsPath),
logger,
}),
};
}
exports.setup = (options = {}) => {
const { Attachments, userDataPath, getRegionCode } = options;
const { Attachments, userDataPath, getRegionCode, logger } = options;
const Migrations = initializeMigrations({
userDataPath,
@ -147,6 +150,7 @@ exports.setup = (options = {}) => {
Attachments,
Type: AttachmentType,
VisualType: VisualAttachment,
logger,
});
const Components = {

View file

@ -108,9 +108,9 @@ exports._replaceUnicodeOrderOverridesSync = attachment => {
exports.replaceUnicodeOrderOverrides = async attachment =>
exports._replaceUnicodeOrderOverridesSync(attachment);
exports.removeSchemaVersion = attachment => {
exports.removeSchemaVersion = ({ attachment, logger }) => {
if (!exports.isValid(attachment)) {
console.log(
logger.error(
'Attachment.removeSchemaVersion: Invalid input attachment:',
attachment
);
@ -197,6 +197,7 @@ exports.captureDimensionsAndScreenshot = async (
getImageDimensions,
makeImageThumbnail,
makeVideoScreenshot,
logger,
}
) => {
const { contentType } = attachment;
@ -212,13 +213,17 @@ exports.captureDimensionsAndScreenshot = async (
if (GoogleChrome.isImageTypeSupported(contentType)) {
try {
const { width, height } = await getImageDimensions(absolutePath);
const { width, height } = await getImageDimensions({
objectUrl: absolutePath,
logger,
});
const thumbnailBuffer = await blobToArrayBuffer(
await makeImageThumbnail(
THUMBNAIL_SIZE,
absolutePath,
THUMBNAIL_CONTENT_TYPE
)
await makeImageThumbnail({
size: THUMBNAIL_SIZE,
objectUrl: absolutePath,
contentType: THUMBNAIL_CONTENT_TYPE,
logger,
})
);
const thumbnailPath = await writeNewAttachmentData(thumbnailBuffer);
@ -234,7 +239,7 @@ exports.captureDimensionsAndScreenshot = async (
},
};
} catch (error) {
console.log(
logger.error(
'captureDimensionsAndScreenshot:',
'error processing image; skipping screenshot generation',
toLogFormat(error)
@ -246,21 +251,29 @@ exports.captureDimensionsAndScreenshot = async (
let screenshotObjectUrl;
try {
const screenshotBuffer = await blobToArrayBuffer(
await makeVideoScreenshot(absolutePath, THUMBNAIL_CONTENT_TYPE)
await makeVideoScreenshot({
objectUrl: absolutePath,
contentType: THUMBNAIL_CONTENT_TYPE,
logger,
})
);
screenshotObjectUrl = makeObjectUrl(
screenshotBuffer,
THUMBNAIL_CONTENT_TYPE
);
const { width, height } = await getImageDimensions(screenshotObjectUrl);
const { width, height } = await getImageDimensions({
objectUrl: screenshotObjectUrl,
logger,
});
const screenshotPath = await writeNewAttachmentData(screenshotBuffer);
const thumbnailBuffer = await blobToArrayBuffer(
await makeImageThumbnail(
THUMBNAIL_SIZE,
screenshotObjectUrl,
THUMBNAIL_CONTENT_TYPE
)
await makeImageThumbnail({
size: THUMBNAIL_SIZE,
objectUrl: screenshotObjectUrl,
contentType: THUMBNAIL_CONTENT_TYPE,
logger,
})
);
const thumbnailPath = await writeNewAttachmentData(thumbnailBuffer);
@ -283,7 +296,7 @@ exports.captureDimensionsAndScreenshot = async (
height,
};
} catch (error) {
console.log(
logger.error(
'captureDimensionsAndScreenshot: error processing video; skipping screenshot generation',
toLogFormat(error)
);

View file

@ -9,7 +9,7 @@ const { isArrayBuffer, isFunction, isUndefined, omit } = require('lodash');
// Promise Attachment
exports.migrateDataToFileSystem = async (
attachment,
{ writeNewAttachmentData } = {}
{ writeNewAttachmentData, logger } = {}
) => {
if (!isFunction(writeNewAttachmentData)) {
throw new TypeError("'writeNewAttachmentData' must be a function");
@ -19,7 +19,7 @@ exports.migrateDataToFileSystem = async (
const hasData = !isUndefined(data);
const shouldSkipSchemaUpgrade = !hasData;
if (shouldSkipSchemaUpgrade) {
console.log('WARNING: `attachment.data` is `undefined`');
logger.warn('WARNING: `attachment.data` is `undefined`');
return attachment;
}

View file

@ -13,7 +13,7 @@ exports.parseAndWriteAvatar = upgradeAttachment => async (
contact,
context = {}
) => {
const { message, regionCode } = context;
const { message, regionCode, logger } = context;
const { avatar } = contact;
// This is to ensure that an omit() call doesn't pull in prototype props/methods
@ -35,7 +35,7 @@ exports.parseAndWriteAvatar = upgradeAttachment => async (
messageId: idForLogging(message),
});
if (error) {
console.log(
logger.error(
'Contact.parseAndWriteAvatar: contact was malformed.',
toLogFormat(error)
);

View file

@ -1,4 +1,4 @@
const { isFunction, isString, omit } = require('lodash');
const { isFunction, isObject, isString, omit } = require('lodash');
const Contact = require('./contact');
const Attachment = require('./attachment');
@ -55,7 +55,7 @@ exports.PRIVATE = PRIVATE;
exports.isValid = () => true;
// Schema
exports.initializeSchemaVersion = message => {
exports.initializeSchemaVersion = ({ message, logger }) => {
const isInitialized =
SchemaVersion.isValid(message.schemaVersion) && message.schemaVersion >= 1;
if (isInitialized) {
@ -82,7 +82,9 @@ exports.initializeSchemaVersion = message => {
: INITIAL_SCHEMA_VERSION;
const messageWithInitialSchema = Object.assign({}, message, {
schemaVersion: inheritedSchemaVersion,
attachments: message.attachments.map(Attachment.removeSchemaVersion),
attachments: message.attachments.map(attachment =>
Attachment.removeSchemaVersion({ attachment, logger })
),
});
return messageWithInitialSchema;
@ -92,17 +94,24 @@ exports.initializeSchemaVersion = message => {
// type UpgradeStep = (Message, Context) -> Promise Message
// SchemaVersion -> UpgradeStep -> UpgradeStep
exports._withSchemaVersion = (schemaVersion, upgrade) => {
exports._withSchemaVersion = ({ schemaVersion, upgrade }) => {
if (!SchemaVersion.isValid(schemaVersion)) {
throw new TypeError("'schemaVersion' is invalid");
throw new TypeError('_withSchemaVersion: schemaVersion is invalid');
}
if (!isFunction(upgrade)) {
throw new TypeError("'upgrade' must be a function");
throw new TypeError('_withSchemaVersion: upgrade must be a function');
}
return async (message, context) => {
if (!context || !isObject(context.logger)) {
throw new TypeError(
'_withSchemaVersion: context must have logger object'
);
}
const { logger } = context;
if (!exports.isValid(message)) {
console.log(
logger.error(
'Message._withSchemaVersion: Invalid input message:',
message
);
@ -117,7 +126,7 @@ exports._withSchemaVersion = (schemaVersion, upgrade) => {
const expectedVersion = schemaVersion - 1;
const hasExpectedVersion = message.schemaVersion === expectedVersion;
if (!hasExpectedVersion) {
console.log(
logger.warn(
'WARNING: Message._withSchemaVersion: Unexpected version:',
`Expected message to have version ${expectedVersion},`,
`but got ${message.schemaVersion}.`,
@ -130,7 +139,7 @@ exports._withSchemaVersion = (schemaVersion, upgrade) => {
try {
upgradedMessage = await upgrade(message, context);
} catch (error) {
console.log(
logger.error(
`Message._withSchemaVersion: error updating message ${message.id}:`,
Errors.toLogFormat(error)
);
@ -138,7 +147,7 @@ exports._withSchemaVersion = (schemaVersion, upgrade) => {
}
if (!exports.isValid(upgradedMessage)) {
console.log(
logger.error(
'Message._withSchemaVersion: Invalid upgraded message:',
upgradedMessage
);
@ -186,6 +195,10 @@ exports._mapQuotedAttachments = upgradeAttachment => async (
if (!message.quote) {
return message;
}
if (!context || !isObject(context.logger)) {
throw new Error('_mapQuotedAttachments: context must have logger object');
}
const { logger } = context;
const upgradeWithContext = async attachment => {
const { thumbnail } = attachment;
@ -194,7 +207,7 @@ exports._mapQuotedAttachments = upgradeAttachment => async (
}
if (!thumbnail.data) {
console.log('Quoted attachment did not have thumbnail data; removing it');
logger.warn('Quoted attachment did not have thumbnail data; removing it');
return omit(attachment, ['thumbnail']);
}
@ -216,39 +229,46 @@ exports._mapQuotedAttachments = upgradeAttachment => async (
});
};
const toVersion0 = async message => exports.initializeSchemaVersion(message);
const toVersion1 = exports._withSchemaVersion(
1,
exports._mapAttachments(Attachment.autoOrientJPEG)
);
const toVersion2 = exports._withSchemaVersion(
2,
exports._mapAttachments(Attachment.replaceUnicodeOrderOverrides)
);
const toVersion3 = exports._withSchemaVersion(
3,
exports._mapAttachments(Attachment.migrateDataToFileSystem)
);
const toVersion4 = exports._withSchemaVersion(
4,
exports._mapQuotedAttachments(Attachment.migrateDataToFileSystem)
);
const toVersion5 = exports._withSchemaVersion(5, initializeAttachmentMetadata);
const toVersion6 = exports._withSchemaVersion(
6,
exports._mapContact(
const toVersion0 = async (message, context) =>
exports.initializeSchemaVersion({ message, logger: context.logger });
const toVersion1 = exports._withSchemaVersion({
schemaVersion: 1,
upgrade: exports._mapAttachments(Attachment.autoOrientJPEG),
});
const toVersion2 = exports._withSchemaVersion({
schemaVersion: 2,
upgrade: exports._mapAttachments(Attachment.replaceUnicodeOrderOverrides),
});
const toVersion3 = exports._withSchemaVersion({
schemaVersion: 3,
upgrade: exports._mapAttachments(Attachment.migrateDataToFileSystem),
});
const toVersion4 = exports._withSchemaVersion({
schemaVersion: 4,
upgrade: exports._mapQuotedAttachments(Attachment.migrateDataToFileSystem),
});
const toVersion5 = exports._withSchemaVersion({
schemaVersion: 5,
upgrade: initializeAttachmentMetadata,
});
const toVersion6 = exports._withSchemaVersion({
schemaVersion: 6,
upgrade: exports._mapContact(
Contact.parseAndWriteAvatar(Attachment.migrateDataToFileSystem)
)
);
),
});
// IMPORTANT: Weve updated our definition of `initializeAttachmentMetadata`, so
// we need to run it again on existing items that have previously been incorrectly
// classified:
const toVersion7 = exports._withSchemaVersion(7, initializeAttachmentMetadata);
const toVersion7 = exports._withSchemaVersion({
schemaVersion: 7,
upgrade: initializeAttachmentMetadata,
});
const toVersion8 = exports._withSchemaVersion(
8,
exports._mapAttachments(Attachment.captureDimensionsAndScreenshot)
);
const toVersion8 = exports._withSchemaVersion({
schemaVersion: 8,
upgrade: exports._mapAttachments(Attachment.captureDimensionsAndScreenshot),
});
const VERSIONS = [
toVersion0,
@ -275,6 +295,7 @@ exports.upgradeSchema = async (
getImageDimensions,
makeImageThumbnail,
makeVideoScreenshot,
logger,
} = {}
) => {
if (!isFunction(writeNewAttachmentData)) {
@ -301,6 +322,9 @@ exports.upgradeSchema = async (
if (!isFunction(makeVideoScreenshot)) {
throw new TypeError('context.makeVideoScreenshot is required');
}
if (!isObject(logger)) {
throw new TypeError('context.logger is required');
}
let message = rawMessage;
// eslint-disable-next-line no-restricted-syntax
@ -317,6 +341,7 @@ exports.upgradeSchema = async (
getImageDimensions,
makeImageThumbnail,
makeVideoScreenshot,
logger,
});
}
@ -339,9 +364,17 @@ exports.createAttachmentLoader = loadAttachmentData => {
// createAttachmentDataWriter :: (RelativePath -> IO Unit)
// Message ->
// IO (Promise Message)
exports.createAttachmentDataWriter = writeExistingAttachmentData => {
exports.createAttachmentDataWriter = ({
writeExistingAttachmentData,
logger,
}) => {
if (!isFunction(writeExistingAttachmentData)) {
throw new TypeError("'writeExistingAttachmentData' must be a function");
throw new TypeError(
'createAttachmentDataWriter: writeExistingAttachmentData must be a function'
);
}
if (!isObject(logger)) {
throw new TypeError('createAttachmentDataWriter: logger must be an object');
}
return async rawMessage => {
@ -349,7 +382,10 @@ exports.createAttachmentDataWriter = writeExistingAttachmentData => {
throw new TypeError("'rawMessage' is not valid");
}
const message = exports.initializeSchemaVersion(rawMessage);
const message = exports.initializeSchemaVersion({
message: rawMessage,
logger,
});
const { attachments, quote, contact } = message;
const hasFilesToWrite =
@ -387,7 +423,7 @@ exports.createAttachmentDataWriter = writeExistingAttachmentData => {
// we want to be bulletproof to thumbnails without data
if (!data || !path) {
console.log(
logger.warn(
'Thumbnail had neither data nor path.',
'id:',
message.id,
@ -418,7 +454,7 @@ exports.createAttachmentDataWriter = writeExistingAttachmentData => {
const messageWithoutAttachmentData = Object.assign(
{},
await writeThumbnails(message),
await writeThumbnails(message, { logger }),
{
contact: await Promise.all((contact || []).map(writeContactAvatar)),
attachments: await Promise.all(

View file

@ -10,7 +10,7 @@ const {
exports.blobToArrayBuffer = blobToArrayBuffer;
exports.getImageDimensions = objectUrl =>
exports.getImageDimensions = ({ objectUrl, logger }) =>
new Promise((resolve, reject) => {
const image = document.createElement('img');
@ -21,14 +21,19 @@ exports.getImageDimensions = objectUrl =>
});
});
image.addEventListener('error', error => {
console.log('getImageDimensions error', toLogFormat(error));
logger.error('getImageDimensions error', toLogFormat(error));
reject(error);
});
image.src = objectUrl;
});
exports.makeImageThumbnail = (size, objectUrl, contentType = 'image/png') =>
exports.makeImageThumbnail = ({
size,
objectUrl,
contentType = 'image/png',
logger,
}) =>
new Promise((resolve, reject) => {
const image = document.createElement('img');
@ -61,14 +66,18 @@ exports.makeImageThumbnail = (size, objectUrl, contentType = 'image/png') =>
});
image.addEventListener('error', error => {
console.log('makeImageThumbnail error', toLogFormat(error));
logger.error('makeImageThumbnail error', toLogFormat(error));
reject(error);
});
image.src = objectUrl;
});
exports.makeVideoScreenshot = (objectUrl, contentType = 'image/png') =>
exports.makeVideoScreenshot = ({
objectUrl,
contentType = 'image/png',
logger,
}) =>
new Promise((resolve, reject) => {
const video = document.createElement('video');
@ -89,25 +98,33 @@ exports.makeVideoScreenshot = (objectUrl, contentType = 'image/png') =>
video.addEventListener('canplay', capture);
video.addEventListener('error', error => {
console.log('makeVideoThumbnail error', toLogFormat(error));
logger.error('makeVideoThumbnail error', toLogFormat(error));
reject(error);
});
video.src = objectUrl;
});
exports.makeVideoThumbnail = async (size, videoObjectUrl) => {
exports.makeVideoThumbnail = async ({ size, videoObjectUrl, logger }) => {
let screenshotObjectUrl;
try {
const type = 'image/png';
const blob = await exports.makeVideoScreenshot(videoObjectUrl, type);
const blob = await exports.makeVideoScreenshot({
objectUrl: videoObjectUrl,
contentType: type,
logger,
});
const data = await blobToArrayBuffer(blob);
screenshotObjectUrl = arrayBufferToObjectURL({
data,
type,
});
return exports.makeImageThumbnail(size, screenshotObjectUrl);
return exports.makeImageThumbnail({
size,
objectUrl: screenshotObjectUrl,
logger,
});
} finally {
exports.revokeObjectUrl(screenshotObjectUrl);
}

View file

@ -6,6 +6,7 @@ const is = require('@sindresorhus/is');
/* global Buffer: false */
/* global setTimeout: false */
/* global log: false */
/* eslint-disable more/no-then, no-bitwise, no-nested-ternary */
@ -159,7 +160,7 @@ function _createSocket(url, { certificateAuthority, proxyUrl }) {
function _promiseAjax(providedUrl, options) {
return new Promise((resolve, reject) => {
const url = providedUrl || `${options.host}/${options.path}`;
console.log(options.type, url);
log.info(options.type, url);
const timeout =
typeof options.timeout !== 'undefined' ? options.timeout : 10000;
@ -220,7 +221,7 @@ function _promiseAjax(providedUrl, options) {
if (options.responseType === 'json') {
if (options.validateResponse) {
if (!_validateResponse(result, options.validateResponse)) {
console.log(options.type, url, response.status, 'Error');
log.error(options.type, url, response.status, 'Error');
reject(
HTTPError(
'promiseAjax: invalid response',
@ -233,10 +234,10 @@ function _promiseAjax(providedUrl, options) {
}
}
if (response.status >= 0 && response.status < 400) {
console.log(options.type, url, response.status, 'Success');
log.info(options.type, url, response.status, 'Success');
resolve(result, response.status);
} else {
console.log(options.type, url, response.status, 'Error');
log.error(options.type, url, response.status, 'Error');
reject(
HTTPError(
'promiseAjax: error response',
@ -249,7 +250,7 @@ function _promiseAjax(providedUrl, options) {
});
})
.catch(e => {
console.log(options.type, url, 0, 'Error');
log.error(options.type, url, 0, 'Error');
const stack = `${e.stack}\nInitial stack:\n${options.stack}`;
reject(HTTPError('promiseAjax catch', 0, e.toString(), stack));
});
@ -650,7 +651,7 @@ function initialize({ url, cdnUrl, certificateAuthority, proxyUrl }) {
}
function getMessageSocket() {
console.log('opening message socket', url);
log.info('opening message socket', url);
const fixedScheme = url
.replace('https://', 'wss://')
.replace('http://', 'ws://');
@ -664,7 +665,7 @@ function initialize({ url, cdnUrl, certificateAuthority, proxyUrl }) {
}
function getProvisioningSocket() {
console.log('opening provisioning socket', url);
log.info('opening provisioning socket', url);
const fixedScheme = url
.replace('https://', 'wss://')
.replace('http://', 'ws://');

View file

@ -67,7 +67,7 @@
userSetting,
});
console.log(
window.log.info(
'Update notifications:',
Object.assign({}, status, {
isNotificationGroupingSupported,
@ -128,7 +128,7 @@
iconUrl = last.iconUrl;
break;
default:
console.log(
window.log.error(
`Error: Unknown user notification setting: '${userSetting}'`
);
break;
@ -161,11 +161,11 @@
return storage.get('notification-setting') || SettingNames.MESSAGE;
},
onRemove() {
console.log('Remove notification');
window.log.info('Remove notification');
this.update();
},
clear() {
console.log('Remove all notifications');
window.log.info('Remove all notifications');
this.reset([]);
this.update();
},

View file

@ -24,7 +24,7 @@
_.contains(ids, receipt.get('reader'))
);
if (receipts.length) {
console.log('Found early read receipts for message');
window.log.info('Found early read receipts for message');
this.remove(receipts);
}
return receipts;
@ -75,7 +75,7 @@
}, reject);
});
}
console.log(
window.log.info(
'No message for read receipt',
receipt.get('reader'),
receipt.get('timestamp')
@ -84,7 +84,7 @@
return null;
})
.catch(error => {
console.log(
window.log.error(
'ReadReceipts.onReceipt error:',
error && error.stack ? error.stack : error
);

View file

@ -14,7 +14,7 @@
timestamp: message.get('sent_at'),
});
if (receipt) {
console.log('Found early read sync for message');
window.log.info('Found early read sync for message');
this.remove(receipt);
return receipt;
}
@ -23,41 +23,49 @@
},
onReceipt(receipt) {
const messages = new Whisper.MessageCollection();
return messages.fetchSentAt(receipt.get('timestamp')).then(() => {
const message = messages.find(
item =>
item.isIncoming() &&
item.isUnread() &&
item.get('source') === receipt.get('sender')
);
const notificationForMessage = message
? Whisper.Notifications.findWhere({ messageId: message.id })
: null;
const removedNotification = Whisper.Notifications.remove(
notificationForMessage
);
const receiptSender = receipt.get('sender');
const receiptTimestamp = receipt.get('timestamp');
const wasMessageFound = Boolean(message);
const wasNotificationFound = Boolean(notificationForMessage);
const wasNotificationRemoved = Boolean(removedNotification);
console.log('Receive read sync:', {
receiptSender,
receiptTimestamp,
wasMessageFound,
wasNotificationFound,
wasNotificationRemoved,
return messages
.fetchSentAt(receipt.get('timestamp'))
.then(() => {
const message = messages.find(
item =>
item.isIncoming() &&
item.isUnread() &&
item.get('source') === receipt.get('sender')
);
const notificationForMessage = message
? Whisper.Notifications.findWhere({ messageId: message.id })
: null;
const removedNotification = Whisper.Notifications.remove(
notificationForMessage
);
const receiptSender = receipt.get('sender');
const receiptTimestamp = receipt.get('timestamp');
const wasMessageFound = Boolean(message);
const wasNotificationFound = Boolean(notificationForMessage);
const wasNotificationRemoved = Boolean(removedNotification);
window.log.info('Receive read sync:', {
receiptSender,
receiptTimestamp,
wasMessageFound,
wasNotificationFound,
wasNotificationRemoved,
});
return message
? message.markRead(receipt.get('read_at')).then(() => {
// This notification may result in messages older than this one being
// marked read. We want those messages to have the same expire timer
// start time as this one, so we pass the read_at value through.
this.notifyConversation(message, receipt.get('read_at'));
this.remove(receipt);
})
: Promise.resolve();
})
.catch(error => {
window.log.error(
'ReadSyncs.onReceipt error:',
error && error.stack ? error.stack : error
);
});
return message
? message.markRead(receipt.get('read_at')).then(() => {
// This notification may result in messages older than this one being
// marked read. We want those messages to have the same expire timer
// start time as this one, so we pass the read_at value through.
this.notifyConversation(message, receipt.get('read_at'));
this.remove(receipt);
})
: Promise.resolve();
});
},
notifyConversation(message, readAt) {
const conversation = ConversationController.get({

View file

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

View file

@ -16,11 +16,11 @@
}
function run() {
console.log('Rotating signed prekey...');
window.log.info('Rotating signed prekey...');
getAccountManager()
.rotateSignedPreKey()
.catch(() => {
console.log(
window.log.error(
'rotateSignedPrekey() failed. Trying again in five seconds'
);
setTimeout(runWhenOnline, 5000);
@ -33,7 +33,7 @@
if (navigator.onLine) {
run();
} else {
console.log(
window.log.info(
'We are offline; keys will be rotated when we are next online'
);
const listener = () => {
@ -49,7 +49,7 @@
const time = storage.get('nextSignedKeyRotationTime', now);
if (scheduledTime !== time || !timeout) {
console.log(
window.log.info(
'Next signed key rotation scheduled for',
new Date(time).toISOString()
);
@ -69,7 +69,7 @@
Whisper.RotateSignedPreKeyListener = {
init(events, newVersion) {
if (initComplete) {
console.log('Rotate signed prekey listener: Already initialized');
window.log.warn('Rotate signed prekey listener: Already initialized');
return;
}
initComplete = true;

View file

@ -212,14 +212,14 @@
return new Promise(resolve => {
prekey.fetch().then(
() => {
console.log('Successfully fetched prekey:', keyId);
window.log.info('Successfully fetched prekey:', keyId);
resolve({
pubKey: prekey.get('publicKey'),
privKey: prekey.get('privateKey'),
});
},
() => {
console.log('Failed to fetch prekey:', keyId);
window.log.error('Failed to fetch prekey:', keyId);
resolve();
}
);
@ -249,7 +249,7 @@
}
return deferred.then(resolve, error => {
console.log(
window.log.error(
'removePreKey error:',
error && error.stack ? error.stack : error
);
@ -271,7 +271,7 @@
prekey
.fetch()
.then(() => {
console.log(
window.log.info(
'Successfully fetched signed prekey:',
prekey.get('id')
);
@ -284,7 +284,7 @@
});
})
.fail(() => {
console.log('Failed to fetch signed prekey:', keyId);
window.log.error('Failed to fetch signed prekey:', keyId);
resolve();
});
});
@ -373,7 +373,7 @@
number,
})
.fail(e => {
console.log('Failed to save session', encodedNumber, e);
window.log.error('Failed to save session', encodedNumber, e);
})
.always(() => {
resolve();
@ -393,7 +393,7 @@
});
},
removeSession(encodedNumber) {
console.log('deleting session for ', encodedNumber);
window.log.info('deleting session for ', encodedNumber);
return new Promise(resolve => {
const session = new Session({ id: encodedNumber });
session
@ -436,7 +436,7 @@
address.getName(),
deviceId
);
console.log('closing session for', sibling.toString());
window.log.info('closing session for', sibling.toString());
const sessionCipher = new libsignal.SessionCipher(
textsecure.storage.protocol,
sibling
@ -454,7 +454,7 @@
number,
deviceId
);
console.log('closing session for', address.toString());
window.log.info('closing session for', address.toString());
const sessionCipher = new libsignal.SessionCipher(
textsecure.storage.protocol,
address
@ -500,19 +500,19 @@
const existing = identityRecord.get('publicKey');
if (!existing) {
console.log('isTrustedForSending: Nothing here, returning true...');
window.log.info('isTrustedForSending: Nothing here, returning true...');
return true;
}
if (!equalArrayBuffers(existing, publicKey)) {
console.log("isTrustedForSending: Identity keys don't match...");
window.log.info("isTrustedForSending: Identity keys don't match...");
return false;
}
if (identityRecord.get('verified') === VerifiedStatus.UNVERIFIED) {
console.log('Needs unverified approval!');
window.log.error('Needs unverified approval!');
return false;
}
if (this.isNonBlockingApprovalRequired(identityRecord)) {
console.log('isTrustedForSending: Needs non-blocking approval!');
window.log.error('isTrustedForSending: Needs non-blocking approval!');
return false;
}
@ -549,7 +549,7 @@
const oldpublicKey = identityRecord.get('publicKey');
if (!oldpublicKey) {
// Lookup failed, or the current key was removed, so save this one.
console.log('Saving new identity...');
window.log.info('Saving new identity...');
identityRecord
.save({
publicKey,
@ -562,7 +562,7 @@
resolve(false);
}, reject);
} else if (!equalArrayBuffers(oldpublicKey, publicKey)) {
console.log('Replacing existing identity...');
window.log.info('Replacing existing identity...');
const previousStatus = identityRecord.get('verified');
let verifiedStatus;
if (
@ -588,7 +588,7 @@
}, reject);
}, reject);
} else if (this.isNonBlockingApprovalRequired(identityRecord)) {
console.log('Setting approval status...');
window.log.info('Setting approval status...');
identityRecord
.save({
nonblockingApproval,
@ -680,7 +680,7 @@
reject(identityRecord.validationError);
}
} else {
console.log('No identity record for specified publicKey');
window.log.info('No identity record for specified publicKey');
resolve();
}
},
@ -821,7 +821,7 @@
})
.always(() => {
if (!isPresent && verifiedStatus === VerifiedStatus.DEFAULT) {
console.log('No existing record for default status');
window.log.info('No existing record for default status');
return resolve();
}

View file

@ -41,7 +41,7 @@ function setupLinux(locale) {
// to other dictionaries
const location = process.env.HUNSPELL_DICTIONARIES || '/usr/share/hunspell';
console.log(
window.log.info(
'Detected Linux. Setting up spell check with locale',
locale,
'and dictionary location',
@ -49,7 +49,9 @@ function setupLinux(locale) {
);
spellchecker.setDictionary(locale, location);
} else {
console.log('Detected Linux. Using default en_US spell check dictionary');
window.log.info(
'Detected Linux. Using default en_US spell check dictionary'
);
}
}
@ -57,7 +59,7 @@ function setupWin7AndEarlier(locale) {
if (process.env.HUNSPELL_DICTIONARIES || locale !== 'en_US') {
const location = process.env.HUNSPELL_DICTIONARIES;
console.log(
window.log.info(
'Detected Windows 7 or below. Setting up spell-check with locale',
locale,
'and dictionary location',
@ -65,7 +67,7 @@ function setupWin7AndEarlier(locale) {
);
spellchecker.setDictionary(locale, location);
} else {
console.log(
window.log.info(
'Detected Windows 7 or below. Using default en_US spell check dictionary'
);
}
@ -87,7 +89,10 @@ if (process.platform === 'linux') {
setupWin7AndEarlier(locale);
} else {
// OSX and Windows 8+ have OS-level spellcheck APIs
console.log('Using OS-level spell check API with locale', process.env.LANG);
window.log.info(
'Using OS-level spell check API with locale',
process.env.LANG
);
}
const simpleChecker = {

View file

@ -31,7 +31,10 @@
throw new Error('Tried to store undefined');
}
if (!ready) {
console.log('Called storage.put before storage is ready. key:', key);
window.log.warn(
'Called storage.put before storage is ready. key:',
key
);
}
const item = items.add({ id: key, value }, { merge: true });
return new Promise((resolve, reject) => {

View file

@ -129,7 +129,7 @@
// this.initialLoadComplete. An example of this: on a phone-pairing setup.
_.defaults(options, { initialLoadComplete: this.initialLoadComplete });
console.log('open inbox');
window.log.info('open inbox');
this.closeInstaller();
if (!this.inboxView) {

View file

@ -29,15 +29,17 @@
this.remove();
},
async onDeleteAllData() {
console.log('Deleting everything!');
window.log.info('Deleting everything!');
this.step = CLEAR_DATA_STEPS.DELETING;
this.render();
try {
await Database.close();
console.log('All database connections closed. Starting delete.');
window.log.info('All database connections closed. Starting delete.');
} catch (error) {
console.log('Something went wrong closing all database connections.');
window.log.error(
'Something went wrong closing all database connections.'
);
}
this.clearAllData();
@ -46,7 +48,7 @@
try {
await Promise.all([Logs.deleteAll(), Database.drop()]);
} catch (error) {
console.log(
window.log.error(
'Something went wrong deleting all data:',
error && error.stack ? error.stack : error
);

View file

@ -13,14 +13,14 @@
const $el = this.$(`.${conversation.cid}`);
if (!$el || !$el.length) {
console.log(
window.log.warn(
'updateLocation: did not find element for conversation',
conversation.idForLogging()
);
return;
}
if ($el.length > 1) {
console.log(
window.log.warn(
'updateLocation: found more than one element for conversation',
conversation.idForLogging()
);
@ -33,7 +33,7 @@
const elIndex = $allConversations.index($el);
if (elIndex < 0) {
console.log(
window.log.warn(
'updateLocation: did not find index for conversation',
conversation.idForLogging()
);

View file

@ -259,7 +259,7 @@
},
unload(reason) {
console.log(
window.log.info(
'unloading conversation',
this.model.idForLogging(),
'due to:',
@ -329,7 +329,7 @@
return;
}
console.log(
window.log.info(
'trimming conversation',
this.model.idForLogging(),
'of',
@ -482,7 +482,7 @@
const view = this.loadingScreen;
if (view) {
const openDelta = Date.now() - this.openStart;
console.log(
window.log.info(
'Conversation',
this.model.idForLogging(),
'took',
@ -507,7 +507,7 @@
this.model.updateVerified().then(() => {
this.onVerifiedChange();
this.statusFetch = null;
console.log('done with status fetch');
window.log.info('done with status fetch');
})
);
@ -786,10 +786,10 @@
},
fetchMessages() {
console.log('fetchMessages');
window.log.info('fetchMessages');
this.$('.bar-container').show();
if (this.inProgressFetch) {
console.log('Multiple fetchMessage calls!');
window.log.warn('Multiple fetchMessage calls!');
}
// Avoiding await, since we want to capture the promise and make it available via
@ -806,7 +806,7 @@
this.inProgressFetch = null;
})
.catch(error => {
console.log(
window.log.error(
'fetchMessages error:',
error && error.stack ? error.stack : error
);
@ -1195,7 +1195,7 @@
this.showSendConfirmationDialog(e, contacts);
} catch (error) {
this.focusMessageFieldAndClearDisabled();
console.log(
window.log.error(
'checkUnverifiedSendMessage error:',
error && error.stack ? error.stack : error
);
@ -1221,7 +1221,7 @@
this.showSendConfirmationDialog(e, contacts);
} catch (error) {
this.focusMessageFieldAndClearDisabled();
console.log(
window.log.error(
'checkUntrustedSendMessage error:',
error && error.stack ? error.stack : error
);
@ -1290,7 +1290,6 @@
if (message) {
const quote = await this.model.makeQuote(this.quotedMessage);
console.log('DEBUG', { quote });
this.quote = quote;
this.focusMessageFieldAndClearDisabled();
@ -1371,7 +1370,7 @@
const attachments = await this.fileInput.getFiles();
const sendDelta = Date.now() - this.sendStart;
console.log('Send pre-checks took', sendDelta, 'milliseconds');
window.log.info('Send pre-checks took', sendDelta, 'milliseconds');
this.model.sendMessage(message, attachments, this.quote);
@ -1381,7 +1380,7 @@
this.forceUpdateMessageFieldSize(e);
this.fileInput.deleteFiles();
} catch (error) {
console.log(
window.log.error(
'Error pulling attached files before send',
error && error.stack ? error.stack : error
);

View file

@ -67,7 +67,7 @@
.focus()
.select();
} catch (error) {
console.log(
window.log.error(
'DebugLogView error:',
error && error.stack ? error.stack : error
);

View file

@ -161,10 +161,11 @@
// we use the variable on this here to ensure cleanup if we're interrupted
this.previewObjectUrl = URL.createObjectURL(file);
const type = 'image/png';
const thumbnail = await VisualAttachment.makeVideoScreenshot(
this.previewObjectUrl,
type
);
const thumbnail = await VisualAttachment.makeVideoScreenshot({
objectUrl: this.previewObjectUrl,
contentType: type,
logger: window.log,
});
URL.revokeObjectURL(this.previewObjectUrl);
const data = await VisualAttachment.blobToArrayBuffer(thumbnail);
@ -197,7 +198,7 @@
this.addThumb('images/file.svg');
}
} catch (e) {
console.log(
window.log.error(
`Was unable to generate thumbnail for file type ${contentType}`,
e && e.stack ? e.stack : e
);
@ -297,10 +298,11 @@
const objectUrl = URL.createObjectURL(file);
const arrayBuffer = await VisualAttachment.makeImageThumbnail(
const arrayBuffer = await VisualAttachment.makeImageThumbnail({
size,
objectUrl
);
objectUrl,
logger: window.log,
});
URL.revokeObjectURL(objectUrl);
return this.readFile(arrayBuffer);

View file

@ -112,7 +112,7 @@
},
error => {
if (error.name !== 'ChooseError') {
console.log(
window.log.error(
'Error choosing directory:',
error && error.stack ? error.stack : error
);
@ -158,7 +158,7 @@
return this.finishLightImport(directory);
})
.catch(error => {
console.log(
window.log.error(
'Error importing:',
error && error.stack ? error.stack : error
);

View file

@ -193,7 +193,7 @@
this.onEmpty();
break;
default:
console.log(
window.log.error(
'Whisper.InboxView::startConnectionListener:',
'Unknown web socket status:',
status

View file

@ -104,19 +104,22 @@
)
.catch(this.handleDisconnect.bind(this));
},
handleDisconnect(e) {
console.log('provisioning failed', e.stack);
handleDisconnect(error) {
window.log.error(
'provisioning failed',
error && error.stack ? error.stack : error
);
this.error = e;
this.error = error;
this.render();
if (e.message === 'websocket closed') {
if (error.message === 'websocket closed') {
this.trigger('disconnected');
} else if (
e.name !== 'HTTPError' ||
(e.code !== CONNECTION_ERROR && e.code !== TOO_MANY_DEVICES)
error.name !== 'HTTPError' ||
(error.code !== CONNECTION_ERROR && error.code !== TOO_MANY_DEVICES)
) {
throw e;
throw error;
}
},
reconnect() {
@ -134,7 +137,7 @@
},
setProvisioningUrl(url) {
if ($('#qr').length === 0) {
console.log('Did not find #qr element in the DOM!');
window.log.error('Did not find #qr element in the DOM!');
return;
}
@ -186,7 +189,7 @@
}
return tsp.removeAllData().then(finish, error => {
console.log(
window.log.error(
'confirmNumber: error clearing database',
error && error.stack ? error.stack : error
);

View file

@ -81,7 +81,10 @@
if (result.name === 'OutgoingIdentityKeyError') {
this.onSafetyNumberChanged();
} else {
console.log('failed to toggle verified:', result.stack);
window.log.error(
'failed to toggle verified:',
result && result.stack ? result.stack : result
);
}
} else {
const keyError = _.some(
@ -92,7 +95,10 @@
this.onSafetyNumberChanged();
} else {
_.forEach(result.errors, error => {
console.log('failed to toggle verified:', error.stack);
window.log.error(
'failed to toggle verified:',
error && error.stack ? error.stack : error
);
});
}
}

View file

@ -51,7 +51,7 @@
if (this.context) {
this.context.close().then(() => {
console.log('audio context closed');
window.log.info('audio context closed');
});
}
this.context = null;
@ -97,10 +97,12 @@
this.close();
if (error && error.name === 'PermissionDeniedError') {
console.log('RecorderView.onError: Microphone access is not allowed!');
window.log.warn(
'RecorderView.onError: Microphone access is not allowed!'
);
window.showPermissionsPopup();
} else {
console.log(
window.log.error(
'RecorderView.onError:',
error && error.stack ? error.stack : error
);

View file

@ -23,7 +23,7 @@
change(e) {
const value = e.target.checked;
this.setFn(value);
console.log(this.name, 'changed to', value);
window.log.info(this.name, 'changed to', value);
},
populate() {
this.$('input').prop('checked', !!this.value);
@ -42,7 +42,7 @@
change(e) {
this.value = e.target.checked;
this.setFn(this.value);
console.log('media-permissions changed to', this.value);
window.log.info('media-permissions changed to', this.value);
},
populate() {
this.$('input').prop('checked', Boolean(this.value));
@ -62,7 +62,7 @@
change(e) {
const value = this.$(e.target).val();
this.setFn(value);
console.log(this.name, 'changed to', value);
window.log.info(this.name, 'changed to', value);
},
populate() {
this.$(`#${this.name}-${this.value}`).attr('checked', 'checked');
@ -177,12 +177,12 @@
onsuccess() {
window.setLastSyncTime(Date.now());
this.lastSyncTime = Date.now();
console.log('sync successful');
window.log.info('sync successful');
this.enable();
this.render();
},
ontimeout() {
console.log('sync timed out');
window.log.error('sync timed out');
this.$('.synced_at').hide();
this.$('.sync_failed').show();
this.enable();
@ -190,7 +190,7 @@
async sync() {
this.$('.sync_failed').hide();
if (window.initialData.isPrimary) {
console.log('Tried to sync from device 1');
window.log.warn('Tried to sync from device 1');
return;
}

View file

@ -46,7 +46,7 @@
.catch(this.log.bind(this));
},
log(s) {
console.log(s);
window.log.info(s);
this.$('#status').text(s);
},
validateCode() {