support for nip95
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user