support for nip95

This commit is contained in:
greenart7c3
2023-08-30 16:40:11 -03:00
parent 9ee1250f3a
commit d1cb699027
7 changed files with 151 additions and 32 deletions
@@ -112,7 +112,7 @@ class Account(
val content = blockList?.content ?: "" val content = blockList?.content ?: ""
if (content.isEmpty()) return@launch if (content.isEmpty()) return@launch
AmberUtils.content = "" AmberUtils.content = ""
AmberUtils.decryptBookmark( AmberUtils.decrypt(
content, content,
keyPair.pubKey.toHexKey() keyPair.pubKey.toHexKey()
) )
@@ -823,31 +823,75 @@ class Account(
} }
fun createNip95(byteArray: ByteArray, headerInfo: FileHeader): Pair<FileStorageEvent, FileStorageHeaderEvent>? { fun createNip95(byteArray: ByteArray, headerInfo: FileHeader): Pair<FileStorageEvent, FileStorageHeaderEvent>? {
if (!isWriteable()) return null if (!isWriteable() && !loginWithAmber) return null
val data = FileStorageEvent.create( if (loginWithAmber) {
mimeType = headerInfo.mimeType ?: "", val unsignedData = FileStorageEvent.create(
data = byteArray, mimeType = headerInfo.mimeType ?: "",
privateKey = keyPair.privKey!! data = byteArray,
) pubKey = keyPair.pubKey.toHexKey()
)
val signedEvent = FileStorageHeaderEvent.create( AmberUtils.openAmber(unsignedData)
data, if (AmberUtils.content.isBlank()) return null
mimeType = headerInfo.mimeType, val data = FileStorageEvent(
hash = headerInfo.hash, unsignedData.id,
size = headerInfo.size.toString(), unsignedData.pubKey,
dimensions = headerInfo.dim, unsignedData.createdAt,
blurhash = headerInfo.blurHash, unsignedData.tags,
description = headerInfo.description, unsignedData.content,
sensitiveContent = headerInfo.sensitiveContent, AmberUtils.content
privateKey = keyPair.privKey!! )
)
return Pair(data, signedEvent) val unsignedEvent = FileStorageHeaderEvent.create(
data,
mimeType = headerInfo.mimeType,
hash = headerInfo.hash,
size = headerInfo.size.toString(),
dimensions = headerInfo.dim,
blurhash = headerInfo.blurHash,
description = headerInfo.description,
sensitiveContent = headerInfo.sensitiveContent,
pubKey = keyPair.pubKey.toHexKey()
)
AmberUtils.openAmber(unsignedEvent)
if (AmberUtils.content.isBlank()) return null
val signedEvent = FileStorageHeaderEvent(
unsignedEvent.id,
unsignedEvent.pubKey,
unsignedEvent.createdAt,
unsignedEvent.tags,
unsignedEvent.content,
AmberUtils.content
)
return Pair(data, signedEvent)
} else {
val data = FileStorageEvent.create(
mimeType = headerInfo.mimeType ?: "",
data = byteArray,
privateKey = keyPair.privKey!!
)
val signedEvent = FileStorageHeaderEvent.create(
data,
mimeType = headerInfo.mimeType,
hash = headerInfo.hash,
size = headerInfo.size.toString(),
dimensions = headerInfo.dim,
blurhash = headerInfo.blurHash,
description = headerInfo.description,
sensitiveContent = headerInfo.sensitiveContent,
privateKey = keyPair.privKey!!
)
return Pair(data, signedEvent)
}
} }
fun sendNip95(data: FileStorageEvent, signedEvent: FileStorageHeaderEvent, relayList: List<Relay>? = null): Note? { fun sendNip95(data: FileStorageEvent, signedEvent: FileStorageHeaderEvent, relayList: List<Relay>? = null): Note? {
if (!isWriteable()) return null if (!isWriteable() && !loginWithAmber) return null
Client.send(data, relayList = relayList) Client.send(data, relayList = relayList)
LocalCache.consume(data, null) LocalCache.consume(data, null)
@@ -1312,7 +1356,7 @@ class Account(
} }
val msg = Event.mapper.writeValueAsString(privTags) val msg = Event.mapper.writeValueAsString(privTags)
AmberUtils.encryptBookmark(msg, keyPair.pubKey.toHexKey()) AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey())
if (AmberUtils.content.isBlank()) { if (AmberUtils.content.isBlank()) {
return null return null
@@ -1357,7 +1401,7 @@ class Account(
} }
val msg = Event.mapper.writeValueAsString(privTags) val msg = Event.mapper.writeValueAsString(privTags)
AmberUtils.encryptBookmark(msg, keyPair.pubKey.toHexKey()) AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey())
if (AmberUtils.content.isBlank()) { if (AmberUtils.content.isBlank()) {
return null return null
@@ -1432,7 +1476,7 @@ class Account(
} }
val msg = Event.mapper.writeValueAsString(privTags) val msg = Event.mapper.writeValueAsString(privTags)
AmberUtils.encryptBookmark(msg, keyPair.pubKey.toHexKey()) AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey())
if (AmberUtils.content.isBlank()) { if (AmberUtils.content.isBlank()) {
return null return null
@@ -1597,7 +1641,7 @@ class Account(
} }
val msg = Event.mapper.writeValueAsString(privTags) val msg = Event.mapper.writeValueAsString(privTags)
AmberUtils.encryptBookmark(msg, keyPair.pubKey.toHexKey()) AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey())
if (AmberUtils.content.isBlank()) { if (AmberUtils.content.isBlank()) {
return null return null
@@ -6,6 +6,7 @@ import androidx.activity.result.ActivityResultLauncher
import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.ui.actions.SignerType import com.vitorpamplona.amethyst.ui.actions.SignerType
import com.vitorpamplona.quartz.encoders.HexKey import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.events.EventInterface
object AmberUtils { object AmberUtils {
var content: String = "" var content: String = ""
@@ -33,7 +34,20 @@ object AmberUtils {
intentResult.launch(intent) intentResult.launch(intent)
} }
fun decryptBookmark(encryptedContent: String, pubKey: HexKey) { fun openAmber(event: EventInterface) {
isActivityRunning = true
openAmber(
event.toJson(),
SignerType.SIGN_EVENT,
IntentUtils.decryptActivityResultLauncher,
""
)
while (isActivityRunning) {
Thread.sleep(250)
}
}
fun decrypt(encryptedContent: String, pubKey: HexKey) {
if (content.isBlank()) { if (content.isBlank()) {
isActivityRunning = true isActivityRunning = true
openAmber( openAmber(
@@ -48,7 +62,7 @@ object AmberUtils {
} }
} }
fun encryptBookmark(decryptedContent: String, pubKey: HexKey) { fun encrypt(decryptedContent: String, pubKey: HexKey) {
if (content.isBlank()) { if (content.isBlank()) {
isActivityRunning = true isActivityRunning = true
openAmber( openAmber(
@@ -285,7 +285,14 @@ open class NewPostViewModel() : ViewModel() {
} }
} }
fun upload(galleryUri: Uri, description: String, sensitiveContent: Boolean, server: ServersAvailable, context: Context, relayList: List<Relay>? = null) { fun upload(
galleryUri: Uri,
description: String,
sensitiveContent: Boolean,
server: ServersAvailable,
context: Context,
relayList: List<Relay>? = null
) {
isUploadingImage = true isUploadingImage = true
contentToAddUrl = null contentToAddUrl = null
@@ -18,7 +18,7 @@ object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
if (account.loginWithAmber) { if (account.loginWithAmber) {
if (AmberUtils.content.isBlank()) { if (AmberUtils.content.isBlank()) {
AmberUtils.decryptBookmark(bookmarks?.content ?: "", account.keyPair.pubKey.toHexKey()) AmberUtils.decrypt(bookmarks?.content ?: "", account.keyPair.pubKey.toHexKey())
bookmarks?.decryptedContent = AmberUtils.content bookmarks?.decryptedContent = AmberUtils.content
} }
@@ -481,7 +481,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithAmber()) {
val bookmarks = accountViewModel.userProfile().latestBookmarkList val bookmarks = accountViewModel.userProfile().latestBookmarkList
AmberUtils.decryptBookmark( AmberUtils.decrypt(
bookmarks?.content ?: "", bookmarks?.content ?: "",
accountViewModel.account.keyPair.pubKey.toHexKey() accountViewModel.account.keyPair.pubKey.toHexKey()
) )
@@ -503,7 +503,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithAmber()) {
val bookmarks = accountViewModel.userProfile().latestBookmarkList val bookmarks = accountViewModel.userProfile().latestBookmarkList
AmberUtils.decryptBookmark( AmberUtils.decrypt(
bookmarks?.content ?: "", bookmarks?.content ?: "",
accountViewModel.account.keyPair.pubKey.toHexKey() accountViewModel.account.keyPair.pubKey.toHexKey()
) )
@@ -526,7 +526,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithAmber()) {
val bookmarks = accountViewModel.userProfile().latestBookmarkList val bookmarks = accountViewModel.userProfile().latestBookmarkList
AmberUtils.decryptBookmark( AmberUtils.decrypt(
bookmarks?.content ?: "", bookmarks?.content ?: "",
accountViewModel.account.keyPair.pubKey.toHexKey() accountViewModel.account.keyPair.pubKey.toHexKey()
) )
@@ -551,7 +551,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
if (accountViewModel.loggedInWithAmber()) { if (accountViewModel.loggedInWithAmber()) {
val bookmarks = accountViewModel.userProfile().latestBookmarkList val bookmarks = accountViewModel.userProfile().latestBookmarkList
AmberUtils.decryptBookmark( AmberUtils.decrypt(
bookmarks?.content ?: "", bookmarks?.content ?: "",
accountViewModel.account.keyPair.pubKey.toHexKey() accountViewModel.account.keyPair.pubKey.toHexKey()
) )
@@ -40,6 +40,21 @@ class FileStorageEvent(
return Base64.getEncoder().encodeToString(bytes) return Base64.getEncoder().encodeToString(bytes)
} }
fun create(
mimeType: String,
data: ByteArray,
pubKey: HexKey,
createdAt: Long = TimeUtils.now()
): FileStorageEvent {
val tags = listOfNotNull(
listOf(TYPE, mimeType)
)
val content = encode(data)
val id = generateId(pubKey, createdAt, kind, tags, content)
return FileStorageEvent(id.toHexKey(), pubKey, createdAt, tags, content, "")
}
fun create( fun create(
mimeType: String, mimeType: String,
data: ByteArray, data: ByteArray,
@@ -39,6 +39,45 @@ class FileStorageHeaderEvent(
private const val TORRENT_INFOHASH = "i" private const val TORRENT_INFOHASH = "i"
private const val BLUR_HASH = "blurhash" private const val BLUR_HASH = "blurhash"
fun create(
storageEvent: FileStorageEvent,
mimeType: String? = null,
description: String? = null,
hash: String? = null,
size: String? = null,
dimensions: String? = null,
blurhash: String? = null,
magnetURI: String? = null,
torrentInfoHash: String? = null,
encryptionKey: AESGCM? = null,
sensitiveContent: Boolean? = null,
pubKey: HexKey,
createdAt: Long = TimeUtils.now()
): FileStorageHeaderEvent {
val tags = listOfNotNull(
listOf("e", storageEvent.id),
mimeType?.let { listOf(MIME_TYPE, mimeType) },
hash?.let { listOf(HASH, it) },
size?.let { listOf(FILE_SIZE, it) },
dimensions?.let { listOf(DIMENSION, it) },
blurhash?.let { listOf(BLUR_HASH, it) },
magnetURI?.let { listOf(MAGNET_URI, it) },
torrentInfoHash?.let { listOf(TORRENT_INFOHASH, it) },
encryptionKey?.let { listOf(ENCRYPTION_KEY, it.key, it.nonce) },
sensitiveContent?.let {
if (it) {
listOf("content-warning", "")
} else {
null
}
}
)
val content = description ?: ""
val id = generateId(pubKey, createdAt, kind, tags, content)
return FileStorageHeaderEvent(id.toHexKey(), pubKey, createdAt, tags, content, "")
}
fun create( fun create(
storageEvent: FileStorageEvent, storageEvent: FileStorageEvent,
mimeType: String? = null, mimeType: String? = null,