From 536dd7b9518bd3d87324fc394fd5f89a9dda8687 Mon Sep 17 00:00:00 2001 From: lilia Date: Thu, 16 Feb 2017 11:59:32 -0800 Subject: [PATCH] Add signed key rotation scheduler Rotate signed prekey every 48hrs, waiting for online access if necessary. After a rotation attempt is made, schedule the next run for 48hrs in the future. We use a timeout to "wake up" and handle the rotation. This timeout gets set on startup and whenever the next rotation time is changed. For paranoia's sake, always clear the current timeout before setting the next one. Since new registrations necessarily upload new signed keys, we reset the scheduled time to T+48hrs on `registration_done` events. // FREEBIE --- background.html | 1 + js/background.js | 2 + js/rotate_signed_prekey_listener.js | 58 +++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 js/rotate_signed_prekey_listener.js diff --git a/background.html b/background.html index f30d6941..0d7df041 100644 --- a/background.html +++ b/background.html @@ -541,6 +541,7 @@ + diff --git a/js/background.js b/js/background.js index bb8d3b10..b707dfbf 100644 --- a/js/background.js +++ b/js/background.js @@ -84,6 +84,8 @@ if (open) { openInbox(); } + + RotateSignedPreKeyListener.init(); }); window.getSyncRequest = function() { diff --git a/js/rotate_signed_prekey_listener.js b/js/rotate_signed_prekey_listener.js new file mode 100644 index 00000000..5204cf9d --- /dev/null +++ b/js/rotate_signed_prekey_listener.js @@ -0,0 +1,58 @@ +/* + * vim: ts=4:sw=4:expandtab + */ + +;(function () { + 'use strict'; + var ROTATION_INTERVAL = 48 * 60 * 60 * 1000; + var timeout; + + function scheduleNextRotation() { + var now = Date.now(); + var nextTime = now + ROTATION_INTERVAL; + storage.put('nextSignedKeyRotationTime', nextTime); + } + + function run() { + console.log('Rotating signed prekey...'); + getAccountManager().rotateSignedPreKey(); + scheduleNextRotation(); + setTimeoutForNextRun(); + } + + function runWhenOnline() { + if (navigator.onLine) { + run(); + } else { + var listener = function() { + window.removeEventListener('online', listener); + run(); + }; + window.addEventListener('online', listener); + } + } + + function setTimeoutForNextRun() { + var now = Date.now(); + var scheduledTime = storage.get('nextSignedKeyRotationTime', now); + console.log('Next signed key rotation scheduled for', new Date(scheduledTime)); + var waitTime = scheduledTime - now; + if (waitTime < 0) { + waitTime = 0; + } + clearTimeout(timeout); + timeout = setTimeout(runWhenOnline, waitTime); + } + + window.RotateSignedPreKeyListener = { + init: function() { + if (Whisper.Registration.isDone()) { + setTimeoutForNextRun(); + } + extension.on('registration_done', function() { + scheduleNextRotation(); + setTimeoutForNextRun(); + }); + } + }; +}());