Cleaning up
This commit is contained in:
@@ -158,8 +158,10 @@ abstract class MarmotOutboundDao(
|
||||
)
|
||||
)
|
||||
|
||||
// Trim retained epochs out of the retention window...
|
||||
val defenestratableMarmotRetainedEpochSecrets = database.marmotRetainedEpochSecretDao()
|
||||
.defenestratableMarmotRetainedEpochSecret(
|
||||
.getDefenestratableMarmotRetainedEpochSecretForChatRoomId(
|
||||
chatRoomId = nostrGroupId,
|
||||
epochCutOffPoint = retainedBefore.epoch - EPOCH_RETENTION_WINDOW.toLong()
|
||||
)
|
||||
logger.d("Defenestratable Retained Epochs: ${defenestratableMarmotRetainedEpochSecrets.map { it.epoch }}")
|
||||
@@ -383,7 +385,7 @@ abstract class MarmotOutboundDao(
|
||||
encryptedContent = groupEvent.encryptedContent(),
|
||||
chatRoomId = localChatRoom.chatRoom.id,
|
||||
nostrEventId = groupEvent.id,
|
||||
userPublicKey = nostrSignerSync.pubKey,
|
||||
userPublicKey = groupEvent.pubKey,
|
||||
publicKey = groupEvent.pubKey
|
||||
)
|
||||
)
|
||||
|
||||
@@ -6,11 +6,16 @@ import androidx.room3.Insert
|
||||
import androidx.room3.OnConflictStrategy.Companion.IGNORE
|
||||
import androidx.room3.Query
|
||||
import at.torch.compose.database.model.MarmotRetainedEpochSecret
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
|
||||
@Dao
|
||||
interface MarmotRetainedEpochSecretDao {
|
||||
@Query("SELECT * FROM MarmotRetainedEpochSecret WHERE epoch < :epochCutOffPoint")
|
||||
suspend fun defenestratableMarmotRetainedEpochSecret(epochCutOffPoint: Long): List<MarmotRetainedEpochSecret>
|
||||
@Query("SELECT * FROM MarmotRetainedEpochSecret WHERE chatRoomId = :chatRoomId")
|
||||
suspend fun getMarmotRetainedEpochSecretForChatRoomId(chatRoomId: HexKey): List<MarmotRetainedEpochSecret>
|
||||
|
||||
|
||||
@Query("SELECT * FROM MarmotRetainedEpochSecret WHERE chatRoomId = :chatRoomId AND epoch < :epochCutOffPoint")
|
||||
suspend fun getDefenestratableMarmotRetainedEpochSecretForChatRoomId(chatRoomId: HexKey, epochCutOffPoint: Long): List<MarmotRetainedEpochSecret>
|
||||
|
||||
@Insert(
|
||||
onConflict = IGNORE
|
||||
|
||||
@@ -9,6 +9,7 @@ import at.torch.compose.database.model.traits.NostrEventEntity
|
||||
import at.torch.compose.database.model.traits.SoftDeletableEntity
|
||||
import at.torch.compose.database.model.traits.TimestampedEntity
|
||||
import at.torch.compose.exceptions.MarmotMissingRetainedExporterSecretsException
|
||||
import at.torch.compose.extensions.exporterSecret
|
||||
import com.vitorpamplona.quartz.marmot.mip03GroupMessages.GroupEvent
|
||||
import com.vitorpamplona.quartz.marmot.mip03GroupMessages.GroupEventEncryption
|
||||
import com.vitorpamplona.quartz.marmot.mls.group.MlsGroup
|
||||
@@ -97,11 +98,7 @@ data class MarmotGroupEvent(
|
||||
): ByteArray? {
|
||||
// Try current epoch key first
|
||||
try {
|
||||
val exporterKey = group.exporterSecret(
|
||||
"marmot",
|
||||
"group-event".encodeToByteArray(),
|
||||
32,
|
||||
)
|
||||
val exporterKey = group.exporterSecret()
|
||||
return GroupEventEncryption.decrypt(encryptedContent, exporterKey)
|
||||
} catch (e: Exception) {
|
||||
// Current epoch key failed — try retained epoch keys
|
||||
|
||||
@@ -8,6 +8,7 @@ import at.torch.compose.database.model.traits.LocalStoreEntity
|
||||
import at.torch.compose.database.model.traits.SoftDeletableEntity
|
||||
import at.torch.compose.database.model.traits.TimestampedEntity
|
||||
import at.torch.compose.database.model.traits.UserViewableEntity
|
||||
import at.torch.compose.extensions.exporterSecret
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.vitorpamplona.quartz.marmot.mip01Groups.MarmotGroupData
|
||||
import com.vitorpamplona.quartz.marmot.mip03GroupMessages.GroupEvent
|
||||
@@ -158,51 +159,4 @@ data class MarmotInnerEvent( // TODO: Rename this to GiftWrapPayload...
|
||||
result = 31 * result + logger.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
suspend fun toSignedNostrEvent(group: MlsGroup): GroupEvent {
|
||||
// TODO: Assert group.id == chatRoomId
|
||||
|
||||
val innerEventTemplate = eventTemplate<Event>(
|
||||
kind = kind,
|
||||
description = content
|
||||
)
|
||||
|
||||
val rumorEvent = RumorAssembler.assembleRumor(
|
||||
publicKey,
|
||||
innerEventTemplate
|
||||
)
|
||||
|
||||
val mlsCiphertext = group.encrypt(rumorEvent.toJson().encodeToByteArray())
|
||||
|
||||
val exporterKey = group.exporterSecret(
|
||||
"marmot",
|
||||
"group-event".encodeToByteArray(),
|
||||
32
|
||||
)
|
||||
val encryptedContent = GroupEventEncryption.encrypt(mlsCiphertext, exporterKey)
|
||||
|
||||
val createdAt = TimeUtils.now()
|
||||
val expirationTime = disappearingExpiration(group, createdAt)
|
||||
val template =
|
||||
GroupEvent.build(
|
||||
encryptedContentBase64 = encryptedContent,
|
||||
nostrGroupId = chatRoomId,
|
||||
createdAt = createdAt,
|
||||
) {
|
||||
if (expirationTime != null) expiration(expirationTime)
|
||||
}
|
||||
|
||||
// Step 4: Sign with a fresh ephemeral keypair
|
||||
val ephemeralSigner = NostrSignerInternal(KeyPair())
|
||||
val signedEvent: GroupEvent = ephemeralSigner.sign(template)
|
||||
|
||||
return GroupEvent(
|
||||
id = signedEvent.id,
|
||||
content = signedEvent.content,
|
||||
createdAt = signedEvent.createdAt,
|
||||
tags = signedEvent.tags,
|
||||
sig = signedEvent.sig,
|
||||
pubKey = signedEvent.pubKey
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,7 @@ import com.vitorpamplona.quartz.marmot.mls.tree.Lifetime
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.EventHasher
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.rumors.RumorAssembler
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
Reference in New Issue
Block a user