Skip to content

Commit 09a4da1

Browse files
Updating topic validation (#141)
- Applying the same approach as iOS for the validation of topics Co-authored-by: Naomi Plasterer <naomi@xmtp.com>
1 parent 3c6594f commit 09a4da1

File tree

3 files changed

+29
-31
lines changed

3 files changed

+29
-31
lines changed

library/src/androidTest/java/org/xmtp/android/library/ConversationTest.kt

+15-20
Original file line numberDiff line numberDiff line change
@@ -824,18 +824,15 @@ class ConversationTest {
824824
val directMessageV1 = Topic.directMessageV1(validId, "sd").description
825825
val directMessageV2 = Topic.directMessageV2(validId).description
826826
val preferenceList = Topic.preferenceList(validId).description
827-
val conversations = bobClient.conversations
828827

829828
// check if validation of topics accepts all types
830-
assertTrue(
831-
conversations.isValidTopic(privateStore) &&
832-
conversations.isValidTopic(contact) &&
833-
conversations.isValidTopic(userIntro) &&
834-
conversations.isValidTopic(userInvite) &&
835-
conversations.isValidTopic(directMessageV1) &&
836-
conversations.isValidTopic(directMessageV2) &&
837-
conversations.isValidTopic(preferenceList),
838-
)
829+
assertTrue(Topic.isValidTopic(privateStore))
830+
assertTrue(Topic.isValidTopic(contact))
831+
assertTrue(Topic.isValidTopic(userIntro))
832+
assertTrue(Topic.isValidTopic(userInvite))
833+
assertTrue(Topic.isValidTopic(directMessageV1))
834+
assertTrue(Topic.isValidTopic(directMessageV2))
835+
assertTrue(Topic.isValidTopic(preferenceList))
839836
}
840837

841838
@Test
@@ -852,15 +849,13 @@ class ConversationTest {
852849
val preferenceList = Topic.preferenceList(invalidId).description
853850
val conversations = bobClient.conversations
854851

855-
// check if validation of topics accepts all types
856-
assertFalse(
857-
conversations.isValidTopic(privateStore) &&
858-
conversations.isValidTopic(contact) &&
859-
conversations.isValidTopic(userIntro) &&
860-
conversations.isValidTopic(userInvite) &&
861-
conversations.isValidTopic(directMessageV1) &&
862-
conversations.isValidTopic(directMessageV2) &&
863-
conversations.isValidTopic(preferenceList),
864-
)
852+
// check if validation of topics no accept all types with invalid topic
853+
assertFalse(Topic.isValidTopic(privateStore))
854+
assertFalse(Topic.isValidTopic(contact))
855+
assertFalse(Topic.isValidTopic(userIntro))
856+
assertFalse(Topic.isValidTopic(userInvite))
857+
assertFalse(Topic.isValidTopic(directMessageV1))
858+
assertFalse(Topic.isValidTopic(directMessageV2))
859+
assertFalse(Topic.isValidTopic(preferenceList))
865860
}
866861
}

library/src/main/java/org/xmtp/android/library/Conversations.kt

+1-11
Original file line numberDiff line numberDiff line change
@@ -177,23 +177,13 @@ data class Conversations(
177177
}
178178

179179
conversationsByTopic += newConversations.filter {
180-
it.peerAddress != client.address && isValidTopic(it.topic)
180+
it.peerAddress != client.address && Topic.isValidTopic(it.topic)
181181
}.map { Pair(it.topic, it) }
182182

183183
// TODO(perf): use DB to persist + sort
184184
return conversationsByTopic.values.sortedByDescending { it.createdAt }
185185
}
186186

187-
fun isValidTopic(topic: String): Boolean {
188-
val regex = Regex("^[\\x00-\\x7F]+$")
189-
val index = topic.indexOf("0/")
190-
if (index != -1) {
191-
val unwrappedTopic = topic.substring(index + 2, topic.lastIndexOf("/proto"))
192-
return unwrappedTopic.matches(regex)
193-
}
194-
return false
195-
}
196-
197187
fun importTopicData(data: TopicData): Conversation {
198188
val conversation: Conversation
199189
if (!data.hasInvitation()) {

library/src/main/java/org/xmtp/android/library/messages/Topic.kt

+13
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,23 @@ sealed class Topic {
2121
addresses.sort()
2222
wrap("dm-${addresses.joinToString(separator = "-")}")
2323
}
24+
2425
is directMessageV2 -> wrap("m-$addresses")
2526
is preferenceList -> wrap("pppp-$identifier")
2627
}
2728
}
2829

2930
private fun wrap(value: String): String = "/xmtp/0/$value/proto"
31+
32+
companion object {
33+
fun isValidTopic(topic: String): Boolean {
34+
val regex = Regex("^[\\x00-\\x7F]+$") // Use this regex to filter non ASCII chars
35+
val index = topic.indexOf("0/")
36+
if (index != -1) {
37+
val unwrappedTopic = topic.substring(index + 2, topic.lastIndexOf("/proto"))
38+
return unwrappedTopic.matches(regex)
39+
}
40+
return false
41+
}
42+
}
3043
}

0 commit comments

Comments
 (0)