mirror of https://github.com/vector-im/riot-web
Persist tracked event ID hash using localStorage
parent
011154396c
commit
f08274585e
|
@ -36,7 +36,7 @@ export default class DecryptionFailureTracker {
|
||||||
failuresToTrack = [];
|
failuresToTrack = [];
|
||||||
|
|
||||||
// Event IDs of failures that were tracked previously
|
// Event IDs of failures that were tracked previously
|
||||||
eventTrackedPreviously = {
|
trackedEventHashMap = {
|
||||||
// [eventIdHash(eventId)]: true
|
// [eventIdHash(eventId)]: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,6 +59,14 @@ export default class DecryptionFailureTracker {
|
||||||
this.trackDecryptionFailure = fn;
|
this.trackDecryptionFailure = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadTrackedEventHashMap() {
|
||||||
|
this.trackedEventHashMap = JSON.parse(localStorage.getItem('mx-decryption-failure-event-id-hashes'));
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTrackedEventHashMap() {
|
||||||
|
localStorage.setItem('mx-decryption-failure-event-id-hashes', JSON.stringify(this.trackedEventHashMap));
|
||||||
|
}
|
||||||
|
|
||||||
eventDecrypted(e) {
|
eventDecrypted(e) {
|
||||||
if (e.isDecryptionFailure()) {
|
if (e.isDecryptionFailure()) {
|
||||||
this.addDecryptionFailureForEvent(e);
|
this.addDecryptionFailureForEvent(e);
|
||||||
|
@ -122,7 +130,7 @@ export default class DecryptionFailureTracker {
|
||||||
// Only track one failure per event
|
// Only track one failure per event
|
||||||
const dedupedFailuresMap = failuresGivenGrace.reduce(
|
const dedupedFailuresMap = failuresGivenGrace.reduce(
|
||||||
(result, failure) => {
|
(result, failure) => {
|
||||||
if (!this.eventTrackedPreviously[eventIdHash(failure.failedEventId)]) {
|
if (!this.trackedEventHashMap[eventIdHash(failure.failedEventId)]) {
|
||||||
return {...result, [failure.failedEventId]: failure};
|
return {...result, [failure.failedEventId]: failure};
|
||||||
} else {
|
} else {
|
||||||
return result;
|
return result;
|
||||||
|
@ -133,11 +141,13 @@ export default class DecryptionFailureTracker {
|
||||||
|
|
||||||
const trackedEventIds = Object.keys(dedupedFailuresMap);
|
const trackedEventIds = Object.keys(dedupedFailuresMap);
|
||||||
|
|
||||||
this.eventTrackedPreviously = trackedEventIds.reduce(
|
this.trackedEventHashMap = trackedEventIds.reduce(
|
||||||
(result, eventId) => ({...result, [eventIdHash(eventId)]: true}),
|
(result, eventId) => ({...result, [eventIdHash(eventId)]: true}),
|
||||||
this.eventTrackedPreviously,
|
this.trackedEventHashMap,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.saveTrackedEventHashMap();
|
||||||
|
|
||||||
const dedupedFailures = trackedEventIds.map((k) => dedupedFailuresMap[k]);
|
const dedupedFailures = trackedEventIds.map((k) => dedupedFailuresMap[k]);
|
||||||
|
|
||||||
this.failuresToTrack = [...this.failuresToTrack, ...dedupedFailures];
|
this.failuresToTrack = [...this.failuresToTrack, ...dedupedFailures];
|
||||||
|
|
|
@ -1313,6 +1313,7 @@ export default React.createClass({
|
||||||
// TODO: Pass reason for failure as third argument to trackEvent
|
// TODO: Pass reason for failure as third argument to trackEvent
|
||||||
Analytics.trackEvent('E2E', 'Decryption failure');
|
Analytics.trackEvent('E2E', 'Decryption failure');
|
||||||
});
|
});
|
||||||
|
dft.loadEventTrackedPreviously();
|
||||||
|
|
||||||
const stopDft = dft.start();
|
const stopDft = dft.start();
|
||||||
|
|
||||||
|
|
|
@ -150,4 +150,34 @@ describe.only('DecryptionFailureTracker', function() {
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not track a failure for an event that was tracked in a previous session', (done) => {
|
||||||
|
// This test uses localStorage, clear it beforehand
|
||||||
|
localStorage.clear();
|
||||||
|
|
||||||
|
const decryptedEvent = createFailedDecryptionEvent();
|
||||||
|
|
||||||
|
const failures = [];
|
||||||
|
const tracker = new DecryptionFailureTracker((failure) => failures.push(failure));
|
||||||
|
|
||||||
|
// Indicate decryption
|
||||||
|
tracker.eventDecrypted(decryptedEvent);
|
||||||
|
|
||||||
|
// Pretend "now" is Infinity
|
||||||
|
// NB: This saves to localStorage specific to DFT
|
||||||
|
tracker.checkFailures(Infinity);
|
||||||
|
|
||||||
|
tracker.trackFailure();
|
||||||
|
|
||||||
|
// Simulate the browser refreshing by destroying tracker and creating a new tracker
|
||||||
|
const secondTracker = new DecryptionFailureTracker((failure) => failures.push(failure));
|
||||||
|
secondTracker.loadTrackedEventHashMap();
|
||||||
|
secondTracker.eventDecrypted(decryptedEvent);
|
||||||
|
secondTracker.checkFailures(Infinity);
|
||||||
|
secondTracker.trackFailure();
|
||||||
|
|
||||||
|
expect(failures.length).toBe(1, 'should track a single failure per event per session, got ' + failures.length);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue