diff --git a/lib/hooks/login-hooks.js b/lib/hooks/login-hooks.js --- a/lib/hooks/login-hooks.js +++ b/lib/hooks/login-hooks.js @@ -15,6 +15,7 @@ import { authoritativeKeyserverID } from '../utils/authoritative-keyserver.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useSelector, useDispatch } from '../utils/redux-utils.js'; +import { waitUntilDatabaseDeleted } from '../utils/wait-until-db-deleted.js'; // We can't just do everything in one async callback, since the server calls // would get bound to Redux state from before the login. In order to pick up the @@ -135,6 +136,7 @@ resolve(); } catch (e) { void dispatchActionPromise(logOutActionTypes, identityLogOut()); + await waitUntilDatabaseDeleted(); reject(e); } finally { setCurrentStep(inactiveStep); diff --git a/lib/utils/wait-until-db-deleted.js b/lib/utils/wait-until-db-deleted.js new file mode 100644 --- /dev/null +++ b/lib/utils/wait-until-db-deleted.js @@ -0,0 +1,20 @@ +// @flow + +let waitingOnDatabaseDeletion = []; + +function waitUntilDatabaseDeleted(): Promise { + return new Promise(resolve => { + waitingOnDatabaseDeletion.push(resolve); + }); +} + +function reportDatabaseDeleted() { + const callbacksToTrigger = waitingOnDatabaseDeletion; + waitingOnDatabaseDeletion = []; + + for (const callback of callbacksToTrigger) { + callback(); + } +} + +export { waitUntilDatabaseDeleted, reportDatabaseDeleted }; diff --git a/native/account/registration/registration-server-call.js b/native/account/registration/registration-server-call.js --- a/native/account/registration/registration-server-call.js +++ b/native/account/registration/registration-server-call.js @@ -24,6 +24,7 @@ import { useDispatch } from 'lib/utils/redux-utils.js'; import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js'; import { setURLPrefix } from 'lib/utils/url-utils.js'; +import { waitUntilDatabaseDeleted } from 'lib/utils/wait-until-db-deleted.js'; import type { RegistrationServerCallInput, @@ -373,6 +374,7 @@ deleteAccountActionTypes, discardIdentityAccountPromise, ); + await waitUntilDatabaseDeleted(); reject(keyserverAuthException); setCurrentStep(inactiveStep); } finally { diff --git a/native/data/sqlite-data-handler.js b/native/data/sqlite-data-handler.js --- a/native/data/sqlite-data-handler.js +++ b/native/data/sqlite-data-handler.js @@ -28,6 +28,7 @@ import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; import { supportingMultipleKeyservers } from 'lib/utils/services-utils.js'; +import { reportDatabaseDeleted } from 'lib/utils/wait-until-db-deleted.js'; import { resolveKeyserverSessionInvalidationUsingNativeCredentials } from '../account/legacy-recover-keyserver-session.js'; import { authoritativeKeyserverID } from '../authoritative-keyserver.js'; @@ -42,6 +43,7 @@ async function clearSensitiveData() { try { await commCoreModule.clearSensitiveData(); + reportDatabaseDeleted(); } catch (error) { console.log( `Error clearing SQLite database: ${ diff --git a/web/shared-worker/sqlite-data-handler.js b/web/shared-worker/sqlite-data-handler.js --- a/web/shared-worker/sqlite-data-handler.js +++ b/web/shared-worker/sqlite-data-handler.js @@ -5,6 +5,7 @@ import { shouldClearData } from 'lib/shared/data-utils.js'; import { getMessageForException } from 'lib/utils/errors.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; +import { reportDatabaseDeleted } from 'lib/utils/wait-until-db-deleted.js'; import { getCommSharedWorker } from './shared-worker-provider.js'; import { useSelector } from '../redux/redux-utils.js'; @@ -43,6 +44,7 @@ ) { try { await sharedWorker.init({ clearDatabase: true }); + reportDatabaseDeleted(); } catch (error) { console.error( `Error clearing sensitive data: ${