SyncAlertTest.kt

3.2 KB · raw

1package com.peachpasswords.sync23import org.junit.Assert.assertEquals4import org.junit.Assert.assertFalse5import org.junit.Assert.assertNull6import org.junit.Assert.assertTrue7import org.junit.Test89class SyncAlertTest {10    @Test fun routine_entry_activity_is_not_a_user_facing_alert() {11        assertFalse(isDeviceTrustAlert(SyncAlert(SyncAlertType.REMOTE_PASSWORD_CHANGE, timestamp = 1L)))12        assertFalse(isDeviceTrustAlert(SyncAlert(SyncAlertType.REMOTE_DELETE, timestamp = 2L)))13        assertTrue(isDeviceTrustAlert(SyncAlert(SyncAlertType.DEVICE_KEY_ROTATED, timestamp = 3L)))14        assertTrue(isDeviceTrustAlert(SyncAlert(SyncAlertType.DEVICE_REVOKED, timestamp = 4L)))15    }1617    @Test fun device_key_rotation_detects_existing_peer_key_changes() {18        val existing = PairedDevice(19            deviceId = "browser",20            deviceName = "Browser",21            deviceType = "extension",22            longTermPublicKeyHex = "aa".repeat(32),23            signingPublicKeyHex = "bb".repeat(32),24            pairedAt = 1L,25        )26        val incoming = ManifestDeviceEntry(27            deviceId = "browser",28            deviceName = "Browser",29            deviceType = "extension",30            longTermPublicKeyHex = "aa".repeat(32),31            signingPublicKeyHex = "cc".repeat(32),32            pairedAt = 1L,33        )3435        val alert = deviceKeyRotationAlert(existing, incoming, nowMs = 99L)3637        assertEquals(SyncAlertType.DEVICE_KEY_ROTATED, alert?.type)38        assertEquals("Browser", alert?.deviceName)39        assertNull(deviceKeyRotationAlert(existing, incoming.copy(signingPublicKeyHex = "bb".repeat(32)), nowMs = 99L))40    }4142    @Test fun `S5 rotation alert names the device from local state not the manifest`() {43        // A hostile issuer relabels the rotating device, hoping the alert reads44        // as a rotation on something the user trusts more.45        val existing = PairedDevice(46            deviceId = "browser",47            deviceName = "Spare Tablet",48            deviceType = "extension",49            longTermPublicKeyHex = "aa".repeat(32),50            signingPublicKeyHex = "bb".repeat(32),51            pairedAt = 1L,52        )53        val incoming = ManifestDeviceEntry(54            deviceId = "browser",55            deviceName = "June's Primary Phone",56            deviceType = "extension",57            longTermPublicKeyHex = "aa".repeat(32),58            signingPublicKeyHex = "cc".repeat(32),59            pairedAt = 1L,60        )6162        val alert = deviceKeyRotationAlert(existing, incoming, nowMs = 99L)6364        assertEquals("Spare Tablet", alert?.deviceName)65    }6667    @Test fun sync_alert_queue_is_bounded_to_latest_two_hundred() {68        val existing = (0 until 199).map {69            SyncAlert(SyncAlertType.DEVICE_KEY_ROTATED, timestamp = it.toLong())70        }71        val incoming = listOf(72            SyncAlert(SyncAlertType.DEVICE_KEY_ROTATED, timestamp = 199L),73            SyncAlert(SyncAlertType.DEVICE_KEY_ROTATED, timestamp = 200L),74        )7576        val bounded = boundedSyncAlerts(existing, incoming)7778        assertEquals(200, bounded.size)79        assertEquals(1L, bounded.first().timestamp)80        assertEquals(200L, bounded.last().timestamp)81    }82}