mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-07-15 09:09:14 +00:00
use domain without prefix in profiles and in database, rename fields and types
This commit is contained in:
+12
-11
@@ -2039,7 +2039,8 @@ data class Profile(
|
||||
val peerType: ChatPeerType? = null,
|
||||
// the badge proof from the wire profile: not interpreted by the UI (display uses crypto-free LocalBadge),
|
||||
// but preserved so passing a link profile back to the core (apiPrepareContact) keeps the proof
|
||||
val badge: BadgeProof? = null
|
||||
val badge: BadgeProof? = null,
|
||||
val contactDomain: SimplexDomainClaim? = null
|
||||
): NamedChat {
|
||||
val profileViewName: String
|
||||
get() {
|
||||
@@ -2069,12 +2070,12 @@ data class LocalProfile(
|
||||
val preferences: ChatPreferences? = null,
|
||||
val peerType: ChatPeerType? = null,
|
||||
val localBadge: LocalBadge? = null,
|
||||
val simplexName: SimplexNameClaim? = null,
|
||||
val simplexNameVerification: Boolean? = null
|
||||
val contactDomain: SimplexDomainClaim? = null,
|
||||
val contactDomainVerified: Boolean? = null
|
||||
): NamedChat {
|
||||
val profileViewName: String = localAlias.ifEmpty { if (fullName == "" || displayName == fullName) displayName else "$displayName ($fullName)" }
|
||||
|
||||
fun toProfile(): Profile = Profile(displayName, fullName, shortDescr, image, localAlias, contactLink, preferences, peerType)
|
||||
fun toProfile(): Profile = Profile(displayName, fullName, shortDescr, image, localAlias, contactLink, preferences, peerType, contactDomain = contactDomain)
|
||||
|
||||
companion object {
|
||||
val sampleData = LocalProfile(
|
||||
@@ -2200,7 +2201,7 @@ data class GroupInfo (
|
||||
val chatTags: List<Long>,
|
||||
val chatItemTTL: Long?,
|
||||
override val localAlias: String,
|
||||
val simplexNameVerification: Boolean? = null,
|
||||
val groupDomainVerified: Boolean? = null,
|
||||
): SomeChat, NamedChat {
|
||||
override val chatType get() = ChatType.Group
|
||||
override val id get() = "#$groupId"
|
||||
@@ -2323,9 +2324,9 @@ object GroupTypeSerializer : KSerializer<GroupType> {
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class SimplexNameClaim(
|
||||
data class SimplexDomainClaim(
|
||||
val name: String,
|
||||
val proof: NameClaimProof? = null
|
||||
val proof: SimplexDomainProof? = null
|
||||
) {
|
||||
val shortName: String get() = name.removePrefix("simplex:/name")
|
||||
}
|
||||
@@ -2333,7 +2334,7 @@ data class SimplexNameClaim(
|
||||
@Serializable
|
||||
data class PublicGroupAccess(
|
||||
val groupWebPage: String? = null,
|
||||
val simplexName: SimplexNameClaim? = null,
|
||||
val groupDomainClaim: SimplexDomainClaim? = null,
|
||||
val domainWebPage: Boolean = false,
|
||||
val allowEmbedding: Boolean = false
|
||||
)
|
||||
@@ -4885,7 +4886,7 @@ enum class SimplexLinkType(val linkType: String) {
|
||||
@Serializable
|
||||
data class SimplexNameInfo(
|
||||
val nameType: SimplexNameType,
|
||||
val nameDomain: SimplexNameDomain
|
||||
val nameDomain: SimplexDomain
|
||||
) {
|
||||
// prefix-less domain for prefilling the set-name field (shortName without the @/# prefix)
|
||||
val editDomain: String
|
||||
@@ -4899,7 +4900,7 @@ data class SimplexNameInfo(
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class SimplexNameDomain(
|
||||
data class SimplexDomain(
|
||||
val nameTLD: SimplexTLD,
|
||||
val domain: String,
|
||||
val subDomain: List<String>
|
||||
@@ -4931,7 +4932,7 @@ enum class SimplexNameType {
|
||||
|
||||
// peer's signed name claim; UI only checks presence
|
||||
@Serializable
|
||||
data class NameClaimProof(
|
||||
data class SimplexDomainProof(
|
||||
val presHeader: String,
|
||||
val signature: String,
|
||||
val linkOwnerId: String? = null
|
||||
|
||||
+34
-34
@@ -1558,17 +1558,17 @@ object ChatController {
|
||||
)
|
||||
}
|
||||
r is API.Error && r.err is ChatError.ChatErrorChat
|
||||
&& r.err.errorType is ChatErrorType.SimplexName -> {
|
||||
val name = r.err.errorType.simplexName.shortName
|
||||
if (r.err.errorType.simplexNameError is SimplexNameError.NoValidLink) {
|
||||
&& r.err.errorType is ChatErrorType.CESimplexDomain -> {
|
||||
val domain = r.err.errorType.simplexDomain.fullDomainName
|
||||
if (r.err.errorType.simplexDomainError is SimplexDomainError.NoValidLink) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.simplex_name_no_valid_link),
|
||||
generalGetString(MR.strings.simplex_name_no_valid_link_desc).format(name)
|
||||
generalGetString(MR.strings.simplex_name_no_valid_link_desc).format(domain)
|
||||
)
|
||||
} else {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.simplex_name_unconfirmed),
|
||||
generalGetString(MR.strings.simplex_name_unconfirmed_desc).format(name)
|
||||
generalGetString(MR.strings.simplex_name_unconfirmed_desc).format(domain)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1631,10 +1631,10 @@ object ChatController {
|
||||
|
||||
// owner-specific wording for setting one's own/channel name; null for other errors (handled by apiConnectResponseAlert)
|
||||
fun simplexNameOwnerError(err: ChatError, isChannel: Boolean): String? =
|
||||
if (err is ChatError.ChatErrorChat && err.errorType is ChatErrorType.SimplexName && err.errorType.simplexNameError is SimplexNameError.NoValidLink) {
|
||||
val name = err.errorType.simplexName.shortName
|
||||
if (isChannel) generalGetString(MR.strings.simplex_name_owner_no_channel_link).format(name)
|
||||
else generalGetString(MR.strings.simplex_name_owner_no_address).format(name)
|
||||
if (err is ChatError.ChatErrorChat && err.errorType is ChatErrorType.CESimplexDomain && err.errorType.simplexDomainError is SimplexDomainError.NoValidLink) {
|
||||
val domain = err.errorType.simplexDomain.fullDomainName
|
||||
if (isChannel) generalGetString(MR.strings.simplex_name_owner_no_channel_link).format(domain)
|
||||
else generalGetString(MR.strings.simplex_name_owner_no_address).format(domain)
|
||||
} else null
|
||||
|
||||
fun connErrorText(e: ChatError): String = when {
|
||||
@@ -1642,8 +1642,8 @@ object ChatController {
|
||||
generalGetString(MR.strings.invalid_connection_link)
|
||||
e is ChatError.ChatErrorChat && e.errorType is ChatErrorType.UnsupportedConnReq ->
|
||||
generalGetString(MR.strings.unsupported_connection_link)
|
||||
e is ChatError.ChatErrorChat && e.errorType is ChatErrorType.SimplexName ->
|
||||
if (e.errorType.simplexNameError is SimplexNameError.NoValidLink)
|
||||
e is ChatError.ChatErrorChat && e.errorType is ChatErrorType.CESimplexDomain ->
|
||||
if (e.errorType.simplexDomainError is SimplexDomainError.NoValidLink)
|
||||
generalGetString(MR.strings.simplex_name_no_valid_link)
|
||||
else generalGetString(MR.strings.simplex_name_unconfirmed)
|
||||
e is ChatError.ChatErrorAgent && e.agentError is AgentErrorType.NO_NAME_SERVERS ->
|
||||
@@ -1823,9 +1823,9 @@ object ChatController {
|
||||
}
|
||||
|
||||
// name is the encoded SimplexName (e.g. "@alice.simplex"); null clears it. Throws on rejection.
|
||||
suspend fun apiSetUserName(rh: Long?, name: String?): User {
|
||||
val userId = currentUserId("apiSetUserName")
|
||||
val r = sendCmd(rh, CC.ApiSetUserName(userId, name))
|
||||
suspend fun apiSetUserDomain(rh: Long?, simplexDomain: String?): User {
|
||||
val userId = currentUserId("apiSetUserDomain")
|
||||
val r = sendCmd(rh, CC.ApiSetUserDomain(userId, simplexDomain))
|
||||
return when {
|
||||
r is API.Result && r.res is CR.UserProfileUpdated -> r.res.user.updateRemoteHostId(rh)
|
||||
r is API.Result && r.res is CR.UserProfileNoChange -> r.res.user.updateRemoteHostId(rh)
|
||||
@@ -1840,17 +1840,17 @@ object ChatController {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun apiVerifyContactName(rh: Long?, contactId: Long): Pair<Contact, String?>? {
|
||||
val r = sendCmd(rh, CC.ApiVerifyContactName(contactId))
|
||||
suspend fun apiVerifyContactDomain(rh: Long?, contactId: Long): Pair<Contact, String?>? {
|
||||
val r = sendCmd(rh, CC.ApiVerifyContactDomain(contactId))
|
||||
if (r is API.Result && r.res is CR.ContactNameVerified) return r.res.contact to r.res.verificationFailure
|
||||
Log.e(TAG, "apiVerifyContactName bad response: ${r.responseType} ${r.details}")
|
||||
Log.e(TAG, "apiVerifyContactDomain bad response: ${r.responseType} ${r.details}")
|
||||
return null
|
||||
}
|
||||
|
||||
suspend fun apiVerifyPublicGroupName(rh: Long?, groupId: Long): Pair<GroupInfo, String?>? {
|
||||
val r = sendCmd(rh, CC.ApiVerifyPublicGroupName(groupId))
|
||||
suspend fun apiVerifyGroupDomain(rh: Long?, groupId: Long): Pair<GroupInfo, String?>? {
|
||||
val r = sendCmd(rh, CC.ApiVerifyGroupDomain(groupId))
|
||||
if (r is API.Result && r.res is CR.GroupNameVerified) return r.res.groupInfo to r.res.verificationFailure
|
||||
Log.e(TAG, "apiVerifyPublicGroupName bad response: ${r.responseType} ${r.details}")
|
||||
Log.e(TAG, "apiVerifyGroupDomain bad response: ${r.responseType} ${r.details}")
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -3885,9 +3885,9 @@ sealed class CC {
|
||||
class ApiShowMyAddress(val userId: Long): CC()
|
||||
class ApiAddMyAddressShortLink(val userId: Long): CC()
|
||||
class ApiSetProfileAddress(val userId: Long, val on: Boolean): CC()
|
||||
class ApiSetUserName(val userId: Long, val name: String?): CC()
|
||||
class ApiVerifyContactName(val contactId: Long): CC()
|
||||
class ApiVerifyPublicGroupName(val groupId: Long): CC()
|
||||
class ApiSetUserDomain(val userId: Long, val simplexDomain: String?): CC()
|
||||
class ApiVerifyContactDomain(val contactId: Long): CC()
|
||||
class ApiVerifyGroupDomain(val groupId: Long): CC()
|
||||
class ApiSetAddressSettings(val userId: Long, val addressSettings: AddressSettings): CC()
|
||||
class ApiGetCallInvitations: CC()
|
||||
class ApiSendCallInvitation(val contact: Contact, val callType: CallType): CC()
|
||||
@@ -4096,10 +4096,10 @@ sealed class CC {
|
||||
is ApiShowMyAddress -> "/_show_address $userId"
|
||||
is ApiAddMyAddressShortLink -> "/_short_link_address $userId"
|
||||
is ApiSetProfileAddress -> "/_profile_address $userId ${onOff(on)}"
|
||||
is ApiSetUserName -> "/_set_name $userId" + (if (name != null) " $name" else "")
|
||||
is ApiSetUserDomain -> "/_set domain $userId" + (if (simplexDomain != null) " $simplexDomain" else "")
|
||||
is ApiSetPublicGroupAccess -> "/_public group access #$groupId ${json.encodeToString(access)}"
|
||||
is ApiVerifyContactName -> "/_verify name @$contactId"
|
||||
is ApiVerifyPublicGroupName -> "/_verify name #$groupId"
|
||||
is ApiVerifyContactDomain -> "/_verify domain @$contactId"
|
||||
is ApiVerifyGroupDomain -> "/_verify domain #$groupId"
|
||||
is ApiSetAddressSettings -> "/_address_settings $userId ${json.encodeToString(addressSettings)}"
|
||||
is ApiAcceptContact -> "/_accept incognito=${onOff(incognito)} $contactReqId"
|
||||
is ApiRejectContact -> "/_reject $contactReqId"
|
||||
@@ -4281,10 +4281,10 @@ sealed class CC {
|
||||
is ApiShowMyAddress -> "apiShowMyAddress"
|
||||
is ApiAddMyAddressShortLink -> "apiAddMyAddressShortLink"
|
||||
is ApiSetProfileAddress -> "apiSetProfileAddress"
|
||||
is ApiSetUserName -> "apiSetUserName"
|
||||
is ApiSetUserDomain -> "apiSetUserDomain"
|
||||
is ApiSetPublicGroupAccess -> "apiSetPublicGroupAccess"
|
||||
is ApiVerifyContactName -> "apiVerifyContactName"
|
||||
is ApiVerifyPublicGroupName -> "apiVerifyPublicGroupName"
|
||||
is ApiVerifyContactDomain -> "apiVerifyContactDomain"
|
||||
is ApiVerifyGroupDomain -> "apiVerifyGroupDomain"
|
||||
is ApiSetAddressSettings -> "apiSetAddressSettings"
|
||||
is ApiAcceptContact -> "apiAcceptContact"
|
||||
is ApiRejectContact -> "apiRejectContact"
|
||||
@@ -7096,9 +7096,9 @@ sealed class OwnerVerification {
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed class SimplexNameError {
|
||||
@Serializable @SerialName("noValidLink") object NoValidLink : SimplexNameError()
|
||||
@Serializable @SerialName("unknownName") object UnknownName : SimplexNameError()
|
||||
sealed class SimplexDomainError {
|
||||
@Serializable @SerialName("noValidLink") object NoValidLink : SimplexDomainError()
|
||||
@Serializable @SerialName("unknownDomain") object UnknownDomain : SimplexDomainError()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@@ -7438,7 +7438,7 @@ sealed class ChatErrorType {
|
||||
is ChatStoreChanged -> "chatStoreChanged"
|
||||
is ConnectionPlanChatError -> "connectionPlan"
|
||||
is InvalidConnReq -> "invalidConnReq"
|
||||
is SimplexName -> "simplexName"
|
||||
is CESimplexDomain -> "simplexDomain"
|
||||
is UnsupportedConnReq -> "unsupportedConnReq"
|
||||
is InvalidChatMessage -> "invalidChatMessage"
|
||||
is ConnReqMessageProhibited -> "connReqMessageProhibited"
|
||||
@@ -7521,7 +7521,7 @@ sealed class ChatErrorType {
|
||||
@Serializable @SerialName("chatStoreChanged") object ChatStoreChanged: ChatErrorType()
|
||||
@Serializable @SerialName("connectionPlan") class ConnectionPlanChatError(val connectionPlan: ConnectionPlan): ChatErrorType()
|
||||
@Serializable @SerialName("invalidConnReq") object InvalidConnReq: ChatErrorType()
|
||||
@Serializable @SerialName("simplexName") class SimplexName(val simplexName: SimplexNameInfo, val simplexNameError: SimplexNameError): ChatErrorType()
|
||||
@Serializable @SerialName("simplexDomain") class CESimplexDomain(val simplexDomain: SimplexDomain, val simplexDomainError: SimplexDomainError): ChatErrorType()
|
||||
@Serializable @SerialName("unsupportedConnReq") object UnsupportedConnReq: ChatErrorType()
|
||||
@Serializable @SerialName("invalidChatMessage") class InvalidChatMessage(val connection: Connection, val message: String): ChatErrorType()
|
||||
@Serializable @SerialName("connReqMessageProhibited") object ConnReqMessageProhibited: ChatErrorType()
|
||||
|
||||
+6
-6
@@ -757,17 +757,17 @@ fun ChatInfoHeader(cInfo: ChatInfo, contact: Contact) {
|
||||
modifier = Modifier.combinedClickable(onClick = copyDisplayName, onLongClick = copyDisplayName).onRightClick(copyDisplayName)
|
||||
)
|
||||
ChatInfoDescription(cInfo, displayName, copyNameToClipboard)
|
||||
val simplexName = contact.profile.simplexName
|
||||
if (simplexName != null && (contact.profile.simplexNameVerification != null || simplexName.proof != null)) {
|
||||
val domain = contact.profile.contactDomain
|
||||
if (domain != null && (contact.profile.contactDomainVerified != null || domain.proof != null)) {
|
||||
SimplexNameView(
|
||||
name = simplexName.shortName,
|
||||
verification = contact.profile.simplexNameVerification,
|
||||
name = domain.shortName,
|
||||
verification = contact.profile.contactDomainVerified,
|
||||
autoVerify = chatModel.controller.appPrefs.privacyVerifySimplexNames.get(),
|
||||
verify = {
|
||||
val rhId = chatModel.remoteHostId()
|
||||
chatModel.controller.apiVerifyContactName(rhId, contact.contactId)?.let { (ct, reason) ->
|
||||
chatModel.controller.apiVerifyContactDomain(rhId, contact.contactId)?.let { (ct, reason) ->
|
||||
chatModel.chatsContext.updateContact(rhId, ct)
|
||||
ct.profile.simplexNameVerification to reason
|
||||
ct.profile.contactDomainVerified to reason
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ fun ChannelWebPageView(
|
||||
val trimmedPage = webPage.value.trim()
|
||||
val newAccess = PublicGroupAccess(
|
||||
groupWebPage = trimmedPage.ifEmpty { null },
|
||||
simplexName = access?.simplexName,
|
||||
groupDomainClaim = access?.groupDomainClaim,
|
||||
domainWebPage = access?.domainWebPage ?: false,
|
||||
allowEmbedding = allowEmbedding.value
|
||||
)
|
||||
|
||||
+8
-8
@@ -184,10 +184,10 @@ fun ModalData.GroupChatInfoView(
|
||||
title = generalGetString(MR.strings.set_simplex_name),
|
||||
footer = generalGetString(MR.strings.set_channel_simplex_name_footer),
|
||||
prefix = "#",
|
||||
initial = groupInfo.groupProfile.publicGroup?.publicGroupAccess?.simplexName?.shortName ?: "",
|
||||
initial = groupInfo.groupProfile.publicGroup?.publicGroupAccess?.groupDomainClaim?.shortName ?: "",
|
||||
save = { name ->
|
||||
val access = groupInfo.groupProfile.publicGroup?.publicGroupAccess ?: PublicGroupAccess()
|
||||
val newAccess = access.copy(simplexName = name?.let { SimplexNameClaim(it) })
|
||||
val newAccess = access.copy(groupDomainClaim = name?.let { SimplexDomainClaim(it) })
|
||||
val gInfo = chatModel.controller.apiSetPublicGroupAccess(rhId, groupInfo.groupId, newAccess)
|
||||
if (gInfo != null) {
|
||||
withContext(Dispatchers.Main) { chatModel.chatsContext.updateGroup(rhId, gInfo) }
|
||||
@@ -975,17 +975,17 @@ private fun GroupChatInfoHeader(cInfo: ChatInfo, groupInfo: GroupInfo) {
|
||||
)
|
||||
ChatInfoDescription(cInfo, displayName, copyNameToClipboard)
|
||||
val access = groupInfo.groupProfile.publicGroup?.publicGroupAccess
|
||||
val groupName = access?.simplexName?.shortName
|
||||
if (groupName != null && (groupInfo.simplexNameVerification != null || access.simplexName?.proof != null)) {
|
||||
val domain = access?.groupDomainClaim?.shortName
|
||||
if (domain != null && (groupInfo.groupDomainVerified != null || access.groupDomainClaim?.proof != null)) {
|
||||
SimplexNameView(
|
||||
name = groupName,
|
||||
verification = groupInfo.simplexNameVerification,
|
||||
name = domain,
|
||||
verification = groupInfo.groupDomainVerified,
|
||||
autoVerify = chatModel.controller.appPrefs.privacyVerifySimplexNames.get(),
|
||||
verify = {
|
||||
val rhId = chatModel.remoteHostId()
|
||||
chatModel.controller.apiVerifyPublicGroupName(rhId, groupInfo.groupId)?.let { (gInfo, reason) ->
|
||||
chatModel.controller.apiVerifyGroupDomain(rhId, groupInfo.groupId)?.let { (gInfo, reason) ->
|
||||
chatModel.chatsContext.updateGroup(rhId, gInfo)
|
||||
gInfo.simplexNameVerification to reason
|
||||
gInfo.groupDomainVerified to reason
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@ fun SetSimplexNameView(
|
||||
val s = name.value.trim()
|
||||
return when {
|
||||
s.isEmpty() -> null
|
||||
s.startsWith("@") || s.startsWith("#") -> prefix + s.substring(1)
|
||||
else -> prefix + s
|
||||
s.startsWith("@") || s.startsWith("#") -> s.substring(1)
|
||||
else -> s
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -373,14 +373,14 @@ private fun UserAddressLayout(
|
||||
title = generalGetString(MR.strings.set_simplex_name),
|
||||
footer = generalGetString(MR.strings.set_user_simplex_name_footer),
|
||||
prefix = "@",
|
||||
initial = user?.profile?.simplexName?.shortName ?: "",
|
||||
save = { name ->
|
||||
initial = user?.profile?.contactDomain?.shortName ?: "",
|
||||
save = { simplexDomain ->
|
||||
try {
|
||||
val u = chatModel.controller.apiSetUserName(user?.remoteHostId, name)
|
||||
val u = chatModel.controller.apiSetUserDomain(user?.remoteHostId, simplexDomain)
|
||||
withContext(Dispatchers.Main) { chatModel.updateUser(u) }
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "apiSetUserName: ${e.message}")
|
||||
Log.e(TAG, "apiSetUserDomain: ${e.message}")
|
||||
false
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user