1package com.peachpasswords.sync23import kotlinx.serialization.SerialName4import kotlinx.serialization.Serializable5import kotlinx.serialization.json.Json678910111213@Serializable14sealed class SyncMessage {15 @Serializable16 @SerialName("SYNC_HELLO")17 data class Hello(18 val vaultId: String,19 val deviceId: String,20 val version: Long,21 val deviceTime: Long,22 ) : SyncMessage()2324 @Serializable25 @SerialName("SYNC_MANIFEST")26 data class Manifest(27 val entries: Map<String, Long>,28 val tombstones: Map<String, Long>,29 ) : SyncMessage()3031 @Serializable32 @SerialName("SYNC_REQUEST")33 data class Request(val entryIds: List<String>) : SyncMessage()3435 @Serializable36 @SerialName("SYNC_ENTRIES")37 data class Entries(val entries: Map<String, String>) : SyncMessage()3839 @Serializable40 @SerialName("SYNC_TOMBSTONES")41 data class Tombstones(val tombstones: Map<String, Long>) : SyncMessage()4243 @Serializable44 @SerialName("SYNC_DEVICE_MANIFEST")45 data class DeviceManifest(val manifest: SignedDeviceManifest?) : SyncMessage()4647 @Serializable48 @SerialName("SYNC_DONE")49 data class Done(50 val entriesReceived: Int = 0,51 val entriesSent: Int = 0,52 ) : SyncMessage()5354 @Serializable55 @SerialName("SYNC_ERROR")56 data class Error(val error: String) : SyncMessage()57}5859@Serializable60data class ManifestDeviceEntry(61 val deviceId: String,62 val deviceName: String,63 val deviceType: String,64 val longTermPublicKeyHex: String,65 val signingPublicKeyHex: String,66 val wsPort: Int? = null,67 val pairedAt: Long,68)6970@Serializable71data class DeviceManifestBody(72 val manifestVersion: Int,73 val issuerDeviceId: String,74 val issuedAt: Long,75 val devices: List<ManifestDeviceEntry>,76 val revoked: List<DeviceRevocation> = emptyList(),77)7879808182838485868788899091929394@Serializable95data class DeviceRevocation(96 val deviceId: String,97 val longTermPublicKeyHex: String,98 val revokedAt: Long,99 val revokedByDeviceId: String,100)101102@Serializable103data class SignedDeviceManifest(104 val body: DeviceManifestBody,105 106 val signatureHex: String,107)108109110111112113114val SyncJson: Json = Json {115 classDiscriminator = "type"116 encodeDefaults = true117 ignoreUnknownKeys = true118}119120fun SyncMessage.encodeToBytes(): ByteArray =121 SyncJson.encodeToString(SyncMessage.serializer(), this).toByteArray(Charsets.UTF_8)122123fun decodeSyncMessage(bytes: ByteArray): SyncMessage =124 SyncJson.decodeFromString(SyncMessage.serializer(), String(bytes, Charsets.UTF_8))