mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-22 19:48:52 +00:00
feat(Contacts): Handle cancel identity verification on the reciever side
Close #8437
This commit is contained in:
parent
a584a31818
commit
ddf27d3038
@ -73,6 +73,10 @@ proc init*(self: Controller) =
|
||||
var args = ContactArgs(e)
|
||||
self.delegate.onVerificationRequestDeclined(args.contactId)
|
||||
|
||||
self.events.on(SIGNAL_CONTACT_VERIFICATION_CANCELLED) do(e: Args):
|
||||
var args = ContactArgs(e)
|
||||
self.delegate.onVerificationRequestCanceled(args.contactId)
|
||||
|
||||
self.events.on(SIGNAL_CONTACT_VERIFICATION_ADDED) do(e: Args):
|
||||
var args = VerificationRequestArgs(e)
|
||||
self.delegate.onVerificationRequestUpdatedOrAdded(args.verificationRequest)
|
||||
@ -161,5 +165,3 @@ proc getReceivedVerificationRequests*(self: Controller): seq[VerificationRequest
|
||||
proc getStatusForContactWithId*(self: Controller, publicKey: string): StatusUpdateDto =
|
||||
return self.contactsService.getStatusForContactWithId(publicKey)
|
||||
|
||||
proc hasReceivedVerificationRequestFrom*(self: Controller, fromId: string): bool =
|
||||
self.contactsService.hasReceivedVerificationRequestFrom(fromId)
|
||||
|
@ -116,10 +116,10 @@ method contactRequestRejectionRemoved*(self: AccessInterface, publicKey: string)
|
||||
method getReceivedVerificationRequests*(self: AccessInterface): seq[VerificationRequest] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method hasReceivedVerificationRequestFrom*(self: AccessInterface, fromId: string): bool {.base.} =
|
||||
method onVerificationRequestDeclined*(self: AccessInterface, publicKey: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onVerificationRequestDeclined*(self: AccessInterface, publicKey: string) {.base.} =
|
||||
method onVerificationRequestCanceled*(self: AccessInterface, publicKey: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onVerificationRequestUpdatedOrAdded*(self: AccessInterface, VerificationRequest: VerificationRequest) {.base.} =
|
||||
|
@ -257,12 +257,12 @@ method acceptVerificationRequest*(self: Module, publicKey: string, response: str
|
||||
method getReceivedVerificationRequests*(self: Module): seq[VerificationRequest] =
|
||||
self.controller.getReceivedVerificationRequests()
|
||||
|
||||
method hasReceivedVerificationRequestFrom*(self: Module, fromId: string): bool =
|
||||
result = self.controller.hasReceivedVerificationRequestFrom(fromId)
|
||||
|
||||
method onVerificationRequestDeclined*(self: Module, publicKey: string) =
|
||||
self.view.receivedContactRequestsModel.removeItemById(publicKey)
|
||||
|
||||
method onVerificationRequestCanceled*(self: Module, publicKey: string) =
|
||||
self.view.receivedContactRequestsModel.removeItemById(publicKey)
|
||||
|
||||
method onVerificationRequestUpdatedOrAdded*(self: Module, request: VerificationRequest) =
|
||||
let item = self.createItemFromPublicKey(request.fromID)
|
||||
item.incomingVerificationStatus = VerificationRequestStatus(request.status)
|
||||
|
@ -186,5 +186,3 @@ QtObject:
|
||||
proc acceptVerificationRequest*(self: View, publicKey: string, response: string) {.slot.} =
|
||||
self.delegate.acceptVerificationRequest(publicKey, response)
|
||||
|
||||
proc hasReceivedVerificationRequestFrom*(self: View, fromId: string): bool {.slot.} =
|
||||
result = self.delegate.hasReceivedVerificationRequestFrom(fromId)
|
||||
|
@ -140,7 +140,6 @@ proc toContactsDto*(jsonObj: JsonNode): ContactsDto =
|
||||
discard jsonObj.getProp("lastUpdatedLocally", result.lastUpdatedLocally)
|
||||
discard jsonObj.getProp("localNickname", result.localNickname)
|
||||
discard jsonObj.getProp("bio", result.bio)
|
||||
|
||||
|
||||
result.requestState = ContactRequestState.None
|
||||
var requestState: int
|
||||
|
@ -192,10 +192,15 @@ QtObject:
|
||||
if self.contacts.hasKey(request.fromId):
|
||||
self.contacts[request.fromId].trustStatus = TrustStatus.Trusted
|
||||
self.contacts[request.fromId].verificationStatus = VerificationStatus.Trusted
|
||||
|
||||
self.events.emit(SIGNAL_CONTACT_TRUSTED,
|
||||
TrustArgs(publicKey: request.fromId, isUntrustworthy: false))
|
||||
self.events.emit(SIGNAL_CONTACT_VERIFIED, ContactArgs(contactId: request.fromId))
|
||||
|
||||
if request.status == VerificationStatus.Canceled:
|
||||
if self.contacts.hasKey(request.fromId):
|
||||
self.contacts[request.fromId].verificationStatus = VerificationStatus.Canceled
|
||||
self.events.emit(SIGNAL_CONTACT_VERIFICATION_CANCELLED, ContactArgs(contactId: request.fromId))
|
||||
|
||||
else:
|
||||
self.events.emit(SIGNAL_CONTACT_VERIFICATION_ADDED, data)
|
||||
|
||||
@ -664,9 +669,6 @@ QtObject:
|
||||
proc getReceivedVerificationRequests*(self: Service): seq[VerificationRequest] =
|
||||
result = toSeq(self.receivedIdentityRequests.values)
|
||||
|
||||
proc hasReceivedVerificationRequestFrom*(self: Service, fromId: string): bool =
|
||||
result = self.receivedIdentityRequests.contains(fromId)
|
||||
|
||||
proc sendVerificationRequest*(self: Service, publicKey: string, challenge: string) =
|
||||
try:
|
||||
let response = status_contacts.sendVerificationRequest(publicKey, challenge)
|
||||
@ -685,8 +687,15 @@ QtObject:
|
||||
|
||||
proc cancelVerificationRequest*(self: Service, publicKey: string) =
|
||||
try:
|
||||
let response = status_contacts.cancelVerificationRequest(publicKey)
|
||||
if(not response.error.isNil):
|
||||
var response = status_contacts.getVerificationRequestSentTo(publicKey)
|
||||
if not response.error.isNil:
|
||||
let msg = response.error.message
|
||||
raise newException(RpcException, msg)
|
||||
|
||||
let request = response.result.toVerificationRequest()
|
||||
|
||||
response = status_contacts.cancelVerificationRequest(request.id)
|
||||
if not response.error.isNil:
|
||||
let msg = response.error.message
|
||||
error "error sending contact verification request", msg
|
||||
return
|
||||
@ -694,7 +703,7 @@ QtObject:
|
||||
var contact = self.getContactById(publicKey)
|
||||
contact.verificationStatus = VerificationStatus.Unverified
|
||||
self.saveContact(contact)
|
||||
|
||||
|
||||
self.events.emit(SIGNAL_CONTACT_VERIFICATION_CANCELLED, ContactArgs(contactId: publicKey))
|
||||
except Exception as e:
|
||||
error "Error canceling verification request", msg = e.msg
|
||||
|
@ -103,8 +103,8 @@ proc getReceivedVerificationRequests*(): RpcResponse[JsonNode] {.raises: [Except
|
||||
let payload = %* []
|
||||
result = callPrivateRPC("getReceivedVerificationRequests".prefix, payload)
|
||||
|
||||
proc cancelVerificationRequest*(pubkey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [pubkey]
|
||||
proc cancelVerificationRequest*(requestId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [requestId]
|
||||
result = callPrivateRPC("cancelVerificationRequest".prefix, payload)
|
||||
|
||||
proc retractContactRequest*(pubkey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
|
@ -133,10 +133,6 @@ SplitView {
|
||||
contactsStore: QtObject {
|
||||
readonly property string myPublicKey: "0xdeadbeef"
|
||||
|
||||
function hasReceivedVerificationRequestFrom(publicKey) {
|
||||
return false
|
||||
}
|
||||
|
||||
function joinPrivateChat(publicKey) {
|
||||
logs.logEvent("contactsStore::joinPrivateChat", ["publicKey"], arguments)
|
||||
}
|
||||
|
@ -115,10 +115,6 @@ QtObject {
|
||||
return JSON.parse(resp);
|
||||
}
|
||||
|
||||
function hasReceivedVerificationRequestFrom(pubKey) {
|
||||
return root.contactsModule.hasReceivedVerificationRequestFrom(pubKey);
|
||||
}
|
||||
|
||||
function verifiedTrusted(pubKey) {
|
||||
root.contactsModule.verifiedTrusted(pubKey);
|
||||
}
|
||||
|
@ -47,23 +47,14 @@ QtObject {
|
||||
}
|
||||
|
||||
function openIncomingIDRequestPopup(publicKey, cb) {
|
||||
try {
|
||||
const request = root.rootStore.profileSectionStore.contactsStore.getVerificationDetailsFromAsJson(publicKey)
|
||||
const popupProperties = {
|
||||
senderPublicKey: request.from,
|
||||
senderDisplayName: request.displayName,
|
||||
senderIcon: request.icon,
|
||||
challengeText: request.challenge,
|
||||
responseText: request.response,
|
||||
messageTimestamp: request.requestedAt,
|
||||
responseTimestamp: request.repliedAt
|
||||
}
|
||||
const popupProperties = {
|
||||
contactsStore: root.rootStore.profileSectionStore.contactsStore,
|
||||
publicKey: publicKey
|
||||
}
|
||||
|
||||
const popup = Global.openPopup(contactVerificationRequestPopupComponent, popupProperties)
|
||||
if (cb)
|
||||
cb(popup)
|
||||
} catch (e) {
|
||||
console.error("Error getting or parsing verification data", e)
|
||||
const popup = Global.openPopup(contactVerificationRequestPopupComponent, popupProperties)
|
||||
if (cb) {
|
||||
cb(popup)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,18 +14,52 @@ import shared.views.chat 1.0
|
||||
StatusModal {
|
||||
id: root
|
||||
|
||||
property string senderPublicKey: ""
|
||||
property string senderDisplayName: ""
|
||||
property string senderIcon: ""
|
||||
property string challengeText: ""
|
||||
property string responseText: ""
|
||||
property string messageTimestamp: ""
|
||||
property string responseTimestamp: ""
|
||||
property var contactsStore
|
||||
property string publicKey
|
||||
|
||||
signal verificationRefused(string senderPublicKey)
|
||||
signal responseSent(string senderPublicKey, string response)
|
||||
|
||||
header.title: qsTr("%1 is asking you to verify your identity").arg(root.senderDisplayName)
|
||||
function updateContactDetails() {
|
||||
try {
|
||||
const request = root.contactsStore.getVerificationDetailsFromAsJson(root.publicKey)
|
||||
|
||||
if (request.requestStatus === Constants.verificationStatus.canceled) {
|
||||
root.close()
|
||||
}
|
||||
|
||||
d.senderPublicKey = request.from,
|
||||
d.senderDisplayName = request.displayName
|
||||
d.senderIcon = request.icon
|
||||
d.challengeText = request.challenge
|
||||
d.responseText = request.response
|
||||
d.messageTimestamp = request.requestedAt
|
||||
d.responseTimestamp = request.repliedAt
|
||||
} catch (e) {
|
||||
console.error("Error getting or parsing verification data", e)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.contactsStore.receivedContactRequestsModel
|
||||
function onCountChanged() {
|
||||
root.updateContactDetails()
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property string senderPublicKey: ""
|
||||
property string senderDisplayName: ""
|
||||
property string senderIcon: ""
|
||||
property string challengeText: ""
|
||||
property string responseText: ""
|
||||
property string messageTimestamp: ""
|
||||
property string responseTimestamp: ""
|
||||
}
|
||||
|
||||
header.title: qsTr("%1 is asking you to verify your identity").arg(d.senderDisplayName)
|
||||
|
||||
x: Math.round(((parent ? parent.width : 0) - width) / 2)
|
||||
y: Math.round(((parent ? parent.height : 0) - height) / 2)
|
||||
@ -34,6 +68,7 @@ StatusModal {
|
||||
height: 230 + verificationMessage.height + verificationResponse.height
|
||||
|
||||
onOpened: {
|
||||
root.updateContactDetails()
|
||||
verificationResponse.input.edit.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
|
||||
@ -51,7 +86,7 @@ StatusModal {
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.padding
|
||||
text: qsTr("%1 would like to verify your identity. Answer the question to prove your identity to %2")
|
||||
.arg(root.senderDisplayName).arg(root.senderDisplayName)
|
||||
.arg(d.senderDisplayName).arg(d.senderDisplayName)
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
@ -62,19 +97,19 @@ StatusModal {
|
||||
width: parent.width
|
||||
isMessage: true
|
||||
shouldRepeatHeader: true
|
||||
messageTimestamp: root.messageTimestamp
|
||||
senderId: root.senderPublicKey
|
||||
senderDisplayName: root.senderDisplayName
|
||||
senderIsEnsVerified: Utils.isEnsVerified(root.senderPublicKey)
|
||||
senderIcon: root.senderIcon
|
||||
messageText: root.challengeText
|
||||
messageTimestamp: d.messageTimestamp
|
||||
senderId: d.senderPublicKey
|
||||
senderDisplayName: d.senderDisplayName
|
||||
senderIsEnsVerified: d.senderPublicKey !== "" && Utils.isEnsVerified(d.senderPublicKey)
|
||||
senderIcon: d.senderIcon
|
||||
messageText: d.challengeText
|
||||
messageContentType: Constants.messageContentType.messageType
|
||||
placeholderMessage: true
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: verificationResponse
|
||||
visible: !responseText
|
||||
visible: !d.responseText
|
||||
anchors.top: verificationMessage.bottom
|
||||
anchors.topMargin: 5
|
||||
input.multiline: true
|
||||
@ -90,30 +125,30 @@ StatusModal {
|
||||
|
||||
MessageView {
|
||||
id: responseMessage
|
||||
visible: !!root.responseText
|
||||
visible: !!d.responseText
|
||||
anchors.top: verificationMessage.bottom
|
||||
width: parent.width
|
||||
isMessage: true
|
||||
shouldRepeatHeader: true
|
||||
messageTimestamp: root.responseTimestamp
|
||||
messageTimestamp: d.responseTimestamp
|
||||
senderId: userProfile.pubKey
|
||||
senderDisplayName: userProfile.displayName
|
||||
senderIsEnsVerified: !!userProfile.preferredName
|
||||
senderIcon: userProfile.icon
|
||||
messageText: root.responseText
|
||||
messageText: d.responseText
|
||||
messageContentType: Constants.messageContentType.messageType
|
||||
placeholderMessage: true
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: responseSent
|
||||
visible: !!root.responseText
|
||||
visible: !!d.responseText
|
||||
width: parent.width
|
||||
color: Theme.palette.baseColor1
|
||||
wrapMode: Text.WordWrap
|
||||
anchors.top: responseMessage.bottom
|
||||
anchors.topMargin: 58
|
||||
text: qsTr("Your answer has been sent to %1.").arg(root.senderDisplayName)
|
||||
text: qsTr("Your answer has been sent to %1.").arg(d.senderDisplayName)
|
||||
font.pixelSize: 13
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
@ -121,32 +156,32 @@ StatusModal {
|
||||
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
visible: !root.responseText
|
||||
visible: !d.responseText
|
||||
text: qsTr("Refuse Verification")
|
||||
onClicked: {
|
||||
root.verificationRefused(root.senderPublicKey)
|
||||
root.verificationRefused(d.senderPublicKey)
|
||||
root.close();
|
||||
}
|
||||
},
|
||||
StatusButton {
|
||||
text: qsTr("Send Answer")
|
||||
visible: !root.responseText
|
||||
visible: !d.responseText
|
||||
enabled: verificationResponse.text !== ""
|
||||
onClicked: {
|
||||
root.responseSent(root.senderPublicKey, Utils.escapeHtml(verificationResponse.text))
|
||||
root.responseText = verificationResponse.text
|
||||
root.responseTimestamp = Date.now()
|
||||
root.responseSent(d.senderPublicKey, Utils.escapeHtml(verificationResponse.text))
|
||||
d.responseText = verificationResponse.text
|
||||
d.responseTimestamp = Date.now()
|
||||
}
|
||||
},
|
||||
StatusFlatButton {
|
||||
visible: root.responseText
|
||||
visible: d.responseText
|
||||
text: qsTr("Change answer")
|
||||
onClicked: {
|
||||
root.responseText = ""
|
||||
d.responseText = ""
|
||||
}
|
||||
},
|
||||
StatusButton {
|
||||
visible: root.responseText
|
||||
visible: d.responseText
|
||||
text: qsTr("Close")
|
||||
onClicked: root.close()
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ Pane {
|
||||
outgoingVerificationStatus !== Constants.verificationStatus.unverified &&
|
||||
outgoingVerificationStatus !== Constants.verificationStatus.verified &&
|
||||
outgoingVerificationStatus !== Constants.verificationStatus.trusted
|
||||
readonly property bool isVerificationRequestReceived: d.isCurrentUser ? false : root.contactsStore.hasReceivedVerificationRequestFrom(root.publicKey)
|
||||
readonly property bool isVerificationRequestReceived: incomingVerificationStatus === Constants.verificationStatus.verifying
|
||||
|
||||
readonly property bool isTrusted: outgoingVerificationStatus === Constants.verificationStatus.trusted ||
|
||||
incomingVerificationStatus === Constants.verificationStatus.trusted
|
||||
|
@ -79,11 +79,11 @@ StatusMenu {
|
||||
return !root.isMe && root.selectedUserPublicKey !== "" &&
|
||||
root.store.contactsStore.hasPendingContactRequest(root.selectedUserPublicKey);
|
||||
}
|
||||
readonly property bool hasReceivedVerificationRequestFrom: {
|
||||
readonly property bool hasActiveReceivedVerificationRequestFrom: {
|
||||
if (!root.selectedUserPublicKey || root.isMe || !root.isContact) {
|
||||
return false
|
||||
}
|
||||
return root.store.contactsStore.hasReceivedVerificationRequestFrom(root.selectedUserPublicKey)
|
||||
return contactDetails.incomingVerificationStatus === Constants.verificationStatus.verifying
|
||||
}
|
||||
readonly property bool isVerificationRequestSent: {
|
||||
if (!root.selectedUserPublicKey || root.isMe || !root.isContact) {
|
||||
@ -254,7 +254,7 @@ StatusMenu {
|
||||
enabled: root.isProfile && !root.isMe && root.isContact
|
||||
&& !root.isBlockedContact
|
||||
&& root.outgoingVerificationStatus === Constants.verificationStatus.unverified
|
||||
&& !root.hasReceivedVerificationRequestFrom
|
||||
&& !root.hasActiveReceivedVerificationRequestFrom
|
||||
onTriggered: {
|
||||
Global.openSendIDRequestPopup(root.selectedUserPublicKey, null)
|
||||
root.close()
|
||||
@ -269,10 +269,10 @@ StatusMenu {
|
||||
icon.name: "checkmark-circle"
|
||||
enabled: root.isProfile && !root.isMe && root.isContact
|
||||
&& !root.isBlockedContact && !root.isTrusted
|
||||
&& (root.hasReceivedVerificationRequestFrom
|
||||
&& (root.hasActiveReceivedVerificationRequestFrom
|
||||
|| root.isVerificationRequestSent)
|
||||
onTriggered: {
|
||||
if (hasReceivedVerificationRequestFrom) {
|
||||
if (hasActiveReceivedVerificationRequestFrom) {
|
||||
Global.openIncomingIDRequestPopup(root.selectedUserPublicKey, null)
|
||||
} else if (root.isVerificationRequestSent) {
|
||||
Global.openOutgoingIDRequestPopup(root.selectedUserPublicKey, null)
|
||||
|
Loading…
x
Reference in New Issue
Block a user