@@ -122,6 +122,9 @@ module Simplex.Messaging.Agent.Protocol
122122 OwnerId ,
123123 ConnectionLink (.. ),
124124 AConnectionLink (.. ),
125+ SimplexNameInfo (.. ),
126+ SimplexTLD (.. ),
127+ SimplexNameType (.. ),
125128 ConnShortLink (.. ),
126129 AConnShortLink (.. ),
127130 CreatedConnLink (.. ),
@@ -138,6 +141,8 @@ module Simplex.Messaging.Agent.Protocol
138141 connReqUriP' ,
139142 simplexConnReqUri ,
140143 simplexShortLink ,
144+ fullDomainName ,
145+ shortNameInfoStr ,
141146 AgentErrorType (.. ),
142147 CommandErrorType (.. ),
143148 ConnectionErrorType (.. ),
@@ -189,10 +194,11 @@ import qualified Data.Aeson.TH as J
189194import qualified Data.Aeson.Types as JT
190195import Data.Attoparsec.ByteString.Char8 (Parser )
191196import qualified Data.Attoparsec.ByteString.Char8 as A
197+ import qualified Data.Attoparsec.Text as AT
192198import qualified Data.ByteString.Base64.URL as B64
193199import Data.ByteString.Char8 (ByteString )
194200import qualified Data.ByteString.Char8 as B
195- import Data.Char (toLower , toUpper )
201+ import Data.Char (isAlpha , isDigit , toLower , toUpper )
196202import Data.Foldable (find )
197203import Data.Functor (($>) )
198204import Data.Int (Int64 )
@@ -1524,6 +1530,61 @@ instance (Typeable c, ConnectionModeI c) => FromField (ConnShortLink c) where fr
15241530
15251531data ContactConnType = CCTContact | CCTChannel | CCTGroup | CCTRelay deriving (Eq , Show )
15261532
1533+ data SimplexNameInfo = SimplexNameInfo
1534+ { nameType :: SimplexNameType ,
1535+ nameTLD :: SimplexTLD ,
1536+ domain :: Text ,
1537+ subDomain :: [Text ] -- parent to child: ["b", "a"] for a.b.domain.simplex
1538+ }
1539+ deriving (Eq , Show )
1540+
1541+ data SimplexTLD = TLDSimplex | TLDTesting | TLDWeb
1542+ deriving (Eq , Show )
1543+
1544+ data SimplexNameType = NTPublicGroup | NTContact
1545+ deriving (Eq , Show )
1546+
1547+ instance StrEncoding SimplexNameType where
1548+ strEncode = \ case
1549+ NTPublicGroup -> " #"
1550+ NTContact -> " @"
1551+ strP = A. char ' #' $> NTPublicGroup <|> A. char ' @' $> NTContact
1552+
1553+ instance StrEncoding SimplexNameInfo where
1554+ strEncode info = " simplex:/name" <> strEncode (nameType info) <> encodeUtf8 (fullDomainName info)
1555+ strP = optional " simplex:/name" *> (strP >>= nameP) <|> nameP NTPublicGroup
1556+ where
1557+ nameP nt = parseName nt . safeDecodeUtf8 <$?> A. takeWhile1 (not . A. isSpace)
1558+ parseName nt s = AT. parseOnly (nameLabelP `AT.sepBy1` AT. char ' .' <* AT. endOfInput) s >>= mkNameInfo nt
1559+ nameLabelP = T. intercalate " -" <$> AT. takeWhile1 (\ c -> isNameLetter c || isDigit c) `AT.sepBy1` AT. char ' -'
1560+ isNameLetter c = isAlpha c && not (c >= ' \x00c0 ' && c <= ' \x024f ' )
1561+ mkNameInfo nt labels = case reverse labels of
1562+ [] -> Left " empty name"
1563+ [name]
1564+ | nt == NTPublicGroup -> Right $ SimplexNameInfo nt TLDSimplex name []
1565+ | otherwise -> Left " contact name requires TLD"
1566+ tld : name : sub -> Right $ case tld of
1567+ " simplex" -> SimplexNameInfo nt TLDSimplex name sub
1568+ " testing" -> SimplexNameInfo nt TLDTesting name sub
1569+ _ -> SimplexNameInfo nt TLDWeb (T. intercalate " ." labels) []
1570+
1571+ fullDomainName :: SimplexNameInfo -> Text
1572+ fullDomainName SimplexNameInfo {nameTLD, domain, subDomain} = T. intercalate " ." (reverse subDomain ++ [domain] ++ tld')
1573+ where
1574+ tld' = case nameTLD of
1575+ TLDSimplex -> [" simplex" ]
1576+ TLDTesting -> [" testing" ]
1577+ TLDWeb -> []
1578+
1579+ shortNameInfoStr :: SimplexNameInfo -> Text
1580+ shortNameInfoStr = \ case
1581+ SimplexNameInfo {nameType = NTPublicGroup , nameTLD = TLDSimplex , domain, subDomain = [] } -> " #" <> domain
1582+ info -> pfx <> fullDomainName info
1583+ where
1584+ pfx = case nameType info of
1585+ NTPublicGroup -> " #"
1586+ NTContact -> " @"
1587+
15271588data AConnShortLink = forall m . ConnectionModeI m => ACSL (SConnectionMode m ) (ConnShortLink m )
15281589
15291590instance Eq AConnShortLink where
@@ -2201,3 +2262,9 @@ instance FromJSON ACreatedConnLink where
22012262instance ToJSON ACreatedConnLink where
22022263 toEncoding (ACCL _ ccLink) = toEncoding ccLink
22032264 toJSON (ACCL _ ccLink) = toJSON ccLink
2265+
2266+ $ (J. deriveJSON (enumJSON $ dropPrefix " TLD" ) ''SimplexTLD)
2267+
2268+ $ (J. deriveJSON (enumJSON $ dropPrefix " NT" ) ''SimplexNameType)
2269+
2270+ $ (J. deriveJSON defaultJSON ''SimplexNameInfo)
0 commit comments