diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift index 2c9f0fefef..2984c3a286 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift @@ -158,7 +158,7 @@ func ciMetaText( r = r + statusIconText(enc ? "lock" : "lock.open", resolved) space = textSpace } - if showSignature, meta.msgVerified.verified && signedFileVerified != false { + if showSignature, meta.msgVerified?.verified == true && signedFileVerified != false { appendSpace() r = r + colored(Text(Image(systemName: "checkmark.seal")), resolved) space = textSpace diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift index 3682c039bb..44284350dc 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift @@ -99,7 +99,7 @@ struct FramedItemView: View { .background { chatItemFrameColorMaybeImageOrVideo(chatItem, theme).modifier(ChatTailPadding()) } .onPreferenceChange(DetermineWidth.Key.self) { msgWidth = $0 } - if let (title, text) = chatItem.meta.itemStatus.statusInfo ?? chatItem.meta.msgVerified.sigMissingInfo { + if let (title, text) = chatItem.meta.itemStatus.statusInfo ?? chatItem.meta.msgVerified?.sigMissingInfo { v.simultaneousGesture(TapGesture().onEnded { AlertManager.shared.showAlert( Alert( diff --git a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift index 33a5bf641b..99de13451f 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift @@ -162,7 +162,7 @@ struct ChatItemInfoView: View { if let deleteAt = meta.itemTimed?.deleteAt { infoRow("Disappears at", localTimestamp(deleteAt)) } - if meta.msgVerified.verified { + if meta.msgVerified?.verified == true { let signedText: LocalizedStringKey = ci.chatDir.sent ? "Signed" : "Signed & verified" HStack { Label { @@ -528,7 +528,7 @@ struct ChatItemInfoView: View { if let deleteAt = meta.itemTimed?.deleteAt { shareText += [String.localizedStringWithFormat(NSLocalizedString("Disappears at: %@", comment: "copied message info"), localTimestamp(deleteAt))] } - if meta.msgVerified.verified { + if meta.msgVerified?.verified == true { shareText += [ci.chatDir.sent ? NSLocalizedString("Signed", comment: "copied message info") : NSLocalizedString("Signed & verified", comment: "copied message info")] diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index c377288566..8fed43089e 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -2796,7 +2796,6 @@ public enum MsgSigStatus: String, Decodable, Equatable, Hashable { public enum MsgVerified: Decodable, Equatable, Hashable { case signed(sigStatus: MsgSigStatus) case sigMissing - case unsigned public var verified: Bool { if case let .signed(sigStatus) = self { return sigStatus == .verified } @@ -3791,7 +3790,7 @@ public struct ChatItem: Identifiable, Decodable, Hashable { deletable: false, editable: false, showGroupAsSender: false, - msgVerified: .unsigned + msgVerified: nil ), content: .sndMsgContent(msgContent: .report(text: text, reason: reason)), quotedItem: CIQuote.getSample(item.id, item.meta.createdAt, item.text, chatDir: item.chatDir), @@ -3816,7 +3815,7 @@ public struct ChatItem: Identifiable, Decodable, Hashable { deletable: false, editable: false, showGroupAsSender: false, - msgVerified: .unsigned + msgVerified: nil ), content: .rcvDeleted(deleteMode: .cidmBroadcast), quotedItem: nil, @@ -3841,7 +3840,7 @@ public struct ChatItem: Identifiable, Decodable, Hashable { deletable: false, editable: false, showGroupAsSender: false, - msgVerified: .unsigned + msgVerified: nil ), content: .sndMsgContent(msgContent: .text("")), quotedItem: nil, @@ -3920,7 +3919,7 @@ public struct CIMeta: Decodable, Hashable { public var deletable: Bool public var editable: Bool public var showGroupAsSender: Bool - public var msgVerified: MsgVerified + public var msgVerified: MsgVerified? public var timestampText: Text { Text(formatTimestampMeta(itemTs)) } public var recent: Bool { updatedAt + 10 > .now } @@ -3947,7 +3946,7 @@ public struct CIMeta: Decodable, Hashable { deletable: deletable, editable: editable, showGroupAsSender: false, - msgVerified: .unsigned + msgVerified: nil ) } @@ -3966,7 +3965,7 @@ public struct CIMeta: Decodable, Hashable { deletable: false, editable: false, showGroupAsSender: false, - msgVerified: .unsigned + msgVerified: nil ) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 0e7725c82b..ca436ce2f5 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -2433,7 +2433,6 @@ enum class MsgSigStatus { sealed class MsgVerified { @Serializable @SerialName("signed") data class Signed(val sigStatus: MsgSigStatus): MsgVerified() @Serializable @SerialName("sigMissing") object SigMissing: MsgVerified() - @Serializable @SerialName("unsigned") object Unsigned: MsgVerified() val verified: Boolean get() = this is Signed && sigStatus == MsgSigStatus.Verified @@ -3577,7 +3576,7 @@ data class CIMeta ( val deletable: Boolean, val editable: Boolean, val showGroupAsSender: Boolean, - val msgVerified: MsgVerified = MsgVerified.Unsigned + val msgVerified: MsgVerified? = null ) { val timestampText: String get() = getTimestampText(itemTs, true) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt index 0c2978d622..0679edd4f9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt @@ -272,7 +272,7 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools if (deleteAt != null) { InfoRow(stringResource(MR.strings.info_row_disappears_at), localTimestamp(deleteAt)) } - if (ci.meta.msgVerified.verified) { + if (ci.meta.msgVerified?.verified == true) { val signedRes = if (sent) MR.strings.info_row_signed else MR.strings.info_row_signed_verified InfoRow(stringResource(signedRes), "", icon = painterResource(MR.images.ic_verified)) } else if (ci.meta.msgVerified is MsgVerified.SigMissing) { @@ -568,7 +568,7 @@ fun itemInfoShareText(chatModel: ChatModel, ci: ChatItem, chatItemInfo: ChatItem if (deleteAt != null) { shareText.add(String.format(generalGetString(MR.strings.share_text_disappears_at), localTimestamp(deleteAt))) } - if (ci.meta.msgVerified.verified) { + if (ci.meta.msgVerified?.verified == true) { shareText.add(generalGetString(if (sent) MR.strings.info_row_signed else MR.strings.info_row_signed_verified)) } else if (ci.meta.msgVerified is MsgVerified.SigMissing) { shareText.add(generalGetString(MR.strings.signature_missing_alert_title)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMetaView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMetaView.kt index c3b72b762b..92f89ccad9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMetaView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIMetaView.kt @@ -112,7 +112,7 @@ private fun CIMetaText( Spacer(Modifier.width(4.dp)) StatusIconText(painterResource(if (encrypted) MR.images.ic_lock else MR.images.ic_lock_open_right), color) } - if (showSignature && meta.msgVerified.verified && signedFileVerified != false) { + if (showSignature && meta.msgVerified?.verified == true && signedFileVerified != false) { Spacer(Modifier.width(4.dp)) StatusIconText(painterResource(MR.images.ic_verified), color) } else if (meta.msgVerified is MsgVerified.SigMissing) { @@ -182,7 +182,7 @@ fun reserveSpaceForMeta( res += iconSpace space = whiteSpace } - if ((showSignature && meta.msgVerified.verified && signedFileVerified != false) || meta.msgVerified is MsgVerified.SigMissing) { + if ((showSignature && meta.msgVerified?.verified == true && signedFileVerified != false) || meta.msgVerified is MsgVerified.SigMissing) { appendSpace() res += iconSpace space = whiteSpace diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt index 348a97470a..bab6576646 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/ChatItemView.kt @@ -127,7 +127,7 @@ fun ChatItemView( modifier = (if (fillMaxWidth) Modifier.fillMaxWidth() else Modifier), contentAlignment = alignment, ) { - val info = cItem.meta.itemStatus.statusInto ?: cItem.meta.msgVerified.sigMissingInfo + val info = cItem.meta.itemStatus.statusInto ?: cItem.meta.msgVerified?.sigMissingInfo val onClick = if (info != null) { { AlertManager.shared.showAlertMsg( diff --git a/bots/api/TYPES.md b/bots/api/TYPES.md index 3984eb3a5e..8fdc60145a 100644 --- a/bots/api/TYPES.md +++ b/bots/api/TYPES.md @@ -874,7 +874,7 @@ Group: - editable: bool - forwardedByMember: int64? - showGroupAsSender: bool -- msgVerified: [MsgVerified](#msgverified) +- msgVerified: [MsgVerified](#msgverified)? - createdAt: UTCTime - updatedAt: UTCTime @@ -2969,9 +2969,6 @@ Signed: SigMissing: - type: "sigMissing" -Unsigned: -- type: "unsigned" - --- diff --git a/packages/simplex-chat-client/types/typescript/src/types.ts b/packages/simplex-chat-client/types/typescript/src/types.ts index d52d3fb5e6..51392900ef 100644 --- a/packages/simplex-chat-client/types/typescript/src/types.ts +++ b/packages/simplex-chat-client/types/typescript/src/types.ts @@ -842,7 +842,7 @@ export interface CIMeta { editable: boolean forwardedByMember?: number // int64 showGroupAsSender: boolean - msgVerified: MsgVerified + msgVerified?: MsgVerified createdAt: string // ISO-8601 timestamp updatedAt: string // ISO-8601 timestamp } @@ -3211,10 +3211,10 @@ export enum MsgSigStatus { SignedNoKey = "signedNoKey", } -export type MsgVerified = MsgVerified.Signed | MsgVerified.SigMissing | MsgVerified.Unsigned +export type MsgVerified = MsgVerified.Signed | MsgVerified.SigMissing export namespace MsgVerified { - export type Tag = "signed" | "sigMissing" | "unsigned" + export type Tag = "signed" | "sigMissing" interface Interface { type: Tag @@ -3228,10 +3228,6 @@ export namespace MsgVerified { export interface SigMissing extends Interface { type: "sigMissing" } - - export interface Unsigned extends Interface { - type: "unsigned" - } } export type NameErrorType = NameErrorType.NO_RESOLVER | NameErrorType.NOT_FOUND | NameErrorType.RESOLVER diff --git a/packages/simplex-chat-python/src/simplex_chat/types/_types.py b/packages/simplex-chat-python/src/simplex_chat/types/_types.py index 062ebd6902..3783420928 100644 --- a/packages/simplex-chat-python/src/simplex_chat/types/_types.py +++ b/packages/simplex-chat-python/src/simplex_chat/types/_types.py @@ -588,7 +588,7 @@ class CIMeta(TypedDict): editable: bool forwardedByMember: NotRequired[int] # int64 showGroupAsSender: bool - msgVerified: "MsgVerified" + msgVerified: NotRequired["MsgVerified"] createdAt: str # ISO-8601 timestamp updatedAt: str # ISO-8601 timestamp @@ -2253,12 +2253,9 @@ class MsgVerified_signed(TypedDict): class MsgVerified_sigMissing(TypedDict): type: Literal["sigMissing"] -class MsgVerified_unsigned(TypedDict): - type: Literal["unsigned"] +MsgVerified = MsgVerified_signed | MsgVerified_sigMissing -MsgVerified = MsgVerified_signed | MsgVerified_sigMissing | MsgVerified_unsigned - -MsgVerified_Tag = Literal["signed", "sigMissing", "unsigned"] +MsgVerified_Tag = Literal["signed", "sigMissing"] class NameErrorType_NO_RESOLVER(TypedDict): type: Literal["NO_RESOLVER"] diff --git a/src/Simplex/Chat/Library/Commands.hs b/src/Simplex/Chat/Library/Commands.hs index c664b64a5c..3e1bf4d47a 100644 --- a/src/Simplex/Chat/Library/Commands.hs +++ b/src/Simplex/Chat/Library/Commands.hs @@ -751,7 +751,7 @@ processChatCommand cxt nm = \case let msgScope = toMsgScope gInfo <$> chatScopeInfo mentions' = M.map (\CIMention {memberId} -> MsgMention {memberId}) ciMentions event = XMsgUpdate itemSharedMId mc mentions' (ttl' <$> itemTimed) (justTrue . (live &&) =<< itemLive) msgScope (Just showGroupAsSender) - reuseSign = case msgVerified of MVSigned _ -> True; _ -> False + reuseSign = case msgVerified of Just (MVSigned _) -> True; _ -> False SndMessage {msgId} <- sendGroupMessage user gInfo scope recipients reuseSign event ci' <- withFastStore' $ \db -> do currentTs <- liftIO getCurrentTime @@ -848,7 +848,7 @@ processChatCommand cxt nm = \case delEvent msgId = let evt = XMsgDel msgId Nothing (toMsgScope gInfo <$> chatScopeInfo) onlyHistory in (groupMsgSigning (onlyHistory || itemSigned) gInfo evt, evt) - itemSigned = case msgVerified of MVSigned _ -> True; _ -> False + itemSigned = case msgVerified of Just (MVSigned _) -> True; _ -> False APIDeleteMemberChatItem gId itemIds -> withUser $ \user -> withGroupLock "deleteChatItem" gId $ do (gInfo, items) <- getCommandGroupChatItems user gId itemIds -- TODO [knocking] check scope is Nothing for all items? (prohibit moderation in support chats?) diff --git a/src/Simplex/Chat/Library/Internal.hs b/src/Simplex/Chat/Library/Internal.hs index bc80940b00..9c9e794ff8 100644 --- a/src/Simplex/Chat/Library/Internal.hs +++ b/src/Simplex/Chat/Library/Internal.hs @@ -2769,13 +2769,13 @@ saveRcvChatItem' user cd msg@RcvMessage {chatMsgEvent, msgSigned, forwardedByMem _ -> Nothing -- TODO [mentions] optimize by avoiding unnecessary parsing -mkChatItem :: (ChatTypeI c, MsgDirectionI d) => ChatDirection c d -> ShowGroupAsSender -> ChatItemId -> CIContent d -> Maybe (CIFile d) -> Maybe (CIQuote c) -> Maybe SharedMsgId -> Maybe CIForwardedFrom -> Maybe CITimed -> Bool -> Bool -> ChatItemTs -> Maybe GroupMemberId -> MsgVerified -> UTCTime -> ChatItem c d +mkChatItem :: (ChatTypeI c, MsgDirectionI d) => ChatDirection c d -> ShowGroupAsSender -> ChatItemId -> CIContent d -> Maybe (CIFile d) -> Maybe (CIQuote c) -> Maybe SharedMsgId -> Maybe CIForwardedFrom -> Maybe CITimed -> Bool -> Bool -> ChatItemTs -> Maybe GroupMemberId -> Maybe MsgVerified -> UTCTime -> ChatItem c d mkChatItem cd showGroupAsSender ciId content file quotedItem sharedMsgId itemForwarded itemTimed live userMention itemTs forwardedByMember msgVerified currentTs = let ts@(_, ft_) = ciContentTexts content hasLink_ = ciContentHasLink content ft_ in mkChatItem_ cd showGroupAsSender ciId content ts file quotedItem sharedMsgId itemForwarded itemTimed live userMention hasLink_ itemTs forwardedByMember msgVerified currentTs -mkChatItem_ :: (ChatTypeI c, MsgDirectionI d) => ChatDirection c d -> ShowGroupAsSender -> ChatItemId -> CIContent d -> (Text, Maybe MarkdownList) -> Maybe (CIFile d) -> Maybe (CIQuote c) -> Maybe SharedMsgId -> Maybe CIForwardedFrom -> Maybe CITimed -> Bool -> Bool -> Bool -> ChatItemTs -> Maybe GroupMemberId -> MsgVerified -> UTCTime -> ChatItem c d +mkChatItem_ :: (ChatTypeI c, MsgDirectionI d) => ChatDirection c d -> ShowGroupAsSender -> ChatItemId -> CIContent d -> (Text, Maybe MarkdownList) -> Maybe (CIFile d) -> Maybe (CIQuote c) -> Maybe SharedMsgId -> Maybe CIForwardedFrom -> Maybe CITimed -> Bool -> Bool -> Bool -> ChatItemTs -> Maybe GroupMemberId -> Maybe MsgVerified -> UTCTime -> ChatItem c d mkChatItem_ cd showGroupAsSender ciId content (itemText, formattedText) file quotedItem sharedMsgId itemForwarded itemTimed live userMention hasLink_ itemTs forwardedByMember msgVerified currentTs = let itemStatus = ciCreateStatus content meta = mkCIMeta ciId content itemText itemStatus Nothing sharedMsgId itemForwarded Nothing False itemTimed (justTrue live) userMention hasLink_ currentTs itemTs forwardedByMember showGroupAsSender msgVerified currentTs currentTs @@ -3100,9 +3100,9 @@ createLocalChatItems user cd itemsData createdAt = do createItem :: DB.Connection -> (CIContent 'MDSnd, Maybe (CIFile 'MDSnd), Maybe CIForwardedFrom, (Text, Maybe MarkdownList)) -> IO (ChatItem 'CTLocal 'MDSnd) createItem db (content, ciFile, itemForwarded, ts@(_, ft_)) = do let hasLink_ = ciContentHasLink content ft_ - ciId <- createNewChatItem_ db user cd False Nothing Nothing content (Nothing, Nothing, Nothing, Nothing, Nothing) itemForwarded Nothing False False hasLink_ createdAt Nothing MVUnsigned createdAt + ciId <- createNewChatItem_ db user cd False Nothing Nothing content (Nothing, Nothing, Nothing, Nothing, Nothing) itemForwarded Nothing False False hasLink_ createdAt Nothing Nothing createdAt forM_ ciFile $ \CIFile {fileId} -> updateFileTransferChatItemId db fileId ciId createdAt - pure $ mkChatItem_ cd False ciId content ts ciFile Nothing Nothing itemForwarded Nothing False False hasLink_ createdAt Nothing MVUnsigned createdAt + pure $ mkChatItem_ cd False ciId content ts ciFile Nothing Nothing itemForwarded Nothing False False hasLink_ createdAt Nothing Nothing createdAt withUser' :: (User -> CM ChatResponse) -> CM ChatResponse withUser' action = diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index 85118ce2ca..822253bd55 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -2300,9 +2300,9 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage = where isSender m' = maybe False (\m -> sameMemberId (memberId' m) m') m_ -- a verified item requires a verified edit (fail-closed): unsigned is a forgery (bad-signature item); signed-but-no-key is unverifiable (drop with a log) - requireVerifiedEdit :: ChatDirection 'CTGroup 'MDRcv -> MsgVerified -> CM (Maybe DeliveryTaskContext) -> CM (Maybe DeliveryTaskContext) + requireVerifiedEdit :: ChatDirection 'CTGroup 'MDRcv -> Maybe MsgVerified -> CM (Maybe DeliveryTaskContext) -> CM (Maybe DeliveryTaskContext) requireVerifiedEdit cd itemVerified action - | itemVerified == MVSigned MSSVerified = + | itemVerified == Just (MVSigned MSSVerified) = case msgSigned of Just MSSVerified -> action Just MSSSignedNoKey -> logWarn "x.msg.update: unverified update of a signed item (no key to verify), dropped" $> Nothing @@ -2413,7 +2413,7 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage = -- a verified item requires a verified delete (fail-closed): unsigned is a forgery (bad-signature item); signed-but-no-key is unverifiable (drop with a log) requireVerifiedDelete :: CChatItem 'CTGroup -> CM (Maybe DeliveryTaskContext) -> CM (Maybe DeliveryTaskContext) requireVerifiedDelete cci@(CChatItem _ ChatItem {chatDir, meta = CIMeta {msgVerified = itemVerified}}) action - | itemVerified == MVSigned MSSVerified = + | itemVerified == Just (MVSigned MSSVerified) = case msgSigned of Just MSSVerified -> action Just MSSSignedNoKey -> logWarn "x.msg.del: unverified delete of a signed item (no key to verify), dropped" $> Nothing diff --git a/src/Simplex/Chat/Messages.hs b/src/Simplex/Chat/Messages.hs index ae0bbd0637..da9fec9053 100644 --- a/src/Simplex/Chat/Messages.hs +++ b/src/Simplex/Chat/Messages.hs @@ -523,7 +523,7 @@ data CIMeta (c :: ChatType) (d :: MsgDirection) = CIMeta editable :: Bool, forwardedByMember :: Maybe GroupMemberId, showGroupAsSender :: ShowGroupAsSender, - msgVerified :: MsgVerified, + msgVerified :: Maybe MsgVerified, createdAt :: UTCTime, updatedAt :: UTCTime } @@ -531,7 +531,7 @@ data CIMeta (c :: ChatType) (d :: MsgDirection) = CIMeta type ShowGroupAsSender = Bool -mkCIMeta :: forall c d. ChatTypeI c => ChatItemId -> CIContent d -> Text -> CIStatus d -> Maybe Bool -> Maybe SharedMsgId -> Maybe CIForwardedFrom -> Maybe (CIDeleted c) -> Bool -> Maybe CITimed -> Maybe Bool -> Bool -> Bool -> UTCTime -> ChatItemTs -> Maybe GroupMemberId -> Bool -> MsgVerified -> UTCTime -> UTCTime -> CIMeta c d +mkCIMeta :: forall c d. ChatTypeI c => ChatItemId -> CIContent d -> Text -> CIStatus d -> Maybe Bool -> Maybe SharedMsgId -> Maybe CIForwardedFrom -> Maybe (CIDeleted c) -> Bool -> Maybe CITimed -> Maybe Bool -> Bool -> Bool -> UTCTime -> ChatItemTs -> Maybe GroupMemberId -> Bool -> Maybe MsgVerified -> UTCTime -> UTCTime -> CIMeta c d mkCIMeta itemId itemContent itemText itemStatus sentViaProxy itemSharedMsgId itemForwarded itemDeleted itemEdited itemTimed itemLive userMention hasLink_ currentTs itemTs forwardedByMember showGroupAsSender msgVerified createdAt updatedAt = let deletable = deletable' itemContent itemDeleted itemTs nominalDay currentTs editable = deletable && isNothing itemForwarded @@ -567,7 +567,7 @@ dummyMeta itemId ts itemText = editable = False, forwardedByMember = Nothing, showGroupAsSender = False, - msgVerified = MVUnsigned, + msgVerified = Nothing, createdAt = ts, updatedAt = ts } diff --git a/src/Simplex/Chat/Store/Messages.hs b/src/Simplex/Chat/Store/Messages.hs index 3d0a92bd86..d9405866bb 100644 --- a/src/Simplex/Chat/Store/Messages.hs +++ b/src/Simplex/Chat/Store/Messages.hs @@ -581,14 +581,14 @@ createNewRcvChatItem db user chatDirection RcvMessage {msgId, chatMsgEvent, msgS CDChannelRcv GroupInfo {membership = GroupMember {memberId = userMemberId}} _ -> (Just $ Just userMemberId == memberId, memberId) -createNewChatItemNoMsg :: forall c d. MsgDirectionI d => DB.Connection -> User -> ChatDirection c d -> ShowGroupAsSender -> CIContent d -> Maybe SharedMsgId -> Bool -> MsgVerified -> UTCTime -> UTCTime -> IO ChatItemId +createNewChatItemNoMsg :: forall c d. MsgDirectionI d => DB.Connection -> User -> ChatDirection c d -> ShowGroupAsSender -> CIContent d -> Maybe SharedMsgId -> Bool -> Maybe MsgVerified -> UTCTime -> UTCTime -> IO ChatItemId createNewChatItemNoMsg db user chatDirection showGroupAsSender ciContent sharedMsgId_ hasLink msgVerified itemTs = createNewChatItem_ db user chatDirection showGroupAsSender Nothing sharedMsgId_ ciContent quoteRow Nothing Nothing False False hasLink itemTs Nothing msgVerified where quoteRow :: NewQuoteRow quoteRow = (Nothing, Nothing, Nothing, Nothing, Nothing) -createNewChatItem_ :: forall c d. MsgDirectionI d => DB.Connection -> User -> ChatDirection c d -> ShowGroupAsSender -> Maybe MessageId -> Maybe SharedMsgId -> CIContent d -> NewQuoteRow -> Maybe CIForwardedFrom -> Maybe CITimed -> Bool -> Bool -> Bool -> UTCTime -> Maybe GroupMemberId -> MsgVerified -> UTCTime -> IO ChatItemId +createNewChatItem_ :: forall c d. MsgDirectionI d => DB.Connection -> User -> ChatDirection c d -> ShowGroupAsSender -> Maybe MessageId -> Maybe SharedMsgId -> CIContent d -> NewQuoteRow -> Maybe CIForwardedFrom -> Maybe CITimed -> Bool -> Bool -> Bool -> UTCTime -> Maybe GroupMemberId -> Maybe MsgVerified -> UTCTime -> IO ChatItemId createNewChatItem_ db User {userId} chatDirection showGroupAsSender msgId_ sharedMsgId ciContent quoteRow itemForwarded timed live userMention hasLink itemTs forwardedByMember msgVerified createdAt = do DB.execute db @@ -610,7 +610,7 @@ createNewChatItem_ db User {userId} chatDirection showGroupAsSender msgId_ share forM_ msgId_ $ \msgId -> insertChatItemMessage_ db ciId msgId createdAt pure ciId where - itemRow :: (SMsgDirection d, UTCTime, CIContent d, Text, Text, CIStatus d, Maybe MsgContentTag, Maybe SharedMsgId, Maybe GroupMemberId, BoolInt) :. (UTCTime, UTCTime, Maybe BoolInt, BoolInt, BoolInt, BoolInt, BoolInt, MsgVerified) :. (Maybe Int, Maybe UTCTime) + itemRow :: (SMsgDirection d, UTCTime, CIContent d, Text, Text, CIStatus d, Maybe MsgContentTag, Maybe SharedMsgId, Maybe GroupMemberId, BoolInt) :. (UTCTime, UTCTime, Maybe BoolInt, BoolInt, BoolInt, BoolInt, BoolInt, Maybe MsgVerified) :. (Maybe Int, Maybe UTCTime) itemRow = (msgDirection @d, itemTs, ciContent, toCIContentTag ciContent, ciContentToText ciContent, ciCreateStatus ciContent, mcTag_, sharedMsgId, forwardedByMember, BI includeInHistory) :. (createdAt, createdAt, BI <$> justTrue live, BI userMention, BI hasLink, BI itemViewed, BI showGroupAsSender, msgVerified) :. ciTimedRow timed quoteRow' = let (a, b, c, d, e) = quoteRow in (a, b, c, BI <$> d, e) idsRow :: (Maybe ContactId, Maybe GroupId, Maybe GroupMemberId, Maybe NoteFolderId) @@ -1116,7 +1116,7 @@ toLocalChatItem currentTs ((itemId, itemTs, AMsgDirection msgDir, itemContentTex _ -> Just (CIDeleted @'CTLocal deletedTs) itemEdited' = maybe False unBI itemEdited itemForwarded = toCIForwardedFrom forwardedFromRow - in mkCIMeta itemId content itemText status (unBI <$> sentViaProxy) sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed (unBI <$> itemLive) userMention hasLink currentTs itemTs Nothing False (fromMaybe MVUnsigned msgSigned) createdAt updatedAt + in mkCIMeta itemId content itemText status (unBI <$> sentViaProxy) sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed (unBI <$> itemLive) userMention hasLink currentTs itemTs Nothing False msgSigned createdAt updatedAt ciTimed :: Maybe CITimed ciTimed = timedTTL >>= \ttl -> Just CITimed {ttl, deleteAt = timedDeleteAt} @@ -2323,7 +2323,7 @@ toDirectChatItem currentTs (((itemId, itemTs, AMsgDirection msgDir, itemContentT _ -> Just (CIDeleted @'CTDirect deletedTs) itemEdited' = maybe False unBI itemEdited itemForwarded = toCIForwardedFrom forwardedFromRow - in mkCIMeta itemId content itemText status (unBI <$> sentViaProxy) sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed (unBI <$> itemLive) userMention hasLink currentTs itemTs Nothing False (fromMaybe MVUnsigned msgSigned) createdAt updatedAt + in mkCIMeta itemId content itemText status (unBI <$> sentViaProxy) sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed (unBI <$> itemLive) userMention hasLink currentTs itemTs Nothing False msgSigned createdAt updatedAt ciTimed :: Maybe CITimed ciTimed = timedTTL >>= \ttl -> Just CITimed {ttl, deleteAt = timedDeleteAt} @@ -2412,7 +2412,7 @@ toGroupChatItem _ -> Just (maybe (CIDeleted @'CTGroup deletedTs) (CIModerated deletedTs) deletedByGroupMember_) itemEdited' = maybe False unBI itemEdited itemForwarded = toCIForwardedFrom forwardedFromRow - in mkCIMeta itemId content itemText status (unBI <$> sentViaProxy) sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed (unBI <$> itemLive) userMention hasLink currentTs itemTs forwardedByMember showGroupAsSender (fromMaybe MVUnsigned msgSigned) createdAt updatedAt + in mkCIMeta itemId content itemText status (unBI <$> sentViaProxy) sharedMsgId itemForwarded itemDeleted' itemEdited' ciTimed (unBI <$> itemLive) userMention hasLink currentTs itemTs forwardedByMember showGroupAsSender msgSigned createdAt updatedAt ciTimed :: Maybe CITimed ciTimed = timedTTL >>= \ttl -> Just CITimed {ttl, deleteAt = timedDeleteAt} diff --git a/src/Simplex/Chat/Types/Shared.hs b/src/Simplex/Chat/Types/Shared.hs index 2768ccd55b..d8917cc00c 100644 --- a/src/Simplex/Chat/Types/Shared.hs +++ b/src/Simplex/Chat/Types/Shared.hs @@ -149,30 +149,24 @@ instance FromField MsgSigStatus where fromField = fromTextField_ textDecode $(JQ.deriveJSON (enumJSON $ dropPrefix "MSS") ''MsgSigStatus) -data MsgVerified = MVSigned {sigStatus :: MsgSigStatus} | MVSigMissing | MVUnsigned +data MsgVerified = MVSigned {sigStatus :: MsgSigStatus} | MVSigMissing deriving (Eq, Show) instance TextEncoding MsgVerified where textEncode = \case MVSigned s -> textEncode s MVSigMissing -> "sig_missing" - MVUnsigned -> "unsigned" textDecode = \case "sig_missing" -> Just MVSigMissing - "unsigned" -> Just MVUnsigned s -> MVSigned <$> textDecode s instance ToField MsgVerified where toField = toField . textEncode instance FromField MsgVerified where fromField = fromTextField_ textDecode -$(JQ.deriveToJSON (sumTypeJSON $ dropPrefix "MV") ''MsgVerified) +$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "MV") ''MsgVerified) -instance FromJSON MsgVerified where - parseJSON = $(JQ.mkParseJSON (sumTypeJSON $ dropPrefix "MV") ''MsgVerified) - omittedField = Just MVUnsigned - -toMsgVerified :: Bool -> Maybe MsgSigStatus -> MsgVerified +toMsgVerified :: Bool -> Maybe MsgSigStatus -> Maybe MsgVerified toMsgVerified signRequired = \case - Just s -> MVSigned s - Nothing -> if signRequired then MVSigMissing else MVUnsigned + Just s -> Just (MVSigned s) + Nothing -> if signRequired then Just MVSigMissing else Nothing diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 3aba8b2281..432642259d 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -395,11 +395,11 @@ sigStatusStr = \case Just MSSSignedNoKey -> " (signed, no key to verify)" Nothing -> "" -msgVerifiedStr :: IsString a => MsgVerified -> a +msgVerifiedStr :: IsString a => Maybe MsgVerified -> a msgVerifiedStr = \case - MVSigned s -> sigStatusStr (Just s) - MVSigMissing -> " (signature missing)" - MVUnsigned -> "" + Just (MVSigned s) -> sigStatusStr (Just s) + Just MVSigMissing -> " (signature missing)" + Nothing -> "" signedStr :: IsString a => Bool -> a signedStr signed = if signed then " (signed)" else ""