// Copyright 2016-2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only /* global _, MessageController, Whisper */ // eslint-disable-next-line func-names (function () { window.Whisper = window.Whisper || {}; async function destroyExpiredMessages() { try { window.SignalContext.log.info( 'destroyExpiredMessages: Loading messages...' ); const messages = await window.Signal.Data.getExpiredMessages({ MessageCollection: Whisper.MessageCollection, }); window.SignalContext.log.info( `destroyExpiredMessages: found ${messages.length} messages to expire` ); const messageIds = []; const inMemoryMessages = []; const messageCleanup = []; messages.forEach(dbMessage => { const message = MessageController.register(dbMessage.id, dbMessage); messageIds.push(message.id); inMemoryMessages.push(message); messageCleanup.push(message.cleanup()); }); // We delete after the trigger to allow the conversation time to process // the expiration before the message is removed from the database. await window.Signal.Data.removeMessages(messageIds); await Promise.all(messageCleanup); inMemoryMessages.forEach(message => { window.SignalContext.log.info('Message expired', { sentAt: message.get('sent_at'), }); const conversation = message.getConversation(); if (conversation) { // An expired message only counts as decrementing the message count, not // the sent message count conversation.decrementMessageCount(); } }); } catch (error) { window.SignalContext.log.error( 'destroyExpiredMessages: Error deleting expired messages', error && error.stack ? error.stack : error ); } window.SignalContext.log.info('destroyExpiredMessages: complete'); checkExpiringMessages(); } let timeout; async function checkExpiringMessages() { window.SignalContext.log.info( 'checkExpiringMessages: checking for expiring messages' ); const soonestExpiry = await window.Signal.Data.getSoonestMessageExpiry(); if (!soonestExpiry) { window.SignalContext.log.info( 'checkExpiringMessages: found no messages to expire' ); return; } let wait = soonestExpiry - Date.now(); // In the past if (wait < 0) { wait = 0; } // Too far in the future, since it's limited to a 32-bit value if (wait > 2147483647) { wait = 2147483647; } window.SignalContext.log.info( `checkExpiringMessages: next message expires ${new Date( soonestExpiry ).toISOString()}; waiting ${wait} ms before clearing` ); clearTimeout(timeout); timeout = setTimeout(destroyExpiredMessages, wait); } const debouncedCheckExpiringMessages = _.debounce( checkExpiringMessages, 1000 ); Whisper.ExpiringMessagesListener = { init(events) { checkExpiringMessages(); events.on('timetravel', debouncedCheckExpiringMessages); }, update: debouncedCheckExpiringMessages, }; })();