Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.session.libsession.utilities

import network.loki.messenger.libsession_util.util.BaseCommunityInfo
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import org.session.libsignal.utilities.toHexString
import org.session.libsession.messaging.open_groups.migrateLegacyServerUrl

object CommunityUrlParser {

private const val publicKeyQuery = "public_key"
private const val hexPubkeyLength = 64

sealed class Error(message: String) : IllegalArgumentException(message) {
data object InvalidUrl : Error("Invalid community URL.")
data object InvalidPublicKey : Error("Invalid public key provided.")
}

data class CommunityUrlInfo(
val baseUrl: String,
val room: String,
val pubKeyHex: String,
)

fun trimQueryParameter(url: String): String = url.substringBefore("?$publicKeyQuery")

fun parse(url: String): CommunityUrlInfo =
try {
val (baseUrl, room, publicKey) = requireNotNull(BaseCommunityInfo.parseFullUrl(url)) {
"Invalid community URL"
}
CommunityUrlInfo(
baseUrl = baseUrl.migrateLegacyServerUrl(),
room = room,
pubKeyHex = publicKey.toHexString(),
)
} catch (_: Exception) {
throw classifyError(url)
}

private fun classifyError(url: String): Error {
val parsedUrl = url.toHttpUrlOrNull() ?: return Error.InvalidUrl
val pathSegments = parsedUrl.pathSegments.filter { it.isNotEmpty() }
val room = when {
pathSegments.firstOrNull() == "r" -> pathSegments.getOrNull(1)
else -> pathSegments.firstOrNull()
} ?: return Error.InvalidUrl

val encodedPubkey = parsedUrl.queryParameter(publicKeyQuery) ?: return Error.InvalidPublicKey
if (encodedPubkey.length != hexPubkeyLength) return Error.InvalidPublicKey

return Error.InvalidUrl
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.CommunityUrlParser
import org.session.libsession.utilities.ExpirationUtil
import org.session.libsession.utilities.NonTranslatableStringConstants.APP_NAME
import org.session.libsession.utilities.OpenGroupUrlParser
import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.DATE_KEY
import org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY
Expand Down Expand Up @@ -1248,9 +1248,9 @@ class ConversationViewModel @AssistedInject constructor(
}

private fun openOrJoinCommunity(url: String){
val openGroup = try {
OpenGroupUrlParser.parseUrl(url)
} catch (_: OpenGroupUrlParser.Error) {
val communityInfo = try {
CommunityUrlParser.parse(url)
} catch (_: CommunityUrlParser.Error) {
Toast.makeText(application, R.string.communityEnterUrlErrorInvalidDescription, Toast.LENGTH_SHORT)
.show()
return
Expand All @@ -1261,14 +1261,14 @@ class ConversationViewModel @AssistedInject constructor(
viewModelScope.launch {
try {
openGroupManager.add(
server = openGroup.server,
room = openGroup.room,
publicKey = openGroup.serverPublicKey,
server = communityInfo.baseUrl,
room = communityInfo.room,
publicKey = communityInfo.pubKeyHex,
)

// after joining or if already joined, open the conversation
_uiEvents.tryEmit(ConversationUiEvent.NavigateToConversation(
address = Address.Community(openGroup.server, openGroup.room),
address = Address.Community(communityInfo.baseUrl, communityInfo.room),
))
} catch (e: Exception) {
Log.e("", "Error joining community", e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import kotlinx.serialization.json.Json
import network.loki.messenger.R
import network.loki.messenger.databinding.ViewOpenGroupInvitationBinding
import org.session.libsession.messaging.utilities.UpdateMessageData
import org.session.libsession.utilities.OpenGroupUrlParser
import org.session.libsession.utilities.CommunityUrlParser
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.util.getAccentColor
import javax.inject.Inject
Expand Down Expand Up @@ -42,7 +42,7 @@ class OpenGroupInvitationView : LinearLayout {
openGroupInvitationIconImageView.setImageResource(iconID)
openGroupInvitationIconBackground.backgroundTintList = ColorStateList.valueOf(backgroundColor)
openGroupTitleTextView.text = data.groupName
openGroupURLTextView.text = OpenGroupUrlParser.trimQueryParameter(data.groupUrl)
openGroupURLTextView.text = CommunityUrlParser.trimQueryParameter(data.groupUrl)
openGroupTitleTextView.setTextColor(textColor)
openGroupJoinMessageTextView.setTextColor(textColor)
openGroupURLTextView.setTextColor(textColor)
Expand All @@ -53,4 +53,4 @@ class OpenGroupInvitationView : LinearLayout {
val data = data ?: return null
return (data.groupName to data.groupUrl)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.groups.LegacyGroupDeprecationManager
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.CommunityUrlParser
import org.session.libsession.utilities.ExpirationUtil
import org.session.libsession.utilities.OpenGroupUrlParser
import org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.recipients.RecipientData
Expand Down Expand Up @@ -393,9 +393,9 @@ class ConversationV3ViewModel @AssistedInject constructor(
}

private fun openOrJoinCommunity(url: String) {
val openGroup = try {
OpenGroupUrlParser.parseUrl(url)
} catch (_: OpenGroupUrlParser.Error) {
val communityInfo = try {
CommunityUrlParser.parse(url)
} catch (_: CommunityUrlParser.Error) {
Toast.makeText(context, R.string.communityEnterUrlErrorInvalidDescription, Toast.LENGTH_SHORT)
.show()
return
Expand All @@ -406,13 +406,13 @@ class ConversationV3ViewModel @AssistedInject constructor(
viewModelScope.launch {
try {
openGroupManager.add(
server = openGroup.server,
room = openGroup.room,
publicKey = openGroup.serverPublicKey,
server = communityInfo.baseUrl,
room = communityInfo.room,
publicKey = communityInfo.pubKeyHex,
)

// after joining or if already joined, open the conversation
val communityAddress = Address.Community(openGroup.server, openGroup.room)
val communityAddress = Address.Community(communityInfo.baseUrl, communityInfo.room)
navigateTo(
destination = ConversationV3Destination.RouteConversation(communityAddress),
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import network.loki.messenger.R
import org.session.libsession.utilities.OpenGroupUrlParser
import org.session.libsession.utilities.CommunityUrlParser
import org.thoughtcrime.securesms.ui.theme.LocalColors
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
import org.thoughtcrime.securesms.ui.theme.LocalType
Expand Down Expand Up @@ -92,7 +92,7 @@ fun CommunityInviteMessage(
)

Text(
text = OpenGroupUrlParser.trimQueryParameter(url),
text = CommunityUrlParser.trimQueryParameter(url),
style = LocalType.current.small,
color = getTextColor(outgoing),
maxLines = 2,
Expand Down Expand Up @@ -143,4 +143,4 @@ fun CommunityInvitePreview(
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import network.loki.messenger.libsession_util.PRIORITY_HIDDEN
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.groups.GroupManagerV2
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.OpenGroupUrlParser
import org.session.libsession.utilities.CommunityUrlParser
import org.session.libsession.utilities.StringSubstitutionConstants.APP_NAME_KEY
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.displayName
Expand Down Expand Up @@ -467,9 +467,9 @@ class HomeViewModel @Inject constructor(
}

private fun openOrJoinCommunity(url: String) {
val openGroup = try {
OpenGroupUrlParser.parseUrl(url)
} catch (_: OpenGroupUrlParser.Error) {
val communityInfo = try {
CommunityUrlParser.parse(url)
} catch (_: CommunityUrlParser.Error) {
Toast.makeText(context, R.string.communityEnterUrlErrorInvalidDescription, Toast.LENGTH_SHORT)
.show()
return
Expand All @@ -481,13 +481,13 @@ class HomeViewModel @Inject constructor(
viewModelScope.launch {
try {
openGroupManager.add(
server = openGroup.server,
room = openGroup.room,
publicKey = openGroup.serverPublicKey,
server = communityInfo.baseUrl,
room = communityInfo.room,
publicKey = communityInfo.pubKeyHex,
)

// after joining or if already joined, open the conversation
val communityAddress = Address.Community(openGroup.server, openGroup.room)
val communityAddress = Address.Community(communityInfo.baseUrl, communityInfo.room)
_uiEvents.emit(UiEvent.OpenConversation(communityAddress))

} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.withContext
import network.loki.messenger.R
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.OpenGroupUrlParser
import org.session.libsession.utilities.CommunityUrlParser
import org.session.libsignal.utilities.AccountId
import org.session.libsignal.utilities.IdPrefix
import org.session.libsignal.utilities.Log
Expand Down Expand Up @@ -111,12 +111,12 @@ class GlobalSearchViewModel @Inject constructor(
// otherwise a dialog is handled by the query event flow
if(communityUrl.joined){
// community is already joined: add it to the result list
val openGroup = OpenGroupUrlParser.parseUrl(communityUrl.url)
val communityInfo = CommunityUrlParser.parse(communityUrl.url)
results = results.copy(
threads = results.threads + recipientRepository.getRecipientSync(
Address.Community(
serverUrl = openGroup.server,
room = openGroup.room
serverUrl = communityInfo.baseUrl,
room = communityInfo.room
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import network.loki.messenger.R
import org.session.libsession.messaging.open_groups.OfficialCommunityRepository
import org.session.libsession.messaging.open_groups.OpenGroupApi
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.OpenGroupUrlParser
import org.session.libsession.utilities.CommunityUrlParser
import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_KEY
import org.session.libsession.utilities.withUserConfigs
import org.session.libsignal.utilities.Log
Expand Down Expand Up @@ -74,33 +74,23 @@ class JoinCommunityViewModel @Inject constructor(
viewModelScope.launch(Dispatchers.Default) {
_state.update { it.copy(loading = true) }

val openGroup = try {
OpenGroupUrlParser.parseUrl(url)
} catch (e: OpenGroupUrlParser.Error) {
val communityInfo = try {
CommunityUrlParser.parse(url)
} catch (e: CommunityUrlParser.Error) {
_state.update { it.copy(loading = false) }
when (e) {
is OpenGroupUrlParser.Error.MalformedURL, OpenGroupUrlParser.Error.NoRoom -> {
withContext(Dispatchers.Main) {
Toast.makeText(
appContext,
appContext.getString(R.string.communityJoinError),
Toast.LENGTH_SHORT
).show()
}
return@launch
}

is OpenGroupUrlParser.Error.InvalidPublicKey, OpenGroupUrlParser.Error.NoPublicKey -> {
withContext(Dispatchers.Main) {
Toast.makeText(
appContext,
appContext.getString(R.string.communityEnterUrlErrorInvalidDescription),
Toast.LENGTH_SHORT
).show()
}
return@launch
}
withContext(Dispatchers.Main) {
Toast.makeText(
appContext,
appContext.getString(
when (e) {
CommunityUrlParser.Error.InvalidUrl -> R.string.communityJoinError
CommunityUrlParser.Error.InvalidPublicKey -> R.string.communityEnterUrlErrorInvalidDescription
}
),
Toast.LENGTH_SHORT
).show()
}
return@launch
}

// Check if we've already joined this community
Expand All @@ -113,13 +103,13 @@ class JoinCommunityViewModel @Inject constructor(

try {
openGroupManager.add(
server = openGroup.server,
room = openGroup.room,
publicKey = openGroup.serverPublicKey,
server = communityInfo.baseUrl,
room = communityInfo.room,
publicKey = communityInfo.pubKeyHex,
)

_uiEvents.emit(UiEvent.NavigateToConversation(
address = Address.Community(openGroup.server, openGroup.room),
address = Address.Community(communityInfo.baseUrl, communityInfo.room),
))
} catch (e: Exception) {
Log.e("Loki", "Couldn't join community.", e)
Expand Down Expand Up @@ -181,4 +171,4 @@ class JoinCommunityViewModel @Inject constructor(
sealed interface UiEvent {
data class NavigateToConversation(val address: Address.Conversable) : UiEvent
}
}
}
Loading