Ensure that all messages in cache are migrated properly
This commit is contained in:
parent
9ff80469a5
commit
44dec45995
3 changed files with 34 additions and 15 deletions
|
@ -338,6 +338,7 @@
|
||||||
db,
|
db,
|
||||||
clearStores: Whisper.Database.clearStores,
|
clearStores: Whisper.Database.clearStores,
|
||||||
handleDOMException: Whisper.Database.handleDOMException,
|
handleDOMException: Whisper.Database.handleDOMException,
|
||||||
|
arrayBufferToString: textsecure.MessageReceiver.arrayBufferToString,
|
||||||
countCallback: count => {
|
countCallback: count => {
|
||||||
window.log.info(`Migration: ${count} messages complete`);
|
window.log.info(`Migration: ${count} messages complete`);
|
||||||
showMigrationStatus(count);
|
showMigrationStatus(count);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* global window, IDBKeyRange */
|
/* global window, IDBKeyRange */
|
||||||
|
|
||||||
const { includes, isFunction, isString, last } = require('lodash');
|
const { includes, isFunction, isString, last, forEach } = require('lodash');
|
||||||
const {
|
const {
|
||||||
saveMessages,
|
saveMessages,
|
||||||
_removeMessages,
|
_removeMessages,
|
||||||
|
@ -25,6 +25,7 @@ async function migrateToSQL({
|
||||||
clearStores,
|
clearStores,
|
||||||
handleDOMException,
|
handleDOMException,
|
||||||
countCallback,
|
countCallback,
|
||||||
|
arrayBufferToString,
|
||||||
}) {
|
}) {
|
||||||
if (!db) {
|
if (!db) {
|
||||||
throw new Error('Need db for IndexedDB connection!');
|
throw new Error('Need db for IndexedDB connection!');
|
||||||
|
@ -32,6 +33,9 @@ async function migrateToSQL({
|
||||||
if (!isFunction(clearStores)) {
|
if (!isFunction(clearStores)) {
|
||||||
throw new Error('Need clearStores function!');
|
throw new Error('Need clearStores function!');
|
||||||
}
|
}
|
||||||
|
if (!isFunction(arrayBufferToString)) {
|
||||||
|
throw new Error('Need arrayBufferToString function!');
|
||||||
|
}
|
||||||
if (!isFunction(handleDOMException)) {
|
if (!isFunction(handleDOMException)) {
|
||||||
throw new Error('Need handleDOMException function!');
|
throw new Error('Need handleDOMException function!');
|
||||||
}
|
}
|
||||||
|
@ -78,7 +82,21 @@ async function migrateToSQL({
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
const status = await migrateStoreToSQLite({
|
const status = await migrateStoreToSQLite({
|
||||||
db,
|
db,
|
||||||
save: saveUnprocesseds,
|
save: async array => {
|
||||||
|
forEach(array, item => {
|
||||||
|
// In the new database, we can't store ArrayBuffers, so we turn these two fields
|
||||||
|
// into strings like MessageReceiver now does before save.
|
||||||
|
if (item.envelope) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
item.envelope = arrayBufferToString(item.envelope);
|
||||||
|
}
|
||||||
|
if (item.decrypted) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
item.decrypted = arrayBufferToString(item.decrypted);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await saveUnprocesseds(array);
|
||||||
|
},
|
||||||
remove: removeUnprocessed,
|
remove: removeUnprocessed,
|
||||||
storeName: 'unprocessed',
|
storeName: 'unprocessed',
|
||||||
handleDOMException,
|
handleDOMException,
|
||||||
|
|
|
@ -31,6 +31,11 @@ function MessageReceiver(username, password, signalingKey, options = {}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageReceiver.stringToArrayBuffer = string =>
|
||||||
|
dcodeIO.ByteBuffer.wrap(string, 'binary').toArrayBuffer();
|
||||||
|
MessageReceiver.arrayBufferToString = arrayBuffer =>
|
||||||
|
dcodeIO.ByteBuffer.wrap(arrayBuffer).toString('binary');
|
||||||
|
|
||||||
MessageReceiver.prototype = new textsecure.EventTarget();
|
MessageReceiver.prototype = new textsecure.EventTarget();
|
||||||
MessageReceiver.prototype.extend({
|
MessageReceiver.prototype.extend({
|
||||||
constructor: MessageReceiver,
|
constructor: MessageReceiver,
|
||||||
|
@ -269,10 +274,10 @@ MessageReceiver.prototype.extend({
|
||||||
try {
|
try {
|
||||||
let envelopePlaintext = item.envelope;
|
let envelopePlaintext = item.envelope;
|
||||||
|
|
||||||
// Up until 0.42.6 we stored envelope and decrypted as strings in IndexedDB,
|
|
||||||
// so we need to be ready for them.
|
|
||||||
if (typeof envelopePlaintext === 'string') {
|
if (typeof envelopePlaintext === 'string') {
|
||||||
envelopePlaintext = this.stringToArrayBuffer(envelopePlaintext);
|
envelopePlaintext = MessageReceiver.stringToArrayBuffer(
|
||||||
|
envelopePlaintext
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const envelope = textsecure.protobuf.Envelope.decode(envelopePlaintext);
|
const envelope = textsecure.protobuf.Envelope.decode(envelopePlaintext);
|
||||||
|
|
||||||
|
@ -280,7 +285,9 @@ MessageReceiver.prototype.extend({
|
||||||
if (decrypted) {
|
if (decrypted) {
|
||||||
let payloadPlaintext = decrypted;
|
let payloadPlaintext = decrypted;
|
||||||
if (typeof payloadPlaintext === 'string') {
|
if (typeof payloadPlaintext === 'string') {
|
||||||
payloadPlaintext = this.stringToArrayBuffer(payloadPlaintext);
|
payloadPlaintext = MessageReceiver.stringToArrayBuffer(
|
||||||
|
payloadPlaintext
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.queueDecryptedEnvelope(envelope, payloadPlaintext);
|
this.queueDecryptedEnvelope(envelope, payloadPlaintext);
|
||||||
} else {
|
} else {
|
||||||
|
@ -312,13 +319,6 @@ MessageReceiver.prototype.extend({
|
||||||
envelope.sourceDevice
|
envelope.sourceDevice
|
||||||
} ${envelope.timestamp.toNumber()}`;
|
} ${envelope.timestamp.toNumber()}`;
|
||||||
},
|
},
|
||||||
stringToArrayBuffer(string) {
|
|
||||||
// eslint-disable-next-line new-cap
|
|
||||||
return dcodeIO.ByteBuffer.wrap(string, 'binary').toArrayBuffer();
|
|
||||||
},
|
|
||||||
arrayBufferToString(arrayBuffer) {
|
|
||||||
return dcodeIO.ByteBuffer.wrap(arrayBuffer).toString('binary');
|
|
||||||
},
|
|
||||||
getAllFromCache() {
|
getAllFromCache() {
|
||||||
window.log.info('getAllFromCache');
|
window.log.info('getAllFromCache');
|
||||||
return textsecure.storage.unprocessed.getAll().then(items => {
|
return textsecure.storage.unprocessed.getAll().then(items => {
|
||||||
|
@ -356,7 +356,7 @@ MessageReceiver.prototype.extend({
|
||||||
const id = this.getEnvelopeId(envelope);
|
const id = this.getEnvelopeId(envelope);
|
||||||
const data = {
|
const data = {
|
||||||
id,
|
id,
|
||||||
envelope: this.arrayBufferToString(plaintext),
|
envelope: MessageReceiver.arrayBufferToString(plaintext),
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
attempts: 1,
|
attempts: 1,
|
||||||
};
|
};
|
||||||
|
@ -365,7 +365,7 @@ MessageReceiver.prototype.extend({
|
||||||
updateCache(envelope, plaintext) {
|
updateCache(envelope, plaintext) {
|
||||||
const id = this.getEnvelopeId(envelope);
|
const id = this.getEnvelopeId(envelope);
|
||||||
const data = {
|
const data = {
|
||||||
decrypted: this.arrayBufferToString(plaintext),
|
decrypted: MessageReceiver.arrayBufferToString(plaintext),
|
||||||
};
|
};
|
||||||
return textsecure.storage.unprocessed.update(id, data);
|
return textsecure.storage.unprocessed.update(id, data);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue