mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2024-09-29 08:20:51 +00:00
Checking HexKeys across the board.. Too many errors in tags.
This commit is contained in:
parent
a153f577c9
commit
d31c11f70d
@ -47,4 +47,37 @@ fun decodePublicKey(key: String): ByteArray {
|
||||
//} else {
|
||||
Hex.decode(key)
|
||||
}
|
||||
}
|
||||
|
||||
data class DirtyKeyInfo(val type: String, val keyHex: String, val restOfWord: String)
|
||||
|
||||
fun parseDirtyWordForKey(mightBeAKey: String): DirtyKeyInfo? {
|
||||
var key = mightBeAKey
|
||||
if (key.startsWith("nostr:", true)) {
|
||||
key = key.substring("nostr:".length)
|
||||
}
|
||||
|
||||
key = key.removePrefix("@")
|
||||
|
||||
if (key.length < 63)
|
||||
return null
|
||||
|
||||
try {
|
||||
|
||||
val keyB32 = key.substring(0, 63)
|
||||
val restOfWord = key.substring(63)
|
||||
|
||||
if (key.startsWith("nsec1", true)) {
|
||||
return DirtyKeyInfo("npub", Persona(privKey = keyB32.bechToBytes()).pubKey.toHexKey(), restOfWord)
|
||||
} else if (key.startsWith("npub1", true)) {
|
||||
return DirtyKeyInfo("npub", keyB32.bechToBytes().toHexKey(), restOfWord)
|
||||
} else if (key.startsWith("note1", true)) {
|
||||
return DirtyKeyInfo("note", keyB32.bechToBytes().toHexKey(), restOfWord)
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
@ -74,6 +74,16 @@ object LocalCache {
|
||||
}
|
||||
}
|
||||
|
||||
fun checkGetOrCreateNote(key: HexKey): Note? {
|
||||
return try {
|
||||
val checkHex = Hex.decode(key) // Checks if this is a valid Hex
|
||||
getOrCreateNote(key)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Log.e("LocalCache", "Invalid Key to create note: $key", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getOrCreateNote(idHex: String): Note {
|
||||
return notes[idHex] ?: run {
|
||||
@ -83,6 +93,17 @@ object LocalCache {
|
||||
}
|
||||
}
|
||||
|
||||
fun checkGetOrCreateChannel(key: HexKey): Channel? {
|
||||
return try {
|
||||
val checkHex = Hex.decode(key) // Checks if this is a valid Hex
|
||||
getOrCreateChannel(key)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Log.e("LocalCache", "Invalid Key to create channel: $key", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Synchronized
|
||||
fun getOrCreateChannel(key: String): Channel {
|
||||
return channels[key] ?: run {
|
||||
@ -145,7 +166,6 @@ object LocalCache {
|
||||
if (isRepeatedMessageSpam(event)) return
|
||||
|
||||
val note = getOrCreateNote(event.id.toHex())
|
||||
|
||||
val author = getOrCreateUser(event.pubKey.toHexKey())
|
||||
|
||||
if (relay != null) {
|
||||
@ -157,7 +177,7 @@ object LocalCache {
|
||||
if (note.event != null) return
|
||||
|
||||
val mentions = event.mentions.mapNotNull { checkGetOrCreateUser(it) }
|
||||
val replyTo = replyToWithoutCitations(event).map { getOrCreateNote(it) }
|
||||
val replyTo = replyToWithoutCitations(event).mapNotNull { checkGetOrCreateNote(it) }
|
||||
|
||||
note.loadEvent(event, author, mentions, replyTo)
|
||||
|
||||
@ -266,7 +286,7 @@ object LocalCache {
|
||||
|
||||
//Log.d("PM", "${author.toBestDisplayName()} to ${recipient?.toBestDisplayName()}")
|
||||
|
||||
val repliesTo = event.tags.filter { it.firstOrNull() == "e" }.mapNotNull { it.getOrNull(1) }.map { getOrCreateNote(it) }
|
||||
val repliesTo = event.tags.filter { it.firstOrNull() == "e" }.mapNotNull { it.getOrNull(1) }.mapNotNull { checkGetOrCreateNote(it) }
|
||||
val mentions = event.tags.filter { it.firstOrNull() == "p" }.mapNotNull { it.getOrNull(1) }.mapNotNull { checkGetOrCreateUser(it) }
|
||||
|
||||
note.loadEvent(event, author, mentions, repliesTo)
|
||||
@ -293,7 +313,7 @@ object LocalCache {
|
||||
|
||||
val author = getOrCreateUser(event.pubKey.toHexKey())
|
||||
val mentions = event.originalAuthor.mapNotNull { checkGetOrCreateUser(it) }
|
||||
val repliesTo = event.boostedPost.map { getOrCreateNote(it) }
|
||||
val repliesTo = event.boostedPost.mapNotNull { checkGetOrCreateNote(it) }
|
||||
|
||||
note.loadEvent(event, author, mentions, repliesTo)
|
||||
|
||||
@ -324,7 +344,7 @@ object LocalCache {
|
||||
|
||||
val author = getOrCreateUser(event.pubKey.toHexKey())
|
||||
val mentions = event.originalAuthor.mapNotNull { checkGetOrCreateUser(it) }
|
||||
val repliesTo = event.originalPost.map { getOrCreateNote(it) }
|
||||
val repliesTo = event.originalPost.mapNotNull { checkGetOrCreateNote(it) }
|
||||
|
||||
note.loadEvent(event, author, mentions, repliesTo)
|
||||
|
||||
@ -369,7 +389,7 @@ object LocalCache {
|
||||
|
||||
val author = getOrCreateUser(event.pubKey.toHexKey())
|
||||
val mentions = event.reportedAuthor.mapNotNull { checkGetOrCreateUser(it) }
|
||||
val repliesTo = event.reportedPost.map { getOrCreateNote(it) }
|
||||
val repliesTo = event.reportedPost.mapNotNull { checkGetOrCreateNote(it) }
|
||||
|
||||
note.loadEvent(event, author, mentions, repliesTo)
|
||||
|
||||
@ -410,7 +430,7 @@ object LocalCache {
|
||||
if (event.channel.isNullOrBlank()) return
|
||||
|
||||
// new event
|
||||
val oldChannel = getOrCreateChannel(event.channel)
|
||||
val oldChannel = checkGetOrCreateChannel(event.channel) ?: return
|
||||
val author = getOrCreateUser(event.pubKey.toHexKey())
|
||||
if (event.createdAt > oldChannel.updatedMetadataAt) {
|
||||
if (oldChannel.creator == null || oldChannel.creator == author) {
|
||||
@ -432,7 +452,7 @@ object LocalCache {
|
||||
if (event.channel.isNullOrBlank()) return
|
||||
if (isRepeatedMessageSpam(event)) return
|
||||
|
||||
val channel = getOrCreateChannel(event.channel)
|
||||
val channel = checkGetOrCreateChannel(event.channel) ?: return
|
||||
|
||||
val note = getOrCreateNote(event.id.toHex())
|
||||
channel.addNote(note)
|
||||
@ -449,7 +469,7 @@ object LocalCache {
|
||||
|
||||
val mentions = event.mentions.mapNotNull { checkGetOrCreateUser(it) }
|
||||
val replyTo = event.replyTos
|
||||
.map { getOrCreateNote(it) }
|
||||
.mapNotNull { checkGetOrCreateNote(it) }
|
||||
.filter { it.event !is ChannelCreateEvent }
|
||||
|
||||
note.channel = channel
|
||||
@ -489,7 +509,7 @@ object LocalCache {
|
||||
|
||||
val author = getOrCreateUser(event.pubKey.toHexKey())
|
||||
val mentions = event.zappedAuthor.mapNotNull { checkGetOrCreateUser(it) }
|
||||
val repliesTo = event.zappedPost.map { getOrCreateNote(it) }
|
||||
val repliesTo = event.zappedPost.mapNotNull { checkGetOrCreateNote(it) }
|
||||
|
||||
note.loadEvent(event, author, mentions, repliesTo)
|
||||
|
||||
@ -525,7 +545,7 @@ object LocalCache {
|
||||
|
||||
val author = getOrCreateUser(event.pubKey.toHexKey())
|
||||
val mentions = event.zappedAuthor.mapNotNull { checkGetOrCreateUser(it) }
|
||||
val repliesTo = event.zappedPost.map { getOrCreateNote(it) }
|
||||
val repliesTo = event.zappedPost.mapNotNull { checkGetOrCreateNote(it) }
|
||||
|
||||
note.loadEvent(event, author, mentions, repliesTo)
|
||||
|
||||
|
@ -9,7 +9,7 @@ class ThreadAssembler {
|
||||
if (note.replyTo == null || note.replyTo?.isEmpty() == true) return note
|
||||
|
||||
val markedAsRoot = note.event?.tags?.firstOrNull { it[0] == "e" && it.size > 3 && it[3] == "root" }?.getOrNull(1)
|
||||
if (markedAsRoot != null) return LocalCache.getOrCreateNote(markedAsRoot)
|
||||
if (markedAsRoot != null) return LocalCache.checkGetOrCreateNote(markedAsRoot)
|
||||
|
||||
val hasNoReplyTo = note.replyTo?.firstOrNull { it.replyTo?.isEmpty() == true }
|
||||
if (hasNoReplyTo != null) return hasNoReplyTo
|
||||
|
@ -76,24 +76,12 @@ class NewPostViewModel: ViewModel() {
|
||||
// adds all references to mentions and reply tos
|
||||
message.text.split('\n').forEach { paragraph: String ->
|
||||
paragraph.split(' ').forEach { word: String ->
|
||||
try {
|
||||
if (word.startsWith("@npub") && word.length >= 64) {
|
||||
val keyB32 = word.substring(0, 64)
|
||||
val results = parseDirtyWordForKey(word)
|
||||
|
||||
val key = decodePublicKey(keyB32.removePrefix("@"))
|
||||
val user = LocalCache.getOrCreateUser(key.toHexKey())
|
||||
|
||||
addUserToMentions(user)
|
||||
} else if (word.startsWith("@note") && word.length >= 64) {
|
||||
val keyB32 = word.substring(0, 64)
|
||||
|
||||
val key = decodePublicKey(keyB32.removePrefix("@"))
|
||||
val note = LocalCache.getOrCreateNote(key.toHexKey())
|
||||
|
||||
addNoteToReplyTos(note)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (results?.type == "npub") {
|
||||
addUserToMentions(LocalCache.getOrCreateUser(results.keyHex))
|
||||
} else if (results?.type == "note") {
|
||||
addNoteToReplyTos(LocalCache.getOrCreateNote(results.keyHex))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,29 +89,16 @@ class NewPostViewModel: ViewModel() {
|
||||
// Tags the text in the correct order.
|
||||
val newMessage = message.text.split('\n').map { paragraph: String ->
|
||||
paragraph.split(' ').map { word: String ->
|
||||
try {
|
||||
if (word.startsWith("@npub") && word.length >= 64) {
|
||||
val keyB32 = word.substring(0, 64)
|
||||
val restOfWord = word.substring(64)
|
||||
val results = parseDirtyWordForKey(word)
|
||||
if (results?.type == "npub") {
|
||||
val user = LocalCache.getOrCreateUser(results.keyHex)
|
||||
|
||||
val key = decodePublicKey(keyB32.removePrefix("@"))
|
||||
val user = LocalCache.getOrCreateUser(key.toHexKey())
|
||||
"#[${tagIndex(user)}]${results.restOfWord}"
|
||||
} else if (results?.type == "note") {
|
||||
val note = LocalCache.getOrCreateNote(results.keyHex)
|
||||
|
||||
"#[${tagIndex(user)}]$restOfWord"
|
||||
} else if (word.startsWith("@note") && word.length >= 64) {
|
||||
val keyB32 = word.substring(0, 64)
|
||||
val restOfWord = word.substring(64)
|
||||
|
||||
val key = decodePublicKey(keyB32.removePrefix("@"))
|
||||
val note = LocalCache.getOrCreateNote(key.toHexKey())
|
||||
|
||||
"#[${tagIndex(note)}]$restOfWord"
|
||||
} else {
|
||||
word
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
// if it can't parse the key, don't try to change.
|
||||
"#[${tagIndex(note)}]${results.restOfWord}"
|
||||
} else {
|
||||
word
|
||||
}
|
||||
}.joinToString(" ")
|
||||
|
@ -1,16 +0,0 @@
|
||||
package com.vitorpamplona.amethyst
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
93
app/src/test/java/com/vitorpamplona/amethyst/KeyParseTest.kt
Normal file
93
app/src/test/java/com/vitorpamplona/amethyst/KeyParseTest.kt
Normal file
@ -0,0 +1,93 @@
|
||||
package com.vitorpamplona.amethyst
|
||||
|
||||
import com.vitorpamplona.amethyst.model.parseDirtyWordForKey
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class KeyParseTest {
|
||||
@Test
|
||||
fun keyParseTestNote() {
|
||||
val result = parseDirtyWordForKey("note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn")
|
||||
assertEquals("note", result?.type)
|
||||
assertEquals("1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", result?.keyHex)
|
||||
assertEquals("", result?.restOfWord)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyParseTestPub() {
|
||||
val result = parseDirtyWordForKey("npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z")
|
||||
assertEquals("npub", result?.type)
|
||||
assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", result?.keyHex)
|
||||
assertEquals("", result?.restOfWord)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyParseTestNoteWithExtraChars() {
|
||||
val result = parseDirtyWordForKey("note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn,")
|
||||
assertEquals("note", result?.type)
|
||||
assertEquals("1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", result?.keyHex)
|
||||
assertEquals(",", result?.restOfWord)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyParseTestPubWithExtraChars() {
|
||||
val result = parseDirtyWordForKey("npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z,")
|
||||
assertEquals("npub", result?.type)
|
||||
assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", result?.keyHex)
|
||||
assertEquals(",", result?.restOfWord)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyParseTestNoteWithExtraCharsAndAt() {
|
||||
val result = parseDirtyWordForKey("@note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn,")
|
||||
assertEquals("note", result?.type)
|
||||
assertEquals("1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", result?.keyHex)
|
||||
assertEquals(",", result?.restOfWord)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyParseTestPubWithExtraCharsAndAt() {
|
||||
val result = parseDirtyWordForKey("@npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z,")
|
||||
assertEquals("npub", result?.type)
|
||||
assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", result?.keyHex)
|
||||
assertEquals(",", result?.restOfWord)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyParseTestNoteWithExtraCharsAndNostrPrefix() {
|
||||
val result = parseDirtyWordForKey("nostr:note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn,")
|
||||
assertEquals("note", result?.type)
|
||||
assertEquals("1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", result?.keyHex)
|
||||
assertEquals(",", result?.restOfWord)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyParseTestPubWithExtraCharsAndNostrPrefix() {
|
||||
val result = parseDirtyWordForKey("nostr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z,")
|
||||
assertEquals("npub", result?.type)
|
||||
assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", result?.keyHex)
|
||||
assertEquals(",", result?.restOfWord)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun keyParseTestUppercaseNoteWithExtraCharsAndNostrPrefix() {
|
||||
val result = parseDirtyWordForKey("Nostr:note1z5e2m0smx6d7e2d0zaq8d3rnd7httm6j0uf8tf90yqqjrs842czshwtkmn,")
|
||||
assertEquals("note", result?.type)
|
||||
assertEquals("1532adbe1b369beca9af174076c4736faeb5ef527f1275a4af200121c0f55605", result?.keyHex)
|
||||
assertEquals(",", result?.restOfWord)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun keyParseTestUppercasePubWithExtraCharsAndNostrPrefix() {
|
||||
val result = parseDirtyWordForKey("nOstr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z,")
|
||||
assertEquals("npub", result?.type)
|
||||
assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", result?.keyHex)
|
||||
assertEquals(",", result?.restOfWord)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user