diff --git a/.eslintrc.js b/.eslintrc.js index 90a5a1897c3c..b4012931f069 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -188,6 +188,17 @@ const typescriptRules = { '@typescript-eslint/no-redeclare': 'error', '@typescript-eslint/no-shadow': 'error', '@typescript-eslint/no-useless-constructor': ['error'], + '@typescript-eslint/no-misused-promises': [ + 'error', + { + checksVoidReturn: false + } + ], + + '@typescript-eslint/no-floating-promises': 'error', + // We allow "void promise", but new call-sites should use `drop(promise)`. + 'no-void': ['error', { 'allowAsStatement': true }], + 'no-shadow': 'off', 'no-useless-constructor': 'off', diff --git a/app/attachment_channel.ts b/app/attachment_channel.ts index e83c17f1b46e..00f580be84d7 100644 --- a/app/attachment_channel.ts +++ b/app/attachment_channel.ts @@ -178,7 +178,7 @@ function deleteOrphanedAttachments({ } // Intentionally not awaiting - runSafe(); + void runSafe(); } export function initialize({ diff --git a/app/main.ts b/app/main.ts index 2e7738a64f48..76daf5af2a75 100644 --- a/app/main.ts +++ b/app/main.ts @@ -43,6 +43,7 @@ import { redactAll, addSensitivePath } from '../ts/util/privacy'; import { createSupportUrl } from '../ts/util/createSupportUrl'; import { missingCaseError } from '../ts/util/missingCaseError'; import { strictAssert } from '../ts/util/assert'; +import { drop } from '../ts/util/drop'; import { consoleLogger } from '../ts/util/consoleLogger'; import type { ThemeSettingType } from '../ts/types/StorageUIKeys'; import { ThemeType } from '../ts/types/Util'; @@ -483,10 +484,10 @@ function handleCommonWindowEvents( window.webContents.on('will-navigate', (event, rawTarget) => { event.preventDefault(); - handleUrl(rawTarget); + drop(handleUrl(rawTarget)); }); window.webContents.setWindowOpenHandler(({ url }) => { - handleUrl(url); + drop(handleUrl(url)); return { action: 'deny' }; }); window.webContents.on( @@ -526,9 +527,11 @@ function handleCommonWindowEvents( return; } - settingsChannel?.invokeCallbackInMainWindow('persistZoomFactor', [ - zoomFactor, - ]); + drop( + settingsChannel?.invokeCallbackInMainWindow('persistZoomFactor', [ + zoomFactor, + ]) + ); lastZoomFactor = zoomFactor; }; @@ -800,12 +803,6 @@ async function createWindow() { mainWindow.on('resize', captureWindowStats); mainWindow.on('move', captureWindowStats); - if (getEnvironment() === Environment.Test) { - mainWindow.loadURL(await prepareFileUrl([__dirname, '../test/index.html'])); - } else { - mainWindow.loadURL(await prepareFileUrl([__dirname, '../background.html'])); - } - if (!enableCI && config.get('openDevTools')) { // Open the DevTools. mainWindow.webContents.openDevTools(); @@ -932,6 +929,16 @@ async function createWindow() { mainWindow.show(); } }); + + if (getEnvironment() === Environment.Test) { + await mainWindow.loadURL( + await prepareFileUrl([__dirname, '../test/index.html']) + ); + } else { + await mainWindow.loadURL( + await prepareFileUrl([__dirname, '../background.html']) + ); + } } // Renderer asks if we are done with the database @@ -1056,12 +1063,14 @@ const TEN_MINUTES = 10 * 60 * 1000; setTimeout(readyForUpdates, TEN_MINUTES); function openContactUs() { - shell.openExternal(createSupportUrl({ locale: app.getLocale() })); + drop(shell.openExternal(createSupportUrl({ locale: app.getLocale() }))); } function openJoinTheBeta() { // If we omit the language, the site will detect the language and redirect - shell.openExternal('https://support.signal.org/hc/articles/360007318471'); + drop( + shell.openExternal('https://support.signal.org/hc/articles/360007318471') + ); } function openReleaseNotes() { @@ -1070,18 +1079,22 @@ function openReleaseNotes() { return; } - shell.openExternal( - `https://github.com/signalapp/Signal-Desktop/releases/tag/v${app.getVersion()}` + drop( + shell.openExternal( + `https://github.com/signalapp/Signal-Desktop/releases/tag/v${app.getVersion()}` + ) ); } function openSupportPage() { // If we omit the language, the site will detect the language and redirect - shell.openExternal('https://support.signal.org/hc/sections/360001602812'); + drop( + shell.openExternal('https://support.signal.org/hc/sections/360001602812') + ); } function openForums() { - shell.openExternal('https://community.signalusers.org/'); + drop(shell.openExternal('https://community.signalusers.org/')); } function showKeyboardShortcuts() { @@ -1143,10 +1156,6 @@ async function showScreenShareWindow(sourceName: string) { handleCommonWindowEvents(screenShareWindow); - screenShareWindow.loadURL( - await prepareFileUrl([__dirname, '../screenShare.html']) - ); - screenShareWindow.on('closed', () => { screenShareWindow = undefined; }); @@ -1160,6 +1169,10 @@ async function showScreenShareWindow(sourceName: string) { ); } }); + + await screenShareWindow.loadURL( + await prepareFileUrl([__dirname, '../screenShare.html']) + ); } let aboutWindow: BrowserWindow | undefined; @@ -1196,8 +1209,6 @@ async function showAbout() { handleCommonWindowEvents(aboutWindow, titleBarOverlay); - aboutWindow.loadURL(await prepareFileUrl([__dirname, '../about.html'])); - aboutWindow.on('closed', () => { aboutWindow = undefined; }); @@ -1207,6 +1218,8 @@ async function showAbout() { aboutWindow.show(); } }); + + await aboutWindow.loadURL(await prepareFileUrl([__dirname, '../about.html'])); } let settingsWindow: BrowserWindow | undefined; @@ -1244,8 +1257,6 @@ async function showSettingsWindow() { handleCommonWindowEvents(settingsWindow, titleBarOverlay); - settingsWindow.loadURL(await prepareFileUrl([__dirname, '../settings.html'])); - settingsWindow.on('closed', () => { settingsWindow = undefined; }); @@ -1258,6 +1269,10 @@ async function showSettingsWindow() { settingsWindow.show(); }); + + await settingsWindow.loadURL( + await prepareFileUrl([__dirname, '../settings.html']) + ); } async function getIsLinked() { @@ -1275,7 +1290,7 @@ async function showStickerCreator() { if (!(await getIsLinked())) { const message = getLocale().i18n('StickerCreator--Authentication--error'); - dialog.showMessageBox({ + await dialog.showMessageBox({ type: 'warning', message, }); @@ -1327,8 +1342,6 @@ async function showStickerCreator() { ) : prepareFileUrl([__dirname, '../sticker-creator/dist/index.html']); - stickerCreatorWindow.loadURL(await appUrl); - stickerCreatorWindow.on('closed', () => { stickerCreatorWindow = undefined; }); @@ -1345,6 +1358,8 @@ async function showStickerCreator() { stickerCreatorWindow.webContents.openDevTools(); } }); + + await stickerCreatorWindow.loadURL(await appUrl); } let debugLogWindow: BrowserWindow | undefined; @@ -1387,10 +1402,6 @@ async function showDebugLogWindow() { handleCommonWindowEvents(debugLogWindow, titleBarOverlay); - debugLogWindow.loadURL( - await prepareFileUrl([__dirname, '../debug_log.html']) - ); - debugLogWindow.on('closed', () => { debugLogWindow = undefined; }); @@ -1403,6 +1414,10 @@ async function showDebugLogWindow() { debugLogWindow.center(); } }); + + await debugLogWindow.loadURL( + await prepareFileUrl([__dirname, '../debug_log.html']) + ); } let permissionsPopupWindow: BrowserWindow | undefined; @@ -1446,13 +1461,6 @@ function showPermissionsPopupWindow(forCalling: boolean, forCamera: boolean) { handleCommonWindowEvents(permissionsPopupWindow); - permissionsPopupWindow.loadURL( - await prepareFileUrl([__dirname, '../permissions_popup.html'], { - forCalling, - forCamera, - }) - ); - permissionsPopupWindow.on('closed', () => { removeDarkOverlay(); permissionsPopupWindow = undefined; @@ -1466,6 +1474,13 @@ function showPermissionsPopupWindow(forCalling: boolean, forCamera: boolean) { permissionsPopupWindow.show(); } }); + + await permissionsPopupWindow.loadURL( + await prepareFileUrl([__dirname, '../permissions_popup.html'], { + forCalling, + forCamera, + }) + ); }); } @@ -1529,7 +1544,7 @@ async function initializeSQL( } // Only if we've initialized things successfully do we set up the corruption handler - runSQLCorruptionHandler(); + drop(runSQLCorruptionHandler()); return { ok: true, error: undefined }; } @@ -1539,7 +1554,7 @@ const onDatabaseError = async (error: string) => { ready = false; if (mainWindow) { - settingsChannel?.invokeCallbackInMainWindow('closeDB', []); + drop(settingsChannel?.invokeCallbackInMainWindow('closeDB', [])); mainWindow.close(); } mainWindow = undefined; @@ -1577,7 +1592,7 @@ let sqlInitPromise: | undefined; ipc.on('database-error', (_event: Electron.Event, error: string) => { - onDatabaseError(error); + drop(onDatabaseError(error)); }); function getAppLocale(): string { @@ -1754,46 +1769,50 @@ app.on('ready', async () => { // lookup should be done only in ephemeral config. const backgroundColor = await getBackgroundColor({ ephemeralOnly: true }); - // eslint-disable-next-line more/no-then - Promise.race([sqlInitPromise, timeout]).then(async maybeTimeout => { - if (maybeTimeout !== 'timeout') { - return; - } - - getLogger().info( - 'sql.initialize is taking more than three seconds; showing loading dialog' - ); - - loadingWindow = new BrowserWindow({ - show: false, - width: 300, - height: 265, - resizable: false, - frame: false, - backgroundColor, - webPreferences: { - ...defaultWebPrefs, - nodeIntegration: false, - sandbox: false, - contextIsolation: true, - preload: join(__dirname, '../ts/windows/loading/preload.js'), - }, - icon: windowIcon, - }); - - loadingWindow.once('ready-to-show', async () => { - if (!loadingWindow) { + drop( + // eslint-disable-next-line more/no-then + Promise.race([sqlInitPromise, timeout]).then(async maybeTimeout => { + if (maybeTimeout !== 'timeout') { return; } - loadingWindow.show(); - // Wait for sql initialization to complete, but ignore errors - await sqlInitPromise; - loadingWindow.destroy(); - loadingWindow = undefined; - }); - loadingWindow.loadURL(await prepareFileUrl([__dirname, '../loading.html'])); - }); + getLogger().info( + 'sql.initialize is taking more than three seconds; showing loading dialog' + ); + + loadingWindow = new BrowserWindow({ + show: false, + width: 300, + height: 265, + resizable: false, + frame: false, + backgroundColor, + webPreferences: { + ...defaultWebPrefs, + nodeIntegration: false, + sandbox: false, + contextIsolation: true, + preload: join(__dirname, '../ts/windows/loading/preload.js'), + }, + icon: windowIcon, + }); + + loadingWindow.once('ready-to-show', async () => { + if (!loadingWindow) { + return; + } + loadingWindow.show(); + // Wait for sql initialization to complete, but ignore errors + await sqlInitPromise; + loadingWindow.destroy(); + loadingWindow = undefined; + }); + + await loadingWindow.loadURL( + await prepareFileUrl([__dirname, '../loading.html']) + ); + }) + ); try { await attachments.clearTempPath(userDataPath); @@ -1858,7 +1877,7 @@ app.on('ready', async () => { shouldMinimizeToSystemTray(await systemTraySettingCache.get()) ); - ensureFilePermissions([ + await ensureFilePermissions([ 'config.json', 'sql/db.sqlite', 'sql/db.sqlite-wal', @@ -1996,7 +2015,7 @@ app.on('activate', () => { if (mainWindow) { mainWindow.show(); } else { - createWindow(); + drop(createWindow()); } }); @@ -2122,7 +2141,7 @@ ipc.on('stop-screen-share', () => { }); ipc.on('show-screen-share', (_event: Electron.Event, sourceName: string) => { - showScreenShareWindow(sourceName); + drop(showScreenShareWindow(sourceName)); }); ipc.on('update-tray-icon', (_event: Electron.Event, unreadCount: number) => { @@ -2311,18 +2330,20 @@ async function ensureFilePermissions(onlyFiles?: Array) { // Touch each file in a queue const q = new PQueue({ concurrency: 5, timeout: 1000 * 60 * 2 }); - q.addAll( - files.map(f => async () => { - const isDir = f.endsWith('/'); - try { - await chmod(normalize(f), isDir ? 0o700 : 0o600); - } catch (error) { - getLogger().error( - 'ensureFilePermissions: Error from chmod', - error.message - ); - } - }) + drop( + q.addAll( + files.map(f => async () => { + const isDir = f.endsWith('/'); + try { + await chmod(normalize(f), isDir ? 0o700 : 0o600); + } catch (error) { + getLogger().error( + 'ensureFilePermissions: Error from chmod', + error.message + ); + } + }) + ) ); await q.onEmpty(); @@ -2345,7 +2366,7 @@ ipc.handle('set-auto-launch', async (_event, value) => { }); ipc.on('show-message-box', (_event, { type, message }) => { - dialog.showMessageBox({ type, message }); + drop(dialog.showMessageBox({ type, message })); }); ipc.on('show-item-in-folder', (_event, folder) => { @@ -2458,7 +2479,7 @@ ipc.handle('getMenuOptions', async () => { ipc.handle('executeMenuAction', async (_event, action: MenuActionType) => { if (action === 'forceUpdate') { - forceUpdate(); + drop(forceUpdate()); } else if (action === 'openContactUs') { openContactUs(); } else if (action === 'openForums') { @@ -2474,15 +2495,15 @@ ipc.handle('executeMenuAction', async (_event, action: MenuActionType) => { } else if (action === 'setupAsStandalone') { setupAsStandalone(); } else if (action === 'showAbout') { - showAbout(); + drop(showAbout()); } else if (action === 'showDebugLog') { - showDebugLogWindow(); + drop(showDebugLogWindow()); } else if (action === 'showKeyboardShortcuts') { showKeyboardShortcuts(); } else if (action === 'showSettings') { - showSettingsWindow(); + drop(showSettingsWindow()); } else if (action === 'showStickerCreator') { - showStickerCreator(); + drop(showStickerCreator()); } else if (action === 'showWindow') { showWindow(); } else { diff --git a/package.json b/package.json index 3bb5ef63ab31..5a983c2b03dc 100644 --- a/package.json +++ b/package.json @@ -251,8 +251,8 @@ "@types/webpack-dev-server": "3.11.3", "@types/websocket": "1.0.0", "@types/yargs": "17.0.7", - "@typescript-eslint/eslint-plugin": "5.43.0", - "@typescript-eslint/parser": "5.43.0", + "@typescript-eslint/eslint-plugin": "5.47.0", + "@typescript-eslint/parser": "5.47.0", "arraybuffer-loader": "1.0.3", "asar": "3.1.0", "axe-core": "4.1.4", @@ -274,7 +274,7 @@ "electron-notarize": "1.2.1", "endanger": "7.0.4", "esbuild": "0.15.8", - "eslint": "8.27.0", + "eslint": "8.30.0", "eslint-config-airbnb-typescript-prettier": "5.0.0", "eslint-config-prettier": "8.5.0", "eslint-plugin-import": "2.26.0", diff --git a/sticker-creator/app/stages/UploadStage.tsx b/sticker-creator/app/stages/UploadStage.tsx index b4a5824bc95a..e4e85fe85767 100644 --- a/sticker-creator/app/stages/UploadStage.tsx +++ b/sticker-creator/app/stages/UploadStage.tsx @@ -29,7 +29,7 @@ export function UploadStage(): JSX.Element { const [complete, setComplete] = React.useState(0); React.useEffect(() => { - (async () => { + void (async () => { const onProgress = () => { setComplete(i => i + 1); }; diff --git a/sticker-creator/components/StickerGrid.tsx b/sticker-creator/components/StickerGrid.tsx index ddb9435e66ac..8a9f5535a2bb 100644 --- a/sticker-creator/components/StickerGrid.tsx +++ b/sticker-creator/components/StickerGrid.tsx @@ -14,6 +14,7 @@ import { DropZone } from '../elements/DropZone'; import { processStickerImage } from '../util/preload'; import { useI18n } from '../util/i18n'; import { MINUTE } from '../../ts/util/durations'; +import { drop } from '../../ts/util/drop'; import * as Errors from '../../ts/types/errors'; const queue = new PQueue({ concurrency: 3, timeout: MINUTE * 30 }); @@ -58,26 +59,28 @@ const InnerGrid = SortableContainer( async paths => { actions.initializeStickers(paths); paths.forEach(path => { - queue.add(async () => { - try { - const stickerImage = await processStickerImage(path); - actions.addImageData(stickerImage); - } catch (e) { - window.SignalContext.log.error( - 'Error processing image:', - Errors.toLogFormat(e) - ); - actions.removeSticker(path); + drop( + queue.add(async () => { + try { + const stickerImage = await processStickerImage(path); + actions.addImageData(stickerImage); + } catch (e) { + window.SignalContext.log.error( + 'Error processing image:', + Errors.toLogFormat(e) + ); + actions.removeSticker(path); - const key = - e instanceof window.ProcessStickerImageError - ? e.errorMessageI18nKey - : 'StickerCreator--Toasts--errorProcessing'; - actions.addToast({ - key, - }); - } - }); + const key = + e instanceof window.ProcessStickerImageError + ? e.errorMessageI18nKey + : 'StickerCreator--Toasts--errorProcessing'; + actions.addToast({ + key, + }); + } + }) + ); }); }, [actions] diff --git a/ts/ConversationController.ts b/ts/ConversationController.ts index bb34d5205b64..41446ea1128d 100644 --- a/ts/ConversationController.ts +++ b/ts/ConversationController.ts @@ -20,6 +20,7 @@ import * as Errors from './types/errors'; import { getContactId } from './messages/helpers'; import { maybeDeriveGroupV2Id } from './groups'; import { assertDev, strictAssert } from './util/assert'; +import { drop } from './util/drop'; import { isGroupV1, isGroupV2 } from './util/whatTypeOfConversation'; import { getConversationUnreadCountForAppBadge } from './util/getConversationUnreadCountForAppBadge'; import { UUID, isValidUuid, UUIDKind } from './types/UUID'; @@ -193,7 +194,7 @@ export class ConversationController { ), 0 ); - window.storage.put('unreadCount', newUnreadCount); + drop(window.storage.put('unreadCount', newUnreadCount)); if (newUnreadCount > 0) { window.setBadgeCount(newUnreadCount); @@ -1119,13 +1120,13 @@ export class ConversationController { this._conversations.resetLookups(); current.captureChange('combineConversations'); - current.updateLastMessage(); + void current.updateLastMessage(); const titleIsUseful = Boolean( obsoleteTitleInfo && getTitleNoDefault(obsoleteTitleInfo) ); if (!fromPniSignature && obsoleteTitleInfo && titleIsUseful) { - current.addConversationMerge(obsoleteTitleInfo); + void current.addConversationMerge(obsoleteTitleInfo); } log.warn(`${logId}: Complete!`); @@ -1305,10 +1306,12 @@ export class ConversationController { timeout: MINUTE * 30, throwOnTimeout: true, }); - queue.addAll( - temporaryConversations.map(item => async () => { - await removeConversation(item.id); - }) + drop( + queue.addAll( + temporaryConversations.map(item => async () => { + await removeConversation(item.id); + }) + ) ); await queue.onIdle(); diff --git a/ts/RemoteConfig.ts b/ts/RemoteConfig.ts index 0b173836eba0..60e82eddb3b5 100644 --- a/ts/RemoteConfig.ts +++ b/ts/RemoteConfig.ts @@ -122,7 +122,7 @@ export const refreshRemoteConfig = async ( }; }, {}); - window.storage.put('remoteConfig', config); + await window.storage.put('remoteConfig', config); }; export const maybeRefreshRemoteConfig = throttle( diff --git a/ts/SignalProtocolStore.ts b/ts/SignalProtocolStore.ts index 231abe315f5a..eab446b13d60 100644 --- a/ts/SignalProtocolStore.ts +++ b/ts/SignalProtocolStore.ts @@ -1419,7 +1419,7 @@ export class SignalProtocolStore extends EventEmitter { } sessionResets[id] = Date.now(); - window.storage.put('sessionResets', sessionResets); + await window.storage.put('sessionResets', sessionResets); try { const { uuid } = qualifiedAddress; @@ -1446,7 +1446,7 @@ export class SignalProtocolStore extends EventEmitter { // If we failed to do the session reset, then we'll allow another attempt sooner // than one hour from now. delete sessionResets[id]; - window.storage.put('sessionResets', sessionResets); + await window.storage.put('sessionResets', sessionResets); log.error( `lightSessionReset/${id}: Encountered error`, diff --git a/ts/background.ts b/ts/background.ts index 735ad0adc43a..1446710cf50b 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -34,6 +34,7 @@ import { DEFAULT_CONVERSATION_COLOR } from './types/Colors'; import { ThemeType } from './types/Util'; import { ChallengeHandler } from './challenge'; import * as durations from './util/durations'; +import { drop } from './util/drop'; import { explodePromise } from './util/explodePromise'; import { isWindowDragElement } from './util/isWindowDragElement'; import { assertDev, strictAssert } from './util/assert'; @@ -299,19 +300,22 @@ export async function startApp(): Promise { track = true ): (event: E) => void { return (event: E): void => { - eventHandlerQueue.add( - createTaskWithTimeout(async () => { - try { - await handler(event); - } finally { - // message/sent: Message.handleDataMessage has its own queue and will - // trigger this event itself when complete. - // error: Error processing (below) also has its own queue and self-trigger. - if (track) { - window.Whisper.events.trigger('incrementProgress'); + drop( + eventHandlerQueue.add( + createTaskWithTimeout(async () => { + try { + await handler(event); + } finally { + // message/sent: Message.handleDataMessage has its own queue and will + // trigger this event itself when complete. + // error: Error processing (below) also has its own queue and + // self-trigger. + if (track) { + window.Whisper.events.trigger('incrementProgress'); + } } - } - }, `queuedEventListener(${event.type}, ${event.timeStamp})`) + }, `queuedEventListener(${event.type}, ${event.timeStamp})`) + ) ); }; } @@ -367,13 +371,13 @@ export async function startApp(): Promise { messageReceiver.addEventListener( 'decryption-error', queuedEventListener((event: DecryptionErrorEvent): void => { - onDecryptionErrorQueue.add(() => onDecryptionError(event)); + drop(onDecryptionErrorQueue.add(() => onDecryptionError(event))); }) ); messageReceiver.addEventListener( 'retry-request', queuedEventListener((event: RetryRequestEvent): void => { - onRetryRequestQueue.add(() => onRetryRequest(event)); + drop(onRetryRequestQueue.add(() => onRetryRequest(event))); }) ); messageReceiver.addEventListener('empty', queuedEventListener(onEmpty)); @@ -413,9 +417,11 @@ export async function startApp(): Promise { window.storage.onready(() => { if (!window.storage.get('defaultConversationColor')) { - window.storage.put( - 'defaultConversationColor', - DEFAULT_CONVERSATION_COLOR + drop( + window.storage.put( + 'defaultConversationColor', + DEFAULT_CONVERSATION_COLOR + ) ); } }); @@ -549,7 +555,7 @@ export async function startApp(): Promise { KeyChangeListener.init(window.textsecure.storage.protocol); window.textsecure.storage.protocol.on('removePreKey', (ourUuid: UUID) => { const uuidKind = window.textsecure.storage.user.getOurUuidKind(ourUuid); - window.getAccountManager().refreshPreKeys(uuidKind); + void window.getAccountManager().refreshPreKeys(uuidKind); }); window.textsecure.storage.protocol.on('removeAllData', () => { @@ -575,7 +581,7 @@ export async function startApp(): Promise { accountManager.addEventListener('registration', () => { window.Whisper.events.trigger('userChanged', false); - window.Signal.Util.Registration.markDone(); + drop(window.Signal.Util.Registration.markDone()); log.info('dispatching registration event'); window.Whisper.events.trigger('registration_done'); }); @@ -643,7 +649,7 @@ export async function startApp(): Promise { } log.info('Storage fetch'); - window.storage.fetch(); + drop(window.storage.fetch()); function mapOldThemeToNew( theme: Readonly< @@ -675,7 +681,7 @@ export async function startApp(): Promise { strictAssert(server !== undefined, 'WebAPI not ready'); - cleanupSessionResets(); + void cleanupSessionResets(); // These make key operations available to IPC handlers created in preload.js window.Events = createIPCEvents({ @@ -685,7 +691,7 @@ export async function startApp(): Promise { window.Signal.Util.flushMessageCounter(); // Stop background processing - AttachmentDownloads.stop(); + void AttachmentDownloads.stop(); idleDetector.stop(); // Stop processing incoming messages @@ -750,7 +756,7 @@ export async function startApp(): Promise { } // Start heartbeat timer - window.storage.put('lastHeartbeat', toDayMillis(Date.now())); + await window.storage.put('lastHeartbeat', toDayMillis(Date.now())); const TWELVE_HOURS = 12 * 60 * 60 * 1000; setInterval( () => window.storage.put('lastHeartbeat', toDayMillis(Date.now())), @@ -772,7 +778,7 @@ export async function startApp(): Promise { log.info( `Clearing remoteBuildExpiration. Previous value was ${remoteBuildExpiration}` ); - window.storage.remove('remoteBuildExpiration'); + await window.storage.remove('remoteBuildExpiration'); } if (window.isBeforeVersion(lastVersion, 'v1.29.2-beta.1')) { @@ -795,9 +801,9 @@ export async function startApp(): Promise { const newThemeSetting = mapOldThemeToNew(themeSetting); if (window.isBeforeVersion(lastVersion, 'v1.25.0')) { if (newThemeSetting === window.systemTheme) { - window.Events.setThemeSetting('system'); + void window.Events.setThemeSetting('system'); } else { - window.Events.setThemeSetting(newThemeSetting); + void window.Events.setThemeSetting(newThemeSetting); } } @@ -855,7 +861,7 @@ export async function startApp(): Promise { await window.Signal.Data.cleanupOrphanedAttachments(); // Don't block on the following operation - window.Signal.Data.ensureFilePermissions(); + void window.Signal.Data.ensureFilePermissions(); } try { @@ -919,7 +925,7 @@ export async function startApp(): Promise { } }); - window.Signal.RemoteConfig.initRemoteConfig(server); + void window.Signal.RemoteConfig.initRemoteConfig(server); let retryReceiptLifespan: number | undefined; try { @@ -980,13 +986,15 @@ export async function startApp(): Promise { const receivedAt = Date.now(); const receivedAtCounter = window.Signal.Util.incrementMessageCounter(); - conversation.queueJob('addDeliveryIssue', () => - conversation.addDeliveryIssue({ - receivedAt, - receivedAtCounter, - senderUuid, - sentAt, - }) + drop( + conversation.queueJob('addDeliveryIssue', () => + conversation.addDeliveryIssue({ + receivedAt, + receivedAtCounter, + senderUuid, + sentAt, + }) + ) ); } }); @@ -1044,7 +1052,7 @@ export async function startApp(): Promise { ); } finally { initializeRedux({ mainWindowStats, menuOptions }); - start(); + void start(); window.Signal.Services.initializeNetworkObserver( window.reduxActions.network ); @@ -1743,7 +1751,7 @@ export async function startApp(): Promise { shiftKey && (key === 'p' || key === 'P') ) { - clearConversationDraftAttachments( + void clearConversationDraftAttachments( conversation.id, conversation.get('draftAttachments') ); @@ -1799,7 +1807,7 @@ export async function startApp(): Promise { ); window.Whisper.events.on('unlinkAndDisconnect', () => { - unlinkAndDisconnect(RemoveAllConfiguration.Full); + void unlinkAndDisconnect(RemoveAllConfiguration.Full); }); async function runStorageService() { @@ -1834,7 +1842,7 @@ export async function startApp(): Promise { const ourE164 = ourConversation?.get('e164'); if (ourE164) { log.warn('Restoring E164 from our conversation'); - window.storage.user.setNumber(ourE164); + await window.storage.user.setNumber(ourE164); } } @@ -1846,7 +1854,7 @@ export async function startApp(): Promise { window.dispatchEvent(new Event('storage_ready')); - badgeImageFileDownloader.checkForFilesToDownload(); + void badgeImageFileDownloader.checkForFilesToDownload(); log.info('Expiration start timestamp cleanup: starting...'); const messagesUnexpectedlyMissingExpirationStartTimestamp = @@ -1895,15 +1903,15 @@ export async function startApp(): Promise { log.info('handling registration event'); strictAssert(server !== undefined, 'WebAPI not ready'); - server.authenticate( + void server.authenticate( window.textsecure.storage.user.getWebAPICredentials() ); // Cancel throttled calls to refreshRemoteConfig since our auth changed. window.Signal.RemoteConfig.maybeRefreshRemoteConfig.cancel(); - window.Signal.RemoteConfig.maybeRefreshRemoteConfig(server); + void window.Signal.RemoteConfig.maybeRefreshRemoteConfig(server); - connect(true); + void connect(true); }); cancelInitializationMessage(); @@ -1919,11 +1927,11 @@ export async function startApp(): Promise { window.Whisper.events.trigger('timetravel'); }); - expiringMessagesDeletionService.update(); - tapToViewMessagesDeletionService.update(); + void expiringMessagesDeletionService.update(); + void tapToViewMessagesDeletionService.update(); window.Whisper.events.on('timetravel', () => { - expiringMessagesDeletionService.update(); - tapToViewMessagesDeletionService.update(); + void expiringMessagesDeletionService.update(); + void tapToViewMessagesDeletionService.update(); }); const isCoreDataValid = Boolean( @@ -1932,7 +1940,7 @@ export async function startApp(): Promise { ); if (isCoreDataValid && window.Signal.Util.Registration.everDone()) { - connect(); + void connect(); window.reduxActions.app.openInbox(); } else { window.reduxActions.app.openInstaller(); @@ -1988,9 +1996,11 @@ export async function startApp(): Promise { const remoteBuildExpirationTimestamp = window.Signal.Util.parseRemoteClientExpiration(value as string); if (remoteBuildExpirationTimestamp) { - window.storage.put( - 'remoteBuildExpiration', - remoteBuildExpirationTimestamp + drop( + window.storage.put( + 'remoteBuildExpiration', + remoteBuildExpirationTimestamp + ) ); window.reduxActions.expiration.hydrateExpirationStatus( window.Signal.Util.hasExpired() @@ -2051,7 +2061,7 @@ export async function startApp(): Promise { disconnectTimer = Timers.setTimeout(disconnect, 1000); if (challengeHandler) { - challengeHandler.onOffline(); + void challengeHandler.onOffline(); } } @@ -2072,7 +2082,7 @@ export async function startApp(): Promise { disconnectTimer = undefined; } - connect(); + void connect(); } function isSocketOnline() { @@ -2089,7 +2099,7 @@ export async function startApp(): Promise { // Clear timer, since we're only called when the timer is expired disconnectTimer = undefined; - AttachmentDownloads.stop(); + void AttachmentDownloads.stop(); if (server !== undefined) { strictAssert( messageReceiver !== undefined, @@ -2132,7 +2142,7 @@ export async function startApp(): Promise { 'Starting up offline; will connect when we have network access' ); window.addEventListener('online', onOnline); - onEmpty(); // this ensures that the loading screen is dismissed + void onEmpty(); // this ensures that the loading screen is dismissed // Switch to inbox view even if contact sync is still running if ( @@ -2173,7 +2183,7 @@ export async function startApp(): Promise { expiration as string ); if (remoteBuildExpirationTimestamp) { - window.storage.put( + await window.storage.put( 'remoteBuildExpiration', remoteBuildExpirationTimestamp ); @@ -2224,7 +2234,7 @@ export async function startApp(): Promise { window.Whisper.deliveryReceiptQueue.pause(); notificationService.disable(); - window.Signal.Services.initializeGroupCredentialFetcher(); + void window.Signal.Services.initializeGroupCredentialFetcher(); strictAssert(server !== undefined, 'WebAPI not initialized'); strictAssert( @@ -2237,14 +2247,14 @@ export async function startApp(): Promise { // If coming here after `offline` event - connect again. await server.onOnline(); - AttachmentDownloads.start({ + void AttachmentDownloads.start({ logger: log, }); if (connectCount === 1) { Stickers.downloadQueuedPacks(); if (!newVersion) { - runStorageService(); + void runStorageService(); } } @@ -2259,8 +2269,8 @@ export async function startApp(): Promise { log.info('Boot after upgrading. Requesting contact sync'); window.getSyncRequest(); - StorageService.reprocessUnknownFields(); - runStorageService(); + void StorageService.reprocessUnknownFields(); + void runStorageService(); try { const manager = window.getAccountManager(); @@ -2280,7 +2290,7 @@ export async function startApp(): Promise { if (!window.storage.get(udSupportKey)) { try { await server.registerSupportForUnauthenticatedDelivery(); - window.storage.put(udSupportKey, true); + await window.storage.put(udSupportKey, true); } catch (error) { log.error( 'Error: Unable to register for unauthenticated delivery support.', @@ -2331,7 +2341,7 @@ export async function startApp(): Promise { !hasThemeSetting && window.textsecure.storage.get('userAgent') === 'OWI' ) { - window.storage.put( + await window.storage.put( 'theme-setting', await window.Events.getThemeSetting() ); @@ -2446,7 +2456,7 @@ export async function startApp(): Promise { } // Intentionally not awaiting - challengeHandler.onOnline(); + void challengeHandler.onOnline(); reconnectBackOff.reset(); } finally { @@ -2594,7 +2604,7 @@ export async function startApp(): Promise { storage, }); - routineProfileRefresher.start(); + void routineProfileRefresher.start(); } // Make sure we have the PNI identity @@ -2632,10 +2642,10 @@ export async function startApp(): Promise { } log.info('manualConnect: calling connect()'); - connect(); + void connect(); } - function onConfiguration(ev: ConfigurationEvent): void { + async function onConfiguration(ev: ConfigurationEvent): Promise { ev.confirm(); const { configuration } = ev; @@ -2646,24 +2656,24 @@ export async function startApp(): Promise { linkPreviews, } = configuration; - window.storage.put('read-receipt-setting', Boolean(readReceipts)); + await window.storage.put('read-receipt-setting', Boolean(readReceipts)); if ( unidentifiedDeliveryIndicators === true || unidentifiedDeliveryIndicators === false ) { - window.storage.put( + await window.storage.put( 'unidentifiedDeliveryIndicators', unidentifiedDeliveryIndicators ); } if (typingIndicators === true || typingIndicators === false) { - window.storage.put('typingIndicators', typingIndicators); + await window.storage.put('typingIndicators', typingIndicators); } if (linkPreviews === true || linkPreviews === false) { - window.storage.put('linkPreviews', linkPreviews); + await window.storage.put('linkPreviews', linkPreviews); } } @@ -2780,7 +2790,7 @@ export async function startApp(): Promise { fromSync: true, }); } else { - Stickers.downloadStickerPack(id, key, { + void Stickers.downloadStickerPack(id, key, { finalStatus: 'installed', fromSync: true, }); @@ -2909,8 +2919,10 @@ export async function startApp(): Promise { ); } - sender.queueJob('sendProfileKeyUpdate', () => - sender.sendProfileKeyUpdate() + drop( + sender.queueJob('sendProfileKeyUpdate', () => + sender.sendProfileKeyUpdate() + ) ); }); }, @@ -2984,9 +2996,11 @@ export async function startApp(): Promise { } if (!message.get('unidentifiedDeliveryReceived')) { - profileKeyResponseQueue.add(() => { - respondWithProfileKeyBatcher.add(sender); - }); + drop( + profileKeyResponseQueue.add(() => { + respondWithProfileKeyBatcher.add(sender); + }) + ); } } @@ -3032,7 +3046,7 @@ export async function startApp(): Promise { const reactionModel = Reactions.getSingleton().add(attributes); // Note: We do not wait for completion here - Reactions.getSingleton().onReaction(reactionModel, message); + void Reactions.getSingleton().onReaction(reactionModel, message); confirm(); return; } @@ -3061,7 +3075,7 @@ export async function startApp(): Promise { const deleteModel = Deletes.getSingleton().add(attributes); // Note: We do not wait for completion here - Deletes.getSingleton().onDelete(deleteModel); + void Deletes.getSingleton().onDelete(deleteModel); confirm(); return; @@ -3073,7 +3087,7 @@ export async function startApp(): Promise { } // Don't wait for handleDataMessage, as it has its own per-conversation queueing - message.handleDataMessage(data.message, event.confirm); + void message.handleDataMessage(data.message, event.confirm); } async function onProfileKeyUpdate({ @@ -3403,7 +3417,7 @@ export async function startApp(): Promise { }; const reactionModel = Reactions.getSingleton().add(attributes); // Note: We do not wait for completion here - Reactions.getSingleton().onReaction(reactionModel, message); + void Reactions.getSingleton().onReaction(reactionModel, message); event.confirm(); return; @@ -3426,7 +3440,7 @@ export async function startApp(): Promise { }; const deleteModel = Deletes.getSingleton().add(attributes); // Note: We do not wait for completion here - Deletes.getSingleton().onDelete(deleteModel); + void Deletes.getSingleton().onDelete(deleteModel); confirm(); return; } @@ -3437,7 +3451,7 @@ export async function startApp(): Promise { } // Don't wait for handleDataMessage, as it has its own per-conversation queueing - message.handleDataMessage(data.message, event.confirm, { + void message.handleDataMessage(data.message, event.confirm, { data, }); } @@ -3517,9 +3531,9 @@ export async function startApp(): Promise { await window.waitForAllBatchers(); } - onEmpty(); + void onEmpty(); - window.Signal.Util.Registration.remove(); + void window.Signal.Util.Registration.remove(); const NUMBER_ID_KEY = 'number_id'; const UUID_ID_KEY = 'uuid_id'; @@ -3580,7 +3594,7 @@ export async function startApp(): Promise { Errors.toLogFormat(eraseError) ); } finally { - window.Signal.Util.Registration.markEverDone(); + await window.Signal.Util.Registration.markEverDone(); } } @@ -3592,7 +3606,7 @@ export async function startApp(): Promise { error instanceof HTTPError && (error.code === 401 || error.code === 403) ) { - unlinkAndDisconnect(RemoveAllConfiguration.Full); + void unlinkAndDisconnect(RemoveAllConfiguration.Full); return; } @@ -3614,7 +3628,7 @@ export async function startApp(): Promise { }; const sync = ViewOnceOpenSyncs.getSingleton().add(attributes); - ViewOnceOpenSyncs.getSingleton().onSync(sync); + void ViewOnceOpenSyncs.getSingleton().onSync(sync); } async function onFetchLatestSync(ev: FetchLatestEvent): Promise { @@ -3656,7 +3670,7 @@ export async function startApp(): Promise { if (storageServiceKey == null) { log.info('onKeysSync: deleting window.storageKey'); - window.storage.remove('storageKey'); + await window.storage.remove('storageKey'); } if (storageServiceKey) { @@ -3713,7 +3727,7 @@ export async function startApp(): Promise { }; const sync = MessageRequests.getSingleton().add(attributes); - MessageRequests.getSingleton().onResponse(sync); + void MessageRequests.getSingleton().onResponse(sync); } function onReadReceipt(event: Readonly): void { @@ -3787,7 +3801,7 @@ export async function startApp(): Promise { const receipt = MessageReceipts.getSingleton().add(attributes); // Note: We do not wait for completion here - MessageReceipts.getSingleton().onReceipt(receipt); + void MessageReceipts.getSingleton().onReceipt(receipt); } function onReadSync(ev: ReadSyncEvent): Promise { @@ -3925,7 +3939,7 @@ export async function startApp(): Promise { const receipt = MessageReceipts.getSingleton().add(attributes); // Note: We don't wait for completion here - MessageReceipts.getSingleton().onReceipt(receipt); + void MessageReceipts.getSingleton().onReceipt(receipt); } } diff --git a/ts/badges/badgeImageFileDownloader.ts b/ts/badges/badgeImageFileDownloader.ts index 908bc423d666..ef4927e37b68 100644 --- a/ts/badges/badgeImageFileDownloader.ts +++ b/ts/badges/badgeImageFileDownloader.ts @@ -58,7 +58,7 @@ class BadgeImageFileDownloader { previousState === BadgeDownloaderState.CheckingWithAnotherCheckEnqueued ) { - this.checkForFilesToDownload(); + void this.checkForFilesToDownload(); } return; } diff --git a/ts/challenge.ts b/ts/challenge.ts index 9d1fe2cdf627..a9882123a153 100644 --- a/ts/challenge.ts +++ b/ts/challenge.ts @@ -210,7 +210,7 @@ export class ChallengeHandler { } if (challenge.token) { - this.solve({ reason, token: challenge.token }); + void this.solve({ reason, token: challenge.token }); } } @@ -247,7 +247,7 @@ export class ChallengeHandler { setTimeout(() => { this.startTimers.delete(conversationId); - this.startQueue(conversationId); + void this.startQueue(conversationId); }, waitTime) ); log.info( @@ -269,7 +269,7 @@ export class ChallengeHandler { return; } - this.solve({ token: challenge.token, reason }); + void this.solve({ token: challenge.token, reason }); } public onResponse(response: IPCResponse): void { diff --git a/ts/components/AvatarEditor.tsx b/ts/components/AvatarEditor.tsx index be19271ed1b4..5b9f3bdc2c95 100644 --- a/ts/components/AvatarEditor.tsx +++ b/ts/components/AvatarEditor.tsx @@ -109,7 +109,7 @@ export function AvatarEditor({ } } - cacheAvatars(); + void cacheAvatars(); return () => { shouldCancel = true; diff --git a/ts/components/AvatarIconEditor.tsx b/ts/components/AvatarIconEditor.tsx index 80f80f8850c8..fb1bf179c739 100644 --- a/ts/components/AvatarIconEditor.tsx +++ b/ts/components/AvatarIconEditor.tsx @@ -45,7 +45,7 @@ export function AvatarIconEditor({ setAvatarBuffer(buffer); } } - loadAvatar(); + void loadAvatar(); return () => { shouldCancel = true; diff --git a/ts/components/AvatarPreview.tsx b/ts/components/AvatarPreview.tsx index 86f55a9eb549..cc1318f35ee5 100644 --- a/ts/components/AvatarPreview.tsx +++ b/ts/components/AvatarPreview.tsx @@ -62,7 +62,7 @@ export function AvatarPreview({ let shouldCancel = false; - (async () => { + void (async () => { try { const buffer = await imagePathToBytes(avatarPath); if (shouldCancel) { diff --git a/ts/components/AvatarUploadButton.tsx b/ts/components/AvatarUploadButton.tsx index a98d450e9f4e..70188e463e51 100644 --- a/ts/components/AvatarUploadButton.tsx +++ b/ts/components/AvatarUploadButton.tsx @@ -30,7 +30,7 @@ export function AvatarUploadButton({ let shouldCancel = false; - (async () => { + void (async () => { let newAvatar: Uint8Array; try { newAvatar = await processImageFile(processingFile); diff --git a/ts/components/BetterAvatar.tsx b/ts/components/BetterAvatar.tsx index 144b7f6d54ab..e69db81dd848 100644 --- a/ts/components/BetterAvatar.tsx +++ b/ts/components/BetterAvatar.tsx @@ -50,7 +50,7 @@ export function BetterAvatar({ return noop; } - makeAvatar(); + void makeAvatar(); return () => { shouldCancel = true; diff --git a/ts/components/CallingAudioIndicator.tsx b/ts/components/CallingAudioIndicator.tsx index cac86276956c..5d8873f2e246 100644 --- a/ts/components/CallingAudioIndicator.tsx +++ b/ts/components/CallingAudioIndicator.tsx @@ -90,7 +90,7 @@ function Bars({ audioLevel }: { audioLevel: number }): ReactElement { useEffect(() => { animatedProps.audioLevel.stop(); - animatedProps.audioLevel.start(audioLevel); + void animatedProps.audioLevel.start(audioLevel); }, [audioLevel, animatedProps]); return ( diff --git a/ts/components/DebugLogWindow.tsx b/ts/components/DebugLogWindow.tsx index 9e1d261b0213..f73cd7567a32 100644 --- a/ts/components/DebugLogWindow.tsx +++ b/ts/components/DebugLogWindow.tsx @@ -86,7 +86,7 @@ export function DebugLogWindow({ setToastType(undefined); } - doFetchLogs(); + void doFetchLogs(); return () => { shouldCancel = true; diff --git a/ts/components/GlobalAudioContext.tsx b/ts/components/GlobalAudioContext.tsx index 2325bfdffd1c..3e40f6504206 100644 --- a/ts/components/GlobalAudioContext.tsx +++ b/ts/components/GlobalAudioContext.tsx @@ -27,7 +27,7 @@ export type Contents = { // `audioContext` global, however, as the browser limits the number that can be // created.) const audioContext = new AudioContext(); -audioContext.suspend(); +void audioContext.suspend(); const waveformCache: WaveformCache = new LRU({ max: MAX_WAVEFORM_COUNT, diff --git a/ts/components/Lightbox.tsx b/ts/components/Lightbox.tsx index efe6f6d0276e..929e8f845110 100644 --- a/ts/components/Lightbox.tsx +++ b/ts/components/Lightbox.tsx @@ -203,7 +203,7 @@ export function Lightbox({ } if (videoElement.paused) { - videoElement.play(); + void videoElement.play(); } else { videoElement.pause(); } diff --git a/ts/components/ProfileEditor.tsx b/ts/components/ProfileEditor.tsx index 7e8a9ca7eff5..b783444c48ed 100644 --- a/ts/components/ProfileEditor.tsx +++ b/ts/components/ProfileEditor.tsx @@ -504,7 +504,7 @@ export function ProfileEditor({ username !== undefined, 'Should not be visible without username' ); - window.navigator.clipboard.writeText(username); + void window.navigator.clipboard.writeText(username); showToast(ToastType.CopiedUsername); }, }, @@ -517,7 +517,7 @@ export function ProfileEditor({ username !== undefined, 'Should not be visible without username' ); - window.navigator.clipboard.writeText( + void window.navigator.clipboard.writeText( generateUsernameLink(username) ); showToast(ToastType.CopiedUsernameLink); diff --git a/ts/components/QrCode.tsx b/ts/components/QrCode.tsx index aeb7304eb00b..5e8d3c2e0844 100644 --- a/ts/components/QrCode.tsx +++ b/ts/components/QrCode.tsx @@ -38,7 +38,7 @@ export function QrCode(props: PropsType): ReactElement { return; } - navigator.clipboard.writeText(data); + void navigator.clipboard.writeText(data); const el = elRef.current; if (!el) { diff --git a/ts/components/SendStoryModal.tsx b/ts/components/SendStoryModal.tsx index 79b4df36586e..7f180c817c87 100644 --- a/ts/components/SendStoryModal.tsx +++ b/ts/components/SendStoryModal.tsx @@ -954,7 +954,7 @@ export function SendStoryModal({ actions={[ { action: () => { - toggleGroupsForStorySend([confirmRemoveGroupId]); + void toggleGroupsForStorySend([confirmRemoveGroupId]); setConfirmRemoveGroupId(undefined); }, style: 'negative', diff --git a/ts/components/StandaloneRegistration.tsx b/ts/components/StandaloneRegistration.tsx index 395efe8c3800..b613897fd31d 100644 --- a/ts/components/StandaloneRegistration.tsx +++ b/ts/components/StandaloneRegistration.tsx @@ -138,7 +138,7 @@ export function StandaloneRegistration({ }); try { - requestVerification(type, number, token); + void requestVerification(type, number, token); setError(undefined); } catch (err) { setError(err.message); @@ -152,7 +152,7 @@ export function StandaloneRegistration({ e.preventDefault(); e.stopPropagation(); - onRequestCode('sms'); + void onRequestCode('sms'); }, [onRequestCode] ); @@ -162,7 +162,7 @@ export function StandaloneRegistration({ e.preventDefault(); e.stopPropagation(); - onRequestCode('voice'); + void onRequestCode('voice'); }, [onRequestCode] ); diff --git a/ts/components/StoriesSettingsModal.tsx b/ts/components/StoriesSettingsModal.tsx index 91c7979620fd..ba5fa05f0da8 100644 --- a/ts/components/StoriesSettingsModal.tsx +++ b/ts/components/StoriesSettingsModal.tsx @@ -311,7 +311,7 @@ export function StoriesSettingsModal({ page={page} onClose={onClose} onCreateList={(name, uuids) => { - onDistributionListCreated(name, uuids); + void onDistributionListCreated(name, uuids); resetChooseViewersScreen(); }} onBackButtonClick={() => diff --git a/ts/components/StoryCreator.tsx b/ts/components/StoryCreator.tsx index 1da82cb62c28..61fc1a14c61b 100644 --- a/ts/components/StoryCreator.tsx +++ b/ts/components/StoryCreator.tsx @@ -149,7 +149,7 @@ export function StoryCreator({ } } - loadAttachment(); + void loadAttachment(); return () => { unmounted = true; diff --git a/ts/components/StoryDetailsModal.tsx b/ts/components/StoryDetailsModal.tsx index 3b7e49a9e294..c1ce7778457a 100644 --- a/ts/components/StoryDetailsModal.tsx +++ b/ts/components/StoryDetailsModal.tsx @@ -204,7 +204,7 @@ export function StoryDetailsModal({ icon: 'StoryDetailsModal__copy-icon', label: i18n('StoryDetailsModal__copy-timestamp'), onClick: () => { - window.navigator.clipboard.writeText(String(timestamp)); + void window.navigator.clipboard.writeText(String(timestamp)); }, }, ]; diff --git a/ts/components/StoryImage.tsx b/ts/components/StoryImage.tsx index 6353318821d4..5dd93c14c5d1 100644 --- a/ts/components/StoryImage.tsx +++ b/ts/components/StoryImage.tsx @@ -72,7 +72,7 @@ export function StoryImage({ if (isPaused) { videoRef.current.pause(); } else { - videoRef.current.play(); + void videoRef.current.play(); } }, [isPaused]); diff --git a/ts/components/StoryViewer.tsx b/ts/components/StoryViewer.tsx index 57d17304ad5b..1a8cfd254acb 100644 --- a/ts/components/StoryViewer.tsx +++ b/ts/components/StoryViewer.tsx @@ -247,7 +247,7 @@ export function StoryViewer({ // are sequentially posted. useEffect(() => { let shouldCancel = false; - (async function hydrateStoryDuration() { + void (async function hydrateStoryDuration() { if (!attachment) { return; } diff --git a/ts/components/StoryViewsNRepliesModal.tsx b/ts/components/StoryViewsNRepliesModal.tsx index a9402cbb6351..e6150ad5af73 100644 --- a/ts/components/StoryViewsNRepliesModal.tsx +++ b/ts/components/StoryViewsNRepliesModal.tsx @@ -618,7 +618,7 @@ function ReplyOrReactionMessage({ icon: 'module-message__context--icon module-message__context__copy-timestamp', label: i18n('icu:StoryViewsNRepliesModal__copy-reply-timestamp'), onClick: () => { - window.navigator.clipboard.writeText(String(reply.timestamp)); + void window.navigator.clipboard.writeText(String(reply.timestamp)); }, }); } diff --git a/ts/components/conversation/MessageAudio.tsx b/ts/components/conversation/MessageAudio.tsx index 617491467f67..9c6d54cf81e2 100644 --- a/ts/components/conversation/MessageAudio.tsx +++ b/ts/components/conversation/MessageAudio.tsx @@ -321,7 +321,7 @@ export function MessageAudio(props: Props): JSX.Element { let canceled = false; - (async () => { + void (async () => { try { if (!attachment.url) { throw new Error( diff --git a/ts/components/conversation/MessageDetail.tsx b/ts/components/conversation/MessageDetail.tsx index 28abb2b14b7d..366d673042c9 100644 --- a/ts/components/conversation/MessageDetail.tsx +++ b/ts/components/conversation/MessageDetail.tsx @@ -367,7 +367,9 @@ export class MessageDetail extends React.Component { icon: 'StoryDetailsModal__copy-icon', label: i18n('StoryDetailsModal__copy-timestamp'), onClick: () => { - window.navigator.clipboard.writeText(String(sentAt)); + void window.navigator.clipboard.writeText( + String(sentAt) + ); }, }, ]} diff --git a/ts/components/conversation/TimelineMessage.stories.tsx b/ts/components/conversation/TimelineMessage.stories.tsx index e7930364d7ca..712c48560ebb 100644 --- a/ts/components/conversation/TimelineMessage.stories.tsx +++ b/ts/components/conversation/TimelineMessage.stories.tsx @@ -163,7 +163,7 @@ function MessageAudioContainer({ setIsActive(true); } if (!playing) { - audio.play(); + void audio.play(); setPlaying(true); setPlayed(true); } @@ -183,7 +183,7 @@ function MessageAudioContainer({ const setIsPlayingAction = (value: boolean) => { if (value) { - audio.play(); + void audio.play(); } else { audio.pause(); } diff --git a/ts/components/conversation/conversation-details/AddGroupMembersModal.tsx b/ts/components/conversation/conversation-details/AddGroupMembersModal.tsx index 2b787a0f4c93..87048c7c6b66 100644 --- a/ts/components/conversation/conversation-details/AddGroupMembersModal.tsx +++ b/ts/components/conversation/conversation-details/AddGroupMembersModal.tsx @@ -249,7 +249,7 @@ export function AddGroupMembersModal({ return renderConfirmAdditionsModal({ groupTitle, makeRequest: () => { - makeRequest(selectedConversationIds); + void makeRequest(selectedConversationIds); }, onClose: onCloseConfirmationDialog, requestState, diff --git a/ts/components/conversation/conversation-details/GroupLinkManagement.tsx b/ts/components/conversation/conversation-details/GroupLinkManagement.tsx index 48baa7ca34c1..26fe29c505a1 100644 --- a/ts/components/conversation/conversation-details/GroupLinkManagement.tsx +++ b/ts/components/conversation/conversation-details/GroupLinkManagement.tsx @@ -138,7 +138,7 @@ export function GroupLinkManagement({ ref={!isAdmin ? focusRef : undefined} onClick={() => { if (conversation.groupLink) { - copyGroupLink(conversation.groupLink); + void copyGroupLink(conversation.groupLink); } }} /> diff --git a/ts/components/emoji/lib.ts b/ts/components/emoji/lib.ts index 22390aaad343..70d8c0d7b431 100644 --- a/ts/components/emoji/lib.ts +++ b/ts/components/emoji/lib.ts @@ -23,6 +23,7 @@ import is from '@sindresorhus/is'; import { getOwn } from '../../util/getOwn'; import * as log from '../../logging/log'; import { MINUTE } from '../../util/durations'; +import { drop } from '../../util/drop'; export const skinTones = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF']; @@ -124,11 +125,11 @@ export const preloadImages = async (): Promise => { const start = Date.now(); data.forEach(emoji => { - imageQueue.add(() => preload(makeImagePath(emoji.image))); + drop(imageQueue.add(() => preload(makeImagePath(emoji.image)))); if (emoji.skin_variations) { Object.values(emoji.skin_variations).forEach(variation => { - imageQueue.add(() => preload(makeImagePath(variation.image))); + drop(imageQueue.add(() => preload(makeImagePath(variation.image)))); }); } }); diff --git a/ts/components/stickers/StickerManager.tsx b/ts/components/stickers/StickerManager.tsx index 18642216ce8a..2f035c1cf87c 100644 --- a/ts/components/stickers/StickerManager.tsx +++ b/ts/components/stickers/StickerManager.tsx @@ -10,7 +10,7 @@ import { Tabs } from '../Tabs'; export type OwnProps = { readonly blessedPacks: ReadonlyArray; - readonly closeStickerPackPreview: (packId: string) => unknown; + readonly closeStickerPackPreview: () => unknown; readonly downloadStickerPack: (packId: string, packKey: string) => unknown; readonly i18n: LocalizerType; readonly installStickerPack: (packId: string, packKey: string) => unknown; diff --git a/ts/components/stickers/StickerPreviewModal.tsx b/ts/components/stickers/StickerPreviewModal.tsx index 59b39805a3f8..f39cb34050ac 100644 --- a/ts/components/stickers/StickerPreviewModal.tsx +++ b/ts/components/stickers/StickerPreviewModal.tsx @@ -14,7 +14,7 @@ import { Button, ButtonVariant } from '../Button'; export type OwnProps = { readonly onClose?: () => unknown; - readonly closeStickerPackPreview: (packId: string) => unknown; + readonly closeStickerPackPreview: () => unknown; readonly downloadStickerPack: ( packId: string, packKey: string, @@ -107,9 +107,18 @@ export const StickerPreviewModal = React.memo(function StickerPreviewModalInner( // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + React.useEffect(() => { + if (pack) { + return; + } + + // Pack fully uninstalled, don't keep the modal open + closeStickerPackPreview(); + }, [pack, closeStickerPackPreview]); + const handleClose = React.useCallback(() => { - if (pack?.id) { - closeStickerPackPreview(pack.id); + if (pack) { + closeStickerPackPreview(); } onClose?.(); }, [closeStickerPackPreview, onClose, pack]); diff --git a/ts/groups.ts b/ts/groups.ts index 153235c29c5c..d7cab332a439 100644 --- a/ts/groups.ts +++ b/ts/groups.ts @@ -1602,7 +1602,7 @@ export async function modifyGroupV2({ `modifyGroupV2/${logId}: Conflict while updating. Timed out; not retrying.` ); // We don't wait here because we're breaking out of the loop immediately. - conversation.fetchLatestGroupV2Data({ force: true }); + void conversation.fetchLatestGroupV2Data({ force: true }); throw error; } else { const errorString = Errors.toLogFormat(error); @@ -2403,7 +2403,7 @@ export async function initiateMigrationToGroupV2( }); if (window.storage.blocked.isGroupBlocked(previousGroupV1Id)) { - window.storage.blocked.addBlockedGroup(groupId); + await window.storage.blocked.addBlockedGroup(groupId); } // Save these most recent updates to conversation @@ -2721,7 +2721,7 @@ export async function respondToGroupV2Migration({ ); if (window.storage.blocked.isGroupBlocked(previousGroupV1Id)) { - window.storage.blocked.addBlockedGroup(groupId); + await window.storage.blocked.addBlockedGroup(groupId); } if (wereWePreviouslyAMember) { @@ -2862,7 +2862,7 @@ export async function respondToGroupV2Migration({ }); if (window.storage.blocked.isGroupBlocked(previousGroupV1Id)) { - window.storage.blocked.addBlockedGroup(groupId); + await window.storage.blocked.addBlockedGroup(groupId); } // Save these most recent updates to conversation @@ -3080,7 +3080,7 @@ async function updateGroup( contact.get('profileKey') !== member.profileKey ) { contactsWithoutProfileKey.push(contact); - contact.setProfileKey(member.profileKey); + void contact.setProfileKey(member.profileKey); } }); @@ -3155,7 +3155,7 @@ async function updateGroup( }; // Cannot await here, would infinitely block queue - waitThenLeave(); + void waitThenLeave(); } } } @@ -3359,7 +3359,7 @@ async function appendChangeMessages( // We updated the message, but didn't add new ones - refresh left pane if (!newMessages && mergedMessages.length > 0) { await conversation.updateLastMessage(); - conversation.updateUnread(); + void conversation.updateUnread(); } } diff --git a/ts/groups/joinViaLink.tsx b/ts/groups/joinViaLink.tsx index 3272547e4695..b23555ef566d 100644 --- a/ts/groups/joinViaLink.tsx +++ b/ts/groups/joinViaLink.tsx @@ -422,7 +422,7 @@ export async function joinViaLink(hash: string): Promise { } }; - fetchAvatar(); + void fetchAvatar(); await promise; } diff --git a/ts/hooks/useTheme.ts b/ts/hooks/useTheme.ts index cc8aec0298cd..a9d9c052b09c 100644 --- a/ts/hooks/useTheme.ts +++ b/ts/hooks/useTheme.ts @@ -46,7 +46,7 @@ export const useTheme = (): ThemeType => { } SignalContext.nativeThemeListener.subscribe(applyTheme); - loop(); + void loop(); return () => { abortController.abort(); diff --git a/ts/jobs/JobQueue.ts b/ts/jobs/JobQueue.ts index 8e05dca5d5a4..03b51993c82d 100644 --- a/ts/jobs/JobQueue.ts +++ b/ts/jobs/JobQueue.ts @@ -130,7 +130,7 @@ export abstract class JobQueue { const stream = this.store.stream(this.queueType); for await (const storedJob of stream) { - this.enqueueStoredJob(storedJob); + void this.enqueueStoredJob(storedJob); } } diff --git a/ts/jobs/conversationJobQueue.ts b/ts/jobs/conversationJobQueue.ts index 0a36e8918276..7d379c0befe5 100644 --- a/ts/jobs/conversationJobQueue.ts +++ b/ts/jobs/conversationJobQueue.ts @@ -412,7 +412,7 @@ export class ConversationJobQueue extends JobQueue { } untrustedUuids.push(uuid); } else if (toProcess instanceof SendMessageChallengeError) { - window.Signal.challengeHandler?.register( + void window.Signal.challengeHandler?.register( { conversationId, createdAt: Date.now(), diff --git a/ts/jobs/helpers/sendDeleteForEveryone.ts b/ts/jobs/helpers/sendDeleteForEveryone.ts index a3ce145e439e..7395e6ecf3ce 100644 --- a/ts/jobs/helpers/sendDeleteForEveryone.ts +++ b/ts/jobs/helpers/sendDeleteForEveryone.ts @@ -71,7 +71,11 @@ export async function sendDeleteForEveryone( if (!shouldContinue) { log.info(`${logId}: Ran out of time. Giving up on sending`); - updateMessageWithFailure(message, [new Error('Ran out of time!')], log); + void updateMessageWithFailure( + message, + [new Error('Ran out of time!')], + log + ); return; } @@ -148,7 +152,7 @@ export async function sendDeleteForEveryone( log.info( `conversation ${conversation.idForLogging()} is not accepted; refusing to send` ); - updateMessageWithFailure( + void updateMessageWithFailure( message, [new Error('Message request was not accepted')], log @@ -159,7 +163,7 @@ export async function sendDeleteForEveryone( log.info( `conversation ${conversation.idForLogging()} is unregistered; refusing to send` ); - updateMessageWithFailure( + void updateMessageWithFailure( message, [new Error('Contact no longer has a Signal account')], log @@ -170,7 +174,7 @@ export async function sendDeleteForEveryone( log.info( `conversation ${conversation.idForLogging()} is blocked; refusing to send` ); - updateMessageWithFailure( + void updateMessageWithFailure( message, [new Error('Contact is blocked')], log diff --git a/ts/jobs/helpers/sendDeleteStoryForEveryone.ts b/ts/jobs/helpers/sendDeleteStoryForEveryone.ts index 2bed97b8cfe1..f8f9a0677080 100644 --- a/ts/jobs/helpers/sendDeleteStoryForEveryone.ts +++ b/ts/jobs/helpers/sendDeleteStoryForEveryone.ts @@ -53,7 +53,11 @@ export async function sendDeleteStoryForEveryone( if (!shouldContinue) { log.info(`${logId}: Ran out of time. Giving up on sending`); - updateMessageWithFailure(message, [new Error('Ran out of time!')], log); + void updateMessageWithFailure( + message, + [new Error('Ran out of time!')], + log + ); return; } @@ -107,7 +111,7 @@ export async function sendDeleteStoryForEveryone( `${logId}: conversation ${conversation.idForLogging()} ` + 'is not accepted; refusing to send' ); - updateMessageWithFailure( + void updateMessageWithFailure( message, [new Error('Message request was not accepted')], log @@ -119,7 +123,7 @@ export async function sendDeleteStoryForEveryone( `${logId}: conversation ${conversation.idForLogging()} ` + 'is unregistered; refusing to send' ); - updateMessageWithFailure( + void updateMessageWithFailure( message, [new Error('Contact no longer has a Signal account')], log @@ -131,7 +135,7 @@ export async function sendDeleteStoryForEveryone( `${logId}: conversation ${conversation.idForLogging()} ` + 'is blocked; refusing to send' ); - updateMessageWithFailure( + void updateMessageWithFailure( message, [new Error('Contact is blocked')], log diff --git a/ts/jobs/helpers/sendNormalMessage.ts b/ts/jobs/helpers/sendNormalMessage.ts index 13c305b3fe46..22b1a22e19eb 100644 --- a/ts/jobs/helpers/sendNormalMessage.ts +++ b/ts/jobs/helpers/sendNormalMessage.ts @@ -196,7 +196,7 @@ export async function sendNormalMessage( log.info( 'No recipients; not sending to ourselves or to group, and no successful sends. Failing job.' ); - markMessageFailed(message, [new Error('No valid recipients')]); + void markMessageFailed(message, [new Error('No valid recipients')]); return; } @@ -281,7 +281,7 @@ export async function sendNormalMessage( log.info( `conversation ${conversation.idForLogging()} is not accepted; refusing to send` ); - markMessageFailed(message, [ + void markMessageFailed(message, [ new Error('Message request was not accepted'), ]); return; @@ -290,7 +290,7 @@ export async function sendNormalMessage( log.info( `conversation ${conversation.idForLogging()} is unregistered; refusing to send` ); - markMessageFailed(message, [ + void markMessageFailed(message, [ new Error('Contact no longer has a Signal account'), ]); return; @@ -299,7 +299,7 @@ export async function sendNormalMessage( log.info( `conversation ${conversation.idForLogging()} is blocked; refusing to send` ); - markMessageFailed(message, [new Error('Contact is blocked')]); + void markMessageFailed(message, [new Error('Contact is blocked')]); return; } @@ -561,7 +561,7 @@ async function markMessageFailed( errors: Array ): Promise { message.markFailed(); - message.saveErrors(errors, { skipSave: true }); + void message.saveErrors(errors, { skipSave: true }); await window.Signal.Data.saveMessage(message.attributes, { ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), }); diff --git a/ts/jobs/helpers/sendReaction.ts b/ts/jobs/helpers/sendReaction.ts index 67c14781ede6..0726d2681625 100644 --- a/ts/jobs/helpers/sendReaction.ts +++ b/ts/jobs/helpers/sendReaction.ts @@ -322,7 +322,7 @@ export async function sendReaction( reactionMessage.hydrateStoryContext(message), ]); - conversation.addSingleMessage( + void conversation.addSingleMessage( window.MessageController.register(reactionMessage.id, reactionMessage) ); } diff --git a/ts/jobs/helpers/sendStory.ts b/ts/jobs/helpers/sendStory.ts index 288dac95c039..2eaa5ca442ad 100644 --- a/ts/jobs/helpers/sendStory.ts +++ b/ts/jobs/helpers/sendStory.ts @@ -399,7 +399,7 @@ export async function sendStory( // conversationJobQueue. errors.forEach(error => { if (error instanceof SendMessageChallengeError) { - window.Signal.challengeHandler?.register( + void window.Signal.challengeHandler?.register( { conversationId: conversation.id, createdAt: Date.now(), @@ -641,7 +641,7 @@ async function markMessageFailed( errors: Array ): Promise { message.markFailed(); - message.saveErrors(errors, { skipSave: true }); + void message.saveErrors(errors, { skipSave: true }); await window.Signal.Data.saveMessage(message.attributes, { ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), }); diff --git a/ts/jobs/initializeAllJobQueues.ts b/ts/jobs/initializeAllJobQueues.ts index bc1103a15f17..22c9e86b50b8 100644 --- a/ts/jobs/initializeAllJobQueues.ts +++ b/ts/jobs/initializeAllJobQueues.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import type { WebAPIType } from '../textsecure/WebAPI'; +import { drop } from '../util/drop'; import { conversationJobQueue } from './conversationJobQueue'; import { deliveryReceiptsJobQueue } from './deliveryReceiptsJobQueue'; @@ -25,22 +26,22 @@ export function initializeAllJobQueues({ reportSpamJobQueue.initialize({ server }); // General conversation send queue - conversationJobQueue.streamJobs(); + drop(conversationJobQueue.streamJobs()); // Single proto send queue, used for a variety of one-off simple messages - singleProtoJobQueue.streamJobs(); + drop(singleProtoJobQueue.streamJobs()); // Syncs to others - deliveryReceiptsJobQueue.streamJobs(); - readReceiptsJobQueue.streamJobs(); - viewedReceiptsJobQueue.streamJobs(); + drop(deliveryReceiptsJobQueue.streamJobs()); + drop(readReceiptsJobQueue.streamJobs()); + drop(viewedReceiptsJobQueue.streamJobs()); // Syncs to ourselves - readSyncJobQueue.streamJobs(); - viewSyncJobQueue.streamJobs(); - viewOnceOpenJobQueue.streamJobs(); + drop(readSyncJobQueue.streamJobs()); + drop(viewSyncJobQueue.streamJobs()); + drop(viewOnceOpenJobQueue.streamJobs()); // Other queues - removeStorageKeyJobQueue.streamJobs(); - reportSpamJobQueue.streamJobs(); + drop(removeStorageKeyJobQueue.streamJobs()); + drop(reportSpamJobQueue.streamJobs()); } diff --git a/ts/logging/main_process_logging.ts b/ts/logging/main_process_logging.ts index 2baacbc66b90..a4037c96174a 100644 --- a/ts/logging/main_process_logging.ts +++ b/ts/logging/main_process_logging.ts @@ -96,7 +96,7 @@ export async function initialize( globalLogger = undefined; if (shouldRestart) { - initialize(getMainWindow); + void initialize(getMainWindow); } }; diff --git a/ts/main/challengeMain.ts b/ts/main/challengeMain.ts index e1f210098790..0c6c5e1c2c16 100644 --- a/ts/main/challengeMain.ts +++ b/ts/main/challengeMain.ts @@ -55,7 +55,7 @@ export class ChallengeMainHandler { private initialize(): void { ipc.on('challenge:request', (event, request) => { - this.onRequest(event, request); + void this.onRequest(event, request); }); } } diff --git a/ts/messageModifiers/AttachmentDownloads.ts b/ts/messageModifiers/AttachmentDownloads.ts index d6fa1bc18a52..bc80569a441d 100644 --- a/ts/messageModifiers/AttachmentDownloads.ts +++ b/ts/messageModifiers/AttachmentDownloads.ts @@ -62,7 +62,7 @@ export async function start(options: StartOptionsType): Promise { enabled = true; await resetAttachmentDownloadPending(); - _tick(); + void _tick(); } export async function stop(): Promise { @@ -133,7 +133,7 @@ export async function addJob( await saveAttachmentDownloadJob(toSave); - _maybeStartJob(); + void _maybeStartJob(); return { ...attachment, @@ -146,7 +146,7 @@ async function _tick(): Promise { clearTimeoutIfNecessary(timeout); timeout = null; - _maybeStartJob(); + void _maybeStartJob(); timeout = setTimeout(_tick, TICK_INTERVAL); } @@ -229,13 +229,13 @@ async function _maybeStartJob(): Promise { Errors.toLogFormat(error) ); } finally { - _maybeStartJob(); + void _maybeStartJob(); } } }; // Note: intentionally not awaiting - postProcess(); + void postProcess(); } } } @@ -360,7 +360,7 @@ async function _runJob(job?: AttachmentDownloadJobType): Promise { await saveAttachmentDownloadJob(failedJob); } finally { delete _activeAttachmentDownloadJobs[id]; - _maybeStartJob(); + void _maybeStartJob(); } } } @@ -420,7 +420,7 @@ async function _finishJob( await removeAttachmentDownloadJob(id); delete _activeAttachmentDownloadJobs[id]; - _maybeStartJob(); + void _maybeStartJob(); } function getActiveJobCount(): number { @@ -472,7 +472,7 @@ async function _addAttachmentToMessage( }); } finally { if (attachment.path) { - window.Signal.Migrations.deleteAttachmentData(attachment.path); + void window.Signal.Migrations.deleteAttachmentData(attachment.path); } } return; diff --git a/ts/messageModifiers/Deletes.ts b/ts/messageModifiers/Deletes.ts index 0e4b1e5aafca..da0ba5844209 100644 --- a/ts/messageModifiers/Deletes.ts +++ b/ts/messageModifiers/Deletes.ts @@ -9,6 +9,7 @@ import { getContactId } from '../messages/helpers'; import * as log from '../logging/log'; import * as Errors from '../types/errors'; import { deleteForEveryone } from '../util/deleteForEveryone'; +import { drop } from '../util/drop'; export type DeleteAttributesType = { targetSentTimestamp: number; @@ -67,36 +68,38 @@ export class Deletes extends Collection { } // Do not await, since this can deadlock the queue - targetConversation.queueJob('Deletes.onDelete', async () => { - log.info('Handling DOE for', del.get('targetSentTimestamp')); + drop( + targetConversation.queueJob('Deletes.onDelete', async () => { + log.info('Handling DOE for', del.get('targetSentTimestamp')); - const messages = await window.Signal.Data.getMessagesBySentAt( - del.get('targetSentTimestamp') - ); - - const targetMessage = messages.find( - m => del.get('fromId') === getContactId(m) && !m.deletedForEveryone - ); - - if (!targetMessage) { - log.info( - 'No message for DOE', - del.get('fromId'), + const messages = await window.Signal.Data.getMessagesBySentAt( del.get('targetSentTimestamp') ); - return; - } + const targetMessage = messages.find( + m => del.get('fromId') === getContactId(m) && !m.deletedForEveryone + ); - const message = window.MessageController.register( - targetMessage.id, - targetMessage - ); + if (!targetMessage) { + log.info( + 'No message for DOE', + del.get('fromId'), + del.get('targetSentTimestamp') + ); - await deleteForEveryone(message, del); + return; + } - this.remove(del); - }); + const message = window.MessageController.register( + targetMessage.id, + targetMessage + ); + + await deleteForEveryone(message, del); + + this.remove(del); + }) + ); } catch (error) { log.error('Deletes.onDelete error:', Errors.toLogFormat(error)); } diff --git a/ts/messageModifiers/MessageRequests.ts b/ts/messageModifiers/MessageRequests.ts index 6c4aa86f19a7..5153306659e0 100644 --- a/ts/messageModifiers/MessageRequests.ts +++ b/ts/messageModifiers/MessageRequests.ts @@ -118,7 +118,7 @@ export class MessageRequests extends Collection { return; } - conversation.applyMessageRequestResponse(sync.get('type'), { + void conversation.applyMessageRequestResponse(sync.get('type'), { fromSync: true, }); diff --git a/ts/messageModifiers/Reactions.ts b/ts/messageModifiers/Reactions.ts index adf57b66d1f1..a37c41e920c3 100644 --- a/ts/messageModifiers/Reactions.ts +++ b/ts/messageModifiers/Reactions.ts @@ -208,7 +208,7 @@ export class Reactions extends Collection { generatedMessage.id, generatedMessage ); - targetConversation.addSingleMessage(messageToAdd); + void targetConversation.addSingleMessage(messageToAdd); } await message.handleReaction(reaction); diff --git a/ts/messageModifiers/ReadSyncs.ts b/ts/messageModifiers/ReadSyncs.ts index 9c18b293912b..a8cbcbe3bedf 100644 --- a/ts/messageModifiers/ReadSyncs.ts +++ b/ts/messageModifiers/ReadSyncs.ts @@ -116,7 +116,7 @@ export class ReadSyncs extends Collection { // onReadMessage 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 readAt value through. - message.getConversation()?.onReadMessage(message, readAt); + void message.getConversation()?.onReadMessage(message, readAt); }; if (window.startupProcessingQueue) { diff --git a/ts/messageModifiers/ViewSyncs.ts b/ts/messageModifiers/ViewSyncs.ts index 4a5a3cba6d91..a8630f42d5be 100644 --- a/ts/messageModifiers/ViewSyncs.ts +++ b/ts/messageModifiers/ViewSyncs.ts @@ -98,7 +98,7 @@ export class ViewSyncs extends Collection { const attachments = message.get('attachments'); if (!attachments?.every(isDownloaded)) { - queueAttachmentDownloads(message.attributes); + void queueAttachmentDownloads(message.attributes); } } diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts index 2f975ca5054b..63124c46e060 100644 --- a/ts/models/conversations.ts +++ b/ts/models/conversations.ts @@ -23,6 +23,7 @@ import type { QuotedMessageType, SenderKeyInfoType, } from '../model-types.d'; +import { drop } from '../util/drop'; import { getInitials } from '../util/getInitials'; import { normalizeUuid } from '../util/normalizeUuid'; import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary'; @@ -880,19 +881,19 @@ export class ConversationModel extends window.Backbone const uuid = this.get('uuid'); if (uuid) { - window.storage.blocked.addBlockedUuid(uuid); + drop(window.storage.blocked.addBlockedUuid(uuid)); blocked = true; } const e164 = this.get('e164'); if (e164) { - window.storage.blocked.addBlockedNumber(e164); + drop(window.storage.blocked.addBlockedNumber(e164)); blocked = true; } const groupId = this.get('groupId'); if (groupId) { - window.storage.blocked.addBlockedGroup(groupId); + drop(window.storage.blocked.addBlockedGroup(groupId)); blocked = true; } @@ -912,19 +913,19 @@ export class ConversationModel extends window.Backbone const uuid = this.get('uuid'); if (uuid) { - window.storage.blocked.removeBlockedUuid(uuid); + drop(window.storage.blocked.removeBlockedUuid(uuid)); unblocked = true; } const e164 = this.get('e164'); if (e164) { - window.storage.blocked.removeBlockedNumber(e164); + drop(window.storage.blocked.removeBlockedNumber(e164)); unblocked = true; } const groupId = this.get('groupId'); if (groupId) { - window.storage.blocked.removeBlockedGroup(groupId); + drop(window.storage.blocked.removeBlockedGroup(groupId)); unblocked = true; } @@ -936,7 +937,7 @@ export class ConversationModel extends window.Backbone this.captureChange('unblock'); } - this.fetchLatestGroupV2Data({ force: true }); + void this.fetchLatestGroupV2Data({ force: true }); } return unblocked; @@ -1010,7 +1011,7 @@ export class ConversationModel extends window.Backbone if (!this.typingRefreshTimer) { const isTyping = true; this.setTypingRefreshTimer(); - this.sendTypingMessage(isTyping); + void this.sendTypingMessage(isTyping); } this.setTypingPauseTimer(); @@ -1026,7 +1027,7 @@ export class ConversationModel extends window.Backbone onTypingRefreshTimeout(): void { const isTyping = true; - this.sendTypingMessage(isTyping); + void this.sendTypingMessage(isTyping); // This timer will continue to reset itself until the pause timer stops it this.setTypingRefreshTimer(); @@ -1042,7 +1043,7 @@ export class ConversationModel extends window.Backbone onTypingPauseTimeout(): void { const isTyping = false; - this.sendTypingMessage(isTyping); + void this.sendTypingMessage(isTyping); this.clearTypingTimers(); } @@ -1331,7 +1332,7 @@ export class ConversationModel extends window.Backbone return; } - this.addSingleMessage(message); + void this.addSingleMessage(message); } // New messages might arrive while we're in the middle of a bulk fetch from the @@ -1380,7 +1381,7 @@ export class ConversationModel extends window.Backbone newestId && messageIds && messageIds[messageIds.length - 1] === newestId; if (isJustSent && existingConversation && !isLatestInMemory) { - this.loadNewestMessages(undefined, undefined); + void this.loadNewestMessages(undefined, undefined); } else if ( // The message has to be not a story or has to be a story reply in direct // conversation. @@ -1452,12 +1453,12 @@ export class ConversationModel extends window.Backbone // scroll directly to the oldest message, because that could scroll the hero off // the screen. if (!newestMessageId && !this.getAccepted() && metrics.oldest) { - this.loadAndScroll(metrics.oldest.id, { disableScroll: true }); + void this.loadAndScroll(metrics.oldest.id, { disableScroll: true }); return; } if (scrollToLatestUnread && metrics.oldestUnseen) { - this.loadAndScroll(metrics.oldestUnseen.id, { + void this.loadAndScroll(metrics.oldestUnseen.id, { disableScroll: !setFocus, }); return; @@ -1939,12 +1940,12 @@ export class ConversationModel extends window.Backbone this.get('profileSharing') || this.get('sentMessageCount') ); if (!oldValue && e164 && haveSentMessage && !disableDiscoveryNotification) { - this.addPhoneNumberDiscovery(e164); + void this.addPhoneNumberDiscovery(e164); } // This user changed their phone number if (oldValue && e164) { - this.addChangeNumberNotification(oldValue, e164); + void this.addChangeNumberNotification(oldValue, e164); } window.Signal.Data.updateConversation(this.attributes); @@ -1966,7 +1967,11 @@ export class ConversationModel extends window.Backbone // for the case where we need to do old and new PNI comparisons. We'll wait // for the PNI update to do that. if (oldValue && oldValue !== this.get('pni')) { - window.textsecure.storage.protocol.removeIdentityKey(UUID.cast(oldValue)); + drop( + window.textsecure.storage.protocol.removeIdentityKey( + UUID.cast(oldValue) + ) + ); } this.captureChange('updateUuid'); @@ -1985,7 +1990,7 @@ export class ConversationModel extends window.Backbone log.warn( `${logId}: Already had previousIdentityKey, new one does not match` ); - this.addKeyChange('trackPreviousIdentityKey - change'); + void this.addKeyChange('trackPreviousIdentityKey - change'); } log.warn(`${logId}: Setting new previousIdentityKey`); @@ -2031,7 +2036,7 @@ export class ConversationModel extends window.Backbone newIdentityRecord.publicKey ) ) { - this.addKeyChange('updatePni - change'); + void this.addKeyChange('updatePni - change'); } else if (!newIdentityRecord && oldIdentityRecord) { this.trackPreviousIdentityKey(oldIdentityRecord.publicKey); } @@ -2052,7 +2057,11 @@ export class ConversationModel extends window.Backbone // If this PNI is going away or going to someone else, we'll delete all its sessions if (oldValue) { - window.textsecure.storage.protocol.removeIdentityKey(UUID.cast(oldValue)); + drop( + window.textsecure.storage.protocol.removeIdentityKey( + UUID.cast(oldValue) + ) + ); } if (pni && !this.get('uuid')) { @@ -2235,7 +2244,7 @@ export class ConversationModel extends window.Backbone isGroupV1(this.attributes) || isDirectConversation(this.attributes) ) { - this.sendProfileKeyUpdate(); + void this.sendProfileKeyUpdate(); } else if ( isGroupV2(this.attributes) && this.isMemberPending(ourACI) @@ -2283,7 +2292,7 @@ export class ConversationModel extends window.Backbone // Delete messages locally, other devices should delete upon receiving // the sync message await this.destroyMessages(); - this.updateLastMessage(); + void this.updateLastMessage(); if (isLocalAction) { this.trigger('unload', 'deleted from message request'); @@ -2302,7 +2311,7 @@ export class ConversationModel extends window.Backbone // Delete messages locally, other devices should delete upon receiving // the sync message await this.destroyMessages(); - this.updateLastMessage(); + void this.updateLastMessage(); if (isLocalAction) { this.trigger('unload', 'blocked and deleted from message request'); @@ -2944,7 +2953,7 @@ export class ConversationModel extends window.Backbone ); this.trigger('newmessage', model); - this.updateUnread(); + void this.updateUnread(); } async addDeliveryIssue({ @@ -2990,7 +2999,7 @@ export class ConversationModel extends window.Backbone this.trigger('newmessage', model); await this.notify(model); - this.updateUnread(); + void this.updateUnread(); } async addKeyChange(reason: string, keyChangedId?: UUID): Promise { @@ -3053,7 +3062,7 @@ export class ConversationModel extends window.Backbone parsedUuid ); groups.forEach(group => { - group.addKeyChange('addKeyChange - group fan-out', parsedUuid); + void group.addKeyChange('addKeyChange - group fan-out', parsedUuid); }); } @@ -3197,14 +3206,14 @@ export class ConversationModel extends window.Backbone ); this.trigger('newmessage', model); - this.updateUnread(); + void this.updateUnread(); const uuid = this.getUuid(); if (isDirectConversation(this.attributes) && uuid) { - window.ConversationController.getAllGroupsInvolvingUuid(uuid).then( + void window.ConversationController.getAllGroupsInvolvingUuid(uuid).then( groups => { groups.forEach(group => { - group.addVerifiedChange(this.id, verified, options); + void group.addVerifiedChange(this.id, verified, options); }); } ); @@ -3263,7 +3272,7 @@ export class ConversationModel extends window.Backbone ); this.trigger('newmessage', model); - this.updateUnread(); + void this.updateUnread(); if (this.get('isArchived')) { this.setArchived(false); @@ -3289,7 +3298,7 @@ export class ConversationModel extends window.Backbone (await window.Signal.Data.hasGroupCallHistoryMessage(this.id, eraId)); if (alreadyHasMessage) { - this.updateLastMessage(); + void this.updateLastMessage(); return false; } @@ -3338,10 +3347,10 @@ export class ConversationModel extends window.Backbone const uuid = this.getUuid(); if (isDirectConversation(this.attributes) && uuid) { - window.ConversationController.getAllGroupsInvolvingUuid(uuid).then( + void window.ConversationController.getAllGroupsInvolvingUuid(uuid).then( groups => { groups.forEach(group => { - group.addProfileChange(profileChange, this.id); + void group.addProfileChange(profileChange, this.id); }); } ); @@ -3892,11 +3901,13 @@ export class ConversationModel extends window.Backbone }, }; - this.enqueueMessageForSend({ - body: undefined, - attachments: [], - sticker, - }); + drop( + this.enqueueMessageForSend({ + body: undefined, + attachments: [], + sticker, + }) + ); window.reduxActions.stickers.useSticker(packId, stickerId); } @@ -4019,7 +4030,7 @@ export class ConversationModel extends window.Backbone if (preview && preview.length) { attachments.forEach(attachment => { if (attachment.path) { - deleteAttachmentData(attachment.path); + void deleteAttachmentData(attachment.path); } }); } @@ -4208,8 +4219,10 @@ export class ConversationModel extends window.Backbone }); // This runs as a job to avoid race conditions - this.queueJob('maybeSetPendingUniversalTimer', async () => - this.maybeSetPendingUniversalTimer(stats.hasUserInitiatedMessages) + drop( + this.queueJob('maybeSetPendingUniversalTimer', async () => + this.maybeSetPendingUniversalTimer(stats.hasUserInitiatedMessages) + ) ); const { preview, activity } = stats; @@ -4608,8 +4621,8 @@ export class ConversationModel extends window.Backbone const message = window.MessageController.register(id, model); - this.addSingleMessage(message); - this.updateUnread(); + void this.addSingleMessage(message); + void this.updateUnread(); log.info( `${logId}: added a notification received_at=${model.get('received_at')}` @@ -4664,10 +4677,10 @@ export class ConversationModel extends window.Backbone model.set({ id }); const message = window.MessageController.register(model.id, model); - this.addSingleMessage(message); + void this.addSingleMessage(message); const options = await getSendOptions(this.attributes); - message.send( + void message.send( handleMessageSend( messaging.leaveGroup(groupId, groupIdentifiers, options), { messageIds: [], sendType: 'legacyGroupChange' } @@ -4739,7 +4752,7 @@ export class ConversationModel extends window.Backbone onChangeProfileKey(): void { if (isDirectConversation(this.attributes)) { - this.getProfiles(); + void this.getProfiles(); } } @@ -4799,9 +4812,9 @@ export class ConversationModel extends window.Backbone ): Promise { if (isMe(this.attributes)) { if (avatarPath) { - window.storage.put('avatarUrl', avatarPath); + await window.storage.put('avatarUrl', avatarPath); } else { - window.storage.remove('avatarUrl'); + await window.storage.remove('avatarUrl'); } } @@ -4938,7 +4951,7 @@ export class ConversationModel extends window.Backbone 'deriveProfileKeyVersion: Failed to derive profile key version, ' + 'clearing profile key.' ); - this.setProfileKey(undefined); + void this.setProfileKey(undefined); return; } @@ -5210,7 +5223,7 @@ export class ConversationModel extends window.Backbone log.info('storageService[captureChange]', logMessage, this.idForLogging()); this.set({ needsStorageServiceSync: true }); - this.queueJob('captureChange', async () => { + void this.queueJob('captureChange', async () => { storageServiceUploadJob(); }); } @@ -5474,7 +5487,7 @@ export class ConversationModel extends window.Backbone } writePinnedConversations(pinnedConversationIds: Array): void { - window.storage.put('pinnedConversationIds', pinnedConversationIds); + drop(window.storage.put('pinnedConversationIds', pinnedConversationIds)); const myId = window.ConversationController.getOurConversationId(); const me = window.ConversationController.get(myId); diff --git a/ts/models/messages.ts b/ts/models/messages.ts index 4b8394f87871..2f66ffbb0bbf 100644 --- a/ts/models/messages.ts +++ b/ts/models/messages.ts @@ -39,6 +39,7 @@ import { isNotNil } from '../util/isNotNil'; import { isNormalNumber } from '../util/isNormalNumber'; import { softAssert, strictAssert } from '../util/assert'; import { missingCaseError } from '../util/missingCaseError'; +import { drop } from '../util/drop'; import { dropNull } from '../util/dropNull'; import { incrementMessageCounter } from '../util/incrementMessageCounter'; import type { ConversationModel } from './conversations'; @@ -1791,7 +1792,7 @@ export class MessageModel extends window.Backbone.Model { saveErrors(errorsToSave); } else { // We skip save because we'll save in the next step. - this.saveErrors(errorsToSave, { skipSave: true }); + void this.saveErrors(errorsToSave, { skipSave: true }); } if (!this.doNotSave) { @@ -1853,7 +1854,7 @@ export class MessageModel extends window.Backbone.Model { saveErrors(errors); } else { // We don't save because we're about to save below. - this.saveErrors(errors, { skipSave: true }); + void this.saveErrors(errors, { skipSave: true }); } throw error; } finally { @@ -2583,15 +2584,19 @@ export class MessageModel extends window.Backbone.Model { // Note: We both queue and batch because we want to wait until we are done // processing incoming messages to start sending outgoing delivery receipts. // The queue can be paused easily. - window.Whisper.deliveryReceiptQueue.add(() => { - window.Whisper.deliveryReceiptBatcher.add({ - messageId, - senderE164: source, - senderUuid: sourceUuid, - timestamp: this.get('sent_at'), - isDirectConversation: isDirectConversation(conversation.attributes), - }); - }); + drop( + window.Whisper.deliveryReceiptQueue.add(() => { + window.Whisper.deliveryReceiptBatcher.add({ + messageId, + senderE164: source, + senderUuid: sourceUuid, + timestamp: this.get('sent_at'), + isDirectConversation: isDirectConversation( + conversation.attributes + ), + }); + }) + ); } const [quote, storyQuote] = await Promise.all([ @@ -2957,7 +2962,7 @@ export class MessageModel extends window.Backbone.Model { // along with an expireTimer), the conversation will be updated by this // point and these calls will return early. if (dataMessage.expireTimer) { - conversation.updateExpirationTimer(dataMessage.expireTimer, { + void conversation.updateExpirationTimer(dataMessage.expireTimer, { source: sourceUuid || source, receivedAt: message.get('received_at'), receivedAtMS: message.get('received_at_ms'), @@ -2970,7 +2975,7 @@ export class MessageModel extends window.Backbone.Model { !isGroupUpdate(message.attributes) && !isEndSession(message.attributes) ) { - conversation.updateExpirationTimer(undefined, { + void conversation.updateExpirationTimer(undefined, { source: sourceUuid || source, receivedAt: message.get('received_at'), receivedAtMS: message.get('received_at_ms'), @@ -2989,14 +2994,14 @@ export class MessageModel extends window.Backbone.Model { ) { conversation.set({ profileSharing: true }); } else if (isDirectConversation(conversation.attributes)) { - conversation.setProfileKey(profileKey); + void conversation.setProfileKey(profileKey); } else { const local = window.ConversationController.lookupOrCreate({ e164: source, uuid: sourceUuid, reason: 'handleDataMessage:setProfileKey', }); - local?.setProfileKey(profileKey); + void local?.setProfileKey(profileKey); } } @@ -3119,7 +3124,7 @@ export class MessageModel extends window.Backbone.Model { await this.modifyTargetMessage(conversation, isFirstRun); log.info(`${idLog}: Batching save`); - this.saveAndNotify(conversation, confirm); + void this.saveAndNotify(conversation, confirm); } catch (error) { const errorForLog = Errors.toLogFormat(error); log.error(`${idLog}: error:`, errorForLog); @@ -3154,7 +3159,9 @@ export class MessageModel extends window.Backbone.Model { confirm(); if (!isStory(this.attributes)) { - conversation.queueJob('updateUnread', () => conversation.updateUnread()); + drop( + conversation.queueJob('updateUnread', () => conversation.updateUnread()) + ); } } @@ -3307,7 +3314,7 @@ export class MessageModel extends window.Backbone.Model { // We run this when `isFirstRun` is false so that it triggers when the // message and the other ones accompanying it in the batch are fully in // the database. - message.getConversation()?.onReadMessage(message, markReadAt); + void message.getConversation()?.onReadMessage(message, markReadAt); } // Check for out-of-order view once open syncs @@ -3450,7 +3457,7 @@ export class MessageModel extends window.Backbone.Model { 'handleReaction: receiving story reaction to ' + `${this.idForLogging()} from someone else` ); - conversation.notify(this, reaction); + void conversation.notify(this, reaction); } } else if (isFromThisDevice) { log.info( @@ -3522,7 +3529,7 @@ export class MessageModel extends window.Backbone.Model { this.set({ reactions }); if (isOutgoing(this.attributes) && isFromSomeoneElse) { - conversation.notify(this, reaction); + void conversation.notify(this, reaction); } await window.Signal.Data.addReaction({ @@ -3583,7 +3590,7 @@ export class MessageModel extends window.Backbone.Model { reactionMessage.hydrateStoryContext(this), ]); - conversation.addSingleMessage( + void conversation.addSingleMessage( window.MessageController.register(reactionMessage.id, reactionMessage) ); @@ -3652,7 +3659,7 @@ export class MessageModel extends window.Backbone.Model { ); // Update the conversation's last message in case this was the last message - this.getConversation()?.updateLastMessage(); + void this.getConversation()?.updateLastMessage(); } finally { this.deletingForEveryone = undefined; } diff --git a/ts/routineProfileRefresh.ts b/ts/routineProfileRefresh.ts index 1063ff0070a7..64c81a31b277 100644 --- a/ts/routineProfileRefresh.ts +++ b/ts/routineProfileRefresh.ts @@ -14,6 +14,7 @@ import type { ConversationModel } from './models/conversations'; import type { StorageInterface } from './types/Storage.d'; import * as Errors from './types/errors'; import { getProfile } from './util/getProfile'; +import { drop } from './util/drop'; import { MINUTE, HOUR, DAY, WEEK, MONTH } from './util/durations'; const STORAGE_KEY = 'lastAttemptedToRefreshProfilesAt'; @@ -155,7 +156,7 @@ export async function routineProfileRefresh({ throwOnTimeout: true, }); for (const conversation of conversationsToRefresh) { - refreshQueue.add(() => refreshConversation(conversation)); + drop(refreshQueue.add(() => refreshConversation(conversation))); } await refreshQueue.onIdle(); diff --git a/ts/services/LinkPreview.ts b/ts/services/LinkPreview.ts index c1836f5fbd3f..d39e92fea2fa 100644 --- a/ts/services/LinkPreview.ts +++ b/ts/services/LinkPreview.ts @@ -92,7 +92,7 @@ function _maybeGrabLinkPreview( return; } - addLinkPreview(link, source, { + void addLinkPreview(link, source, { disableFetch: !window.Events.getLinkPreviewSetting(), }); } diff --git a/ts/services/areWeASubscriber.ts b/ts/services/areWeASubscriber.ts index d0a60cc1bac2..1f0e8c36dbf5 100644 --- a/ts/services/areWeASubscriber.ts +++ b/ts/services/areWeASubscriber.ts @@ -19,13 +19,13 @@ export class AreWeASubscriberService { const subscriberId = storage.get('subscriberId'); if (!subscriberId || !subscriberId.byteLength) { - storage.put('areWeASubscriber', false); + await storage.put('areWeASubscriber', false); return; } await waitForOnline(navigator, window); - storage.put( + await storage.put( 'areWeASubscriber', await server.getHasSubscription(subscriberId) ); diff --git a/ts/services/audioRecorder.ts b/ts/services/audioRecorder.ts index 3f2c735a9925..1a53e066a0e1 100644 --- a/ts/services/audioRecorder.ts +++ b/ts/services/audioRecorder.ts @@ -39,7 +39,7 @@ export class RecorderClass { this.stream = undefined; if (this.context) { - this.context.close(); + void this.context.close(); this.context = undefined; } } diff --git a/ts/services/calling.ts b/ts/services/calling.ts index beaa93641e0e..478b9f72d2b1 100644 --- a/ts/services/calling.ts +++ b/ts/services/calling.ts @@ -71,6 +71,7 @@ import * as Errors from '../types/errors'; import type { ConversationModel } from '../models/conversations'; import * as Bytes from '../Bytes'; import { uuidToBytes, bytesToUuid } from '../Crypto'; +import { drop } from '../util/drop'; import { dropNull, shallowDropNull } from '../util/dropNull'; import { getOwn } from '../util/getOwn'; import { isNormalNumber } from '../util/isNormalNumber'; @@ -311,9 +312,11 @@ export class CallingClass { window.storage.get('previousAudioDeviceModule') ); this.currentAudioDeviceModule = getAudioDeviceModule(); - window.storage.put( - 'previousAudioDeviceModule', - this.currentAudioDeviceModule + drop( + window.storage.put( + 'previousAudioDeviceModule', + this.currentAudioDeviceModule + ) ); RingRTC.setConfig({ @@ -348,7 +351,7 @@ export class CallingClass { } }); - this.cleanExpiredGroupCallRingsAndLoop(); + void this.cleanExpiredGroupCallRingsAndLoop(); } private attemptToGiveOurUuidToRingRtc(): void { @@ -699,7 +702,7 @@ export class CallingClass { eraId ) { updateMessageState = GroupCallUpdateMessageState.SentLeft; - this.sendGroupCallUpdateMessage(conversationId, eraId); + void this.sendGroupCallUpdateMessage(conversationId, eraId); } } else { this.callsByConversation[conversationId] = groupCall; @@ -717,7 +720,7 @@ export class CallingClass { eraId ) { updateMessageState = GroupCallUpdateMessageState.SentJoin; - this.sendGroupCallUpdateMessage(conversationId, eraId); + void this.sendGroupCallUpdateMessage(conversationId, eraId); } } @@ -749,10 +752,10 @@ export class CallingClass { eraId ) { updateMessageState = GroupCallUpdateMessageState.SentJoin; - this.sendGroupCallUpdateMessage(conversationId, eraId); + void this.sendGroupCallUpdateMessage(conversationId, eraId); } - this.updateCallHistoryForGroupCall( + void this.updateCallHistoryForGroupCall( conversationId, groupCall.getPeekInfo() ); @@ -1458,7 +1461,7 @@ export class CallingClass { device.index, truncateForLogging(device.name) ); - window.Events.setPreferredAudioInputDevice(device); + void window.Events.setPreferredAudioInputDevice(device); RingRTC.setAudioInput(device.index); } @@ -1468,7 +1471,7 @@ export class CallingClass { device.index, truncateForLogging(device.name) ); - window.Events.setPreferredAudioOutputDevice(device); + void window.Events.setPreferredAudioOutputDevice(device); RingRTC.setAudioOutput(device.index); } @@ -1482,7 +1485,7 @@ export class CallingClass { async setPreferredCamera(device: string): Promise { log.info('MediaDevice: setPreferredCamera', device); - window.Events.setPreferredVideoInputDevice(device); + void window.Events.setPreferredVideoInputDevice(device); await this.videoCapturer.setPreferredDevice(device); } @@ -2107,7 +2110,7 @@ export class CallingClass { acceptedTime = Date.now(); } - conversation.addCallHistory( + void conversation.addCallHistory( { callMode: CallMode.Direct, wasIncoming: call.isIncoming, @@ -2125,7 +2128,7 @@ export class CallingClass { wasVideoCall: boolean, timestamp: number ) { - conversation.addCallHistory( + void conversation.addCallHistory( { callMode: CallMode.Direct, wasIncoming: true, @@ -2156,7 +2159,7 @@ export class CallingClass { } // Otherwise it will show up as a missed call. - conversation.addCallHistory( + void conversation.addCallHistory( { callMode: CallMode.Direct, wasIncoming: true, @@ -2264,7 +2267,7 @@ export class CallingClass { } setTimeout(() => { - this.cleanExpiredGroupCallRingsAndLoop(); + void this.cleanExpiredGroupCallRingsAndLoop(); }, CLEAN_EXPIRED_GROUP_CALL_RINGS_INTERVAL); } } diff --git a/ts/services/expiringMessagesDeletion.ts b/ts/services/expiringMessagesDeletion.ts index 36430b38fb7b..89ac28a36228 100644 --- a/ts/services/expiringMessagesDeletion.ts +++ b/ts/services/expiringMessagesDeletion.ts @@ -78,7 +78,7 @@ class ExpiringMessagesDeletionService { window.SignalContext.log.info( 'destroyExpiredMessages: done, scheduling another check' ); - this.update(); + void this.update(); } private async checkExpiringMessages() { diff --git a/ts/services/groupCredentialFetcher.ts b/ts/services/groupCredentialFetcher.ts index c4e5fe9987d0..1ded8fedce39 100644 --- a/ts/services/groupCredentialFetcher.ts +++ b/ts/services/groupCredentialFetcher.ts @@ -191,7 +191,7 @@ export async function maybeFetchNewCredentials(): Promise { log.info(`${logId}: Saving new credentials...`); // Note: we don't wait for this to finish - window.storage.put('groupCredentials', finalCredentials); + await window.storage.put('groupCredentials', finalCredentials); log.info(`${logId}: Save complete.`); } diff --git a/ts/services/networkObserver.ts b/ts/services/networkObserver.ts index b375e0d6723e..19a8c572397c 100644 --- a/ts/services/networkObserver.ts +++ b/ts/services/networkObserver.ts @@ -26,7 +26,7 @@ export function initializeNetworkObserver( if (socketStatus === SocketStatus.CLOSED) { // If we couldn't connect during startup - we should still switch SQL to // the main process to avoid stalling UI. - window.Signal.Data.goBackToMainProcess(); + void window.Signal.Data.goBackToMainProcess(); } networkActions.checkNetworkStatus({ diff --git a/ts/services/notifications.ts b/ts/services/notifications.ts index f5308c12ac63..a5393b8f661e 100644 --- a/ts/services/notifications.ts +++ b/ts/services/notifications.ts @@ -157,7 +157,7 @@ class NotificationService extends EventEmitter { audioNotificationSupport === AudioNotificationSupport.Custom ) { // We kick off the sound to be played. No need to await it. - new Sound({ src: 'sounds/notification.ogg' }).play(); + void new Sound({ src: 'sounds/notification.ogg' }).play(); } this.lastNotification = notification; diff --git a/ts/services/profiles.ts b/ts/services/profiles.ts index 55058bffae54..4217feeae5a0 100644 --- a/ts/services/profiles.ts +++ b/ts/services/profiles.ts @@ -26,6 +26,7 @@ import { isMe } from '../util/whatTypeOfConversation'; import { getUserLanguages } from '../util/userLanguages'; import { parseBadgesFromServer } from '../badges/parseBadgesFromServer'; import { strictAssert } from '../util/assert'; +import { drop } from '../util/drop'; import { findRetryAfterTimeFromError } from '../jobs/helpers/findRetryAfterTimeFromError'; import { SEALED_SENDER } from '../types/SealedSender'; import { HTTPError } from '../textsecure/Errors'; @@ -123,7 +124,7 @@ export class ProfileService { if (isRecord(error) && 'code' in error && error.code === 413) { this.clearAll('got 413 from server'); const time = findRetryAfterTimeFromError(error); - this.pause(time); + void this.pause(time); } } finally { this.jobsByConversationId.delete(conversationId); @@ -139,7 +140,7 @@ export class ProfileService { }; this.jobsByConversationId.set(conversationId, jobData); - this.jobQueue.add(job); + drop(this.jobQueue.add(job)); return promise; } @@ -416,7 +417,7 @@ async function doGetProfile(c: ConversationModel): Promise { } if (profile.paymentAddress && isMe(c.attributes)) { - window.storage.put('paymentAddress', profile.paymentAddress); + await window.storage.put('paymentAddress', profile.paymentAddress); } if (profile.capabilities) { diff --git a/ts/services/storage.ts b/ts/services/storage.ts index cc7ff258b142..ed5b2032a321 100644 --- a/ts/services/storage.ts +++ b/ts/services/storage.ts @@ -361,7 +361,7 @@ async function generateManifest( if (isNewItem) { postUploadUpdateFunctions.push(() => { - dataInterface.modifyStoryDistribution({ + void dataInterface.modifyStoryDistribution({ ...storyDistributionList, storageID, storageVersion: version, @@ -394,7 +394,7 @@ async function generateManifest( if (isNewItem) { postUploadUpdateFunctions.push(() => { - dataInterface.addUninstalledStickerPack({ + void dataInterface.addUninstalledStickerPack({ ...stickerPack, storageID, storageVersion: version, @@ -436,7 +436,7 @@ async function generateManifest( if (isNewItem) { postUploadUpdateFunctions.push(() => { - dataInterface.createOrUpdateStickerPack({ + void dataInterface.createOrUpdateStickerPack({ ...stickerPack, storageID, storageVersion: version, @@ -784,7 +784,7 @@ async function uploadManifest( } log.info(`storageService.upload(${version}): setting new manifestVersion`); - window.storage.put('manifestVersion', version); + await window.storage.put('manifestVersion', version); conflictBackOff.reset(); backOff.reset(); @@ -883,7 +883,7 @@ async function fetchManifest( try { const credentials = await window.textsecure.messaging.getStorageCredentials(); - window.storage.put('storageCredentials', credentials); + await window.storage.put('storageCredentials', credentials); const manifestBinary = await window.textsecure.messaging.getStorageManifest( { @@ -1247,7 +1247,7 @@ async function processManifest( `storageService.process(${version}): localKey=${missingKey} was not ` + 'in remote manifest' ); - dataInterface.addUninstalledStickerPack({ + void dataInterface.addUninstalledStickerPack({ ...stickerPack, storageID: undefined, storageVersion: undefined, @@ -1265,7 +1265,7 @@ async function processManifest( `storageService.process(${version}): localKey=${missingKey} was not ` + 'in remote manifest' ); - dataInterface.createOrUpdateStickerPack({ + void dataInterface.createOrUpdateStickerPack({ ...stickerPack, storageID: undefined, storageVersion: undefined, @@ -1283,7 +1283,7 @@ async function processManifest( `storageService.process(${version}): localKey=${missingKey} was not ` + 'in remote manifest' ); - dataInterface.modifyStoryDistribution({ + void dataInterface.modifyStoryDistribution({ ...storyDistributionList, storageID: undefined, storageVersion: undefined, @@ -1688,7 +1688,7 @@ async function sync( const previousFetchComplete = window.storage.get('storageFetchComplete'); const manifestFromStorage = window.storage.get('manifestVersion'); if (!previousFetchComplete && isNumber(manifestFromStorage)) { - window.storage.put('storageFetchComplete', true); + await window.storage.put('storageFetchComplete', true); } const localManifestVersion = manifestFromStorage || 0; @@ -1931,7 +1931,7 @@ export const storageServiceUploadJob = debounce(() => { return; } - storageJobQueue(async () => { + void storageJobQueue(async () => { await upload(); }, `upload v${window.storage.get('manifestVersion')}`); }, 500); diff --git a/ts/services/storageRecordOps.ts b/ts/services/storageRecordOps.ts index a0d86747fd89..9c2705cb5faf 100644 --- a/ts/services/storageRecordOps.ts +++ b/ts/services/storageRecordOps.ts @@ -523,14 +523,14 @@ function applyMessageRequestState( const messageRequestEnum = Proto.SyncMessage.MessageRequestResponse.Type; if (record.blocked) { - conversation.applyMessageRequestResponse(messageRequestEnum.BLOCK, { + void conversation.applyMessageRequestResponse(messageRequestEnum.BLOCK, { fromSync: true, viaStorageServiceSync: true, }); } else if (record.whitelisted) { // unblocking is also handled by this function which is why the next // condition is part of the else-if and not separate - conversation.applyMessageRequestResponse(messageRequestEnum.ACCEPT, { + void conversation.applyMessageRequestResponse(messageRequestEnum.ACCEPT, { fromSync: true, viaStorageServiceSync: true, }); @@ -893,7 +893,7 @@ export async function mergeGroupV2Record( // We don't await this because this could take a very long time, waiting for queues to // empty, etc. - waitThenRespondToGroupV2Migration({ + void waitThenRespondToGroupV2Migration({ conversation, }); } else if (isGroupNewToUs) { @@ -903,7 +903,7 @@ export async function mergeGroupV2Record( // We don't await this because this could take a very long time, waiting for queues to // empty, etc. - waitThenMaybeUpdateGroup( + void waitThenMaybeUpdateGroup( { conversation, dropInitialJoinMessage, @@ -1001,7 +1001,7 @@ export async function mergeContactRecord( ) { // Local name doesn't match remote name, fetch profile if (localName) { - conversation.getProfiles(); + void conversation.getProfiles(); details.push('refreshing profile'); } else { conversation.set({ @@ -1134,36 +1134,36 @@ export async function mergeAccountRecord( const updatedConversations = new Array(); - window.storage.put('read-receipt-setting', Boolean(readReceipts)); + await window.storage.put('read-receipt-setting', Boolean(readReceipts)); if (typeof sealedSenderIndicators === 'boolean') { - window.storage.put('sealedSenderIndicators', sealedSenderIndicators); + await window.storage.put('sealedSenderIndicators', sealedSenderIndicators); } if (typeof typingIndicators === 'boolean') { - window.storage.put('typingIndicators', typingIndicators); + await window.storage.put('typingIndicators', typingIndicators); } if (typeof linkPreviews === 'boolean') { - window.storage.put('linkPreviews', linkPreviews); + await window.storage.put('linkPreviews', linkPreviews); } if (typeof preferContactAvatars === 'boolean') { const previous = window.storage.get('preferContactAvatars'); - window.storage.put('preferContactAvatars', preferContactAvatars); + await window.storage.put('preferContactAvatars', preferContactAvatars); if (Boolean(previous) !== Boolean(preferContactAvatars)) { - window.ConversationController.forceRerender(); + await window.ConversationController.forceRerender(); } } if (typeof primarySendsSms === 'boolean') { - window.storage.put('primarySendsSms', primarySendsSms); + await window.storage.put('primarySendsSms', primarySendsSms); } if (typeof accountE164 === 'string' && accountE164) { - window.storage.put('accountE164', accountE164); - window.storage.user.setNumber(accountE164); + await window.storage.put('accountE164', accountE164); + await window.storage.user.setNumber(accountE164); } if (preferredReactionEmoji.canBeSynced(rawPreferredReactionEmoji)) { @@ -1176,10 +1176,13 @@ export async function mergeAccountRecord( rawPreferredReactionEmoji.length ); } - window.storage.put('preferredReactionEmoji', rawPreferredReactionEmoji); + await window.storage.put( + 'preferredReactionEmoji', + rawPreferredReactionEmoji + ); } - setUniversalExpireTimer( + void setUniversalExpireTimer( DurationInSeconds.fromSeconds(universalExpireTimer || 0) ); @@ -1206,15 +1209,18 @@ export async function mergeAccountRecord( phoneNumberSharingModeToStore = PhoneNumberSharingMode.Everybody; break; } - window.storage.put('phoneNumberSharingMode', phoneNumberSharingModeToStore); + await window.storage.put( + 'phoneNumberSharingMode', + phoneNumberSharingModeToStore + ); const discoverability = notDiscoverableByPhoneNumber ? PhoneNumberDiscoverability.NotDiscoverable : PhoneNumberDiscoverability.Discoverable; - window.storage.put('phoneNumberDiscoverability', discoverability); + await window.storage.put('phoneNumberDiscoverability', discoverability); if (profileKey) { - ourProfileKeyService.set(profileKey); + void ourProfileKeyService.set(profileKey); } if (pinnedConversations) { @@ -1323,40 +1329,52 @@ export async function mergeAccountRecord( updatedConversations.push(conversation); }); - window.storage.put('pinnedConversationIds', remotelyPinnedConversationIds); + await window.storage.put( + 'pinnedConversationIds', + remotelyPinnedConversationIds + ); } if (subscriberId instanceof Uint8Array) { - window.storage.put('subscriberId', subscriberId); + await window.storage.put('subscriberId', subscriberId); } if (typeof subscriberCurrencyCode === 'string') { - window.storage.put('subscriberCurrencyCode', subscriberCurrencyCode); + await window.storage.put('subscriberCurrencyCode', subscriberCurrencyCode); } - window.storage.put('displayBadgesOnProfile', Boolean(displayBadgesOnProfile)); - window.storage.put('keepMutedChatsArchived', Boolean(keepMutedChatsArchived)); - window.storage.put('hasSetMyStoriesPrivacy', Boolean(hasSetMyStoriesPrivacy)); + await window.storage.put( + 'displayBadgesOnProfile', + Boolean(displayBadgesOnProfile) + ); + await window.storage.put( + 'keepMutedChatsArchived', + Boolean(keepMutedChatsArchived) + ); + await window.storage.put( + 'hasSetMyStoriesPrivacy', + Boolean(hasSetMyStoriesPrivacy) + ); { const hasViewedOnboardingStoryBool = Boolean(hasViewedOnboardingStory); - window.storage.put( + await window.storage.put( 'hasViewedOnboardingStory', hasViewedOnboardingStoryBool ); if (hasViewedOnboardingStoryBool) { - findAndDeleteOnboardingStoryIfExists(); + void findAndDeleteOnboardingStoryIfExists(); } } { const hasStoriesDisabled = Boolean(storiesDisabled); - window.storage.put('hasStoriesDisabled', hasStoriesDisabled); + await window.storage.put('hasStoriesDisabled', hasStoriesDisabled); window.textsecure.server?.onHasStoriesDisabledChange(hasStoriesDisabled); } switch (storyViewReceiptsEnabled) { case Proto.OptionalBool.ENABLED: - window.storage.put('storyViewReceiptsEnabled', true); + await window.storage.put('storyViewReceiptsEnabled', true); break; case Proto.OptionalBool.DISABLED: - window.storage.put('storyViewReceiptsEnabled', false); + await window.storage.put('storyViewReceiptsEnabled', false); break; case Proto.OptionalBool.UNSET: default: @@ -1396,7 +1414,7 @@ export async function mergeAccountRecord( const avatarUrl = dropNull(accountRecord.avatarUrl); await conversation.setProfileAvatar(avatarUrl, profileKey); - window.storage.put('avatarUrl', avatarUrl); + await window.storage.put('avatarUrl', avatarUrl); } const { hasConflict, details: extraDetails } = doesRecordHavePendingChanges( @@ -1663,7 +1681,7 @@ export async function mergeStickerPackRecord( } ); } else { - Stickers.downloadStickerPack(stickerPack.id, stickerPack.key, { + void Stickers.downloadStickerPack(stickerPack.id, stickerPack.key, { finalStatus: 'installed', fromStorageService: true, }); diff --git a/ts/services/tapToViewMessagesDeletionService.ts b/ts/services/tapToViewMessagesDeletionService.ts index 13d9a22220c9..192e308166a2 100644 --- a/ts/services/tapToViewMessagesDeletionService.ts +++ b/ts/services/tapToViewMessagesDeletionService.ts @@ -76,7 +76,7 @@ class TapToViewMessagesDeletionService { clearTimeoutIfNecessary(this.timeout); this.timeout = setTimeout(async () => { await eraseTapToViewMessages(); - this.update(); + void this.update(); }, wait); } } diff --git a/ts/shims/storage.ts b/ts/shims/storage.ts index 8ea8736baecd..b5f8e4cc4e2d 100644 --- a/ts/shims/storage.ts +++ b/ts/shims/storage.ts @@ -4,11 +4,11 @@ import type { StorageAccessType } from '../types/Storage.d'; // Matching window.storage.put API -export function put( +export async function put( key: K, value: StorageAccessType[K] -): void { - window.storage.put(key, value); +): Promise { + await window.storage.put(key, value); } export async function remove(key: keyof StorageAccessType): Promise { diff --git a/ts/sql/Client.ts b/ts/sql/Client.ts index 94b5be03dd06..2bb62f00538c 100644 --- a/ts/sql/Client.ts +++ b/ts/sql/Client.ts @@ -37,6 +37,7 @@ import * as Errors from '../types/errors'; import type { StoredJob } from '../jobs/types'; import { formatJobForInsert } from '../jobs/formatJobForInsert'; import { cleanupMessage } from '../util/cleanup'; +import { drop } from '../util/drop'; import type { AllItemsType, @@ -631,8 +632,8 @@ async function saveMessage( softAssert(isValidUuid(id), 'saveMessage: messageId is not a UUID'); - expiringMessagesDeletionService.update(); - tapToViewMessagesDeletionService.update(); + void expiringMessagesDeletionService.update(); + void tapToViewMessagesDeletionService.update(); return id; } @@ -646,8 +647,8 @@ async function saveMessages( options ); - expiringMessagesDeletionService.update(); - tapToViewMessagesDeletionService.update(); + void expiringMessagesDeletionService.update(); + void tapToViewMessagesDeletionService.update(); } async function removeMessage(id: string): Promise { @@ -781,9 +782,11 @@ async function removeAllMessagesInConversation( // Note: It's very important that these models are fully hydrated because // we need to delete all associated on-disk files along with the database delete. const queue = new PQueue({ concurrency: 3, timeout: MINUTE * 30 }); - queue.addAll( - messages.map( - (message: MessageType) => async () => cleanupMessage(message) + drop( + queue.addAll( + messages.map( + (message: MessageType) => async () => cleanupMessage(message) + ) ) ); // eslint-disable-next-line no-await-in-loop diff --git a/ts/state/ducks/audioPlayer.ts b/ts/state/ducks/audioPlayer.ts index aa158a3f0084..e4b69f5d446f 100644 --- a/ts/state/ducks/audioPlayer.ts +++ b/ts/state/ducks/audioPlayer.ts @@ -122,7 +122,7 @@ function setIsPlaying(value: boolean): SetIsPlayingAction { if (!value) { globalMessageAudio.pause(); } else { - globalMessageAudio.play(); + void globalMessageAudio.play(); } return { type: 'audioPlayer/SET_IS_PLAYING', @@ -244,7 +244,7 @@ function loadAndPlayMessageAudio( // navigates away from the conversation // TODO: DESKTOP-4158 if (nextVoiceNoteMessage) { - stateChangeConfirmUpSound.play(); + void stateChangeConfirmUpSound.play(); dispatch( loadAndPlayMessageAudio( nextVoiceNoteMessage.id, @@ -255,7 +255,7 @@ function loadAndPlayMessageAudio( ) ); } else if (isConsecutive) { - stateChangeConfirmDownSound.play(); + void stateChangeConfirmDownSound.play(); } }, }); diff --git a/ts/state/ducks/audioRecorder.ts b/ts/state/ducks/audioRecorder.ts index 675af804309a..af68b2a106a9 100644 --- a/ts/state/ducks/audioRecorder.ts +++ b/ts/state/ducks/audioRecorder.ts @@ -197,7 +197,7 @@ function cancelRecording(): ThunkAction< function errorRecording( errorDialogAudioRecorderType: ErrorDialogAudioRecorderType ): ErrorRecordingAction { - recorder.stop(); + void recorder.stop(); return { type: ERROR_RECORDING, diff --git a/ts/state/ducks/badges.ts b/ts/state/ducks/badges.ts index a6e794f7ebd7..19a4e08cf3c7 100644 --- a/ts/state/ducks/badges.ts +++ b/ts/state/ducks/badges.ts @@ -76,7 +76,7 @@ function updateOrCreate( payload: badges, }); - badgeImageFileDownloader.checkForFilesToDownload(); + void badgeImageFileDownloader.checkForFilesToDownload(); }; } diff --git a/ts/state/ducks/calling.ts b/ts/state/ducks/calling.ts index 1eb14dfa508f..7ffebcc24a59 100644 --- a/ts/state/ducks/calling.ts +++ b/ts/state/ducks/calling.ts @@ -864,7 +864,7 @@ function groupCallStateChange( }); if (didSomeoneStartPresenting) { - callingTones.someonePresenting(); + void callingTones.someonePresenting(); } if (payload.connectionState === GroupCallConnectionState.NotConnected) { @@ -978,7 +978,7 @@ function openSystemPreferencesAction(): ThunkAction< never > { return () => { - openSystemPreferences(); + void openSystemPreferences(); }; } diff --git a/ts/state/ducks/composer.ts b/ts/state/ducks/composer.ts index 0d08bb611ddf..771d77abd045 100644 --- a/ts/state/ducks/composer.ts +++ b/ts/state/ducks/composer.ts @@ -177,7 +177,7 @@ function onClearAttachments(conversationId: string): NoopActionType { throw new Error('onClearAttachments: No conversation found'); } - clearConversationDraftAttachments( + void clearConversationDraftAttachments( conversation.id, conversation.get('draftAttachments') ); @@ -194,7 +194,7 @@ function cancelJoinRequest(conversationId: string): NoopActionType { throw new Error('cancelJoinRequest: No conversation found'); } - longRunningTaskWrapper({ + void longRunningTaskWrapper({ idForLogging: conversation.idForLogging(), name: 'cancelJoinRequest', task: async () => conversation.cancelJoinRequest(), @@ -383,7 +383,10 @@ function sendMultiMediaMessage( extraReduxActions: () => { conversation.setMarkedUnread(false); resetLinkPreview(); - clearConversationDraftAttachments(conversationId, draftAttachments); + void clearConversationDraftAttachments( + conversationId, + draftAttachments + ); setQuoteByMessageId(conversationId, undefined)( dispatch, getState, @@ -447,7 +450,7 @@ function sendStickerMessage( } const { packId, stickerId } = options; - conversation.sendStickerMessage(packId, stickerId); + void conversation.sendStickerMessage(packId, stickerId); } catch (error) { log.error('clickSend error:', Errors.toLogFormat(error)); } diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index 9695a2ee1fb8..157a8964dfec 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -19,6 +19,7 @@ import * as log from '../../logging/log'; import { calling } from '../../services/calling'; import { getOwn } from '../../util/getOwn'; import { assertDev, strictAssert } from '../../util/assert'; +import { drop } from '../../util/drop'; import type { DurationInSeconds } from '../../util/durations'; import * as universalExpireTimer from '../../util/universalExpireTimer'; import * as Attachment from '../../types/Attachment'; @@ -1086,7 +1087,7 @@ function blockGroupLinkRequests( throw new Error('blockGroupLinkRequests: Conversation not found!'); } - conversation.blockGroupLinkRequests(uuid); + void conversation.blockGroupLinkRequests(uuid); return { type: 'NOOP', @@ -1102,7 +1103,7 @@ function loadNewerMessages( throw new Error('loadNewerMessages: Conversation not found!'); } - conversation.loadNewerMessages(newestMessageId); + void conversation.loadNewerMessages(newestMessageId); return { type: 'NOOP', @@ -1119,7 +1120,7 @@ function loadNewestMessages( throw new Error('loadNewestMessages: Conversation not found!'); } - conversation.loadNewestMessages(newestMessageId, setFocus); + void conversation.loadNewestMessages(newestMessageId, setFocus); return { type: 'NOOP', @@ -1135,7 +1136,7 @@ function loadOlderMessages( throw new Error('loadOlderMessages: Conversation not found!'); } - conversation.loadOlderMessages(oldestMessageId); + void conversation.loadOlderMessages(oldestMessageId); return { type: 'NOOP', payload: null, @@ -1181,7 +1182,7 @@ function removeMember( throw new Error('removeMember: Conversation not found!'); } - longRunningTaskWrapper({ + void longRunningTaskWrapper({ idForLogging: conversation.idForLogging(), name: 'removeMember', task: () => conversation.removeFromGroupV2(memberConversationId), @@ -1211,7 +1212,7 @@ function updateSharedGroups(conversationId: string): NoopActionType { throw new Error('updateSharedGroups: Conversation not found!'); } - conversation.throttledUpdateSharedGroups?.(); + void conversation.throttledUpdateSharedGroups?.(); return { type: 'NOOP', @@ -1508,7 +1509,7 @@ function deleteMessage({ ); } - window.Signal.Data.removeMessage(messageId); + void window.Signal.Data.removeMessage(messageId); if (isOutgoing(message.attributes)) { conversation.decrementSentMessageCount(); } else { @@ -1538,7 +1539,7 @@ function destroyMessages( task: async () => { conversation.trigger('unload', 'delete messages'); await conversation.destroyMessages(); - conversation.updateLastMessage(); + void conversation.updateLastMessage(); }, }); @@ -1596,29 +1597,33 @@ export const markViewed = (messageId: string): void => { message.set(messageUpdaterMarkViewed(message.attributes, Date.now())); if (isIncoming(message.attributes)) { - viewedReceiptsJobQueue.add({ - viewedReceipt: { - messageId, - senderE164, - senderUuid, - timestamp, - isDirectConversation: isDirectConversation( - message.getConversation()?.attributes - ), - }, - }); + drop( + viewedReceiptsJobQueue.add({ + viewedReceipt: { + messageId, + senderE164, + senderUuid, + timestamp, + isDirectConversation: isDirectConversation( + message.getConversation()?.attributes + ), + }, + }) + ); } - viewSyncJobQueue.add({ - viewSyncs: [ - { - messageId, - senderE164, - senderUuid, - timestamp, - }, - ], - }); + drop( + viewSyncJobQueue.add({ + viewSyncs: [ + { + messageId, + senderE164, + senderUuid, + timestamp, + }, + ], + }) + ); }; function setAccessControlAddFromInviteLinkSetting( @@ -2317,7 +2322,7 @@ function getProfilesForConversation(conversationId: string): NoopActionType { throw new Error('getProfilesForConversation: no conversation found'); } - conversation.getProfiles(); + void conversation.getProfiles(); return { type: 'NOOP', @@ -2341,7 +2346,7 @@ function conversationStoppedByMissingVerification(payload: { } // Intentionally not awaiting here - conversation.getProfiles(); + void conversation.getProfiles(); }); return { @@ -2784,7 +2789,7 @@ function blockAndReportSpam( const messageRequestEnum = Proto.SyncMessage.MessageRequestResponse.Type; const idForLogging = conversation.idForLogging(); - longRunningTaskWrapper({ + void longRunningTaskWrapper({ name: 'blockAndReportSpam', idForLogging, task: async () => { @@ -2819,7 +2824,7 @@ function acceptConversation(conversationId: string): NoopActionType { const messageRequestEnum = Proto.SyncMessage.MessageRequestResponse.Type; - longRunningTaskWrapper({ + void longRunningTaskWrapper({ name: 'acceptConversation', idForLogging: conversation.idForLogging(), task: conversation.syncMessageRequestResponse.bind( @@ -2844,7 +2849,7 @@ function blockConversation(conversationId: string): NoopActionType { const messageRequestEnum = Proto.SyncMessage.MessageRequestResponse.Type; - longRunningTaskWrapper({ + void longRunningTaskWrapper({ name: 'blockConversation', idForLogging: conversation.idForLogging(), task: conversation.syncMessageRequestResponse.bind( @@ -2869,7 +2874,7 @@ function deleteConversation(conversationId: string): NoopActionType { const messageRequestEnum = Proto.SyncMessage.MessageRequestResponse.Type; - longRunningTaskWrapper({ + void longRunningTaskWrapper({ name: 'deleteConversation', idForLogging: conversation.idForLogging(), task: conversation.syncMessageRequestResponse.bind( @@ -2892,7 +2897,7 @@ function initiateMigrationToGroupV2(conversationId: string): NoopActionType { ); } - longRunningTaskWrapper({ + void longRunningTaskWrapper({ idForLogging: conversation.idForLogging(), name: 'initiateMigrationToGroupV2', task: () => doInitiateMigrationToGroupV2(conversation), @@ -3121,7 +3126,7 @@ export function scrollToMessage( return; } - conversation.loadAndScroll(messageId); + void conversation.loadAndScroll(messageId); }; } @@ -3221,7 +3226,7 @@ function removeMemberFromGroup( const conversationModel = window.ConversationController.get(conversationId); if (conversationModel) { const idForLogging = conversationModel.idForLogging(); - longRunningTaskWrapper({ + void longRunningTaskWrapper({ name: 'removeMemberFromGroup', idForLogging, task: () => conversationModel.removeFromGroupV2(contactId), @@ -3372,7 +3377,7 @@ function toggleAdmin( return dispatch => { const conversationModel = window.ConversationController.get(conversationId); if (conversationModel) { - conversationModel.toggleAdmin(contactId); + void conversationModel.toggleAdmin(contactId); } dispatch({ type: 'NOOP', @@ -3387,7 +3392,7 @@ function updateConversationModelSharedGroups( return dispatch => { const conversation = window.ConversationController.get(conversationId); if (conversation && conversation.throttledUpdateSharedGroups) { - conversation.throttledUpdateSharedGroups(); + void conversation.throttledUpdateSharedGroups(); } dispatch({ type: 'NOOP', @@ -3457,7 +3462,7 @@ function showArchivedConversations(): ShowArchivedConversationsActionType { function doubleCheckMissingQuoteReference(messageId: string): NoopActionType { const message = window.MessageController.getById(messageId); if (message) { - message.doubleCheckMissingQuoteReference(); + void message.doubleCheckMissingQuoteReference(); } return { diff --git a/ts/state/ducks/globalModals.ts b/ts/state/ducks/globalModals.ts index 72988545dcb8..bd37a6855026 100644 --- a/ts/state/ducks/globalModals.ts +++ b/ts/state/ducks/globalModals.ts @@ -443,11 +443,10 @@ function closeStickerPackPreview(): ThunkAction< return async (dispatch, getState) => { const packId = getState().globalModals.stickerPackPreviewId; - if (!packId) { - return; + if (packId && Stickers.getStickerPack(packId) !== undefined) { + await Stickers.removeEphemeralPack(packId); } - await Stickers.removeEphemeralPack(packId); dispatch({ type: CLOSE_STICKER_PACK_PREVIEW, }); @@ -460,7 +459,7 @@ export function showStickerPackPreview( ): ShowStickerPackPreviewActionType { // Intentionally not awaiting this so that we can show the modal right away. // The modal has a loading spinner on it. - Stickers.downloadEphemeralPack(packId, packKey); + void Stickers.downloadEphemeralPack(packId, packKey); return { type: SHOW_STICKER_PACK_PREVIEW, diff --git a/ts/state/ducks/items.ts b/ts/state/ducks/items.ts index d451356ea031..8ac80d2cf051 100644 --- a/ts/state/ducks/items.ts +++ b/ts/state/ducks/items.ts @@ -8,6 +8,7 @@ import type { StateType as RootStateType } from '../reducer'; import * as storageShim from '../../shims/storage'; import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions'; import { useBoundActions } from '../../hooks/useBoundActions'; +import { drop } from '../../util/drop'; import type { ConversationColorType, CustomColorType, @@ -100,16 +101,19 @@ export const useActions = (): BoundActionCreatorsMapObject => function putItem( key: K, value: StorageAccessType[K] -): ItemPutAction { - storageShim.put(key, value); - - return { - type: 'items/PUT', - payload: null, +): ThunkAction { + return async dispatch => { + dispatch({ + type: 'items/PUT', + payload: null, + }); + await storageShim.put(key, value); }; } -function onSetSkinTone(tone: number): ItemPutAction { +function onSetSkinTone( + tone: number +): ThunkAction { return putItem('skinTone', tone); } @@ -124,7 +128,7 @@ function putItemExternal(key: string, value: unknown): ItemPutExternalAction { } function removeItem(key: keyof StorageAccessType): ItemRemoveAction { - storageShim.remove(key); + drop(storageShim.remove(key)); return { type: 'items/REMOVE', diff --git a/ts/state/ducks/lightbox.ts b/ts/state/ducks/lightbox.ts index a1e4d4ddf748..ee52cc2e5898 100644 --- a/ts/state/ducks/lightbox.ts +++ b/ts/state/ducks/lightbox.ts @@ -77,7 +77,7 @@ function closeLightbox(): ThunkAction< if (!item.attachment.path) { return; } - window.Signal.Migrations.deleteTempFile(item.attachment.path); + void window.Signal.Migrations.deleteTempFile(item.attachment.path); }); } diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index c0939dee26b3..b224ee3a97bc 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -209,7 +209,7 @@ const doSearch = debounce( return; } - (async () => { + void (async () => { dispatch({ type: 'SEARCH_MESSAGES_RESULTS_FULFILLED', payload: { @@ -220,7 +220,7 @@ const doSearch = debounce( })(); if (!searchConversationId) { - (async () => { + void (async () => { const { conversationIds, contactIds } = await queryConversationsAndContacts(query, { ourConversationId, diff --git a/ts/state/ducks/stickers.ts b/ts/state/ducks/stickers.ts index c34892136fc1..75165136366e 100644 --- a/ts/state/ducks/stickers.ts +++ b/ts/state/ducks/stickers.ts @@ -193,7 +193,7 @@ function downloadStickerPack( const { finalStatus } = options || { finalStatus: undefined }; // We're just kicking this off, since it will generate more redux events - externalDownloadStickerPack(packId, packKey, { finalStatus }); + void externalDownloadStickerPack(packId, packKey, { finalStatus }); return { type: 'NOOP', @@ -223,7 +223,7 @@ async function doInstallStickerPack( if (!fromSync && !fromStorageService) { // Kick this off, but don't wait for it - sendStickerPackSync(packId, packKey, true); + void sendStickerPackSync(packId, packKey, true); } if (!fromStorageService) { @@ -268,7 +268,7 @@ async function doUninstallStickerPack( if (!fromSync && !fromStorageService) { // Kick this off, but don't wait for it - sendStickerPackSync(packId, packKey, false); + void sendStickerPackSync(packId, packKey, false); } if (!fromStorageService) { diff --git a/ts/state/ducks/stories.ts b/ts/state/ducks/stories.ts index f864fc6ac2e3..f1d715f31832 100644 --- a/ts/state/ducks/stories.ts +++ b/ts/state/ducks/stories.ts @@ -25,6 +25,7 @@ import { ReadStatus } from '../../messages/MessageReadStatus'; import { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog'; import { StoryViewDirectionType, StoryViewModeType } from '../../types/Stories'; import { assertDev } from '../../util/assert'; +import { drop } from '../../util/drop'; import { blockSendUntilConversationsAreVerified } from '../../util/blockSendUntilConversationsAreVerified'; import { deleteStoryForEveryone as doDeleteStoryForEveryone } from '../../util/deleteStoryForEveryone'; import { deleteGroupStoryReplyForEveryone as doDeleteGroupStoryReplyForEveryone } from '../../util/deleteGroupStoryReplyForEveryone'; @@ -374,14 +375,14 @@ function markStoryRead( const isSignalOnboardingStory = message.get('sourceUuid') === SIGNAL_ACI; if (isSignalOnboardingStory) { - markOnboardingStoryAsRead(); + void markOnboardingStoryAsRead(); return; } const storyReadDate = Date.now(); message.set(markViewed(message.attributes, storyReadDate)); - window.Signal.Data.saveMessage(message.attributes, { + void window.Signal.Data.saveMessage(message.attributes, { ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), }); @@ -395,11 +396,11 @@ function markStoryRead( const viewSyncs: Array = [viewedReceipt]; if (!window.ConversationController.areWePrimaryDevice()) { - viewSyncJobQueue.add({ viewSyncs }); + drop(viewSyncJobQueue.add({ viewSyncs })); } if (window.Events.getStoryViewReceiptsEnabled()) { - viewedReceiptsJobQueue.add({ viewedReceipt }); + drop(viewedReceiptsJobQueue.add({ viewedReceipt })); } await dataInterface.addNewStoryRead({ diff --git a/ts/state/ducks/storyDistributionLists.ts b/ts/state/ducks/storyDistributionLists.ts index e1eca03f9d6f..8254a94d9edd 100644 --- a/ts/state/ducks/storyDistributionLists.ts +++ b/ts/state/ducks/storyDistributionLists.ts @@ -291,7 +291,7 @@ function hideMyStoriesFrom( storageServiceUploadJob(); - window.storage.put('hasSetMyStoriesPrivacy', true); + await window.storage.put('hasSetMyStoriesPrivacy', true); dispatch({ type: HIDE_MY_STORIES_FROM, @@ -338,7 +338,7 @@ function removeMembersFromDistributionList( toRemove = []; // The user has now configured My Stories - window.storage.put('hasSetMyStoriesPrivacy', true); + await window.storage.put('hasSetMyStoriesPrivacy', true); } await dataInterface.modifyStoryDistributionWithMembers( @@ -410,7 +410,7 @@ function setMyStoriesToAllSignalConnections(): ThunkAction< storageServiceUploadJob(); } - window.storage.put('hasSetMyStoriesPrivacy', true); + await window.storage.put('hasSetMyStoriesPrivacy', true); dispatch({ type: RESET_MY_STORIES, @@ -467,7 +467,7 @@ function updateStoryViewers( storageServiceUploadJob(); if (listId === MY_STORY_ID) { - window.storage.put('hasSetMyStoriesPrivacy', true); + await window.storage.put('hasSetMyStoriesPrivacy', true); } dispatch({ diff --git a/ts/state/smart/App.tsx b/ts/state/smart/App.tsx index ae17359bab38..87afa7071ee1 100644 --- a/ts/state/smart/App.tsx +++ b/ts/state/smart/App.tsx @@ -91,10 +91,10 @@ const mapStateToProps = (state: StateType) => { theme: getTheme(state), executeMenuRole: (role: MenuItemConstructorOptions['role']): void => { - window.SignalContext.executeMenuRole(role); + void window.SignalContext.executeMenuRole(role); }, executeMenuAction: (action: MenuActionType): void => { - window.SignalContext.executeMenuAction(action); + void window.SignalContext.executeMenuAction(action); }, titleBarDoubleClick: (): void => { window.titleBarDoubleClick(); diff --git a/ts/state/smart/InstallScreen.tsx b/ts/state/smart/InstallScreen.tsx index a46c08010c23..c6393fd12494 100644 --- a/ts/state/smart/InstallScreen.tsx +++ b/ts/state/smart/InstallScreen.tsx @@ -196,7 +196,7 @@ export function SmartInstallScreen(): ReactElement { return result; }; - (async () => { + void (async () => { try { await accountManager.registerSecondDevice( updateProvisioningUrl, diff --git a/ts/test-both/util/retryPlaceholders_test.ts b/ts/test-both/util/retryPlaceholders_test.ts index be2234b98827..2f281698180d 100644 --- a/ts/test-both/util/retryPlaceholders_test.ts +++ b/ts/test-both/util/retryPlaceholders_test.ts @@ -17,8 +17,8 @@ describe('RetryPlaceholders', () => { const NOW = 1_000_000; let clock: any; - beforeEach(() => { - window.storage.put(STORAGE_KEY, undefined as any); + beforeEach(async () => { + await window.storage.put(STORAGE_KEY, undefined as any); clock = sinon.useFakeTimers({ now: NOW, @@ -40,19 +40,19 @@ describe('RetryPlaceholders', () => { } describe('constructor', () => { - it('loads previously-saved data on creation', () => { + it('loads previously-saved data on creation', async () => { const items: Array = [ getDefaultItem(), { ...getDefaultItem(), conversationId: 'conversation-id-2' }, ]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(2, placeholders.getCount()); }); - it('starts with no data if provided data fails to parse', () => { - window.storage.put(STORAGE_KEY, [ + it('starts with no data if provided data fails to parse', async () => { + await window.storage.put(STORAGE_KEY, [ { item: 'is wrong shape!' }, { bad: 'is not good!' }, ] as any); @@ -70,9 +70,9 @@ describe('RetryPlaceholders', () => { assert.strictEqual(1, placeholders.getCount()); }); - it('throws if provided data fails to parse', () => { + it('throws if provided data fails to parse', async () => { const placeholders = new RetryPlaceholders(); - assert.isRejected( + await assert.isRejected( placeholders.add({ item: 'is wrong shape!', } as any), @@ -87,10 +87,10 @@ describe('RetryPlaceholders', () => { assert.strictEqual(0, placeholders.getCount()); assert.isUndefined(placeholders.getNextToExpire()); }); - it('returns only item if just one item', () => { + it('returns only item if just one item', async () => { const item = getDefaultItem(); const items: Array = [item]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(1, placeholders.getCount()); @@ -106,7 +106,7 @@ describe('RetryPlaceholders', () => { receivedAt: NOW + 10, }; const items: Array = [older, newer]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(2, placeholders.getCount()); @@ -134,7 +134,7 @@ describe('RetryPlaceholders', () => { receivedAt: NOW + 15, }; const items: Array = [older, newer]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(2, placeholders.getCount()); @@ -151,7 +151,7 @@ describe('RetryPlaceholders', () => { receivedAt: NOW + 15, }; const items: Array = [older, newer]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(2, placeholders.getCount()); @@ -169,7 +169,7 @@ describe('RetryPlaceholders', () => { receivedAt: getDeltaIntoPast() - 900, }; const items: Array = [older, newer]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(2, placeholders.getCount()); @@ -192,7 +192,7 @@ describe('RetryPlaceholders', () => { conversationId: 'conversation-id-2', }; const items: Array = [older, newer]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(2, placeholders.getCount()); @@ -219,7 +219,7 @@ describe('RetryPlaceholders', () => { receivedAt: NOW + 15, }; const items: Array = [convo1a, convo1b, convo2a]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(3, placeholders.getCount()); @@ -293,7 +293,7 @@ describe('RetryPlaceholders', () => { sentAt: NOW - 11, }; const items: Array = [older, newer]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(2, placeholders.getCount()); @@ -316,7 +316,7 @@ describe('RetryPlaceholders', () => { sentAt, }; const items: Array = [older, newer]; - window.storage.put(STORAGE_KEY, items); + await window.storage.put(STORAGE_KEY, items); const placeholders = new RetryPlaceholders(); assert.strictEqual(2, placeholders.getCount()); diff --git a/ts/test-electron/SignalProtocolStore_test.ts b/ts/test-electron/SignalProtocolStore_test.ts index ba77e478332e..66c50d29f80c 100644 --- a/ts/test-electron/SignalProtocolStore_test.ts +++ b/ts/test-electron/SignalProtocolStore_test.ts @@ -124,7 +124,7 @@ describe('SignalProtocolStore', () => { before(async () => { store = window.textsecure.storage.protocol; - store.hydrateCaches(); + await store.hydrateCaches(); identityKey = { pubKey: getPublicKey(), privKey: getPrivateKey(), @@ -140,8 +140,10 @@ describe('SignalProtocolStore', () => { clampPrivateKey(identityKey.privKey); clampPrivateKey(testKey.privKey); - window.storage.put('registrationIdMap', { [ourUuid.toString()]: 1337 }); - window.storage.put('identityKeyMap', { + await window.storage.put('registrationIdMap', { + [ourUuid.toString()]: 1337, + }); + await window.storage.put('identityKeyMap', { [ourUuid.toString()]: { privKey: identityKey.privKey, pubKey: identityKey.pubKey, diff --git a/ts/test-electron/background_test.ts b/ts/test-electron/background_test.ts index 0f6d8f10ff69..79072a798a65 100644 --- a/ts/test-electron/background_test.ts +++ b/ts/test-electron/background_test.ts @@ -21,34 +21,34 @@ describe('#isOverHourIntoPast', () => { }); describe('#cleanupSessionResets', () => { - it('leaves empty object alone', () => { - window.storage.put('sessionResets', {}); - cleanupSessionResets(); + it('leaves empty object alone', async () => { + await window.storage.put('sessionResets', {}); + await cleanupSessionResets(); const actual = window.storage.get('sessionResets'); const expected = {}; assert.deepEqual(actual, expected); }); - it('filters out any timestamp older than one hour', () => { + it('filters out any timestamp older than one hour', async () => { const startValue = { one: Date.now() - 1, two: Date.now(), three: Date.now() - 65 * 60 * 1000, }; - window.storage.put('sessionResets', startValue); - cleanupSessionResets(); + await window.storage.put('sessionResets', startValue); + await cleanupSessionResets(); const actual = window.storage.get('sessionResets'); const expected = pick(startValue, ['one', 'two']); assert.deepEqual(actual, expected); }); - it('filters out falsey items', () => { + it('filters out falsey items', async () => { const startValue = { one: 0, two: Date.now(), }; - window.storage.put('sessionResets', startValue); - cleanupSessionResets(); + await window.storage.put('sessionResets', startValue); + await cleanupSessionResets(); const actual = window.storage.get('sessionResets'); const expected = pick(startValue, ['two']); diff --git a/ts/test-electron/models/messages_test.ts b/ts/test-electron/models/messages_test.ts index 51d3c70b2bfb..988d58c956b8 100644 --- a/ts/test-electron/models/messages_test.ts +++ b/ts/test-electron/models/messages_test.ts @@ -51,21 +51,22 @@ describe('Message', () => { STORAGE_KEYS_TO_RESTORE.forEach(key => { oldStorageValues.set(key, window.textsecure.storage.get(key)); }); - window.textsecure.storage.put('number_id', `${me}.2`); - window.textsecure.storage.put('uuid_id', `${ourUuid}.2`); + await window.textsecure.storage.put('number_id', `${me}.2`); + await window.textsecure.storage.put('uuid_id', `${ourUuid}.2`); }); after(async () => { await window.Signal.Data.removeAll(); await window.storage.fetch(); - oldStorageValues.forEach((oldValue, key) => { - if (oldValue) { - window.textsecure.storage.put(key, oldValue); - } else { - window.textsecure.storage.remove(key); - } - }); + await Promise.all( + Array.from(oldStorageValues.entries()).map(([key, oldValue]) => { + if (oldValue) { + return window.textsecure.storage.put(key, oldValue); + } + return window.textsecure.storage.remove(key); + }) + ); }); beforeEach(function beforeEach() { diff --git a/ts/test-electron/services/profiles_test.ts b/ts/test-electron/services/profiles_test.ts index 08617684b602..9a4fd4323256 100644 --- a/ts/test-electron/services/profiles_test.ts +++ b/ts/test-electron/services/profiles_test.ts @@ -4,6 +4,7 @@ import { assert } from 'chai'; import { sleep } from '../../util'; import { MINUTE } from '../../util/durations'; +import { drop } from '../../util/drop'; import { ProfileService } from '../../services/profiles'; import { UUID } from '../../types/UUID'; @@ -55,9 +56,9 @@ describe('util/profiles', () => { const service = new ProfileService(getProfileWithIncrement); // Queued and immediately started due to concurrency = 3 - service.get(UUID_1); - service.get(UUID_2); - service.get(UUID_3); + drop(service.get(UUID_1)); + drop(service.get(UUID_2)); + drop(service.get(UUID_3)); // Queued but only run after paused queue restarts const lastPromise = service.get(UUID_4); diff --git a/ts/test-electron/services/senderCertificate_test.ts b/ts/test-electron/services/senderCertificate_test.ts index 5f49297958f9..7258d3fc18ae 100644 --- a/ts/test-electron/services/senderCertificate_test.ts +++ b/ts/test-electron/services/senderCertificate_test.ts @@ -9,6 +9,7 @@ import * as sinon from 'sinon'; import { v4 as uuid } from 'uuid'; import Long from 'long'; import * as durations from '../../util/durations'; +import { drop } from '../../util/drop'; import * as Bytes from '../../Bytes'; import { SenderCertificateMode } from '../../textsecure/OutgoingMessage'; import { SignalService as Proto } from '../../protobuf'; @@ -232,8 +233,8 @@ describe('SenderCertificateService', () => { const service = initializeTestService(); - service.get(SenderCertificateMode.WithE164); - service.get(SenderCertificateMode.WithoutE164); + drop(service.get(SenderCertificateMode.WithE164)); + drop(service.get(SenderCertificateMode.WithoutE164)); await service.clear(); diff --git a/ts/test-electron/state/ducks/conversations_test.ts b/ts/test-electron/state/ducks/conversations_test.ts index dde27ae5c07d..b8d63e8186d3 100644 --- a/ts/test-electron/state/ducks/conversations_test.ts +++ b/ts/test-electron/state/ducks/conversations_test.ts @@ -2172,7 +2172,7 @@ describe('both/state/ducks/conversations', () => { assert.isUndefined( nextState.conversationsByGroupId.jkl.conversationColor ); - window.storage.remove('defaultConversationColor'); + await window.storage.remove('defaultConversationColor'); }); }); diff --git a/ts/test-electron/textsecure/KeyChangeListener_test.ts b/ts/test-electron/textsecure/KeyChangeListener_test.ts index bdd14072f172..a98ac6b88e6b 100644 --- a/ts/test-electron/textsecure/KeyChangeListener_test.ts +++ b/ts/test-electron/textsecure/KeyChangeListener_test.ts @@ -7,6 +7,7 @@ import { v4 as getGuid } from 'uuid'; import { getRandomBytes } from '../../Crypto'; import { Address } from '../../types/Address'; import { UUID } from '../../types/UUID'; +import { explodePromise } from '../../util/explodePromise'; import { SignalProtocolStore } from '../../SignalProtocolStore'; import type { ConversationModel } from '../../models/conversations'; import * as KeyChangeListener from '../../textsecure/KeyChangeListener'; @@ -76,13 +77,15 @@ describe('KeyChangeListener', () => { }); describe('When we have a conversation with this contact', () => { - it('generates a key change notice in the private conversation with this contact', done => { + it('generates a key change notice in the private conversation with this contact', async () => { const original = convo.addKeyChange; + const { resolve, promise } = explodePromise(); convo.addKeyChange = async () => { convo.addKeyChange = original; - done(); + resolve(); }; - store.saveIdentity(address, newKey); + await store.saveIdentity(address, newKey); + return promise; }); }); @@ -108,15 +111,18 @@ describe('KeyChangeListener', () => { await window.Signal.Data.removeConversation(groupConvo.id); }); - it('generates a key change notice in the group conversation with this contact', done => { + it('generates a key change notice in the group conversation with this contact', async () => { const original = groupConvo.addKeyChange; + + const { resolve, promise } = explodePromise(); groupConvo.addKeyChange = async (_, keyChangedId) => { assert.equal(uuidWithKeyChange, keyChangedId?.toString()); groupConvo.addKeyChange = original; - done(); + resolve(); }; - store.saveIdentity(address, newKey); + await store.saveIdentity(address, newKey); + return promise; }); }); }); diff --git a/ts/test-electron/util/waitForOnline_test.ts b/ts/test-electron/util/waitForOnline_test.ts index be3dcf571ffa..4885e1736ff2 100644 --- a/ts/test-electron/util/waitForOnline_test.ts +++ b/ts/test-electron/util/waitForOnline_test.ts @@ -92,7 +92,7 @@ describe('waitForOnline', () => { }); let done = false; - (async () => { + void (async () => { await waitForOnline(fakeNavigator, fakeWindow, { timeout: 9999 }); done = true; })(); diff --git a/ts/test-mock/benchmarks/convo_open_bench.ts b/ts/test-mock/benchmarks/convo_open_bench.ts index 76fe90b91394..e21c6f479329 100644 --- a/ts/test-mock/benchmarks/convo_open_bench.ts +++ b/ts/test-mock/benchmarks/convo_open_bench.ts @@ -11,7 +11,7 @@ import { Bootstrap, debug, stats, RUN_COUNT, DISCARD_COUNT } from './fixtures'; const CONVERSATION_SIZE = 1000; // messages const DELAY = 50; // milliseconds -(async () => { +void (async () => { const bootstrap = new Bootstrap({ benchmark: true, }); diff --git a/ts/test-mock/benchmarks/group_send_bench.ts b/ts/test-mock/benchmarks/group_send_bench.ts index 42bacecdd456..4f0c444d9dbf 100644 --- a/ts/test-mock/benchmarks/group_send_bench.ts +++ b/ts/test-mock/benchmarks/group_send_bench.ts @@ -23,7 +23,7 @@ import { const CONVERSATION_SIZE = 500; // messages const LAST_MESSAGE = 'start sending messages now'; -(async () => { +void (async () => { const bootstrap = new Bootstrap({ benchmark: true, }); diff --git a/ts/test-mock/benchmarks/send_bench.ts b/ts/test-mock/benchmarks/send_bench.ts index 3097286b8d32..4427573c78b6 100644 --- a/ts/test-mock/benchmarks/send_bench.ts +++ b/ts/test-mock/benchmarks/send_bench.ts @@ -13,7 +13,7 @@ const CONVERSATION_SIZE = 500; // messages const LAST_MESSAGE = 'start sending messages now'; -(async () => { +void (async () => { const bootstrap = new Bootstrap({ benchmark: true, }); diff --git a/ts/test-mock/benchmarks/startup_bench.ts b/ts/test-mock/benchmarks/startup_bench.ts index 0956c03c3ef1..6150090ee4f9 100644 --- a/ts/test-mock/benchmarks/startup_bench.ts +++ b/ts/test-mock/benchmarks/startup_bench.ts @@ -10,7 +10,7 @@ const MESSAGE_BATCH_SIZE = 1000; // messages const ENABLE_RECEIPTS = Boolean(process.env.ENABLE_RECEIPTS); -(async () => { +void (async () => { const bootstrap = new Bootstrap({ benchmark: true, }); diff --git a/ts/test-mock/benchmarks/storage_sync_bench.ts b/ts/test-mock/benchmarks/storage_sync_bench.ts index 65dacab386c7..4a103fbaed82 100644 --- a/ts/test-mock/benchmarks/storage_sync_bench.ts +++ b/ts/test-mock/benchmarks/storage_sync_bench.ts @@ -9,7 +9,7 @@ import { Bootstrap } from './fixtures'; const CONTACT_COUNT = 1000; -(async () => { +void (async () => { const contactNames = new Array(); for (let i = 0; i < CONTACT_COUNT; i += 1) { contactNames.push(`Contact ${i}`); diff --git a/ts/test-mock/pnp/merge_test.ts b/ts/test-mock/pnp/merge_test.ts index 0dc1fd655ebd..dd33e5a115d2 100644 --- a/ts/test-mock/pnp/merge_test.ts +++ b/ts/test-mock/pnp/merge_test.ts @@ -131,7 +131,7 @@ describe('pnp/merge', function needsName() { ); { const state = await phone.expectStorageState('consistency check'); - phone.setStorageState( + await phone.setStorageState( state .removeRecord( item => diff --git a/ts/test-mock/pnp/send_gv2_invite_test.ts b/ts/test-mock/pnp/send_gv2_invite_test.ts index 1a28397ad90e..90a695e68b80 100644 --- a/ts/test-mock/pnp/send_gv2_invite_test.ts +++ b/ts/test-mock/pnp/send_gv2_invite_test.ts @@ -182,7 +182,7 @@ describe('pnp/send gv2 invite', function needsName() { const detailsHeader = conversationStack.locator( '_react=ConversationDetailsHeader' ); - detailsHeader.locator('button >> "My group"').click(); + await detailsHeader.locator('button >> "My group"').click(); const modal = window.locator('.module-Modal:has-text("Edit group")'); diff --git a/ts/test-mock/rate-limit/story_test.ts b/ts/test-mock/rate-limit/story_test.ts index 4f5cf32a144e..2a4be249b728 100644 --- a/ts/test-mock/rate-limit/story_test.ts +++ b/ts/test-mock/rate-limit/story_test.ts @@ -51,7 +51,7 @@ describe('story/no-sender-key', function needsName() { }, }, }); - phone.setStorageState(state); + await phone.setStorageState(state); app = await bootstrap.link(); }); diff --git a/ts/test-mock/storage/sticker_test.ts b/ts/test-mock/storage/sticker_test.ts index 755d30af19b8..66d5a07d3e76 100644 --- a/ts/test-mock/storage/sticker_test.ts +++ b/ts/test-mock/storage/sticker_test.ts @@ -114,7 +114,9 @@ describe('storage service', function needsName() { const window = await app.getWindow(); const leftPane = window.locator('.left-pane-wrapper'); - const conversationStack = window.locator('.conversation-stack'); + const conversationView = window.locator( + '.ConversationView__template > .react-wrapper' + ); debug('sending two sticker pack links'); await firstContact.sendText( @@ -137,7 +139,7 @@ describe('storage service', function needsName() { debug('installing first sticker pack via UI'); const state = await phone.expectStorageState('initial state'); - await conversationStack + await conversationView .locator(`a:has-text("${STICKER_PACKS[0].id.toString('hex')}")`) .click({ noWaitAfter: true }); await window @@ -181,7 +183,7 @@ describe('storage service', function needsName() { debug('uninstalling first sticker pack via UI'); const state = await phone.expectStorageState('initial state'); - await conversationStack + await conversationView .locator(`a:has-text("${STICKER_PACKS[0].id.toString('hex')}")`) .click({ noWaitAfter: true }); await window @@ -227,12 +229,17 @@ describe('storage service', function needsName() { ); } - debug('opening sticker picker'); - conversationStack + debug('opening sticker manager'); + await conversationView .locator('.CompositionArea .module-sticker-button__button') .click(); - const stickerPicker = conversationStack.locator('.module-sticker-picker'); + const stickerManager = conversationView.locator( + '_react=StickerManagerInner' + ); + + debug('switching to Installed tab'); + await stickerManager.locator('.Tabs__tab >> "Installed"').click(); { debug('installing first sticker pack via storage service'); @@ -257,10 +264,10 @@ describe('storage service', function needsName() { }); debug('waiting for sticker pack to become visible'); - stickerPicker + await stickerManager .locator( - 'button.module-sticker-picker__header__button' + - `[key="${STICKER_PACKS[0].id.toString('hex')}"]` + '_react=StickerManagerPackRowInner' + + `[pack.id="${STICKER_PACKS[0].id.toString('hex')}"]` ) .waitFor(); } @@ -277,10 +284,10 @@ describe('storage service', function needsName() { }); debug('waiting for sticker pack to become visible'); - stickerPicker + await stickerManager .locator( - 'button.module-sticker-picker__header__button' + - `[key="${STICKER_PACKS[1].id.toString('hex')}"]` + '_react=StickerManagerPackRowInner' + + `[pack.id="${STICKER_PACKS[1].id.toString('hex')}"]` ) .waitFor(); @@ -301,7 +308,7 @@ describe('storage service', function needsName() { ); assert.strictEqual( stickerPack?.record.stickerPack?.position, - 6, + 7, 'Wrong sticker pack position' ); } diff --git a/ts/test-node/jobs/JobQueue_test.ts b/ts/test-node/jobs/JobQueue_test.ts index e935061f3550..a0e0a1dedcdc 100644 --- a/ts/test-node/jobs/JobQueue_test.ts +++ b/ts/test-node/jobs/JobQueue_test.ts @@ -13,6 +13,7 @@ import PQueue from 'p-queue'; import { JobError } from '../../jobs/JobError'; import { TestJobQueueStore } from './TestJobQueueStore'; import { missingCaseError } from '../../util/missingCaseError'; +import { drop } from '../../util/drop'; import type { LoggerType } from '../../types/Logging'; import { JobQueue } from '../../jobs/JobQueue'; @@ -51,7 +52,7 @@ describe('JobQueue', () => { assert.deepEqual(results, new Set()); assert.isEmpty(store.storedJobs); - addQueue.streamJobs(); + drop(addQueue.streamJobs()); store.pauseStream('test add queue'); const job1 = await addQueue.add({ a: 1, b: 2 }); @@ -85,7 +86,7 @@ describe('JobQueue', () => { async run(): Promise { try { updateActiveJobCount(1); - sleep(1); + await sleep(1); } finally { updateActiveJobCount(-1); } @@ -99,7 +100,7 @@ describe('JobQueue', () => { queueType: 'test queue', maxAttempts: 100, }); - queue.streamJobs(); + drop(queue.streamJobs()); const createPromise1 = queue.add(1); const createPromise2 = queue.add(2); @@ -153,7 +154,7 @@ describe('JobQueue', () => { queueType: 'test queue', maxAttempts: 100, }); - queue.streamJobs(); + drop(queue.streamJobs()); const jobs = await Promise.all([ queue.add(1), @@ -193,8 +194,8 @@ describe('JobQueue', () => { store.pauseStream('test 1'); store.pauseStream('test 2'); - queue1.streamJobs(); - queue2.streamJobs(); + drop(queue1.streamJobs()); + drop(queue2.streamJobs()); await queue1.add('one'); await queue2.add('A'); @@ -253,7 +254,7 @@ describe('JobQueue', () => { maxAttempts: 1, }); - queue.streamJobs(); + drop(queue.streamJobs()); const insert = sinon.stub().resolves(); @@ -316,7 +317,7 @@ describe('JobQueue', () => { maxAttempts: 5, }); - retryQueue.streamJobs(); + drop(retryQueue.streamJobs()); await ( await retryQueue.add('foo') @@ -371,7 +372,7 @@ describe('JobQueue', () => { maxAttempts: 6, }); - queue.streamJobs(); + drop(queue.streamJobs()); try { await ( @@ -418,7 +419,7 @@ describe('JobQueue', () => { logger: fakeLogger, }); - queue.streamJobs(); + drop(queue.streamJobs()); const job = await queue.add(1); await job.completion; @@ -460,7 +461,7 @@ describe('JobQueue', () => { maxAttempts: 999, }); - queue.streamJobs(); + drop(queue.streamJobs()); const job = await queue.add('this will fail to parse'); @@ -504,7 +505,7 @@ describe('JobQueue', () => { maxAttempts: 999, }); - queue.streamJobs(); + drop(queue.streamJobs()); (await queue.add('invalid')).completion.catch(noop); (await queue.add('invalid')).completion.catch(noop); @@ -538,7 +539,7 @@ describe('JobQueue', () => { maxAttempts: 999, }); - queue.streamJobs(); + drop(queue.streamJobs()); await (await queue.add('invalid 1')).completion.catch(noop); await (await queue.add('invalid 2')).completion.catch(noop); @@ -572,7 +573,7 @@ describe('JobQueue', () => { maxAttempts: 999, }); - queue.streamJobs(); + drop(queue.streamJobs()); const addPromise = queue.add(undefined); assert.isFalse(inserted); @@ -606,7 +607,7 @@ describe('JobQueue', () => { maxAttempts: 999, }); - queue.streamJobs(); + drop(queue.streamJobs()); await ( await queue.add(123) @@ -639,7 +640,7 @@ describe('JobQueue', () => { maxAttempts: 999, }); - queue.streamJobs(); + drop(queue.streamJobs()); store.pauseStream('test queue'); const job = await queue.add(undefined); @@ -681,7 +682,7 @@ describe('JobQueue', () => { maxAttempts: 5, }); - queue.streamJobs(); + drop(queue.streamJobs()); store.pauseStream('test queue'); const job = await queue.add(undefined); @@ -763,7 +764,7 @@ describe('JobQueue', () => { sinon.assert.notCalled(fakeStore.stream as sinon.SinonStub); - noopQueue.streamJobs(); + drop(noopQueue.streamJobs()); sinon.assert.calledOnce(fakeStore.stream as sinon.SinonStub); @@ -804,7 +805,7 @@ describe('JobQueue', () => { maxAttempts: 99, }); - noopQueue.streamJobs(); + drop(noopQueue.streamJobs()); await assert.isRejected(noopQueue.streamJobs()); await assert.isRejected(noopQueue.streamJobs()); diff --git a/ts/test-node/jobs/TestJobQueueStore.ts b/ts/test-node/jobs/TestJobQueueStore.ts index c680bdfec10e..4c6003d765cb 100644 --- a/ts/test-node/jobs/TestJobQueueStore.ts +++ b/ts/test-node/jobs/TestJobQueueStore.ts @@ -8,6 +8,7 @@ import EventEmitter, { once } from 'events'; import type { JobQueueStore, StoredJob } from '../../jobs/types'; import { sleep } from '../../util/sleep'; +import { drop } from '../../util/drop'; export class TestJobQueueStore implements JobQueueStore { events = new EventEmitter(); @@ -20,7 +21,7 @@ export class TestJobQueueStore implements JobQueueStore { constructor(jobs: ReadonlyArray = []) { jobs.forEach(job => { - this.insert(job); + drop(this.insert(job)); }); } diff --git a/ts/test-node/jobs/helpers/handleMultipleSendErrors_test.ts b/ts/test-node/jobs/helpers/handleMultipleSendErrors_test.ts index 579856a92016..2f0626f323bf 100644 --- a/ts/test-node/jobs/helpers/handleMultipleSendErrors_test.ts +++ b/ts/test-node/jobs/helpers/handleMultipleSendErrors_test.ts @@ -105,7 +105,7 @@ describe('handleMultipleSendErrors', () => { it('sleeps for the longest 413 Retry-After time', async () => { let done = false; - (async () => { + void (async () => { try { await handleMultipleSendErrors({ ...defaultOptions, @@ -134,7 +134,7 @@ describe('handleMultipleSendErrors', () => { it("doesn't sleep longer than the remaining time", async () => { let done = false; - (async () => { + void (async () => { try { await handleMultipleSendErrors({ ...defaultOptions, diff --git a/ts/test-node/jobs/helpers/sleepForRateLimitRetryAfterTime_test.ts b/ts/test-node/jobs/helpers/sleepForRateLimitRetryAfterTime_test.ts index 5ebc0c2800d0..071b943db0a1 100644 --- a/ts/test-node/jobs/helpers/sleepForRateLimitRetryAfterTime_test.ts +++ b/ts/test-node/jobs/helpers/sleepForRateLimitRetryAfterTime_test.ts @@ -5,6 +5,7 @@ import { assert } from 'chai'; import * as sinon from 'sinon'; import { HTTPError } from '../../../textsecure/Errors'; import * as durations from '../../../util/durations'; +import { drop } from '../../../util/drop'; import { sleepForRateLimitRetryAfterTime } from '../../../jobs/helpers/sleepForRateLimitRetryAfterTime'; @@ -42,7 +43,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { it('waits for 1 minute if the error lacks Retry-After info', async () => { let done = false; - (async () => { + void (async () => { await sleepForRateLimitRetryAfterTime({ err: {}, log: createLogger(), @@ -67,7 +68,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { let done = false; - (async () => { + void (async () => { await sleepForRateLimitRetryAfterTime({ err, log: createLogger(), @@ -92,7 +93,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { let done = false; - (async () => { + void (async () => { await sleepForRateLimitRetryAfterTime({ err, log: createLogger(), @@ -117,7 +118,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { let done = false; - (async () => { + void (async () => { await sleepForRateLimitRetryAfterTime({ err: { httpError }, log: createLogger(), @@ -142,7 +143,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { let done = false; - (async () => { + void (async () => { await sleepForRateLimitRetryAfterTime({ err: { httpError }, log: createLogger(), @@ -167,7 +168,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { let done = false; - (async () => { + void (async () => { await sleepForRateLimitRetryAfterTime({ err, log: createLogger(), @@ -189,7 +190,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { let done = false; - (async () => { + void (async () => { await sleepForRateLimitRetryAfterTime({ err, log: createLogger(), @@ -210,7 +211,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { response: {}, }); - sleepForRateLimitRetryAfterTime({ err, log, timeRemaining: 9999999 }); + drop(sleepForRateLimitRetryAfterTime({ err, log, timeRemaining: 9999999 })); await clock.nextAsync(); sinon.assert.calledOnce(log.info); @@ -225,7 +226,7 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => { response: {}, }); - sleepForRateLimitRetryAfterTime({ err, log, timeRemaining: 9999999 }); + drop(sleepForRateLimitRetryAfterTime({ err, log, timeRemaining: 9999999 })); await clock.nextAsync(); sinon.assert.calledOnce(log.info); diff --git a/ts/test-node/util/sleep_test.ts b/ts/test-node/util/sleep_test.ts index 4bd8f9505a9c..5ee1660fbf9a 100644 --- a/ts/test-node/util/sleep_test.ts +++ b/ts/test-node/util/sleep_test.ts @@ -20,7 +20,7 @@ describe('sleep', () => { it('returns a promise that resolves after the specified number of milliseconds', async function test() { let isDone = false; - (async () => { + void (async () => { await sleep(123); isDone = true; })(); diff --git a/ts/textsecure/AccountManager.ts b/ts/textsecure/AccountManager.ts index 90cac426d021..31ec9f0ecd66 100644 --- a/ts/textsecure/AccountManager.ts +++ b/ts/textsecure/AccountManager.ts @@ -721,7 +721,7 @@ export default class AccountManager extends EventTarget { // Intentionally not awaiting becase `updatePNIIdentity` runs on an // Encrypted queue of MessageReceiver and we don't want to await remote // endpoints and block message processing. - this.queueTask(async () => { + void this.queueTask(async () => { try { const keys = await this.generateKeys( SIGNED_KEY_GEN_BATCH_SIZE, @@ -847,8 +847,8 @@ export default class AccountManager extends EventTarget { await Promise.all(promises); // This is primarily for the signed prekey summary it logs out - this.cleanSignedPreKeys(UUIDKind.ACI); - this.cleanSignedPreKeys(UUIDKind.PNI); + void this.cleanSignedPreKeys(UUIDKind.ACI); + void this.cleanSignedPreKeys(UUIDKind.PNI); return { ...result, @@ -885,7 +885,7 @@ export default class AccountManager extends EventTarget { // Intentionally not awaiting since this is processed on encrypted queue // of MessageReceiver. - this.queueTask(async () => { + void this.queueTask(async () => { try { const keys = await this.generateKeys( SIGNED_KEY_GEN_BATCH_SIZE, diff --git a/ts/textsecure/KeyChangeListener.ts b/ts/textsecure/KeyChangeListener.ts index abda4861e3e2..8b0b97c4df24 100644 --- a/ts/textsecure/KeyChangeListener.ts +++ b/ts/textsecure/KeyChangeListener.ts @@ -13,7 +13,7 @@ export function init(signalProtocolStore: SignalProtocolStore): void { uuid.toString(), 'private' ); - conversation.addKeyChange(reason); + void conversation.addKeyChange(reason); } ); } diff --git a/ts/textsecure/MessageReceiver.ts b/ts/textsecure/MessageReceiver.ts index fe21f8b1b965..e85210539d2d 100644 --- a/ts/textsecure/MessageReceiver.ts +++ b/ts/textsecure/MessageReceiver.ts @@ -40,6 +40,7 @@ import { verifySignature } from '../Curve'; import { strictAssert } from '../util/assert'; import type { BatcherType } from '../util/batcher'; import { createBatcher } from '../util/batcher'; +import { drop } from '../util/drop'; import { dropNull } from '../util/dropNull'; import { normalizeUuid } from '../util/normalizeUuid'; import { parseIntOrThrow } from '../util/parseIntOrThrow'; @@ -312,7 +313,7 @@ export default class MessageReceiver processBatch: (items: Array) => { // Not returning the promise here because we don't want to stall // the batch. - this.decryptAndCacheBatch(items); + void this.decryptAndCacheBatch(items); }, }); this.cacheRemoveBatcher = createBatcher({ @@ -337,13 +338,15 @@ export default class MessageReceiver request.respond(200, 'OK'); if (request.verb === 'PUT' && request.path === '/api/v1/queue/empty') { - this.incomingQueue.add( - createTaskWithTimeout( - async () => { - this.onEmpty(); - }, - 'incomingQueue/onEmpty', - TASK_WITH_TIMEOUT_OPTIONS + drop( + this.incomingQueue.add( + createTaskWithTimeout( + async () => { + this.onEmpty(); + }, + 'incomingQueue/onEmpty', + TASK_WITH_TIMEOUT_OPTIONS + ) ) ); } @@ -422,22 +425,26 @@ export default class MessageReceiver } }; - this.incomingQueue.add( - createTaskWithTimeout( - job, - 'incomingQueue/websocket', - TASK_WITH_TIMEOUT_OPTIONS + drop( + this.incomingQueue.add( + createTaskWithTimeout( + job, + 'incomingQueue/websocket', + TASK_WITH_TIMEOUT_OPTIONS + ) ) ); } public reset(): void { // We always process our cache before processing a new websocket message - this.incomingQueue.add( - createTaskWithTimeout( - async () => this.queueAllCached(), - 'incomingQueue/queueAllCached', - TASK_WITH_TIMEOUT_OPTIONS + drop( + this.incomingQueue.add( + createTaskWithTimeout( + async () => this.queueAllCached(), + 'incomingQueue/queueAllCached', + TASK_WITH_TIMEOUT_OPTIONS + ) ) ); @@ -626,11 +633,13 @@ export default class MessageReceiver // private async dispatchAndWait(id: string, event: Event): Promise { - this.appQueue.add( - createTaskWithTimeout( - async () => Promise.all(this.dispatchEvent(event)), - `dispatchEvent(${event.type}, ${id})`, - TASK_WITH_TIMEOUT_OPTIONS + drop( + this.appQueue.add( + createTaskWithTimeout( + async () => Promise.all(this.dispatchEvent(event)), + `dispatchEvent(${event.type}, ${id})`, + TASK_WITH_TIMEOUT_OPTIONS + ) ) ); } @@ -707,16 +716,24 @@ export default class MessageReceiver ); // We don't await here because we don't want this to gate future message processing - this.appQueue.add( - createTaskWithTimeout(emitEmpty, 'emitEmpty', TASK_WITH_TIMEOUT_OPTIONS) + drop( + this.appQueue.add( + createTaskWithTimeout( + emitEmpty, + 'emitEmpty', + TASK_WITH_TIMEOUT_OPTIONS + ) + ) ); }; const waitForEncryptedQueue = async () => { - this.addToQueue( - waitForDecryptedQueue, - 'onEmpty/waitForDecrypted', - TaskType.Decrypted + drop( + this.addToQueue( + waitForDecryptedQueue, + 'onEmpty/waitForDecrypted', + TaskType.Decrypted + ) ); }; @@ -725,25 +742,29 @@ export default class MessageReceiver // Resetting count so everything from the websocket after this starts at zero this.count = 0; - this.addToQueue( - waitForEncryptedQueue, - 'onEmpty/waitForEncrypted', - TaskType.Encrypted + drop( + this.addToQueue( + waitForEncryptedQueue, + 'onEmpty/waitForEncrypted', + TaskType.Encrypted + ) ); }; const waitForCacheAddBatcher = async () => { await this.decryptAndCacheBatcher.onIdle(); - this.incomingQueue.add( - createTaskWithTimeout( - waitForIncomingQueue, - 'onEmpty/waitForIncoming', - TASK_WITH_TIMEOUT_OPTIONS + drop( + this.incomingQueue.add( + createTaskWithTimeout( + waitForIncomingQueue, + 'onEmpty/waitForIncoming', + TASK_WITH_TIMEOUT_OPTIONS + ) ) ); }; - waitForCacheAddBatcher(); + drop(waitForCacheAddBatcher()); } private updateProgress(count: number): void { @@ -835,15 +856,20 @@ export default class MessageReceiver }; // Maintain invariant: encrypted queue => decrypted queue - this.addToQueue( - async () => { - this.queueDecryptedEnvelope(decryptedEnvelope, payloadPlaintext); - }, - `queueDecryptedEnvelope(${getEnvelopeId(decryptedEnvelope)})`, - TaskType.Encrypted + drop( + this.addToQueue( + async () => { + void this.queueDecryptedEnvelope( + decryptedEnvelope, + payloadPlaintext + ); + }, + `queueDecryptedEnvelope(${getEnvelopeId(decryptedEnvelope)})`, + TaskType.Encrypted + ) ); } else { - this.queueCachedEnvelope(item, envelope); + void this.queueCachedEnvelope(item, envelope); } } catch (error) { log.error( @@ -876,11 +902,13 @@ export default class MessageReceiver if (this.isEmptied) { this.clearRetryTimeout(); this.retryCachedTimeout = setTimeout(() => { - this.incomingQueue.add( - createTaskWithTimeout( - async () => this.queueAllCached(), - 'queueAllCached', - TASK_WITH_TIMEOUT_OPTIONS + drop( + this.incomingQueue.add( + createTaskWithTimeout( + async () => this.queueAllCached(), + 'queueAllCached', + TASK_WITH_TIMEOUT_OPTIONS + ) ) ); }, RETRY_TIMEOUT); @@ -1155,11 +1183,13 @@ export default class MessageReceiver logId = getEnvelopeId(unsealedEnvelope); const taskId = `dispatchEvent(EnvelopeEvent(${logId}))`; - this.addToQueue( - async () => - this.dispatchAndWait(taskId, new EnvelopeEvent(unsealedEnvelope)), - taskId, - TaskType.Decrypted + drop( + this.addToQueue( + async () => + this.dispatchAndWait(taskId, new EnvelopeEvent(unsealedEnvelope)), + taskId, + TaskType.Decrypted + ) ); return this.decryptEnvelope(stores, unsealedEnvelope, uuidKind); @@ -1887,10 +1917,12 @@ export default class MessageReceiver ); // Avoid deadlocks by scheduling processing on decrypted queue - this.addToQueue( - async () => this.dispatchEvent(event), - `decrypted/dispatchEvent/DecryptionErrorEvent(${envelopeId})`, - TaskType.Decrypted + drop( + this.addToQueue( + async () => this.dispatchEvent(event), + `decrypted/dispatchEvent/DecryptionErrorEvent(${envelopeId})`, + TaskType.Decrypted + ) ); } else { this.removeFromCache(envelope); @@ -2099,7 +2131,7 @@ export default class MessageReceiver }, this.removeFromCache.bind(this, envelope) ); - this.dispatchAndWait(logId, ev); + void this.dispatchAndWait(logId, ev); return; } @@ -2158,7 +2190,7 @@ export default class MessageReceiver }, this.removeFromCache.bind(this, envelope) ); - this.dispatchAndWait(logId, ev); + void this.dispatchAndWait(logId, ev); }); return; } @@ -2828,7 +2860,7 @@ export default class MessageReceiver } if (sentMessage.storyMessage) { - this.handleStoryMessage( + void this.handleStoryMessage( envelope, sentMessage.storyMessage, sentMessage @@ -2867,7 +2899,7 @@ export default class MessageReceiver return this.handleContacts(envelope, syncMessage.contacts); } if (syncMessage.groups) { - this.handleGroups(envelope, syncMessage.groups); + void this.handleGroups(envelope, syncMessage.groups); return; } if (syncMessage.blocked) { @@ -3333,7 +3365,7 @@ export default class MessageReceiver if (changed) { log.info('handleBlocked: Block list changed, forcing re-render.'); const uniqueIdentifiers = Array.from(new Set(allIdentifiers)); - window.ConversationController.forceRerender(uniqueIdentifiers); + void window.ConversationController.forceRerender(uniqueIdentifiers); } } diff --git a/ts/textsecure/OutgoingMessage.ts b/ts/textsecure/OutgoingMessage.ts index 94343eb3b5a1..17d994882bcb 100644 --- a/ts/textsecure/OutgoingMessage.ts +++ b/ts/textsecure/OutgoingMessage.ts @@ -520,7 +520,7 @@ export default class OutgoingMessage { this.numberCompleted(); if (this.sendLogCallback) { - this.sendLogCallback({ + void this.sendLogCallback({ identifier, deviceIds, }); @@ -559,7 +559,7 @@ export default class OutgoingMessage { this.numberCompleted(); if (this.sendLogCallback) { - this.sendLogCallback({ + void this.sendLogCallback({ identifier, deviceIds, }); diff --git a/ts/textsecure/RotateSignedPreKeyListener.ts b/ts/textsecure/RotateSignedPreKeyListener.ts index 6990e65cc056..7e66e0c2c3ec 100644 --- a/ts/textsecure/RotateSignedPreKeyListener.ts +++ b/ts/textsecure/RotateSignedPreKeyListener.ts @@ -19,7 +19,7 @@ export class RotateSignedPreKeyListener { protected scheduleRotationForNow(): void { const now = Date.now(); - window.textsecure.storage.put('nextSignedKeyRotationTime', now); + void window.textsecure.storage.put('nextSignedKeyRotationTime', now); } protected setTimeoutForNextRun(): void { @@ -46,7 +46,7 @@ export class RotateSignedPreKeyListener { private scheduleNextRotation(): void { const now = Date.now(); const nextTime = now + ROTATION_INTERVAL; - window.textsecure.storage.put('nextSignedKeyRotationTime', nextTime); + void window.textsecure.storage.put('nextSignedKeyRotationTime', nextTime); } private async run(): Promise { @@ -67,7 +67,7 @@ export class RotateSignedPreKeyListener { private runWhenOnline() { if (window.navigator.onLine) { - this.run(); + void this.run(); } else { log.info('We are offline; keys will be rotated when we are next online'); const listener = () => { diff --git a/ts/textsecure/SendMessage.ts b/ts/textsecure/SendMessage.ts index 7671bc08c11b..246cd06c3d6d 100644 --- a/ts/textsecure/SendMessage.ts +++ b/ts/textsecure/SendMessage.ts @@ -1246,7 +1246,7 @@ export default class MessageSender { }); recipients.forEach(identifier => { - this.queueJobForIdentifier(identifier, async () => + void this.queueJobForIdentifier(identifier, async () => outgoing.sendToIdentifier(identifier) ); }); @@ -2186,7 +2186,7 @@ export default class MessageSender { return; } - if (!initialSavePromise) { + if (initialSavePromise === undefined) { initialSavePromise = window.Signal.Data.insertSentProto( { contentHint, diff --git a/ts/textsecure/SocketManager.ts b/ts/textsecure/SocketManager.ts index f3ff4e1890fe..debc2d598e5f 100644 --- a/ts/textsecure/SocketManager.ts +++ b/ts/textsecure/SocketManager.ts @@ -219,7 +219,7 @@ export class SocketManager extends EventListener { } } - reconnect(); + void reconnect(); return; } @@ -244,7 +244,7 @@ export class SocketManager extends EventListener { return; } - reconnect(); + void reconnect(); }); } diff --git a/ts/textsecure/SyncRequest.ts b/ts/textsecure/SyncRequest.ts index 4fb7b36c5696..2020e312c8ed 100644 --- a/ts/textsecure/SyncRequest.ts +++ b/ts/textsecure/SyncRequest.ts @@ -139,6 +139,6 @@ export default class SyncRequest { } start(): void { - this.inner.start(); + void this.inner.start(); } } diff --git a/ts/textsecure/WebAPI.ts b/ts/textsecure/WebAPI.ts index dca72790d9a6..5bb24eaf6398 100644 --- a/ts/textsecure/WebAPI.ts +++ b/ts/textsecure/WebAPI.ts @@ -1130,7 +1130,7 @@ export function initialize({ }); if (useWebSocket) { - socketManager.authenticate({ username, password }); + void socketManager.authenticate({ username, password }); } const { directoryUrl, directoryMRENCLAVE } = directoryConfig; @@ -1368,7 +1368,7 @@ export function initialize({ function checkSockets(): void { // Intentionally not awaiting - socketManager.check(); + void socketManager.check(); } async function onOnline(): Promise { @@ -1392,7 +1392,7 @@ export function initialize({ } function onHasStoriesDisabledChange(newValue: boolean): void { - socketManager.onHasStoriesDisabledChange(newValue); + void socketManager.onHasStoriesDisabledChange(newValue); } async function getConfig() { diff --git a/ts/textsecure/WebsocketResources.ts b/ts/textsecure/WebsocketResources.ts index e13c55146390..69b44eb523ae 100644 --- a/ts/textsecure/WebsocketResources.ts +++ b/ts/textsecure/WebsocketResources.ts @@ -227,7 +227,7 @@ export default class WebSocketResource extends EventTarget { if (!this.keepalive) { return; } - this.keepalive.send(); + void this.keepalive.send(); } public close(code = 3000, reason?: string): void { diff --git a/ts/textsecure/cds/CDSSocketManagerBase.ts b/ts/textsecure/cds/CDSSocketManagerBase.ts index 623e9580639a..99ab50bf5920 100644 --- a/ts/textsecure/cds/CDSSocketManagerBase.ts +++ b/ts/textsecure/cds/CDSSocketManagerBase.ts @@ -81,7 +81,7 @@ export abstract class CDSSocketManagerBase< throw error; } finally { log.info('CDSSocketManager: closing socket'); - socket.close(3000, 'Normal'); + void socket.close(3000, 'Normal'); } } diff --git a/ts/types/Stickers.ts b/ts/types/Stickers.ts index dfd3f9f3f1c6..45bea5716226 100644 --- a/ts/types/Stickers.ts +++ b/ts/types/Stickers.ts @@ -180,7 +180,10 @@ export function downloadQueuedPacks(): void { const { key, status } = packsToDownload[id]; // The queuing is done inside this function, no need to await here - downloadStickerPack(id, key, { finalStatus: status, suppressError: true }); + void downloadStickerPack(id, key, { + finalStatus: status, + suppressError: true, + }); } packsToDownload = {}; @@ -217,7 +220,7 @@ function capturePacksToDownload( // These packs should never end up in the database, but if they do we'll delete them if (existing.status === 'ephemeral') { - deletePack(id); + void deletePack(id); return; } diff --git a/ts/util/batcher.ts b/ts/util/batcher.ts index 9401325e5396..0e73950a9b24 100644 --- a/ts/util/batcher.ts +++ b/ts/util/batcher.ts @@ -8,6 +8,7 @@ import * as log from '../logging/log'; import * as Errors from '../types/errors'; import { clearTimeoutIfNecessary } from './clearTimeoutIfNecessary'; import { MINUTE } from './durations'; +import { drop } from './drop'; declare global { // We want to extend `window`'s properties, so we need an interface. @@ -67,9 +68,11 @@ export function createBatcher( const itemsRef = items; items = []; - queue.add(async () => { - await options.processBatch(itemsRef); - }); + drop( + queue.add(async () => { + await options.processBatch(itemsRef); + }) + ); } function add(item: ItemType) { diff --git a/ts/util/cleanup.ts b/ts/util/cleanup.ts index 83c0665a3aa4..c75393bf3119 100644 --- a/ts/util/cleanup.ts +++ b/ts/util/cleanup.ts @@ -78,7 +78,7 @@ async function cleanupStoryReplies( replies.forEach(reply => { const model = window.MessageController.register(reply.id, reply); model.unset('storyReplyContext'); - model.hydrateStoryContext(null); + void model.hydrateStoryContext(null); }); } diff --git a/ts/util/createIPCEvents.tsx b/ts/util/createIPCEvents.tsx index 1c73d779410b..bc3267d8ec50 100644 --- a/ts/util/createIPCEvents.tsx +++ b/ts/util/createIPCEvents.tsx @@ -527,7 +527,7 @@ export function createIPCEvents( }, installStickerPack: async (packId, key) => { - Stickers.downloadStickerPack(packId, key, { + void Stickers.downloadStickerPack(packId, key, { finalStatus: 'installed', }); }, diff --git a/ts/util/deleteGroupStoryReplyForEveryone.ts b/ts/util/deleteGroupStoryReplyForEveryone.ts index ccf938b560cc..c7a1ee162274 100644 --- a/ts/util/deleteGroupStoryReplyForEveryone.ts +++ b/ts/util/deleteGroupStoryReplyForEveryone.ts @@ -31,7 +31,7 @@ export async function deleteGroupStoryReplyForEveryone( return; } - sendDeleteForEveryoneMessage(group.attributes, { + void sendDeleteForEveryoneMessage(group.attributes, { deleteForEveryoneDuration: DAY, id: replyMessageId, timestamp, diff --git a/ts/util/deleteStoryForEveryone.ts b/ts/util/deleteStoryForEveryone.ts index a7675dc61eea..6623cbf77de0 100644 --- a/ts/util/deleteStoryForEveryone.ts +++ b/ts/util/deleteStoryForEveryone.ts @@ -35,7 +35,7 @@ export async function deleteStoryForEveryone( story.conversationId ); if (sourceConversation && isGroupV2(sourceConversation.attributes)) { - sendDeleteForEveryoneMessage(sourceConversation.attributes, { + void sendDeleteForEveryoneMessage(sourceConversation.attributes, { deleteForEveryoneDuration: DAY, id: story.messageId, timestamp: story.timestamp, @@ -212,5 +212,5 @@ export async function deleteStoryForEveryone( }, noop ); - onStoryRecipientUpdate(ev); + void onStoryRecipientUpdate(ev); } diff --git a/ts/util/downloadOnboardingStory.ts b/ts/util/downloadOnboardingStory.ts index 6ce82bc1cff5..3c0fef37995a 100644 --- a/ts/util/downloadOnboardingStory.ts +++ b/ts/util/downloadOnboardingStory.ts @@ -128,7 +128,7 @@ async function continueDownloadingOnboardingStory(): Promise { message.trigger('change'); }); - window.storage.put( + await window.storage.put( 'existingOnboardingStoryMessageIds', storyMessages.map(message => message.id) ); diff --git a/ts/util/drop.ts b/ts/util/drop.ts new file mode 100644 index 000000000000..dae17f39db75 --- /dev/null +++ b/ts/util/drop.ts @@ -0,0 +1,8 @@ +// Copyright 2022 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +// Use this function when asynchronous action has to run without blocking its +// parent. +export function drop(promise: Promise | undefined): void { + void promise; +} diff --git a/ts/util/findAndDeleteOnboardingStoryIfExists.ts b/ts/util/findAndDeleteOnboardingStoryIfExists.ts index 852d41b57fed..ed6cd24e2eb0 100644 --- a/ts/util/findAndDeleteOnboardingStoryIfExists.ts +++ b/ts/util/findAndDeleteOnboardingStoryIfExists.ts @@ -41,7 +41,7 @@ export async function findAndDeleteOnboardingStoryIfExists(): Promise { await window.Signal.Data.removeMessages(existingOnboardingStoryMessageIds); - window.storage.put('existingOnboardingStoryMessageIds', undefined); + await window.storage.put('existingOnboardingStoryMessageIds', undefined); const signalConversation = await window.ConversationController.getOrCreateSignalConversation(); diff --git a/ts/util/handleMessageSend.ts b/ts/util/handleMessageSend.ts index 95f75f5e053a..7c28e29b278c 100644 --- a/ts/util/handleMessageSend.ts +++ b/ts/util/handleMessageSend.ts @@ -111,7 +111,7 @@ function processError(error: unknown): void { `handleMessageSend: Got 401/403 for ${conversation.idForLogging()}, removing profile key` ); - conversation.setProfileKey(undefined); + void conversation.setProfileKey(undefined); } if (conversation.get('sealedSender') === SEALED_SENDER.UNKNOWN) { log.warn( diff --git a/ts/util/handleRetry.ts b/ts/util/handleRetry.ts index c104986fc883..d382ec1bf064 100644 --- a/ts/util/handleRetry.ts +++ b/ts/util/handleRetry.ts @@ -39,6 +39,7 @@ import { SignalService as Proto } from '../protobuf'; import * as log from '../logging/log'; import MessageSender from '../textsecure/SendMessage'; import type { StoryDistributionListDataType } from '../state/ducks/storyDistributionLists'; +import { drop } from './drop'; const RETRY_LIMIT = 5; @@ -690,14 +691,18 @@ async function requestResend(decryptionError: DecryptionErrorEventData) { } log.warn(`requestResend/${logId}: No content hint, adding error immediately`); - conversation.queueJob('addDeliveryIssue', async () => { - conversation.addDeliveryIssue({ - receivedAt: receivedAtDate, - receivedAtCounter, - senderUuid, - sentAt: timestamp, - }); - }); + drop( + conversation.queueJob('addDeliveryIssue', async () => { + drop( + conversation.addDeliveryIssue({ + receivedAt: receivedAtDate, + receivedAtCounter, + senderUuid, + sentAt: timestamp, + }) + ); + }) + ); } function scheduleSessionReset(senderUuid: string, senderDevice: number) { @@ -710,13 +715,15 @@ function scheduleSessionReset(senderUuid: string, senderDevice: number) { ); } - lightSessionResetQueue.add(async () => { - const ourUuid = window.textsecure.storage.user.getCheckedUuid(); + drop( + lightSessionResetQueue.add(async () => { + const ourUuid = window.textsecure.storage.user.getCheckedUuid(); - await window.textsecure.storage.protocol.lightSessionReset( - new QualifiedAddress(ourUuid, Address.create(senderUuid, senderDevice)) - ); - }); + await window.textsecure.storage.protocol.lightSessionReset( + new QualifiedAddress(ourUuid, Address.create(senderUuid, senderDevice)) + ); + }) + ); } function startAutomaticSessionReset(decryptionError: DecryptionErrorEventData) { @@ -740,7 +747,14 @@ function startAutomaticSessionReset(decryptionError: DecryptionErrorEventData) { const receivedAt = Date.now(); const receivedAtCounter = window.Signal.Util.incrementMessageCounter(); - conversation.queueJob('addChatSessionRefreshed', async () => { - conversation.addChatSessionRefreshed({ receivedAt, receivedAtCounter }); - }); + drop( + conversation.queueJob('addChatSessionRefreshed', async () => { + drop( + conversation.addChatSessionRefreshed({ + receivedAt, + receivedAtCounter, + }) + ); + }) + ); } diff --git a/ts/util/markConversationRead.ts b/ts/util/markConversationRead.ts index 065bc1f0c388..5e074621bda4 100644 --- a/ts/util/markConversationRead.ts +++ b/ts/util/markConversationRead.ts @@ -13,6 +13,7 @@ import { tapToViewMessagesDeletionService } from '../services/tapToViewMessagesD import { isGroup, isDirectConversation } from './whatTypeOfConversation'; import * as log from '../logging/log'; import { getConversationIdForLogging } from './idForLogging'; +import { drop } from './drop'; import { isConversationAccepted } from './isConversationAccepted'; import { ReadStatus } from '../messages/MessageReadStatus'; @@ -133,7 +134,7 @@ export async function markConversationRead( 'markConversationRead: We are primary device; not sending read syncs' ); } else { - readSyncJobQueue.add({ readSyncs }); + drop(readSyncJobQueue.add({ readSyncs })); } if (isConversationAccepted(conversationAttrs)) { @@ -144,8 +145,8 @@ export async function markConversationRead( } } - expiringMessagesDeletionService.update(); - tapToViewMessagesDeletionService.update(); + void expiringMessagesDeletionService.update(); + void tapToViewMessagesDeletionService.update(); return true; } diff --git a/ts/util/markOnboardingStoryAsRead.ts b/ts/util/markOnboardingStoryAsRead.ts index 57a4dbcb1265..6f36944785b7 100644 --- a/ts/util/markOnboardingStoryAsRead.ts +++ b/ts/util/markOnboardingStoryAsRead.ts @@ -38,11 +38,11 @@ export async function markOnboardingStoryAsRead(): Promise { }) .filter(isNotNil); - window.Signal.Data.saveMessages(messageAttributes, { + await window.Signal.Data.saveMessages(messageAttributes, { ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), }); - window.storage.put('hasViewedOnboardingStory', true); + await window.storage.put('hasViewedOnboardingStory', true); storageServiceUploadJob(); } diff --git a/ts/util/maybeForwardMessage.ts b/ts/util/maybeForwardMessage.ts index 6302054c820e..347dc42be6fa 100644 --- a/ts/util/maybeForwardMessage.ts +++ b/ts/util/maybeForwardMessage.ts @@ -89,7 +89,7 @@ export async function maybeForwardMessage( } : undefined; - conversation.enqueueMessageForSend( + void conversation.enqueueMessageForSend( { body: undefined, attachments: [], @@ -99,7 +99,7 @@ export async function maybeForwardMessage( ); } else if (contact?.length) { const contactWithHydratedAvatar = await loadContactData(contact); - conversation.enqueueMessageForSend( + void conversation.enqueueMessageForSend( { body: undefined, attachments: [], @@ -124,7 +124,7 @@ export async function maybeForwardMessage( ) ); - conversation.enqueueMessageForSend( + void conversation.enqueueMessageForSend( { body: messageBody || undefined, attachments: attachmentsToSend, diff --git a/ts/util/messageBatcher.ts b/ts/util/messageBatcher.ts index af1a26df9ad7..eb239788269d 100644 --- a/ts/util/messageBatcher.ts +++ b/ts/util/messageBatcher.ts @@ -24,7 +24,7 @@ export function queueUpdateMessage(messageAttr: MessageAttributesType): void { if (shouldBatch) { updateMessageBatcher.add(messageAttr); } else { - window.Signal.Data.saveMessage(messageAttr, { + void window.Signal.Data.saveMessage(messageAttr, { ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), }); } diff --git a/ts/util/onStoryRecipientUpdate.ts b/ts/util/onStoryRecipientUpdate.ts index e74702efa6da..158742933e8a 100644 --- a/ts/util/onStoryRecipientUpdate.ts +++ b/ts/util/onStoryRecipientUpdate.ts @@ -12,6 +12,7 @@ import { isStory } from '../state/selectors/message'; import { normalizeUuid } from './normalizeUuid'; import { queueUpdateMessage } from './messageBatcher'; import { isMe } from './whatTypeOfConversation'; +import { drop } from './drop'; export async function onStoryRecipientUpdate( event: StoryRecipientUpdateEvent @@ -45,156 +46,161 @@ export async function onStoryRecipientUpdate( return; } - targetConversation.queueJob(logId, async () => { - log.info(`${logId}: updating`); + drop( + targetConversation.queueJob(logId, async () => { + log.info(`${logId}: updating`); - // Build up some maps for fast/easy lookups - const isAllowedToReply = new Map(); - const distributionListIdToConversationIds = new Map>(); - data.storyMessageRecipients.forEach(item => { - if (!item.destinationUuid) { - return; - } - - const convo = window.ConversationController.get( - normalizeUuid(item.destinationUuid, `${logId}.destinationUuid`) - ); - - if (!convo || !item.distributionListIds) { - return; - } - - for (const rawUuid of item.distributionListIds) { - const uuid = normalizeUuid(rawUuid, `${logId}.distributionListId`); - - const existing = distributionListIdToConversationIds.get(uuid); - if (existing === undefined) { - distributionListIdToConversationIds.set(uuid, new Set([convo.id])); - } else { - existing.add(convo.id); + // Build up some maps for fast/easy lookups + const isAllowedToReply = new Map(); + const distributionListIdToConversationIds = new Map< + string, + Set + >(); + data.storyMessageRecipients.forEach(item => { + if (!item.destinationUuid) { + return; } - } - isAllowedToReply.set(convo.id, item.isAllowedToReply !== false); - }); - const ourConversationId = - window.ConversationController.getOurConversationIdOrThrow(); - const now = Date.now(); + const convo = window.ConversationController.get( + normalizeUuid(item.destinationUuid, `${logId}.destinationUuid`) + ); - const messages = await window.Signal.Data.getMessagesBySentAt(timestamp); - - // Now we figure out who needs to be added and who needs to removed - const handledMessages = messages.filter(item => { - if (!isStory(item)) { - return false; - } - - const { sendStateByConversationId, storyDistributionListId } = item; - - if (!sendStateByConversationId || !storyDistributionListId) { - return false; - } - - const newConversationIds = - distributionListIdToConversationIds.get(storyDistributionListId) ?? - new Set(); - - const nextSendStateByConversationId = { - ...sendStateByConversationId, - }; - - // Find conversation ids present in the local send state, but missing - // in the remote state, and remove them from the local state. - for (const oldId of Object.keys(sendStateByConversationId)) { - if (!newConversationIds.has(oldId)) { - const recipient = window.ConversationController.get(oldId); - - const recipientLogId = recipient - ? getConversationIdForLogging(recipient.attributes) - : oldId; - - log.info(`${logId}: removing`, { - recipient: recipientLogId, - messageId: item.id, - storyDistributionListId, - }); - delete nextSendStateByConversationId[oldId]; + if (!convo || !item.distributionListIds) { + return; } - } - // Find conversation ids present in the remote send state, but missing in - // the local send state, and add them to the local state. - for (const newId of newConversationIds) { - if (sendStateByConversationId[newId] === undefined) { - const recipient = window.ConversationController.get(newId); + for (const rawUuid of item.distributionListIds) { + const uuid = normalizeUuid(rawUuid, `${logId}.distributionListId`); - const recipientLogId = recipient - ? getConversationIdForLogging(recipient.attributes) - : newId; - - log.info(`${logId}: adding`, { - recipient: recipientLogId, - messageId: item.id, - storyDistributionListId, - }); - nextSendStateByConversationId[newId] = { - isAllowedToReplyToStory: Boolean(isAllowedToReply.get(newId)), - status: SendStatus.Sent, - updatedAt: now, - }; + const existing = distributionListIdToConversationIds.get(uuid); + if (existing === undefined) { + distributionListIdToConversationIds.set(uuid, new Set([convo.id])); + } else { + existing.add(convo.id); + } } - } + isAllowedToReply.set(convo.id, item.isAllowedToReply !== false); + }); - if (isEqual(sendStateByConversationId, nextSendStateByConversationId)) { - log.info(`${logId}: sendStateByConversationId does not need update`, { - messageId: item.id, - }); - return true; - } + const ourConversationId = + window.ConversationController.getOurConversationIdOrThrow(); + const now = Date.now(); - const message = window.MessageController.register(item.id, item); + const messages = await window.Signal.Data.getMessagesBySentAt(timestamp); - const sendStateConversationIds = new Set( - Object.keys(nextSendStateByConversationId) - ); + // Now we figure out who needs to be added and who needs to removed + const handledMessages = messages.filter(item => { + if (!isStory(item)) { + return false; + } - if ( - sendStateConversationIds.size === 0 || - (sendStateConversationIds.size === 1 && - sendStateConversationIds.has(ourConversationId)) - ) { - log.info(`${logId} DOE`, { - messageId: item.id, - storyDistributionListId, - }); - const delAttributes: DeleteAttributesType = { - fromId: ourConversationId, - serverTimestamp: Number(item.serverTimestamp), - targetSentTimestamp: item.timestamp, + const { sendStateByConversationId, storyDistributionListId } = item; + + if (!sendStateByConversationId || !storyDistributionListId) { + return false; + } + + const newConversationIds = + distributionListIdToConversationIds.get(storyDistributionListId) ?? + new Set(); + + const nextSendStateByConversationId = { + ...sendStateByConversationId, }; - const doe = new DeleteModel(delAttributes); - // There are no longer any remaining members for this message so lets - // run it through deleteForEveryone which marks the message as - // deletedForEveryone locally. - // - // NOTE: We don't call `Deletes.onDelete()` so the message lookup by - // sent timestamp doesn't happen (it would return all copies of the - // story, not just the one we want to delete). - message.handleDeleteForEveryone(doe); - } else { - message.set({ - sendStateByConversationId: nextSendStateByConversationId, - }); - queueUpdateMessage(message.attributes); + // Find conversation ids present in the local send state, but missing + // in the remote state, and remove them from the local state. + for (const oldId of Object.keys(sendStateByConversationId)) { + if (!newConversationIds.has(oldId)) { + const recipient = window.ConversationController.get(oldId); + + const recipientLogId = recipient + ? getConversationIdForLogging(recipient.attributes) + : oldId; + + log.info(`${logId}: removing`, { + recipient: recipientLogId, + messageId: item.id, + storyDistributionListId, + }); + delete nextSendStateByConversationId[oldId]; + } + } + + // Find conversation ids present in the remote send state, but missing in + // the local send state, and add them to the local state. + for (const newId of newConversationIds) { + if (sendStateByConversationId[newId] === undefined) { + const recipient = window.ConversationController.get(newId); + + const recipientLogId = recipient + ? getConversationIdForLogging(recipient.attributes) + : newId; + + log.info(`${logId}: adding`, { + recipient: recipientLogId, + messageId: item.id, + storyDistributionListId, + }); + nextSendStateByConversationId[newId] = { + isAllowedToReplyToStory: Boolean(isAllowedToReply.get(newId)), + status: SendStatus.Sent, + updatedAt: now, + }; + } + } + + if (isEqual(sendStateByConversationId, nextSendStateByConversationId)) { + log.info(`${logId}: sendStateByConversationId does not need update`, { + messageId: item.id, + }); + return true; + } + + const message = window.MessageController.register(item.id, item); + + const sendStateConversationIds = new Set( + Object.keys(nextSendStateByConversationId) + ); + + if ( + sendStateConversationIds.size === 0 || + (sendStateConversationIds.size === 1 && + sendStateConversationIds.has(ourConversationId)) + ) { + log.info(`${logId} DOE`, { + messageId: item.id, + storyDistributionListId, + }); + const delAttributes: DeleteAttributesType = { + fromId: ourConversationId, + serverTimestamp: Number(item.serverTimestamp), + targetSentTimestamp: item.timestamp, + }; + const doe = new DeleteModel(delAttributes); + + // There are no longer any remaining members for this message so lets + // run it through deleteForEveryone which marks the message as + // deletedForEveryone locally. + // + // NOTE: We don't call `Deletes.onDelete()` so the message lookup by + // sent timestamp doesn't happen (it would return all copies of the + // story, not just the one we want to delete). + void message.handleDeleteForEveryone(doe); + } else { + message.set({ + sendStateByConversationId: nextSendStateByConversationId, + }); + queueUpdateMessage(message.attributes); + } + + return true; + }); + + if (handledMessages.length) { + window.Whisper.events.trigger('incrementProgress'); + confirm(); } - - return true; - }); - - if (handledMessages.length) { - window.Whisper.events.trigger('incrementProgress'); - confirm(); - } - }); + }) + ); } diff --git a/ts/util/queueAttachmentDownloads.ts b/ts/util/queueAttachmentDownloads.ts index 22f242692448..024288516fec 100644 --- a/ts/util/queueAttachmentDownloads.ts +++ b/ts/util/queueAttachmentDownloads.ts @@ -236,7 +236,7 @@ export async function queueAttachmentDownloads( } if (!status) { // Save the packId/packKey for future download/install - savePackMetadata(packId, packKey, { messageId }); + void savePackMetadata(packId, packKey, { messageId }); } else { await dataInterface.addStickerPackReference(messageId, packId); } diff --git a/ts/util/registration.ts b/ts/util/registration.ts index e2bb12e181a7..cd62637dab86 100644 --- a/ts/util/registration.ts +++ b/ts/util/registration.ts @@ -1,13 +1,13 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -export function markEverDone(): void { - window.storage.put('chromiumRegistrationDoneEver', ''); +export async function markEverDone(): Promise { + await window.storage.put('chromiumRegistrationDoneEver', ''); } -export function markDone(): void { - markEverDone(); - window.storage.put('chromiumRegistrationDone', ''); +export async function markDone(): Promise { + await markEverDone(); + await window.storage.put('chromiumRegistrationDone', ''); } export async function remove(): Promise { diff --git a/ts/util/sendStoryMessage.ts b/ts/util/sendStoryMessage.ts index 322a48f5bd37..a2d7b435bb28 100644 --- a/ts/util/sendStoryMessage.ts +++ b/ts/util/sendStoryMessage.ts @@ -222,7 +222,7 @@ export async function sendStoryMessage( for (const group of groupsToUpdate) { group.set('storySendMode', StorySendMode.Always); } - window.Signal.Data.updateConversations( + void window.Signal.Data.updateConversations( groupsToUpdate.map(group => group.attributes) ); for (const group of groupsToUpdate) { @@ -290,7 +290,7 @@ export async function sendStoryMessage( const model = new window.Whisper.Message(messageAttributes); const message = window.MessageController.register(model.id, model); - ourConversation.addSingleMessage(model, { isJustSent: true }); + void ourConversation.addSingleMessage(model, { isJustSent: true }); log.info( `stories.sendStoryMessage: saving message ${messageAttributes.timestamp}` @@ -341,7 +341,7 @@ export async function sendStoryMessage( const message = window.MessageController.register(model.id, model); const conversation = message.getConversation(); - conversation?.addSingleMessage(model, { isJustSent: true }); + void conversation?.addSingleMessage(model, { isJustSent: true }); log.info( `stories.sendStoryMessage: saving message ${messageAttributes.timestamp}` diff --git a/ts/util/waitBatcher.ts b/ts/util/waitBatcher.ts index 5653e0490209..1e3a8a9a6461 100644 --- a/ts/util/waitBatcher.ts +++ b/ts/util/waitBatcher.ts @@ -132,14 +132,14 @@ export function createWaitBatcher( // time is bounded by `options.wait` and not extended by further pushes. timeout = setTimeout(() => { timeout = null; - _kickBatchOff(); + void _kickBatchOff(); }, options.wait); } if (items.length >= options.maxSize) { clearTimeoutIfNecessary(timeout); timeout = null; - _kickBatchOff(); + void _kickBatchOff(); } await promise; diff --git a/ts/views/conversation_view.tsx b/ts/views/conversation_view.tsx index d27f6a70f524..7b1a5d298c34 100644 --- a/ts/views/conversation_view.tsx +++ b/ts/views/conversation_view.tsx @@ -134,7 +134,7 @@ export class ConversationView extends window.Backbone.View { window.Signal.Data.updateConversation(this.model.attributes); - this.model.updateLastMessage(); + void this.model.updateLastMessage(); } this.conversationView?.remove(); @@ -168,7 +168,7 @@ export class ConversationView extends window.Backbone.View { const message = await getMessageById(messageId); if (message) { - this.model.loadAndScroll(messageId); + void this.model.loadAndScroll(messageId); return; } @@ -181,14 +181,14 @@ export class ConversationView extends window.Backbone.View { } const loadAndUpdate = async () => { - Promise.all([ + void Promise.all([ this.model.loadNewestMessages(undefined, undefined), this.model.updateLastMessage(), this.model.updateUnread(), ]); }; - loadAndUpdate(); + void loadAndUpdate(); window.reduxActions.composer.setComposerFocus(this.model.id); @@ -200,17 +200,17 @@ export class ConversationView extends window.Backbone.View { ); } - this.model.fetchLatestGroupV2Data(); + void this.model.fetchLatestGroupV2Data(); strictAssert( this.model.throttledMaybeMigrateV1Group !== undefined, 'Conversation model should be initialized' ); - this.model.throttledMaybeMigrateV1Group(); + void this.model.throttledMaybeMigrateV1Group(); strictAssert( this.model.throttledFetchSMSOnlyUUID !== undefined, 'Conversation model should be initialized' ); - this.model.throttledFetchSMSOnlyUUID(); + void this.model.throttledFetchSMSOnlyUUID(); const ourUuid = window.textsecure.storage.user.getUuid(UUIDKind.ACI); if ( @@ -224,7 +224,7 @@ export class ConversationView extends window.Backbone.View { await this.model.throttledGetProfiles(); } - this.model.updateVerified(); + void this.model.updateVerified(); } getMessageDetail({ diff --git a/ts/windows/applyTheme.ts b/ts/windows/applyTheme.ts index cb47bb10ec8b..4000b713bcdd 100644 --- a/ts/windows/applyTheme.ts +++ b/ts/windows/applyTheme.ts @@ -25,9 +25,9 @@ async function applyThemeLoop() { } } -applyTheme(); -applyThemeLoop(); +void applyTheme(); +void applyThemeLoop(); window.SignalContext.nativeThemeListener.subscribe(() => { - applyTheme(); + void applyTheme(); }); diff --git a/ts/windows/main/phase1-ipc.ts b/ts/windows/main/phase1-ipc.ts index e2fe2b71a8e8..7865bbd77799 100644 --- a/ts/windows/main/phase1-ipc.ts +++ b/ts/windows/main/phase1-ipc.ts @@ -155,7 +155,7 @@ window.setMenuBarVisibility = visibility => window.updateSystemTraySetting = ( systemTraySetting /* : Readonly */ ) => { - ipc.invoke('update-system-tray-setting', systemTraySetting); + void ipc.invoke('update-system-tray-setting', systemTraySetting); }; window.restart = () => { @@ -322,7 +322,7 @@ ipc.on('show-group-via-link', (_event, info) => { const { hash } = info; const { showGroupViaLink } = window.Events; if (showGroupViaLink) { - showGroupViaLink(hash); + void showGroupViaLink(hash); } }); @@ -332,7 +332,7 @@ ipc.on('show-conversation-via-signal.me', (_event, info) => { const { showConversationViaSignalDotMe } = window.Events; if (showConversationViaSignalDotMe) { - showConversationViaSignalDotMe(hash); + void showConversationViaSignalDotMe(hash); } }); @@ -347,7 +347,7 @@ ipc.on('install-sticker-pack', (_event, info) => { const { packId, packKey } = info; const { installStickerPack } = window.Events; if (installStickerPack) { - installStickerPack(packId, packKey); + void installStickerPack(packId, packKey); } }); diff --git a/ts/windows/permissions/preload.ts b/ts/windows/permissions/preload.ts index f3d264c6dce1..a1d51de93231 100644 --- a/ts/windows/permissions/preload.ts +++ b/ts/windows/permissions/preload.ts @@ -39,7 +39,7 @@ contextBridge.exposeInMainWorld('SignalContext', { } function onClose() { - SignalContext.executeMenuRole('close'); + void SignalContext.executeMenuRole('close'); } ReactDOM.render( @@ -48,9 +48,9 @@ contextBridge.exposeInMainWorld('SignalContext', { message, onAccept: () => { if (!forCamera) { - mediaPermissions.setValue(true); + void mediaPermissions.setValue(true); } else { - mediaCameraPermissions.setValue(true); + void mediaCameraPermissions.setValue(true); } onClose(); }, diff --git a/ts/windows/settings/preload.ts b/ts/windows/settings/preload.ts index 7a7b76e05728..eb63252132d3 100644 --- a/ts/windows/settings/preload.ts +++ b/ts/windows/settings/preload.ts @@ -311,7 +311,7 @@ const renderPreferences = async () => { onHasStoriesDisabledChanged: reRender(async (value: boolean) => { await settingHasStoriesDisabled.setValue(value); if (!value) { - ipcDeleteAllMyStories(); + void ipcDeleteAllMyStories(); } return value; }), @@ -379,7 +379,7 @@ const renderPreferences = async () => { function reRender(f: (value: Value) => Promise) { return async (value: Value) => { await f(value); - renderPreferences(); + void renderPreferences(); }; } diff --git a/yarn.lock b/yarn.lock index 2b7f733633e9..024f509df3f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1451,15 +1451,15 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.8.tgz#d64575fc46bf4eb689352aa9f8a139271b6e1647" integrity sha512-pE5RQsOTSERCtfZdfCT25wzo7dfhOSlhAXcsZmuvRYhendOv7djcdvtINdnDp2DAjP17WXlBB4nBO6sHLczmsg== -"@eslint/eslintrc@^1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" - integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== +"@eslint/eslintrc@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.0.tgz#8ec64e0df3e7a1971ee1ff5158da87389f167a63" + integrity sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A== dependencies: ajv "^6.12.4" debug "^4.3.2" espree "^9.4.0" - globals "^13.15.0" + globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" @@ -1580,10 +1580,10 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@humanwhocodes/config-array@^0.11.6": - version "0.11.7" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f" - integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw== +"@humanwhocodes/config-array@^0.11.8": + version "0.11.8" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" + integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -3923,7 +3923,22 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@5.43.0", "@typescript-eslint/eslint-plugin@^5.6.0": +"@typescript-eslint/eslint-plugin@5.47.0": + version "5.47.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz#dadb79df3b0499699b155839fd6792f16897d910" + integrity sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ== + dependencies: + "@typescript-eslint/scope-manager" "5.47.0" + "@typescript-eslint/type-utils" "5.47.0" + "@typescript-eslint/utils" "5.47.0" + debug "^4.3.4" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + regexpp "^3.2.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/eslint-plugin@^5.6.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.43.0.tgz#4a5248eb31b454715ddfbf8cfbf497529a0a78bc" integrity sha512-wNPzG+eDR6+hhW4yobEmpR36jrqqQv1vxBq5LJO3fBAktjkvekfr4BRl+3Fn1CM/A+s8/EiGUbOMDoYqWdbtXA== @@ -3938,7 +3953,17 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@5.43.0", "@typescript-eslint/parser@^5.6.0": +"@typescript-eslint/parser@5.47.0": + version "5.47.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.47.0.tgz#62e83de93499bf4b500528f74bf2e0554e3a6c8d" + integrity sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw== + dependencies: + "@typescript-eslint/scope-manager" "5.47.0" + "@typescript-eslint/types" "5.47.0" + "@typescript-eslint/typescript-estree" "5.47.0" + debug "^4.3.4" + +"@typescript-eslint/parser@^5.6.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.43.0.tgz#9c86581234b88f2ba406f0b99a274a91c11630fd" integrity sha512-2iHUK2Lh7PwNUlhFxxLI2haSDNyXvebBO9izhjhMoDC+S3XI9qt2DGFUsiJ89m2k7gGYch2aEpYqV5F/+nwZug== @@ -3956,6 +3981,14 @@ "@typescript-eslint/types" "5.43.0" "@typescript-eslint/visitor-keys" "5.43.0" +"@typescript-eslint/scope-manager@5.47.0": + version "5.47.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz#f58144a6b0ff58b996f92172c488813aee9b09df" + integrity sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw== + dependencies: + "@typescript-eslint/types" "5.47.0" + "@typescript-eslint/visitor-keys" "5.47.0" + "@typescript-eslint/type-utils@5.43.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.43.0.tgz#91110fb827df5161209ecca06f70d19a96030be6" @@ -3966,11 +3999,26 @@ debug "^4.3.4" tsutils "^3.21.0" +"@typescript-eslint/type-utils@5.47.0": + version "5.47.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.47.0.tgz#2b440979c574e317d3473225ae781f292c99e55d" + integrity sha512-1J+DFFrYoDUXQE1b7QjrNGARZE6uVhBqIvdaXTe5IN+NmEyD68qXR1qX1g2u4voA+nCaelQyG8w30SAOihhEYg== + dependencies: + "@typescript-eslint/typescript-estree" "5.47.0" + "@typescript-eslint/utils" "5.47.0" + debug "^4.3.4" + tsutils "^3.21.0" + "@typescript-eslint/types@5.43.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.43.0.tgz#e4ddd7846fcbc074325293515fa98e844d8d2578" integrity sha512-jpsbcD0x6AUvV7tyOlyvon0aUsQpF8W+7TpJntfCUWU1qaIKu2K34pMwQKSzQH8ORgUrGYY6pVIh1Pi8TNeteg== +"@typescript-eslint/types@5.47.0": + version "5.47.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.47.0.tgz#67490def406eaa023dbbd8da42ee0d0c9b5229d3" + integrity sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg== + "@typescript-eslint/typescript-estree@5.43.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.43.0.tgz#b6883e58ba236a602c334be116bfc00b58b3b9f2" @@ -3984,6 +4032,19 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@5.47.0": + version "5.47.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz#ed971a11c5c928646d6ba7fc9dfdd6e997649aca" + integrity sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q== + dependencies: + "@typescript-eslint/types" "5.47.0" + "@typescript-eslint/visitor-keys" "5.47.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + "@typescript-eslint/utils@5.43.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.43.0.tgz#00fdeea07811dbdf68774a6f6eacfee17fcc669f" @@ -3998,6 +4059,20 @@ eslint-utils "^3.0.0" semver "^7.3.7" +"@typescript-eslint/utils@5.47.0": + version "5.47.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.47.0.tgz#b5005f7d2696769a1fdc1e00897005a25b3a0ec7" + integrity sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw== + dependencies: + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.47.0" + "@typescript-eslint/types" "5.47.0" + "@typescript-eslint/typescript-estree" "5.47.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + semver "^7.3.7" + "@typescript-eslint/visitor-keys@5.43.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.43.0.tgz#cbbdadfdfea385310a20a962afda728ea106befa" @@ -4006,6 +4081,14 @@ "@typescript-eslint/types" "5.43.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@5.47.0": + version "5.47.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz#4aca4efbdf6209c154df1f7599852d571b80bb45" + integrity sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg== + dependencies: + "@typescript-eslint/types" "5.47.0" + eslint-visitor-keys "^3.3.0" + "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -8260,13 +8343,13 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@8.27.0: - version "8.27.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.27.0.tgz#d547e2f7239994ad1faa4bb5d84e5d809db7cf64" - integrity sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ== +eslint@8.30.0: + version "8.30.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.30.0.tgz#83a506125d089eef7c5b5910eeea824273a33f50" + integrity sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ== dependencies: - "@eslint/eslintrc" "^1.3.3" - "@humanwhocodes/config-array" "^0.11.6" + "@eslint/eslintrc" "^1.4.0" + "@humanwhocodes/config-array" "^0.11.8" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" @@ -8285,7 +8368,7 @@ eslint@8.27.0: file-entry-cache "^6.0.1" find-up "^5.0.0" glob-parent "^6.0.2" - globals "^13.15.0" + globals "^13.19.0" grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" @@ -9538,10 +9621,10 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.15.0: - version "13.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== +globals@^13.19.0: + version "13.19.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8" + integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ== dependencies: type-fest "^0.20.2"