mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-06-03 21:21:46 +00:00
directory bot: use short links, command /link to upgrade group link (#6130)
* directory bot: use short links, command /link to upgrade group link * test * enable all tests * update comparison for scenario when only link changed * use DB IDs when listing groups registered by admins
This commit is contained in:
@@ -124,13 +124,13 @@ data DirectoryCmdTag (r :: DirectoryRole) where
|
||||
DCDeleteGroup_ :: DirectoryCmdTag 'DRUser
|
||||
DCMemberRole_ :: DirectoryCmdTag 'DRUser
|
||||
DCGroupFilter_ :: DirectoryCmdTag 'DRUser
|
||||
DCShowUpgradeGroupLink_ :: DirectoryCmdTag 'DRUser
|
||||
DCApproveGroup_ :: DirectoryCmdTag 'DRAdmin
|
||||
DCRejectGroup_ :: DirectoryCmdTag 'DRAdmin
|
||||
DCSuspendGroup_ :: DirectoryCmdTag 'DRAdmin
|
||||
DCResumeGroup_ :: DirectoryCmdTag 'DRAdmin
|
||||
DCListLastGroups_ :: DirectoryCmdTag 'DRAdmin
|
||||
DCListPendingGroups_ :: DirectoryCmdTag 'DRAdmin
|
||||
DCShowGroupLink_ :: DirectoryCmdTag 'DRAdmin
|
||||
DCSendToGroupOwner_ :: DirectoryCmdTag 'DRAdmin
|
||||
DCInviteOwnerToGroup_ :: DirectoryCmdTag 'DRAdmin
|
||||
-- DCAddBlockedWord_ :: DirectoryCmdTag 'DRAdmin
|
||||
@@ -156,13 +156,13 @@ data DirectoryCmd (r :: DirectoryRole) where
|
||||
DCDeleteGroup :: UserGroupRegId -> GroupName -> DirectoryCmd 'DRUser
|
||||
DCMemberRole :: UserGroupRegId -> Maybe GroupName -> Maybe GroupMemberRole -> DirectoryCmd 'DRUser
|
||||
DCGroupFilter :: UserGroupRegId -> Maybe GroupName -> Maybe DirectoryMemberAcceptance -> DirectoryCmd 'DRUser
|
||||
DCShowUpgradeGroupLink :: GroupId -> Maybe GroupName -> DirectoryCmd 'DRUser
|
||||
DCApproveGroup :: {groupId :: GroupId, displayName :: GroupName, groupApprovalId :: GroupApprovalId} -> DirectoryCmd 'DRAdmin
|
||||
DCRejectGroup :: GroupId -> GroupName -> DirectoryCmd 'DRAdmin
|
||||
DCSuspendGroup :: GroupId -> GroupName -> DirectoryCmd 'DRAdmin
|
||||
DCResumeGroup :: GroupId -> GroupName -> DirectoryCmd 'DRAdmin
|
||||
DCListLastGroups :: Int -> DirectoryCmd 'DRAdmin
|
||||
DCListPendingGroups :: Int -> DirectoryCmd 'DRAdmin
|
||||
DCShowGroupLink :: GroupId -> GroupName -> DirectoryCmd 'DRAdmin
|
||||
DCSendToGroupOwner :: GroupId -> GroupName -> Text -> DirectoryCmd 'DRAdmin
|
||||
DCInviteOwnerToGroup :: GroupId -> GroupName -> DirectoryCmd 'DRAdmin
|
||||
-- DCAddBlockedWord :: Text -> DirectoryCmd 'DRAdmin
|
||||
@@ -200,13 +200,13 @@ directoryCmdP =
|
||||
"delete" -> u DCDeleteGroup_
|
||||
"role" -> u DCMemberRole_
|
||||
"filter" -> u DCGroupFilter_
|
||||
"link" -> u DCShowUpgradeGroupLink_
|
||||
"approve" -> au DCApproveGroup_
|
||||
"reject" -> au DCRejectGroup_
|
||||
"suspend" -> au DCSuspendGroup_
|
||||
"resume" -> au DCResumeGroup_
|
||||
"last" -> au DCListLastGroups_
|
||||
"pending" -> au DCListPendingGroups_
|
||||
"link" -> au DCShowGroupLink_
|
||||
"owner" -> au DCSendToGroupOwner_
|
||||
"invite" -> au DCInviteOwnerToGroup_
|
||||
-- "block_word" -> au DCAddBlockedWord_
|
||||
@@ -266,6 +266,7 @@ directoryCmdP =
|
||||
"=all" $> PCAll
|
||||
<|> ("=noimage" <|> "=no_image" <|> "=no-image") $> PCNoImage
|
||||
<|> pure PCAll
|
||||
DCShowUpgradeGroupLink_ -> gc_ DCShowUpgradeGroupLink
|
||||
DCApproveGroup_ -> do
|
||||
(groupId, displayName) <- gc (,)
|
||||
groupApprovalId <- A.space *> A.decimal
|
||||
@@ -275,7 +276,6 @@ directoryCmdP =
|
||||
DCResumeGroup_ -> gc DCResumeGroup
|
||||
DCListLastGroups_ -> DCListLastGroups <$> (A.space *> A.decimal <|> pure 10)
|
||||
DCListPendingGroups_ -> DCListPendingGroups <$> (A.space *> A.decimal <|> pure 10)
|
||||
DCShowGroupLink_ -> gc DCShowGroupLink
|
||||
DCSendToGroupOwner_ -> do
|
||||
(groupId, displayName) <- gc (,)
|
||||
msg <- A.space *> A.takeText
|
||||
@@ -299,17 +299,17 @@ directoryCmdTag = \case
|
||||
DCRecentGroups -> "new"
|
||||
DCSubmitGroup _ -> "submit"
|
||||
DCConfirmDuplicateGroup {} -> "confirm"
|
||||
DCListUserGroups -> "list"
|
||||
DCListUserGroups -> "list"
|
||||
DCDeleteGroup {} -> "delete"
|
||||
DCApproveGroup {} -> "approve"
|
||||
DCMemberRole {} -> "role"
|
||||
DCGroupFilter {} -> "filter"
|
||||
DCShowUpgradeGroupLink {} -> "link"
|
||||
DCRejectGroup {} -> "reject"
|
||||
DCSuspendGroup {} -> "suspend"
|
||||
DCResumeGroup {} -> "resume"
|
||||
DCListLastGroups _ -> "last"
|
||||
DCListPendingGroups _ -> "pending"
|
||||
DCShowGroupLink {} -> "link"
|
||||
DCSendToGroupOwner {} -> "owner"
|
||||
DCInviteOwnerToGroup {} -> "invite"
|
||||
-- DCAddBlockedWord _ -> "block_word"
|
||||
|
||||
@@ -29,7 +29,7 @@ import Control.Monad.IO.Class
|
||||
import Data.List (find, intercalate)
|
||||
import Data.List.NonEmpty (NonEmpty (..))
|
||||
import qualified Data.Map.Strict as M
|
||||
import Data.Maybe (fromMaybe, isJust, maybeToList)
|
||||
import Data.Maybe (fromMaybe, isJust, isNothing, maybeToList)
|
||||
import Data.Set (Set)
|
||||
import qualified Data.Set as S
|
||||
import Data.Text (Text)
|
||||
@@ -72,7 +72,12 @@ import Simplex.Messaging.Util (safeDecodeUtf8, tshow, ($>>=), (<$$>))
|
||||
import System.Directory (getAppUserDataDirectory)
|
||||
import System.Process (readProcess)
|
||||
|
||||
data GroupProfileUpdate = GPNoServiceLink | GPServiceLinkAdded | GPServiceLinkRemoved | GPHasServiceLink | GPServiceLinkError
|
||||
data GroupProfileUpdate
|
||||
= GPNoServiceLink
|
||||
| GPServiceLinkAdded {linkNow :: Text}
|
||||
| GPServiceLinkRemoved
|
||||
| GPHasServiceLink {linkBefore :: Text, linkNow :: Text}
|
||||
| GPServiceLinkError
|
||||
|
||||
data DuplicateGroup
|
||||
= DGUnique -- display name or full name is unique
|
||||
@@ -223,6 +228,7 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
SDRSuperUser -> deSuperUserCommand ct ciId cmd
|
||||
DELogChatResponse r -> logInfo r
|
||||
where
|
||||
groupLinkText (CCLink cReq sLnk_) = maybe (strEncodeTxt $ simplexChatContact cReq) strEncodeTxt sLnk_
|
||||
withAdminUsers action = void . forkIO $ do
|
||||
forM_ superUsers $ \KnownContact {contactId} -> action contactId
|
||||
forM_ adminUsers $ \KnownContact {contactId} -> action contactId
|
||||
@@ -354,14 +360,14 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
let GroupInfo {groupId, groupProfile = GroupProfile {displayName}} = g
|
||||
notifyOwner gr $ "Joined the group " <> displayName <> ", creating the link…"
|
||||
sendChatCmd cc (APICreateGroupLink groupId GRMember) >>= \case
|
||||
Right CRGroupLinkCreated {groupLink = GroupLink {connLinkContact = CCLink gLink _}} -> do
|
||||
Right CRGroupLinkCreated {groupLink = GroupLink {connLinkContact = gLink}} -> do
|
||||
setGroupStatus st gr GRSPendingUpdate
|
||||
notifyOwner
|
||||
gr
|
||||
"Created the public link to join the group via this directory service that is always online.\n\n\
|
||||
\Please add it to the group welcome message.\n\
|
||||
\For example, add:"
|
||||
notifyOwner gr $ "Link to join the group " <> displayName <> ": " <> strEncodeTxt (simplexChatContact gLink)
|
||||
notifyOwner gr $ "Link to join the group " <> displayName <> ": " <> groupLinkText gLink
|
||||
Left (ChatError e) -> case e of
|
||||
CEGroupUserRole {} -> notifyOwner gr "Failed creating group link, as service is no longer an admin."
|
||||
CEGroupMemberUserRemoved -> notifyOwner gr "Failed creating group link, as service is removed from the group."
|
||||
@@ -386,20 +392,20 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
groupProfileUpdate >>= \case
|
||||
GPNoServiceLink ->
|
||||
notifyOwner gr $ "The profile updated for " <> userGroupRef <> byMember <> ", but the group link is not added to the welcome message."
|
||||
GPServiceLinkAdded -> groupLinkAdded gr byMember
|
||||
GPServiceLinkAdded _ -> groupLinkAdded gr byMember
|
||||
GPServiceLinkRemoved ->
|
||||
notifyOwner gr $
|
||||
"The group link of " <> userGroupRef <> " is removed from the welcome message" <> byMember <> ", please add it."
|
||||
GPHasServiceLink -> groupLinkAdded gr byMember
|
||||
GPHasServiceLink {} -> groupLinkAdded gr byMember
|
||||
GPServiceLinkError -> do
|
||||
notifyOwner gr $
|
||||
("Error: " <> serviceName <> " has no group link for " <> userGroupRef)
|
||||
<> " after profile was updated" <> byMember <> ". Please report the error to the developers."
|
||||
logError $ "Error: no group link for " <> userGroupRef
|
||||
GRSPendingApproval n -> processProfileChange gr byMember $ n + 1
|
||||
GRSActive -> processProfileChange gr byMember 1
|
||||
GRSSuspended -> processProfileChange gr byMember 1
|
||||
GRSSuspendedBadRoles -> processProfileChange gr byMember 1
|
||||
GRSPendingApproval n -> processProfileChange gr byMember False $ n + 1
|
||||
GRSActive -> processProfileChange gr byMember True 1
|
||||
GRSSuspended -> processProfileChange gr byMember False 1
|
||||
GRSSuspendedBadRoles -> processProfileChange gr byMember False 1
|
||||
GRSRemoved -> pure ()
|
||||
where
|
||||
GroupInfo {groupId, groupProfile = p} = fromGroup
|
||||
@@ -407,7 +413,7 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
sameProfile
|
||||
GroupProfile {displayName = n, fullName = fn, shortDescr = sd, image = i, description = d}
|
||||
GroupProfile {displayName = n', fullName = fn', shortDescr = sd', image = i', description = d'} =
|
||||
n == n' && fn == fn' && i == i' && sd == sd' && d == d'
|
||||
n == n' && fn == fn' && i == i' && sd == sd' && (T.words <$> d) == (T.words <$> d')
|
||||
groupLinkAdded gr byMember = do
|
||||
getDuplicateGroup toGroup >>= \case
|
||||
Nothing -> notifyOwner gr "Error: getDuplicateGroup. Please notify the developers."
|
||||
@@ -419,53 +425,65 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
("Thank you! The group link for " <> userGroupReference gr toGroup <> " is added to the welcome message" <> byMember)
|
||||
<> ".\nYou will be notified once the group is added to the directory - it may take up to 48 hours."
|
||||
checkRolesSendToApprove gr gaId
|
||||
processProfileChange gr byMember n' = do
|
||||
setGroupStatus st gr GRSPendingUpdate
|
||||
processProfileChange gr byMember isActive n' = do
|
||||
let userGroupRef = userGroupReference gr toGroup
|
||||
groupRef = groupReference toGroup
|
||||
groupProfileUpdate >>= \case
|
||||
GPNoServiceLink -> do
|
||||
setGroupStatus st gr GRSPendingUpdate
|
||||
notifyOwner gr $
|
||||
("The group profile is updated for " <> userGroupRef <> byMember <> ", but no link is added to the welcome message.\n\n")
|
||||
<> "The group will remain hidden from the directory until the group link is added and the group is re-approved."
|
||||
GPServiceLinkRemoved -> do
|
||||
setGroupStatus st gr GRSPendingUpdate
|
||||
notifyOwner gr $
|
||||
("The group link for " <> userGroupRef <> " is removed from the welcome message" <> byMember)
|
||||
<> ".\n\nThe group is hidden from the directory until the group link is added and the group is re-approved."
|
||||
notifyAdminUsers $ "The group link is removed from " <> groupRef <> ", de-listed."
|
||||
GPServiceLinkAdded -> do
|
||||
GPServiceLinkAdded _ -> do
|
||||
setGroupStatus st gr $ GRSPendingApproval n'
|
||||
notifyOwner gr $
|
||||
("The group link is added to " <> userGroupRef <> byMember)
|
||||
<> "!\nIt is hidden from the directory until approved."
|
||||
notifyAdminUsers $ "The group link is added to " <> groupRef <> byMember <> "."
|
||||
checkRolesSendToApprove gr n'
|
||||
GPHasServiceLink -> do
|
||||
setGroupStatus st gr $ GRSPendingApproval n'
|
||||
notifyOwner gr $
|
||||
("The group " <> userGroupRef <> " is updated" <> byMember)
|
||||
<> "!\nIt is hidden from the directory until approved."
|
||||
notifyAdminUsers $ "The group " <> groupRef <> " is updated" <> byMember <> "."
|
||||
checkRolesSendToApprove gr n'
|
||||
GPHasServiceLink {linkBefore, linkNow}
|
||||
| isActive && onlyLinkChanged p p' -> do
|
||||
notifyOwner gr $
|
||||
("The group " <> userGroupRef <> " is updated" <> byMember)
|
||||
<> "!\nThe group is listed in directory."
|
||||
notifyAdminUsers $ "The group " <> groupRef <> " is updated" <> byMember <> " - only link or whitespace changes.\nThe group remained listed in directory."
|
||||
| otherwise -> do
|
||||
setGroupStatus st gr $ GRSPendingApproval n'
|
||||
notifyOwner gr $
|
||||
("The group " <> userGroupRef <> " is updated" <> byMember)
|
||||
<> "!\nIt is hidden from the directory until approved."
|
||||
notifyAdminUsers $ "The group " <> groupRef <> " is updated" <> byMember <> "."
|
||||
checkRolesSendToApprove gr n'
|
||||
where
|
||||
onlyLinkChanged
|
||||
GroupProfile {displayName = dn, fullName = fn, shortDescr = sd, image = i, description = d}
|
||||
GroupProfile {displayName = dn', fullName = fn', shortDescr = sd', image = i', description = d'} =
|
||||
dn == dn' && fn == fn' && i == i' && sd == sd' && (T.words . T.replace linkBefore "" <$> d) == (T.words . T.replace linkNow "" <$> d')
|
||||
GPServiceLinkError -> logError $ "Error: no group link for " <> groupRef <> " pending approval."
|
||||
groupProfileUpdate = profileUpdate <$> sendChatCmd cc (APIGetGroupLink groupId)
|
||||
where
|
||||
profileUpdate = \case
|
||||
Right CRGroupLink {groupLink = GroupLink {connLinkContact = CCLink cr sl_}} ->
|
||||
let hadLinkBefore = profileHasGroupLink fromGroup
|
||||
hasLinkNow = profileHasGroupLink toGroup
|
||||
profileHasGroupLink GroupInfo {groupProfile = gp} =
|
||||
maybe False (any ftHasLink) $ parseMaybeMarkdownList =<< description gp
|
||||
let linkBefore_ = profileGroupLinkText fromGroup
|
||||
linkNow_ = profileGroupLinkText toGroup
|
||||
profileGroupLinkText GroupInfo {groupProfile = gp} =
|
||||
maybe Nothing (fmap (\(FormattedText _ t) -> t) . find ftHasLink) $ parseMaybeMarkdownList =<< description gp
|
||||
ftHasLink = \case
|
||||
FormattedText (Just SimplexLink {simplexUri = ACL SCMContact cLink}) _ -> case cLink of
|
||||
CLFull cr' -> sameConnReqContact cr' cr
|
||||
CLShort sl' -> maybe False (sameShortLinkContact sl') sl_
|
||||
_ -> False
|
||||
in if
|
||||
| hadLinkBefore && hasLinkNow -> GPHasServiceLink
|
||||
| hadLinkBefore -> GPServiceLinkRemoved
|
||||
| hasLinkNow -> GPServiceLinkAdded
|
||||
| otherwise -> GPNoServiceLink
|
||||
in case (linkBefore_, linkNow_) of
|
||||
(Just linkBefore, Just linkNow) -> GPHasServiceLink linkBefore linkNow
|
||||
(Just _, Nothing) -> GPServiceLinkRemoved
|
||||
(Nothing, Just linkNow) -> GPServiceLinkAdded linkNow
|
||||
(Nothing, Nothing) -> GPNoServiceLink
|
||||
_ -> GPServiceLinkError
|
||||
checkRolesSendToApprove gr gaId = do
|
||||
(badRolesMsg <$$> getGroupRolesStatus toGroup gr) >>= \case
|
||||
@@ -706,8 +724,9 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
DCListUserGroups ->
|
||||
getUserGroupRegs st (contactId' ct) >>= \grs -> do
|
||||
sendReply $ tshow (length grs) <> " registered group(s)"
|
||||
void . forkIO $ forM_ (reverse grs) $ \gr@GroupReg {userGroupRegId} ->
|
||||
sendGroupInfo ct gr userGroupRegId Nothing
|
||||
void . forkIO $ forM_ (reverse grs) $ \gr@GroupReg {dbGroupId, userGroupRegId} ->
|
||||
let useGroupId = if isAdmin then dbGroupId else userGroupRegId
|
||||
in sendGroupInfo ct gr useGroupId Nothing
|
||||
DCDeleteGroup gId gName ->
|
||||
(if isAdmin then withGroupAndReg sendReply else withUserGroupReg) gId gName $ \GroupInfo {groupProfile = GroupProfile {displayName}} gr -> do
|
||||
delGroupReg st gr
|
||||
@@ -718,7 +737,7 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
case mRole_ of
|
||||
Nothing ->
|
||||
getGroupLink' cc user g >>= \case
|
||||
Just GroupLink {connLinkContact = CCLink gLink _, acceptMemberRole} -> do
|
||||
Just GroupLink {connLinkContact = gLink, acceptMemberRole} -> do
|
||||
let anotherRole = case acceptMemberRole of GRObserver -> GRMember; _ -> GRObserver
|
||||
sendReply $
|
||||
initialRole n acceptMemberRole
|
||||
@@ -731,7 +750,7 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
Nothing -> sendReply $ "Error: the initial member role for the group " <> n <> " was NOT upgated."
|
||||
where
|
||||
initialRole n mRole = "The initial member role for the group " <> n <> " is set to *" <> strEncodeTxt mRole <> "*\n"
|
||||
onlyViaLink gLink = "*Please note*: it applies only to members joining via this link: " <> strEncodeTxt (simplexChatContact gLink)
|
||||
onlyViaLink gLink = "*Please note*: it applies only to members joining via this link: " <> groupLinkText gLink
|
||||
DCGroupFilter gId gName_ acceptance_ ->
|
||||
(if isAdmin then withGroupAndReg_ sendReply else withUserGroupReg_) gId gName_ $ \g _gr -> do
|
||||
let GroupInfo {groupProfile = GroupProfile {displayName = n}} = g
|
||||
@@ -760,6 +779,56 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
Nothing -> "_disabled_"
|
||||
Just PCAll -> "_enabled_"
|
||||
Just PCNoImage -> "_enabled for profiles without image_"
|
||||
DCShowUpgradeGroupLink gId gName_ ->
|
||||
(if isAdmin then withGroupAndReg_ sendReply else withUserGroupReg_) gId gName_ $ \GroupInfo {localDisplayName = gName} _ -> do
|
||||
let groupRef = groupReference' gId gName
|
||||
withGroupLinkResult groupRef (sendChatCmd cc $ APIGetGroupLink gId) $
|
||||
\GroupLink {connLinkContact = gLink@(CCLink _ sLnk_), acceptMemberRole, shortLinkDataSet, shortLinkLargeDataSet = BoolDef slLargeDataSet} -> do
|
||||
let shouldBeUpgraded = isNothing sLnk_ || not shortLinkDataSet || not slLargeDataSet
|
||||
sendReply $ T.unlines $
|
||||
[ "The link to join the group " <> groupRef <> ":",
|
||||
groupLinkText gLink,
|
||||
"New member role: " <> strEncodeTxt acceptMemberRole
|
||||
]
|
||||
<> ["The link is being upgraded..." | shouldBeUpgraded]
|
||||
when shouldBeUpgraded $ do
|
||||
withGroupLinkResult groupRef (sendChatCmd cc $ APIAddGroupShortLink gId) $
|
||||
\GroupLink {connLinkContact = CCLink _ sLnk_'} ->
|
||||
sendComposedMessage cc ct Nothing $ MCText $ T.unlines $
|
||||
case (sLnk_, sLnk_') of
|
||||
(Just _, Just _) -> ["The group link is upgraded for: " <> groupRef, "No changes to group needed."]
|
||||
(Nothing, Just sLnk) ->
|
||||
[ "Please replace the old link in welcome message of your group " <> groupRef <> " with this link:",
|
||||
strEncodeTxt sLnk,
|
||||
"",
|
||||
"If this is the only change, the group will remain listed in directory without re-approval."
|
||||
]
|
||||
(_, Nothing) ->
|
||||
["The short link is not created for " <> groupRef, "Please report it to the developers."]
|
||||
-- Left (ChatErrorStore (SEGroupLinkNotFound _)) ->
|
||||
-- sendReply $ "The group " <> groupRef <> " has no public link."
|
||||
-- Right r -> do
|
||||
-- ts <- getCurrentTime
|
||||
-- tz <- getCurrentTimeZone
|
||||
-- let resp = T.pack $ serializeChatResponse (Nothing, Just user) (config cc) ts tz Nothing r
|
||||
-- sendReply $ "Unexpected error:\n" <> resp
|
||||
-- Left e -> do
|
||||
-- let resp = T.pack $ serializeChatError True (config cc) e
|
||||
-- sendReply $ "Unexpected error:\n" <> resp
|
||||
where
|
||||
withGroupLinkResult groupRef a cb =
|
||||
a >>= \case
|
||||
Right CRGroupLink {groupLink} -> cb groupLink
|
||||
Left (ChatErrorStore (SEGroupLinkNotFound _)) ->
|
||||
sendReply $ "The group " <> groupRef <> " has no public link."
|
||||
Right r -> do
|
||||
ts <- getCurrentTime
|
||||
tz <- getCurrentTimeZone
|
||||
let resp = T.pack $ serializeChatResponse (Nothing, Just user) (config cc) ts tz Nothing r
|
||||
sendReply $ "Unexpected error:\n" <> resp
|
||||
Left e -> do
|
||||
let resp = T.pack $ serializeChatError True (config cc) e
|
||||
sendReply $ "Unexpected error:\n" <> resp
|
||||
DCUnknownCommand -> sendReply "Unknown command"
|
||||
DCCommandError tag -> sendReply $ "Command error: " <> tshow tag
|
||||
where
|
||||
@@ -894,26 +963,6 @@ directoryServiceEvent st opts@DirectoryOpts {adminUsers, superUsers, serviceName
|
||||
_ -> sendReply $ "The group " <> groupRef <> " is not suspended, can't be resumed."
|
||||
DCListLastGroups count -> listGroups count False
|
||||
DCListPendingGroups count -> listGroups count True
|
||||
DCShowGroupLink groupId gName -> do
|
||||
let groupRef = groupReference' groupId gName
|
||||
withGroupAndReg sendReply groupId gName $ \_ _ ->
|
||||
sendChatCmd cc (APIGetGroupLink groupId) >>= \case
|
||||
Right CRGroupLink {groupLink = GroupLink {connLinkContact = CCLink cReq _, acceptMemberRole}} ->
|
||||
sendReply $ T.unlines
|
||||
[ "The link to join the group " <> groupRef <> ":",
|
||||
strEncodeTxt $ simplexChatContact cReq,
|
||||
"New member role: " <> strEncodeTxt acceptMemberRole
|
||||
]
|
||||
Left (ChatErrorStore (SEGroupLinkNotFound _)) ->
|
||||
sendReply $ "The group " <> groupRef <> " has no public link."
|
||||
Right r -> do
|
||||
ts <- getCurrentTime
|
||||
tz <- getCurrentTimeZone
|
||||
let resp = T.pack $ serializeChatResponse (Nothing, Just user) (config cc) ts tz Nothing r
|
||||
sendReply $ "Unexpected error:\n" <> resp
|
||||
Left e -> do
|
||||
let resp = T.pack $ serializeChatError True (config cc) e
|
||||
sendReply $ "Unexpected error:\n" <> resp
|
||||
DCSendToGroupOwner groupId gName msg -> do
|
||||
let groupRef = groupReference' groupId gName
|
||||
withGroupAndReg sendReply groupId gName $ \_ gr@GroupReg {dbContactId} -> do
|
||||
@@ -1054,11 +1103,11 @@ getGroupLink' :: ChatController -> User -> GroupInfo -> IO (Maybe GroupLink)
|
||||
getGroupLink' cc user gInfo =
|
||||
withDB "getGroupLink" cc $ \db -> getGroupLink db user gInfo
|
||||
|
||||
setGroupLinkRole :: ChatController -> GroupInfo -> GroupMemberRole -> IO (Maybe ConnReqContact)
|
||||
setGroupLinkRole :: ChatController -> GroupInfo -> GroupMemberRole -> IO (Maybe CreatedLinkContact)
|
||||
setGroupLinkRole cc GroupInfo {groupId} mRole = resp <$> sendChatCmd cc (APIGroupLinkMemberRole groupId mRole)
|
||||
where
|
||||
resp = \case
|
||||
Right (CRGroupLink {groupLink = GroupLink {connLinkContact = CCLink gLink _sLnk}}) -> Just gLink
|
||||
Right (CRGroupLink {groupLink = GroupLink {connLinkContact}}) -> Just connLinkContact
|
||||
_ -> Nothing
|
||||
|
||||
unexpectedError :: Text -> Text
|
||||
|
||||
@@ -253,8 +253,39 @@ testSuspendResume ps =
|
||||
superUser #> "@SimpleX-Directory /link 1:privacy"
|
||||
superUser <# "SimpleX-Directory> > /link 1:privacy"
|
||||
superUser <## " The link to join the group ID 1 (privacy):"
|
||||
superUser <##. "https://simplex.chat/contact"
|
||||
superUser <##. "https://localhost/g#"
|
||||
superUser <## "New member role: member"
|
||||
-- get and change the link to the equivalent - should not ask to re-approve
|
||||
bob #> "@SimpleX-Directory /link 1"
|
||||
bob <# "SimpleX-Directory> > /link 1"
|
||||
bob <## " The link to join the group ID 1 (privacy):"
|
||||
gLink <- getTermLine bob
|
||||
gLink `shouldStartWith` "https://localhost/g#"
|
||||
bob <## "New member role: member"
|
||||
bob ##> "/show welcome #privacy"
|
||||
bob <## "Welcome message:"
|
||||
bob <## ("Link to join the group privacy: " <> gLink)
|
||||
bob ##> ("/set welcome #privacy Link to join the group privacy: " <> gLink <> "?same_link=true")
|
||||
bob <## "welcome message changed to:"
|
||||
bob <## ("Link to join the group privacy: " <> gLink <> "?same_link=true")
|
||||
bob <# "SimpleX-Directory> The group ID 1 (privacy) is updated!"
|
||||
bob <## "The group is listed in directory."
|
||||
superUser <# "SimpleX-Directory> The group ID 1 (privacy) is updated - only link or whitespace changes."
|
||||
superUser <## "The group remained listed in directory."
|
||||
-- upgrade link
|
||||
-- make it upgradeable first
|
||||
superUser #> "@SimpleX-Directory /x /sql chat UPDATE user_contact_links SET short_link_data_set = 0"
|
||||
superUser <# "SimpleX-Directory> > /x /sql chat UPDATE user_contact_links SET short_link_data_set = 0"
|
||||
superUser <## ""
|
||||
bob #> "@SimpleX-Directory /link 1"
|
||||
bob <# "SimpleX-Directory> > /link 1"
|
||||
bob <## " The link to join the group ID 1 (privacy):"
|
||||
bob <##. "https://localhost/g#"
|
||||
bob <## "New member role: member"
|
||||
bob <## "The link is being upgraded..."
|
||||
bob <# "SimpleX-Directory> The group link is upgraded for: ID 1 (privacy)"
|
||||
bob <## "No changes to group needed."
|
||||
-- send message to group owner
|
||||
superUser #> "@SimpleX-Directory /owner 1:privacy hello there"
|
||||
superUser <# "SimpleX-Directory> > /owner 1:privacy hello there"
|
||||
superUser <## " Forwarded to @bob, the owner of the group ID 1 (privacy)"
|
||||
@@ -324,7 +355,7 @@ testSetRole ps =
|
||||
cath <## "connection request sent!"
|
||||
cath <## "#privacy: joining the group..."
|
||||
cath <## "#privacy: you joined the group"
|
||||
cath <#. "#privacy SimpleX-Directory> Link to join the group privacy: https://simplex.chat/"
|
||||
cath <#. "#privacy SimpleX-Directory> Link to join the group privacy: https://localhost/g#"
|
||||
cath <## "#privacy: member bob (Bob) is connected"
|
||||
bob <## "#privacy: SimpleX-Directory added cath (Catherine) to the group (connecting...)"
|
||||
bob <## "#privacy: new member cath is connected"
|
||||
|
||||
Reference in New Issue
Block a user