From 9e7a29e0f22afbfe5bdc0544735ad31d78758c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Tue, 13 Jan 2026 20:41:55 +0100 Subject: Commands to create and accept invites --- README.md | 13 ++++++++++++- main/Main.hs | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 28b203d..a84a3aa 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ are signed, so message author can not be forged. history, but the chatroom will no longer be listed as available and no futher updates for this chatroom will be collected or shared with other peers. -### Add contacts +### Contact list To ensure the identity of the contact and prevent man-in-the-middle attack, generated verification code needs to be confirmed on both devices to add @@ -175,6 +175,17 @@ new contact, list peers using `/peers` command and select one with `/`. `/contact-reject` : Reject contact request or verification code of selected peer. +`/invite-contact ` +: Create an invite in the form of URL, which can be sent via means outside of + the erebos protocol. The recipient can accept it using the `invite-accept` + command. After accepting, contact entry is created with the given ``. + The created invite can be used only once. + +`/invite-accept ` +: Accept received URL-formatted invite. The erebos tool will try to find and + connect to a device belonging to the issuing identity to confirm the invite. + If successful, corresponding contact entry will be created. + ### Attach other devices Multiple devices can be attached to single identity to be used by the same diff --git a/main/Main.hs b/main/Main.hs index c1f30f2..227451f 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -623,6 +623,8 @@ commands = , ( "contact-add", cmdContactAdd ) , ( "contact-accept", cmdContactAccept ) , ( "contact-reject", cmdContactReject ) + , ( "invite-contact", cmdInviteContact ) + , ( "invite-accept", cmdInviteAccept ) , ( "conversations", cmdConversations ) , ( "new", cmdNew ) , ( "details", cmdDetails ) @@ -955,6 +957,45 @@ cmdContactAccept = contactAccept =<< getSelectedPeer cmdContactReject :: Command cmdContactReject = contactReject =<< getSelectedPeer +cmdInviteContact :: Command +cmdInviteContact = do + term <- asks ciTerminal + name <- asks ciLine >>= \case + line | not (null line) -> return $ T.pack line + _ -> liftIO $ do + setPrompt term "Name: " + getInputLine term $ KeepPrompt . maybe T.empty T.pack + (lookupSharedValue . lsShared . fromStored <$> getLocalHead) >>= \case + Just (self :: ComposedIdentity) -> do + invite <- createSingleContactInvite name + dgst : _ <- return $ refDigest . storedRef <$> idDataF self + cmdPutStrLn $ "https://app.erebosprotocol.net/#inv" <> (maybe "" (("=" <>) . showInviteToken) (inviteToken invite)) <> "&from=blake2%23" <> drop 7 (show dgst) + Nothing -> do + throwOtherError "no shared identity" + +cmdInviteAccept :: Command +cmdInviteAccept = do + term <- asks ciTerminal + url <- asks ciLine >>= \case + line | not (null line) -> return $ T.pack line + _ -> liftIO $ do + setPrompt term "URL: " + getInputLine term $ KeepPrompt . maybe T.empty T.pack + case T.breakOn "://" url of + ( proto, url' ) + | proto `elem` [ "http", "https" ] + , ( _, url'' ) <- T.breakOn "#" url' + , Just ( '#', params ) <- T.uncons url'' + , [ pfrom, pinv ] <- sort $ T.splitOn "&" params + , ( nfrom, tfrom ) <- T.splitAt 14 pfrom, nfrom == "from=blake2%23" + , ( ninv, tinv ) <- T.splitAt 4 pinv, ninv == "inv=" + , Just from <- readRefDigest $ T.encodeUtf8 $ "blake2#" <> tfrom + , Just token <- parseInviteToken tinv + -> do + server <- asks ciServer + acceptInvite server from token + _ -> throwOtherError "invalit invite URL" + cmdConversations :: Command cmdConversations = do conversations <- lookupConversations -- cgit v1.2.3