diff --git a/ts/background.ts b/ts/background.ts index dd7ff439db02..51e3f6127ece 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -760,6 +760,11 @@ export async function startApp(): Promise { }); } + if (window.isBeforeVersion(lastVersion, 'v5.18.0')) { + await window.storage.remove('senderCertificate'); + await window.storage.remove('senderCertificateNoE164'); + } + // This one should always be last - it could restart the app if (window.isBeforeVersion(lastVersion, 'v1.15.0-beta.5')) { await deleteAllLogs(); @@ -3345,7 +3350,7 @@ export async function startApp(): Promise { ); try { - log.info('unlinkAndDisconnect: removing configuration'); + log.info(`unlinkAndDisconnect: removing configuration, mode ${mode}`); await window.textsecure.storage.protocol.removeAllConfiguration(mode); // This was already done in the database with removeAllConfiguration; this does it diff --git a/ts/services/senderCertificate.ts b/ts/services/senderCertificate.ts index c11b44ce6dff..a1dc1e96fd6c 100644 --- a/ts/services/senderCertificate.ts +++ b/ts/services/senderCertificate.ts @@ -75,6 +75,24 @@ export class SenderCertificateService { return this.fetchCertificate(mode); } + // This is intended to be called when our credentials have been deleted, so any fetches + // made until this function is complete would fail anyway. + async clear(): Promise { + log.info( + 'Sender certificate service: Clearing in-progress fetches and ' + + 'deleting cached certificates' + ); + await Promise.all(this.fetchPromises.values()); + + const { storage } = this; + assert( + storage, + 'Sender certificate service method was called before it was initialized' + ); + await storage.remove('senderCertificate'); + await storage.remove('senderCertificateNoE164'); + } + private getStoredCertificate( mode: SenderCertificateMode ): undefined | SerializedCertificateType { diff --git a/ts/test-electron/services/senderCertificate_test.ts b/ts/test-electron/services/senderCertificate_test.ts index 4c80fd6390f9..b3b809cde898 100644 --- a/ts/test-electron/services/senderCertificate_test.ts +++ b/ts/test-electron/services/senderCertificate_test.ts @@ -218,5 +218,32 @@ describe('SenderCertificateService', () => { assert.isUndefined(await service.get(SenderCertificateMode.WithE164)); }); + + it('clear waits for any outstanding requests then erases storage', async () => { + let count = 0; + + fakeServer = { + getSenderCertificate: sinon.spy(async () => { + await new Promise(resolve => setTimeout(resolve, 500)); + + count += 1; + return { + certificate: Bytes.toBase64(fakeValidEncodedCertificate), + }; + }), + }; + + const service = initializeTestService(); + + service.get(SenderCertificateMode.WithE164); + service.get(SenderCertificateMode.WithoutE164); + + await service.clear(); + + assert.equal(count, 2); + + assert.isUndefined(fakeStorage.get('senderCertificate')); + assert.isUndefined(fakeStorage.get('senderCertificateNoE164')); + }); }); }); diff --git a/ts/textsecure/AccountManager.ts b/ts/textsecure/AccountManager.ts index 65279fad89a2..f98311e97d3e 100644 --- a/ts/textsecure/AccountManager.ts +++ b/ts/textsecure/AccountManager.ts @@ -17,6 +17,8 @@ import ProvisioningCipher from './ProvisioningCipher'; import { IncomingWebSocketRequest } from './WebsocketResources'; import createTaskWithTimeout from './TaskWithTimeout'; import * as Bytes from '../Bytes'; +import { RemoveAllConfiguration } from '../types/RemoveAllConfiguration'; +import { senderCertificateService } from '../services/senderCertificate'; import { deriveAccessKey, generateRegistrationId, @@ -499,33 +501,32 @@ export default class AccountManager extends EventTarget { if (uuidChanged || numberChanged) { if (uuidChanged) { log.warn( - 'New uuid is different from old uuid; deleting all previous data' + 'createAccount: New uuid is different from old uuid; deleting all previous data' ); } if (numberChanged) { log.warn( - 'New number is different from old number; deleting all previous data' + 'createAccount: New number is different from old number; deleting all previous data' ); } try { await storage.protocol.removeAllData(); - log.info('Successfully deleted previous data'); + log.info('createAccount: Successfully deleted previous data'); } catch (error) { log.error( 'Something went wrong deleting data from previous number', error && error.stack ? error.stack : error ); } + } else { + log.info('createAccount: Erasing configuration (soft)'); + await storage.protocol.removeAllConfiguration( + RemoveAllConfiguration.Soft + ); } - await Promise.all([ - storage.user.removeCredentials(), - storage.remove('regionCode'), - storage.remove('userAgent'), - storage.remove('profileKey'), - storage.remove('read-receipt-setting'), - ]); + await senderCertificateService.clear(); if (previousUuid) { await Promise.all([