aboutsummaryrefslogtreecommitdiffstats
path: root/filamento
diff options
context:
space:
mode:
Diffstat (limited to 'filamento')
-rw-r--r--filamento/src/caps.rs2
-rw-r--r--filamento/src/chat.rs10
-rw-r--r--filamento/src/db.rs247
-rw-r--r--filamento/src/error.rs9
-rw-r--r--filamento/src/lib.rs126
-rw-r--r--filamento/src/logic/local_only.rs14
-rw-r--r--filamento/src/logic/mod.rs8
-rw-r--r--filamento/src/logic/offline.rs23
-rw-r--r--filamento/src/logic/online.rs101
-rw-r--r--filamento/src/logic/process_stanza.rs107
-rw-r--r--filamento/src/roster.rs4
-rw-r--r--filamento/src/user.rs4
12 files changed, 338 insertions, 317 deletions
diff --git a/filamento/src/caps.rs b/filamento/src/caps.rs
index 43f1cf4..e0587ff 100644
--- a/filamento/src/caps.rs
+++ b/filamento/src/caps.rs
@@ -377,7 +377,7 @@ pub fn node_to_hash(node: String) -> Result<Hash, HashNodeConversionError> {
#[cfg(test)]
mod tests {
- use peanuts::{Writer, element::IntoElement, loggable::Loggable};
+ use peanuts::Writer;
use stanza::{
xep_0004::{Field, FieldType, Value, X, XType},
xep_0030::info::{Feature, Identity},
diff --git a/filamento/src/chat.rs b/filamento/src/chat.rs
index 5f58866..c02654f 100644
--- a/filamento/src/chat.rs
+++ b/filamento/src/chat.rs
@@ -1,7 +1,7 @@
use std::fmt::{Display, Write};
use chrono::{DateTime, Utc};
-use jid::JID;
+use jid::{BareJID, JID};
use rusqlite::{
ToSql,
types::{FromSql, ToSqlOutput, Value},
@@ -15,7 +15,7 @@ pub struct Message {
pub id: Uuid,
// does not contain full user information
// bare jid (for now)
- pub from: JID,
+ pub from: BareJID,
pub delivery: Option<Delivery>,
pub timestamp: DateTime<Utc>,
// TODO: originally_from
@@ -97,7 +97,7 @@ pub struct Body {
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "reactive_stores", derive(reactive_stores::Store))]
pub struct Chat {
- pub correspondent: JID,
+ pub correspondent: BareJID,
pub have_chatted: bool,
// pub unread_messages: i32,
// pub latest_message: Message,
@@ -109,13 +109,13 @@ pub struct Chat {
pub enum ChatUpdate {}
impl Chat {
- pub fn new(correspondent: JID, have_chatted: bool) -> Self {
+ pub fn new(correspondent: BareJID, have_chatted: bool) -> Self {
Self {
correspondent,
have_chatted,
}
}
- pub fn correspondent(&self) -> &JID {
+ pub fn correspondent(&self) -> &BareJID {
&self.correspondent
}
}
diff --git a/filamento/src/db.rs b/filamento/src/db.rs
index 1b5afe6..385382a 100644
--- a/filamento/src/db.rs
+++ b/filamento/src/db.rs
@@ -2,7 +2,7 @@ use core::fmt::Display;
use std::{collections::HashSet, ops::Deref, path::Path, sync::Arc};
use chrono::{DateTime, Utc};
-use jid::JID;
+use jid::{BareJID, FullJID, JID};
use rusqlite::{Connection, OptionalExtension};
use tokio::sync::{Mutex, MutexGuard};
use tokio::sync::{mpsc, oneshot};
@@ -58,53 +58,22 @@ impl Db {
pub async fn create_connect_and_migrate(
path: impl AsRef<Path> + Send,
) -> Result<Self, DatabaseOpenError> {
- let (sender, receiver) = mpsc::channel(20);
- let (result_send, result_recv) = oneshot::channel();
- spawn_blocking(move || {
- let result = DbActor::new(path, receiver).await;
- match result {
- Ok(a) => {
- result_send.send(Ok(()));
- a.run()
- }
- Err(e) => {
- result_send.send(Err(e));
- }
- }
- });
- match result_recv.await {
- Ok(r) => match r {
- Ok(o) => Ok(Self { sender }),
- Err(e) => return Err(e),
- },
- Err(e) => return Err(e.into()),
- }
+ let (sender, receiver) = mpsc::unbounded_channel();
+
+ let actor = DbActor::new(path, receiver)?;
+ spawn_blocking(move || actor.run());
+
+ Ok(Self { sender })
}
#[cfg(not(target_arch = "wasm32"))]
pub async fn create_connect_and_migrate_memory() -> Result<Self, DatabaseOpenError> {
- let (sender, receiver) = mpsc::channel(20);
- let (result_send, result_recv) = oneshot::channel();
- spawn_blocking(move || {
- let result = DbActor::new_memory(receiver).await;
- match result {
- Ok(a) => {
- result_send.send(Ok(()));
- // TODO: async run when not wasm
- a.run()
- }
- Err(e) => {
- result_send.send(Err(e));
- }
- }
- });
- match result_recv.await {
- Ok(r) => match r {
- Ok(o) => Ok(Self { sender }),
- Err(e) => return Err(e),
- },
- Err(e) => return Err(e.into()),
- }
+ let (sender, receiver) = mpsc::unbounded_channel();
+
+ let actor = DbActor::new_memory(receiver)?;
+ spawn_blocking(move || actor.run());
+
+ Ok(Self { sender })
}
/// `file_name` should be a file not in a directory
@@ -183,7 +152,7 @@ impl Db {
}
// TODO: this is not a 'read' user
- pub(crate) async fn read_user(&self, user: JID) -> Result<User, Error> {
+ pub(crate) async fn read_user(&self, user: BareJID) -> Result<User, Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::ReadUser { user, result };
self.sender.send(command);
@@ -192,7 +161,7 @@ impl Db {
}
/// returns whether or not the nickname was updated
- pub(crate) async fn delete_user_nick(&self, jid: JID) -> Result<bool, Error> {
+ pub(crate) async fn delete_user_nick(&self, jid: BareJID) -> Result<bool, Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::DeleteUserNick { jid, result };
self.sender.send(command);
@@ -201,7 +170,7 @@ impl Db {
}
/// returns whether or not the nickname was updated
- pub(crate) async fn upsert_user_nick(&self, jid: JID, nick: String) -> Result<bool, Error> {
+ pub(crate) async fn upsert_user_nick(&self, jid: BareJID, nick: String) -> Result<bool, Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::UpsertUserNick { jid, nick, result };
self.sender.send(command);
@@ -212,7 +181,7 @@ impl Db {
/// returns whether or not the avatar was updated, and the file to delete if there existed an old avatar
pub(crate) async fn delete_user_avatar(
&self,
- jid: JID,
+ jid: BareJID,
) -> Result<(bool, Option<String>), Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::DeleteUserAvatar { jid, result };
@@ -224,7 +193,7 @@ impl Db {
/// returns whether or not the avatar was updated, and the file to delete if there existed an old avatar
pub(crate) async fn upsert_user_avatar(
&self,
- jid: JID,
+ jid: BareJID,
avatar: String,
) -> Result<(bool, Option<String>), Error> {
let (result, recv) = oneshot::channel();
@@ -259,7 +228,7 @@ impl Db {
result
}
- pub(crate) async fn read_contact(&self, contact: JID) -> Result<Contact, Error> {
+ pub(crate) async fn read_contact(&self, contact: BareJID) -> Result<Contact, Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::ReadContact { contact, result };
self.sender.send(command);
@@ -267,7 +236,10 @@ impl Db {
result
}
- pub(crate) async fn read_contact_opt(&self, contact: JID) -> Result<Option<Contact>, Error> {
+ pub(crate) async fn read_contact_opt(
+ &self,
+ contact: BareJID,
+ ) -> Result<Option<Contact>, Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::ReadContactOpt { contact, result };
self.sender.send(command);
@@ -292,7 +264,7 @@ impl Db {
result
}
- pub(crate) async fn delete_contact(&self, contact: JID) -> Result<(), Error> {
+ pub(crate) async fn delete_contact(&self, contact: BareJID) -> Result<(), Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::DeleteContact { contact, result };
self.sender.send(command);
@@ -336,7 +308,7 @@ impl Db {
// TODO: what happens if a correspondent changes from a user to a contact? maybe just have correspondent be a user, then have the client make the user show up as a contact in ui if they are in the loaded roster.
- pub(crate) async fn read_chat(&self, chat: JID) -> Result<Chat, Error> {
+ pub(crate) async fn read_chat(&self, chat: BareJID) -> Result<Chat, Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::ReadChat { chat, result };
self.sender.send(command);
@@ -344,7 +316,7 @@ impl Db {
result
}
- pub(crate) async fn read_chat_and_user(&self, chat: JID) -> Result<(Chat, User), Error> {
+ pub(crate) async fn read_chat_and_user(&self, chat: BareJID) -> Result<(Chat, User), Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::ReadChatAndUser { chat, result };
self.sender.send(command);
@@ -352,7 +324,7 @@ impl Db {
result
}
- pub(crate) async fn mark_chat_as_chatted(&self, chat: JID) -> Result<(), Error> {
+ pub(crate) async fn mark_chat_as_chatted(&self, chat: BareJID) -> Result<(), Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::MarkChatAsChatted { chat, result };
self.sender.send(command);
@@ -363,7 +335,7 @@ impl Db {
pub(crate) async fn update_chat_correspondent(
&self,
old_chat: Chat,
- new_correspondent: JID,
+ new_correspondent: BareJID,
) -> Result<Chat, Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::UpdateChatCorrespondent {
@@ -378,7 +350,7 @@ impl Db {
// pub(crate) async fn update_chat
- pub(crate) async fn delete_chat(&self, chat: JID) -> Result<(), Error> {
+ pub(crate) async fn delete_chat(&self, chat: BareJID) -> Result<(), Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::DeleteChat { chat, result };
self.sender.send(command);
@@ -434,8 +406,8 @@ impl Db {
pub(crate) async fn create_message(
&self,
message: Message,
- chat: JID,
- from: JID,
+ chat: BareJID,
+ from: FullJID,
) -> Result<(), Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::CreateMessage {
@@ -449,7 +421,7 @@ impl Db {
result
}
- pub(crate) async fn upsert_chat_and_user(&self, chat: JID) -> Result<bool, Error> {
+ pub(crate) async fn upsert_chat_and_user(&self, chat: BareJID) -> Result<bool, Error> {
let (result, recv) = oneshot::channel();
let command = DbCommand::UpsertChatAndUser { chat, result };
self.sender.send(command);
@@ -463,10 +435,8 @@ impl Db {
&self,
message: Message,
// TODO: enforce two kinds of jid. bare and full
- // must be bare jid
- chat: JID,
- // full jid
- from: JID,
+ chat: BareJID,
+ from: FullJID,
) -> Result<(), Error> {
tracing::info!("MSGDEBUG create_message_with_user_resource exists");
let (result, recv) = oneshot::channel();
@@ -514,9 +484,9 @@ impl Db {
DeleteCachedStatus => delete_cached_status() -> ();
UpsertCachedStatus => upsert_cached_status(status: Online) -> ();
ReadCachedStatus => read_cached_status() -> Online;
- ReadMessageHistoryWithUsers => read_message_history_with_users(chat: JID) -> Vec<(Message, User)>;
+ ReadMessageHistoryWithUsers => read_message_history_with_users(chat: BareJID) -> Vec<(Message, User)>;
// TODO: paging
- ReadMessageHistory => read_message_history(chat: JID) -> Vec<Message>;
+ ReadMessageHistory => read_message_history(chat: BareJID) -> Vec<Message>;
ReadMessage => read_message(message: Uuid) -> Message;
DeleteMessage => delete_message(message: Uuid) -> ()
);
@@ -546,24 +516,24 @@ pub enum DbCommand {
result: oneshot::Sender<Result<(), Error>>,
},
ReadUser {
- user: JID,
+ user: BareJID,
result: oneshot::Sender<Result<User, Error>>,
},
DeleteUserNick {
- jid: JID,
+ jid: BareJID,
result: oneshot::Sender<Result<bool, Error>>,
},
UpsertUserNick {
- jid: JID,
+ jid: BareJID,
nick: String,
result: oneshot::Sender<Result<bool, Error>>,
},
DeleteUserAvatar {
- jid: JID,
+ jid: BareJID,
result: oneshot::Sender<Result<(bool, Option<String>), Error>>,
},
UpsertUserAvatar {
- jid: JID,
+ jid: BareJID,
avatar: String,
result: oneshot::Sender<Result<(bool, Option<String>), Error>>,
},
@@ -576,11 +546,11 @@ pub enum DbCommand {
result: oneshot::Sender<Result<(), Error>>,
},
ReadContact {
- contact: JID,
+ contact: BareJID,
result: oneshot::Sender<Result<Contact, Error>>,
},
ReadContactOpt {
- contact: JID,
+ contact: BareJID,
result: oneshot::Sender<Result<Option<Contact>, Error>>,
},
UpdateContact {
@@ -592,7 +562,7 @@ pub enum DbCommand {
result: oneshot::Sender<Result<(), Error>>,
},
DeleteContact {
- contact: JID,
+ contact: BareJID,
result: oneshot::Sender<Result<(), Error>>,
},
ReplaceCachedRoster {
@@ -610,24 +580,24 @@ pub enum DbCommand {
result: oneshot::Sender<Result<(), Error>>,
},
ReadChat {
- chat: JID,
+ chat: BareJID,
result: oneshot::Sender<Result<Chat, Error>>,
},
ReadChatAndUser {
- chat: JID,
+ chat: BareJID,
result: oneshot::Sender<Result<(Chat, User), Error>>,
},
MarkChatAsChatted {
- chat: JID,
+ chat: BareJID,
result: oneshot::Sender<Result<(), Error>>,
},
UpdateChatCorrespondent {
old_chat: Chat,
- new_correspondent: JID,
+ new_correspondent: BareJID,
result: oneshot::Sender<Result<Chat, Error>>,
},
DeleteChat {
- chat: JID,
+ chat: BareJID,
result: oneshot::Sender<Result<(), Error>>,
},
ReadChats {
@@ -652,18 +622,18 @@ pub enum DbCommand {
// },
CreateMessage {
message: Message,
- chat: JID,
- from: JID,
+ chat: BareJID,
+ from: FullJID,
result: oneshot::Sender<Result<(), Error>>,
},
UpsertChatAndUser {
- chat: JID,
+ chat: BareJID,
result: oneshot::Sender<Result<bool, Error>>,
},
CreateMessageWithUserResource {
message: Message,
- chat: JID,
- from: JID,
+ chat: BareJID,
+ from: FullJID,
result: oneshot::Sender<Result<(), Error>>,
},
UpdateMessageDelivery {
@@ -680,11 +650,11 @@ pub enum DbCommand {
result: oneshot::Sender<Result<Message, Error>>,
},
ReadMessageHistory {
- chat: JID,
+ chat: BareJID,
result: oneshot::Sender<Result<Vec<Message>, Error>>,
},
ReadMessageHistoryWithUsers {
- chat: JID,
+ chat: BareJID,
result: oneshot::Sender<Result<Vec<(Message, User)>, Error>>,
},
ReadCachedStatus {
@@ -758,17 +728,19 @@ impl Display for DbCommand {
impl DbActor {
/// must be run in blocking spawn
#[cfg(not(target_arch = "wasm32"))]
- pub(crate) fn new(path: impl AsRef<Path>, receiver: mpsc::Receiver<DbCommand>) -> Self {
+ pub(crate) fn new(
+ path: impl AsRef<Path>,
+ receiver: mpsc::UnboundedReceiver<DbCommand>,
+ ) -> Result<Self, DatabaseOpenError> {
if let Some(dir) = path.as_ref().parent() {
if dir.is_dir() {
} else {
- tokio::fs::create_dir_all(dir).await?;
+ std::fs::create_dir_all(dir)?;
}
- let _file = tokio::fs::OpenOptions::new()
+ let _file = std::fs::OpenOptions::new()
.append(true)
.create(true)
- .open(path.as_ref())
- .await?;
+ .open(path.as_ref())?;
}
let url = format!(
"{}",
@@ -786,7 +758,9 @@ impl DbActor {
/// must be run in blocking spawn
#[cfg(not(target_arch = "wasm32"))]
- pub(crate) fn new_memory(receiver: mpsc::Receiver<DbCommand>) -> Self {
+ pub(crate) fn new_memory(
+ receiver: mpsc::UnboundedReceiver<DbCommand>,
+ ) -> Result<Self, DatabaseOpenError> {
let db = Connection::open_in_memory()?;
db.execute_batch(include_str!("../migrations/1.sql"))?;
Ok(Self { db, receiver })
@@ -850,7 +824,7 @@ impl DbActor {
result.send(self.read_contact(contact));
}
DbCommand::ReadContactOpt { contact, result } => {
- result.send(self.read_contact_opt(&contact));
+ result.send(self.read_contact_opt(contact));
}
DbCommand::UpdateContact { contact, result } => {
result.send(self.update_contact(contact));
@@ -978,7 +952,7 @@ impl DbActor {
}
// TODO: this is not a 'read' user
- pub(crate) fn read_user(&self, user: JID) -> Result<User, Error> {
+ pub(crate) fn read_user(&self, user: BareJID) -> Result<User, Error> {
let db = &self.db;
let user_opt = db
.query_row(
@@ -1007,7 +981,7 @@ impl DbActor {
}
/// returns whether or not the nickname was updated
- pub(crate) fn delete_user_nick(&self, jid: JID) -> Result<bool, Error> {
+ pub(crate) fn delete_user_nick(&self, jid: BareJID) -> Result<bool, Error> {
let rows_affected;
{
rows_affected = self.db.execute("insert into users (jid, nick) values (?1, ?2) on conflict do update set nick = ?3 where nick is not ?4", (jid, None::<String>, None::<String>, None::<String>))?;
@@ -1020,7 +994,7 @@ impl DbActor {
}
/// returns whether or not the nickname was updated
- pub(crate) fn upsert_user_nick(&self, jid: JID, nick: String) -> Result<bool, Error> {
+ pub(crate) fn upsert_user_nick(&self, jid: BareJID, nick: String) -> Result<bool, Error> {
let rows_affected;
{
rows_affected = self.db.execute("insert into users (jid, nick) values (?1, ?2) on conflict do update set nick = ?3 where nick is not ?4", (jid, &nick, &nick, &nick))?;
@@ -1033,7 +1007,7 @@ impl DbActor {
}
/// returns whether or not the avatar was updated, and the file to delete if there existed an old avatar
- pub(crate) fn delete_user_avatar(&self, jid: JID) -> Result<(bool, Option<String>), Error> {
+ pub(crate) fn delete_user_avatar(&self, jid: BareJID) -> Result<(bool, Option<String>), Error> {
let (old_avatar, rows_affected): (Option<String>, _);
{
let db = &self.db;
@@ -1054,7 +1028,7 @@ impl DbActor {
/// returns whether or not the avatar was updated, and the file to delete if there existed an old avatar
pub(crate) fn upsert_user_avatar(
&self,
- jid: JID,
+ jid: BareJID,
avatar: String,
) -> Result<(bool, Option<String>), Error> {
let (old_avatar, rows_affected): (Option<String>, _);
@@ -1108,7 +1082,7 @@ impl DbActor {
Ok(())
}
- pub(crate) fn read_contact(&self, contact: JID) -> Result<Contact, Error> {
+ pub(crate) fn read_contact(&self, contact: BareJID) -> Result<Contact, Error> {
let db = &self.db;
let mut contact_item = db.query_row(
"select user_jid, name, subscription from roster where user_jid = ?1",
@@ -1130,7 +1104,7 @@ impl DbActor {
Ok(contact_item)
}
- pub(crate) fn read_contact_opt(&self, contact: &JID) -> Result<Option<Contact>, Error> {
+ pub(crate) fn read_contact_opt(&self, contact: BareJID) -> Result<Option<Contact>, Error> {
let db = &self.db;
let contact_item = db
.query_row(
@@ -1210,7 +1184,7 @@ impl DbActor {
Ok(())
}
- pub(crate) fn delete_contact(&self, contact: JID) -> Result<(), Error> {
+ pub(crate) fn delete_contact(&self, contact: BareJID) -> Result<(), Error> {
self.db
.execute("delete from roster where user_jid = ?1", [&contact])?;
Ok(())
@@ -1288,19 +1262,21 @@ impl DbActor {
// TODO: what happens if a correspondent changes from a user to a contact? maybe just have correspondent be a user, then have the client make the user show up as a contact in ui if they are in the loaded roster.
- /// should be a bare jid
/// TODO: this is NOT a read
- pub(crate) fn read_chat(&self, chat: JID) -> Result<Chat, Error> {
- let chat_opt = self.db.query_row(
- "select correspondent, have_chatted from chats where correspondent = ?1",
- [&chat],
- |row| {
- Ok(Chat {
- correspondent: row.get(0)?,
- have_chatted: row.get(1)?,
- })
- },
- ).optional()?;
+ pub(crate) fn read_chat(&self, chat: BareJID) -> Result<Chat, Error> {
+ let chat_opt = self
+ .db
+ .query_row(
+ "select correspondent, have_chatted from chats where correspondent = ?1",
+ [&chat],
+ |row| {
+ Ok(Chat {
+ correspondent: row.get(0)?,
+ have_chatted: row.get(1)?,
+ })
+ },
+ )
+ .optional()?;
match chat_opt {
Some(chat) => return Ok(chat),
None => {
@@ -1314,7 +1290,7 @@ impl DbActor {
}
}
- pub(crate) fn read_chat_and_user(&self, chat: JID) -> Result<(Chat, User), Error> {
+ pub(crate) fn read_chat_and_user(&self, chat: BareJID) -> Result<(Chat, User), Error> {
let user = self.read_user(chat.clone())?;
let chat_opt = self.db.query_row(
"select correspondent, have_chatted, jid, nick, avatar from chats join users on correspondent = jid where correspondent = ?1",
@@ -1346,7 +1322,7 @@ impl DbActor {
}
}
- pub(crate) fn mark_chat_as_chatted(&self, chat: JID) -> Result<(), Error> {
+ pub(crate) fn mark_chat_as_chatted(&self, chat: BareJID) -> Result<(), Error> {
self.db.execute(
"update chats set have_chatted = true where correspondent = ?1",
[chat],
@@ -1357,7 +1333,7 @@ impl DbActor {
pub(crate) fn update_chat_correspondent(
&self,
old_chat: Chat,
- new_correspondent: JID,
+ new_correspondent: BareJID,
) -> Result<Chat, Error> {
let new_jid = &new_correspondent;
let old_jid = old_chat.correspondent();
@@ -1374,7 +1350,7 @@ impl DbActor {
// pub(crate) fn update_chat
- pub(crate) fn delete_chat(&self, chat: JID) -> Result<(), Error> {
+ pub(crate) fn delete_chat(&self, chat: BareJID) -> Result<(), Error> {
self.db
.execute("delete from chats where correspondent = ?1", [chat])?;
Ok(())
@@ -1484,7 +1460,7 @@ impl DbActor {
}
#[tracing::instrument]
- fn read_chat_id(&self, chat: JID) -> Result<Uuid, Error> {
+ fn read_chat_id(&self, chat: BareJID) -> Result<Uuid, Error> {
let chat_id = self.db.query_row(
"select id from chats where correspondent = ?1",
[chat],
@@ -1510,8 +1486,8 @@ impl DbActor {
pub(crate) fn create_message(
&self,
message: Message,
- chat: JID,
- from: JID,
+ chat: BareJID,
+ from: FullJID,
) -> Result<(), Error> {
let from_jid = from.as_bare();
let chat_id = self.read_chat_id(chat)?;
@@ -1520,18 +1496,17 @@ impl DbActor {
Ok(())
}
- pub(crate) fn upsert_chat_and_user(&self, chat: &JID) -> Result<bool, Error> {
- let bare_chat = chat.as_bare();
+ pub(crate) fn upsert_chat_and_user(&self, chat: &BareJID) -> Result<bool, Error> {
let db = &self.db;
db.execute(
"insert into users (jid) values (?1) on conflict do nothing",
- [&bare_chat],
+ [&chat],
)?;
let id = Uuid::new_v4();
- db.execute("insert into chats (id, correspondent, have_chatted) values (?1, ?2, ?3) on conflict do nothing", (id, &bare_chat, false))?;
+ db.execute("insert into chats (id, correspondent, have_chatted) values (?1, ?2, ?3) on conflict do nothing", (id, &chat, false))?;
let chat = db.query_row(
"select correspondent, have_chatted from chats where correspondent = ?1",
- [&bare_chat],
+ [&chat],
|row| {
Ok(Chat {
correspondent: row.get(0)?,
@@ -1547,21 +1522,15 @@ impl DbActor {
pub(crate) fn create_message_with_user_resource(
&self,
message: Message,
- // TODO: enforce two kinds of jid. bare and full
- // must be bare jid
- chat: JID,
- // full jid
- from: JID,
+ chat: BareJID,
+ from: FullJID,
) -> Result<(), Error> {
let from_jid = from.as_bare();
- let chat = chat.as_bare();
tracing::debug!("creating resource");
- if let Some(resource) = &from.resourcepart {
- self.db.execute(
- "insert into resources (bare_jid, resource) values (?1, ?2) on conflict do nothing",
- (&from_jid, resource),
- )?;
- }
+ self.db.execute(
+ "insert into resources (bare_jid, resource) values (?1, ?2) on conflict do nothing",
+ (&from_jid, &from.resourcepart),
+ )?;
self.create_message(message, chat, from)?;
Ok(())
}
@@ -1615,7 +1584,7 @@ impl DbActor {
}
// TODO: paging
- pub(crate) fn read_message_history(&self, chat: JID) -> Result<Vec<Message>, Error> {
+ pub(crate) fn read_message_history(&self, chat: BareJID) -> Result<Vec<Message>, Error> {
let chat_id = self.read_chat_id(chat)?;
let messages = self
.db
@@ -1638,7 +1607,7 @@ impl DbActor {
pub(crate) fn read_message_history_with_users(
&self,
- chat: JID,
+ chat: BareJID,
) -> Result<Vec<(Message, User)>, Error> {
let chat_id = self.read_chat_id(chat)?;
let messages = self
diff --git a/filamento/src/error.rs b/filamento/src/error.rs
index af3320f..721d532 100644
--- a/filamento/src/error.rs
+++ b/filamento/src/error.rs
@@ -3,6 +3,7 @@ use std::{num::TryFromIntError, string::FromUtf8Error, sync::Arc};
use base64::DecodeError;
use image::ImageError;
use jid::JID;
+use jid::JIDError;
use lampada::error::{ActorError, ReadError, WriteError};
use stanza::client::{Stanza, iq::Query};
use thiserror::Error;
@@ -297,7 +298,7 @@ pub enum DatabaseOpenError {
// #[error("migration: {0}")]
// Migration(Arc<rusqlite::migrate::MigrateError>),
#[error("io: {0}")]
- Io(Arc<tokio::io::Error>),
+ Io(Arc<std::io::Error>),
#[error("invalid path")]
InvalidPath,
#[error("tokio oneshot recv error: {0}")]
@@ -310,8 +311,8 @@ pub enum DatabaseOpenError {
// }
// }
-impl From<tokio::io::Error> for DatabaseOpenError {
- fn from(e: tokio::io::Error) -> Self {
+impl From<std::io::Error> for DatabaseOpenError {
+ fn from(e: std::io::Error) -> Self {
Self::Io(Arc::new(e))
}
}
@@ -332,6 +333,8 @@ pub enum PresenceError {
MissingFrom,
#[error("stanza error: {0:?}")]
StanzaError(Option<stanza::client::error::Error>),
+ #[error("received subscription request from a non-bare jid")]
+ InvalidSubscriptionRequest(#[from] JIDError),
}
#[derive(Debug, Error, Clone)]
diff --git a/filamento/src/lib.rs b/filamento/src/lib.rs
index 068bfe8..d3033b7 100644
--- a/filamento/src/lib.rs
+++ b/filamento/src/lib.rs
@@ -16,7 +16,7 @@ use error::{
};
use files::FileStore;
use futures::FutureExt;
-use jid::JID;
+use jid::{BareJID, JID};
use lampada::{
Connected, CoreClient, CoreClientCommand, Logic, SupervisorSender, WriteMessage,
error::{ActorError, CommandError, ConnectionError, ReadError, WriteError},
@@ -68,45 +68,55 @@ pub enum Command<Fs: FileStore> {
oneshot::Sender<Result<Vec<((Chat, User), (Message, User))>, DatabaseError>>,
),
/// get a specific chat by jid
- GetChat(JID, oneshot::Sender<Result<Chat, DatabaseError>>),
+ GetChat(BareJID, oneshot::Sender<Result<Chat, DatabaseError>>),
/// get a specific chat and user by jid
- GetChatAndUser(JID, oneshot::Sender<Result<(Chat, User), DatabaseError>>),
+ GetChatAndUser(
+ BareJID,
+ oneshot::Sender<Result<(Chat, User), DatabaseError>>,
+ ),
/// get message history for chat (does appropriate mam things)
GetMessage(Uuid, oneshot::Sender<Result<Message, DatabaseError>>),
// TODO: paging and filtering
- GetMessages(JID, oneshot::Sender<Result<Vec<Message>, DatabaseError>>),
+ GetMessages(
+ BareJID,
+ oneshot::Sender<Result<Vec<Message>, DatabaseError>>,
+ ),
/// get message history for chat (does appropriate mam things)
// TODO: paging and filtering
GetMessagesWithUsers(
- JID,
+ BareJID,
oneshot::Sender<Result<Vec<(Message, User)>, DatabaseError>>,
),
/// delete a chat from your chat history, along with all the corresponding messages
- DeleteChat(JID, oneshot::Sender<Result<(), DatabaseError>>),
+ DeleteChat(BareJID, oneshot::Sender<Result<(), DatabaseError>>),
/// delete a message from your chat history
DeleteMessage(Uuid, oneshot::Sender<Result<(), DatabaseError>>),
/// get a user from your users database
- GetUser(JID, oneshot::Sender<Result<User, DatabaseError>>),
+ GetUser(BareJID, oneshot::Sender<Result<User, DatabaseError>>),
/// add a contact to your roster, with a status of none, no subscriptions.
- AddContact(JID, oneshot::Sender<Result<(), RosterError>>),
+ AddContact(BareJID, oneshot::Sender<Result<(), RosterError>>),
/// send a friend request i.e. a subscription request with a subscription pre-approval. if not already added to roster server adds to roster.
- BuddyRequest(JID, oneshot::Sender<Result<(), SubscribeError>>),
+ BuddyRequest(BareJID, oneshot::Sender<Result<(), SubscribeError>>),
/// send a subscription request, without pre-approval. if not already added to roster server adds to roster.
- SubscriptionRequest(JID, oneshot::Sender<Result<(), SubscribeError>>),
+ SubscriptionRequest(BareJID, oneshot::Sender<Result<(), SubscribeError>>),
/// accept a friend request by accepting a pending subscription and sending a subscription request back. if not already added to roster adds to roster.
- AcceptBuddyRequest(JID, oneshot::Sender<Result<(), SubscribeError>>),
+ AcceptBuddyRequest(BareJID, oneshot::Sender<Result<(), SubscribeError>>),
/// accept a pending subscription and doesn't send a subscription request back. if not already added to roster adds to roster.
- AcceptSubscriptionRequest(JID, oneshot::Sender<Result<(), SubscribeError>>),
+ AcceptSubscriptionRequest(BareJID, oneshot::Sender<Result<(), SubscribeError>>),
/// unsubscribe to a contact, but don't remove their subscription.
- UnsubscribeFromContact(JID, oneshot::Sender<Result<(), WriteError>>),
+ UnsubscribeFromContact(BareJID, oneshot::Sender<Result<(), WriteError>>),
/// stop a contact from being subscribed, but stay subscribed to the contact.
- UnsubscribeContact(JID, oneshot::Sender<Result<(), WriteError>>),
+ UnsubscribeContact(BareJID, oneshot::Sender<Result<(), WriteError>>),
/// remove subscriptions to and from contact, but keep in roster.
- UnfriendContact(JID, oneshot::Sender<Result<(), WriteError>>),
+ UnfriendContact(BareJID, oneshot::Sender<Result<(), WriteError>>),
/// remove a contact from the contact list. will remove subscriptions if not already done then delete contact from roster.
- DeleteContact(JID, oneshot::Sender<Result<(), RosterError>>),
+ DeleteContact(BareJID, oneshot::Sender<Result<(), RosterError>>),
/// update contact. contact details will be overwritten with the contents of the contactupdate struct.
- UpdateContact(JID, ContactUpdate, oneshot::Sender<Result<(), RosterError>>),
+ UpdateContact(
+ BareJID,
+ ContactUpdate,
+ oneshot::Sender<Result<(), RosterError>>,
+ ),
/// set online status. if disconnected, will be cached so when client connects, will be sent as the initial presence.
SetStatus(Online, oneshot::Sender<Result<(), StatusError>>),
/// send presence stanza
@@ -120,7 +130,7 @@ pub enum Command<Fs: FileStore> {
// TODO: should probably make it so people can add non-contact auto presence sharing in the client (most likely through setting an internal setting)
/// send a message to a jid (any kind of jid that can receive a message, e.g. a user or a
/// chatroom). if disconnected, will be cached so when client connects, message will be sent.
- SendMessage(JID, Body),
+ SendMessage(BareJID, Body),
// TODO: resend failed messages
// ResendMessage(Uuid),
/// disco info query
@@ -146,7 +156,7 @@ pub enum Command<Fs: FileStore> {
sender: oneshot::Sender<Result<(), PEPError>>,
},
GetPEPItem {
- jid: Option<JID>,
+ jid: Option<BareJID>,
node: String,
id: String,
sender: oneshot::Sender<Result<pep::Item, PEPError>>,
@@ -171,7 +181,7 @@ pub enum UpdateMessage {
Offline(Offline),
/// (only update app roster state, don't replace)
RosterUpdate(Contact, User),
- RosterDelete(JID),
+ RosterDelete(BareJID),
/// presences should be stored with users in the ui, not contacts, as presences can be received from anyone
Presence {
from: JID,
@@ -180,22 +190,23 @@ pub enum UpdateMessage {
// TODO: receipts
// MessageDispatched(Uuid),
Message {
- to: JID,
+ // TODO: rename to chat?
+ to: BareJID,
from: User,
message: Message,
},
MessageDelivery {
id: Uuid,
- chat: JID,
+ chat: BareJID,
delivery: Delivery,
},
- SubscriptionRequest(jid::JID),
+ SubscriptionRequest(BareJID),
NickChanged {
- jid: JID,
+ jid: BareJID,
nick: Option<String>,
},
AvatarChanged {
- jid: JID,
+ jid: BareJID,
id: Option<String>,
},
}
@@ -259,7 +270,7 @@ impl<Fs: FileStore + Clone + Send + Sync + 'static> Client<Fs> {
timeout: Duration::from_secs(20),
};
- let logic = ClientLogic::new(client.clone(), jid.as_bare(), db, update_send, file_store);
+ let logic = ClientLogic::new(client.clone(), jid.to_bare(), db, update_send, file_store);
let actor: CoreClient<ClientLogic<Fs>> =
CoreClient::new(jid, password, command_receiver, None, sup_recv, logic);
@@ -373,7 +384,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(chats)
}
- pub async fn get_chat(&self, jid: JID) -> Result<Chat, CommandError<DatabaseError>> {
+ pub async fn get_chat(&self, jid: BareJID) -> Result<Chat, CommandError<DatabaseError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::GetChat(jid, send)))
.await
@@ -385,12 +396,17 @@ impl<Fs: FileStore> Client<Fs> {
Ok(chat)
}
- pub async fn get_chat_and_user(&self, jid: JID) -> Result<(Chat, User), CommandError<DatabaseError>> {
+ pub async fn get_chat_and_user(
+ &self,
+ jid: BareJID,
+ ) -> Result<(Chat, User), CommandError<DatabaseError>> {
let (send, recv) = oneshot::channel();
- self.send(CoreClientCommand::Command(Command::GetChatAndUser(jid, send)))
- .await
- .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
- let result= timeout(self.timeout, recv)
+ self.send(CoreClientCommand::Command(Command::GetChatAndUser(
+ jid, send,
+ )))
+ .await
+ .map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
+ let result = timeout(self.timeout, recv)
.await
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
@@ -411,7 +427,7 @@ impl<Fs: FileStore> Client<Fs> {
pub async fn get_messages(
&self,
- jid: JID,
+ jid: BareJID,
) -> Result<Vec<Message>, CommandError<DatabaseError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::GetMessages(jid, send)))
@@ -426,7 +442,7 @@ impl<Fs: FileStore> Client<Fs> {
pub async fn get_messages_with_users(
&self,
- jid: JID,
+ jid: BareJID,
) -> Result<Vec<(Message, User)>, CommandError<DatabaseError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::GetMessagesWithUsers(
@@ -441,7 +457,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(messages)
}
- pub async fn delete_chat(&self, jid: JID) -> Result<(), CommandError<DatabaseError>> {
+ pub async fn delete_chat(&self, jid: BareJID) -> Result<(), CommandError<DatabaseError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::DeleteChat(jid, send)))
.await
@@ -465,7 +481,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn get_user(&self, jid: JID) -> Result<User, CommandError<DatabaseError>> {
+ pub async fn get_user(&self, jid: BareJID) -> Result<User, CommandError<DatabaseError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::GetUser(jid, send)))
.await
@@ -477,7 +493,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn add_contact(&self, jid: JID) -> Result<(), CommandError<RosterError>> {
+ pub async fn add_contact(&self, jid: BareJID) -> Result<(), CommandError<RosterError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::AddContact(jid, send)))
.await
@@ -489,7 +505,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn buddy_request(&self, jid: JID) -> Result<(), CommandError<SubscribeError>> {
+ pub async fn buddy_request(&self, jid: BareJID) -> Result<(), CommandError<SubscribeError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::BuddyRequest(jid, send)))
.await
@@ -501,7 +517,10 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn subscription_request(&self, jid: JID) -> Result<(), CommandError<SubscribeError>> {
+ pub async fn subscription_request(
+ &self,
+ jid: BareJID,
+ ) -> Result<(), CommandError<SubscribeError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::SubscriptionRequest(
jid, send,
@@ -515,7 +534,10 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn accept_buddy_request(&self, jid: JID) -> Result<(), CommandError<SubscribeError>> {
+ pub async fn accept_buddy_request(
+ &self,
+ jid: BareJID,
+ ) -> Result<(), CommandError<SubscribeError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::AcceptBuddyRequest(
jid, send,
@@ -531,7 +553,7 @@ impl<Fs: FileStore> Client<Fs> {
pub async fn accept_subscription_request(
&self,
- jid: JID,
+ jid: BareJID,
) -> Result<(), CommandError<SubscribeError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(
@@ -546,7 +568,10 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn unsubscribe_from_contact(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
+ pub async fn unsubscribe_from_contact(
+ &self,
+ jid: BareJID,
+ ) -> Result<(), CommandError<WriteError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::UnsubscribeFromContact(
jid, send,
@@ -560,7 +585,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn unsubscribe_contact(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
+ pub async fn unsubscribe_contact(&self, jid: BareJID) -> Result<(), CommandError<WriteError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::UnsubscribeContact(
jid, send,
@@ -574,7 +599,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn unfriend_contact(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
+ pub async fn unfriend_contact(&self, jid: BareJID) -> Result<(), CommandError<WriteError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::UnfriendContact(
jid, send,
@@ -588,7 +613,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn delete_contact(&self, jid: JID) -> Result<(), CommandError<RosterError>> {
+ pub async fn delete_contact(&self, jid: BareJID) -> Result<(), CommandError<RosterError>> {
let (send, recv) = oneshot::channel();
self.send(CoreClientCommand::Command(Command::DeleteContact(
jid, send,
@@ -604,7 +629,7 @@ impl<Fs: FileStore> Client<Fs> {
pub async fn update_contact(
&self,
- jid: JID,
+ jid: BareJID,
update: ContactUpdate,
) -> Result<(), CommandError<RosterError>> {
let (send, recv) = oneshot::channel();
@@ -632,7 +657,7 @@ impl<Fs: FileStore> Client<Fs> {
Ok(result)
}
- pub async fn send_message(&self, jid: JID, body: Body) -> Result<(), ActorError> {
+ pub async fn send_message(&self, jid: BareJID, body: Body) -> Result<(), ActorError> {
self.send(CoreClientCommand::Command(Command::SendMessage(jid, body)))
.await?;
Ok(())
@@ -711,7 +736,8 @@ impl<Fs: FileStore> Client<Fs> {
pub async fn get_pep_item(
&self,
- jid: Option<JID>,
+ // i think this is correct?, should not be able to send pep requests to a full jid.
+ jid: Option<BareJID>,
node: String,
id: String,
) -> Result<pep::Item, CommandError<PEPError>> {
@@ -811,7 +837,7 @@ mod tests {
info!("sending message");
client
.send_message(
- JID::from_str("cel@blos.sm").unwrap(),
+ BareJID::from_str("cel@blos.sm").unwrap(),
chat::Body {
body: "hallo!!!".to_string(),
},
@@ -821,7 +847,7 @@ mod tests {
info!("sent message");
client
.send_message(
- JID::from_str("cel@blos.sm").unwrap(),
+ BareJID::from_str("cel@blos.sm").unwrap(),
chat::Body {
body: "hallo 2".to_string(),
},
diff --git a/filamento/src/logic/local_only.rs b/filamento/src/logic/local_only.rs
index f5705f4..7f3a2e6 100644
--- a/filamento/src/logic/local_only.rs
+++ b/filamento/src/logic/local_only.rs
@@ -1,4 +1,4 @@
-use jid::JID;
+use jid::{BareJID, JID};
use uuid::Uuid;
use crate::{
@@ -39,14 +39,14 @@ pub async fn handle_get_chats_ordered_with_latest_messages_and_users<Fs: FileSto
pub async fn handle_get_chat<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
- jid: JID,
+ jid: BareJID,
) -> Result<Chat, DatabaseError> {
Ok(logic.db().read_chat(jid).await?)
}
pub async fn handle_get_chat_and_user<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
- jid: JID,
+ jid: BareJID,
) -> Result<(Chat, User), DatabaseError> {
Ok(logic.db().read_chat_and_user(jid).await?)
}
@@ -60,21 +60,21 @@ pub async fn handle_get_message<Fs: FileStore + Clone>(
pub async fn handle_get_messages<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
- jid: JID,
+ jid: BareJID,
) -> Result<Vec<Message>, DatabaseError> {
Ok(logic.db().read_message_history(jid).await?)
}
pub async fn handle_get_messages_with_users<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
- jid: JID,
+ jid: BareJID,
) -> Result<Vec<(Message, User)>, DatabaseError> {
Ok(logic.db().read_message_history_with_users(jid).await?)
}
pub async fn handle_delete_chat<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
- jid: JID,
+ jid: BareJID,
) -> Result<(), DatabaseError> {
Ok(logic.db().delete_chat(jid).await?)
}
@@ -88,7 +88,7 @@ pub async fn handle_delete_messaage<Fs: FileStore + Clone>(
pub async fn handle_get_user<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
- jid: JID,
+ jid: BareJID,
) -> Result<User, DatabaseError> {
Ok(logic.db().read_user(jid).await?)
}
diff --git a/filamento/src/logic/mod.rs b/filamento/src/logic/mod.rs
index 5e05dac..146f3b0 100644
--- a/filamento/src/logic/mod.rs
+++ b/filamento/src/logic/mod.rs
@@ -1,6 +1,6 @@
use std::{collections::HashMap, sync::Arc};
-use jid::JID;
+use jid::{BareJID, JID};
use lampada::{Connected, Logic, error::ReadError};
use stanza::client::Stanza;
use tokio::sync::{Mutex, mpsc, oneshot};
@@ -25,7 +25,7 @@ mod process_stanza;
#[derive(Clone)]
pub struct ClientLogic<Fs: FileStore> {
client: Client<Fs>,
- bare_jid: JID,
+ jid: BareJID,
db: Db,
pending: Pending,
update_sender: mpsc::Sender<UpdateMessage>,
@@ -80,7 +80,7 @@ impl Pending {
impl<Fs: FileStore> ClientLogic<Fs> {
pub fn new(
client: Client<Fs>,
- bare_jid: JID,
+ jid: BareJID,
db: Db,
update_sender: mpsc::Sender<UpdateMessage>,
file_store: Fs,
@@ -90,7 +90,7 @@ impl<Fs: FileStore> ClientLogic<Fs> {
pending: Pending::new(),
update_sender,
client,
- bare_jid,
+ jid,
file_store,
}
}
diff --git a/filamento/src/logic/offline.rs b/filamento/src/logic/offline.rs
index 606b04f..aa84f3d 100644
--- a/filamento/src/logic/offline.rs
+++ b/filamento/src/logic/offline.rs
@@ -1,6 +1,7 @@
use std::process::id;
use chrono::Utc;
+use jid::FullJID;
use lampada::error::WriteError;
use tracing::error;
use uuid::Uuid;
@@ -19,9 +20,13 @@ use crate::{
};
use super::{
+ ClientLogic,
local_only::{
- handle_delete_chat, handle_delete_messaage, handle_get_chat, handle_get_chat_and_user, handle_get_chats, handle_get_chats_ordered, handle_get_chats_ordered_with_latest_messages, handle_get_chats_ordered_with_latest_messages_and_users, handle_get_message, handle_get_messages, handle_get_messages_with_users, handle_get_user
- }, ClientLogic
+ handle_delete_chat, handle_delete_messaage, handle_get_chat, handle_get_chat_and_user,
+ handle_get_chats, handle_get_chats_ordered, handle_get_chats_ordered_with_latest_messages,
+ handle_get_chats_ordered_with_latest_messages_and_users, handle_get_message,
+ handle_get_messages, handle_get_messages_with_users, handle_get_user,
+ },
};
pub async fn handle_offline<Fs: FileStore + Clone>(logic: ClientLogic<Fs>, command: Command<Fs>) {
@@ -153,7 +158,7 @@ pub async fn handle_offline_result<Fs: FileStore + Clone>(
let message = Message {
id,
- from: logic.bare_jid.clone(),
+ from: logic.jid.clone(),
// TODO: failure reason
delivery: Some(Delivery::Failed),
timestamp,
@@ -163,11 +168,15 @@ pub async fn handle_offline_result<Fs: FileStore + Clone>(
// TODO: mark these as potentially failed upon client launch
if let Err(e) = logic
.db()
+ // TODO: can create message without a resource....
.create_message_with_user_resource(
message.clone(),
jid.clone(),
// TODO: when message is queued and sent, the from must also be updated with the correct resource
- logic.bare_jid.clone(),
+ FullJID {
+ bare_jid: logic.jid.clone(),
+ resourcepart: "unsent".to_string(),
+ },
)
.await
{
@@ -177,12 +186,12 @@ pub async fn handle_offline_result<Fs: FileStore + Clone>(
.await;
}
- let from = match logic.db().read_user(logic.bare_jid.clone()).await {
+ let from = match logic.db().read_user(logic.jid.clone()).await {
Ok(u) => u,
Err(e) => {
error!("{}", e);
User {
- jid: logic.bare_jid.clone(),
+ jid: logic.jid.clone(),
nick: None,
avatar: None,
}
@@ -192,7 +201,7 @@ pub async fn handle_offline_result<Fs: FileStore + Clone>(
logic
.update_sender()
.send(crate::UpdateMessage::Message {
- to: jid.as_bare(),
+ to: jid,
message,
from,
})
diff --git a/filamento/src/logic/online.rs b/filamento/src/logic/online.rs
index 9814ff2..febd3e1 100644
--- a/filamento/src/logic/online.rs
+++ b/filamento/src/logic/online.rs
@@ -3,7 +3,7 @@ use std::{io::Cursor, time::Duration};
use base64::{prelude::BASE64_STANDARD, Engine};
use chrono::Utc;
use image::ImageReader;
-use jid::JID;
+use jid::{BareJID, JID};
use lampada::{Connected, WriteMessage, error::WriteError};
use sha1::{Digest, Sha1};
use stanza::{
@@ -41,7 +41,7 @@ pub async fn handle_get_roster<Fs: FileStore + Clone>(
) -> Result<Vec<Contact>, RosterError> {
let iq_id = Uuid::new_v4().to_string();
let stanza = Stanza::Iq(Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq_id.to_string(),
to: None,
r#type: IqType::Get,
@@ -101,7 +101,7 @@ pub async fn handle_get_roster_with_users<Fs: FileStore + Clone>(
) -> Result<Vec<(Contact, User)>, RosterError> {
let iq_id = Uuid::new_v4().to_string();
let stanza = Stanza::Iq(Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq_id.to_string(),
to: None,
r#type: IqType::Get,
@@ -162,11 +162,11 @@ pub async fn handle_get_roster_with_users<Fs: FileStore + Clone>(
pub async fn handle_add_contact<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
connection: Connected,
- jid: JID,
+ jid: BareJID,
) -> Result<(), RosterError> {
let iq_id = Uuid::new_v4().to_string();
let set_stanza = Stanza::Iq(Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq_id.clone(),
to: None,
r#type: IqType::Set,
@@ -220,9 +220,10 @@ pub async fn handle_add_contact<Fs: FileStore + Clone>(
pub async fn handle_buddy_request<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
connection: Connected,
- jid: JID,
+ jid: BareJID,
) -> Result<(), SubscribeError> {
- let client_user = logic.db.read_user(logic.bare_jid.clone()).await?;
+ let jid: JID = jid.into();
+ let client_user = logic.db.read_user(logic.jid.clone()).await?;
let nick = client_user.nick.map(|nick| Nick(nick));
let presence = Stanza::Presence(stanza::client::presence::Presence {
to: Some(jid.clone()),
@@ -243,13 +244,13 @@ pub async fn handle_buddy_request<Fs: FileStore + Clone>(
pub async fn handle_subscription_request<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
connection: Connected,
- jid: JID,
+ jid: BareJID,
) -> Result<(), SubscribeError> {
// TODO: i should probably have builders
- let client_user = logic.db.read_user(logic.bare_jid.clone()).await?;
+ let client_user = logic.db.read_user(logic.jid.clone()).await?;
let nick = client_user.nick.map(|nick| Nick(nick));
let presence = Stanza::Presence(stanza::client::presence::Presence {
- to: Some(jid),
+ to: Some(jid.into()),
r#type: Some(stanza::client::presence::PresenceType::Subscribe),
nick,
..Default::default()
@@ -261,15 +262,16 @@ pub async fn handle_subscription_request<Fs: FileStore + Clone>(
pub async fn handle_accept_buddy_request<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
connection: Connected,
- jid: JID,
+ jid: BareJID,
) -> Result<(), SubscribeError> {
+ let jid: JID = jid.into();
let presence = Stanza::Presence(stanza::client::presence::Presence {
to: Some(jid.clone()),
r#type: Some(stanza::client::presence::PresenceType::Subscribed),
..Default::default()
});
connection.write_handle().write(presence).await?;
- let client_user = logic.db.read_user(logic.bare_jid.clone()).await?;
+ let client_user = logic.db.read_user(logic.jid.clone()).await?;
let nick = client_user.nick.map(|nick| Nick(nick));
let presence = Stanza::Presence(stanza::client::presence::Presence {
to: Some(jid),
@@ -284,12 +286,12 @@ pub async fn handle_accept_buddy_request<Fs: FileStore + Clone>(
pub async fn handle_accept_subscription_request<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
connection: Connected,
- jid: JID,
+ jid: BareJID,
) -> Result<(), SubscribeError> {
- let client_user = logic.db.read_user(logic.bare_jid.clone()).await?;
+ let client_user = logic.db.read_user(logic.jid.clone()).await?;
let nick = client_user.nick.map(|nick| Nick(nick));
let presence = Stanza::Presence(stanza::client::presence::Presence {
- to: Some(jid),
+ to: Some(jid.into()),
r#type: Some(stanza::client::presence::PresenceType::Subscribe),
nick,
..Default::default()
@@ -300,10 +302,10 @@ pub async fn handle_accept_subscription_request<Fs: FileStore + Clone>(
pub async fn handle_unsubscribe_from_contact(
connection: Connected,
- jid: JID,
+ jid: BareJID,
) -> Result<(), WriteError> {
let presence = Stanza::Presence(stanza::client::presence::Presence {
- to: Some(jid),
+ to: Some(jid.into()),
r#type: Some(stanza::client::presence::PresenceType::Unsubscribe),
..Default::default()
});
@@ -311,9 +313,9 @@ pub async fn handle_unsubscribe_from_contact(
Ok(())
}
-pub async fn handle_unsubscribe_contact(connection: Connected, jid: JID) -> Result<(), WriteError> {
+pub async fn handle_unsubscribe_contact(connection: Connected, jid: BareJID) -> Result<(), WriteError> {
let presence = Stanza::Presence(stanza::client::presence::Presence {
- to: Some(jid),
+ to: Some(jid.into()),
r#type: Some(stanza::client::presence::PresenceType::Unsubscribed),
..Default::default()
});
@@ -321,7 +323,8 @@ pub async fn handle_unsubscribe_contact(connection: Connected, jid: JID) -> Resu
Ok(())
}
-pub async fn handle_unfriend_contact(connection: Connected, jid: JID) -> Result<(), WriteError> {
+pub async fn handle_unfriend_contact(connection: Connected, jid: BareJID) -> Result<(), WriteError> {
+ let jid: JID = jid.into();
let presence = Stanza::Presence(stanza::client::presence::Presence {
to: Some(jid.clone()),
r#type: Some(stanza::client::presence::PresenceType::Unsubscribe),
@@ -340,11 +343,11 @@ pub async fn handle_unfriend_contact(connection: Connected, jid: JID) -> Result<
pub async fn handle_delete_contact<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
connection: Connected,
- jid: JID,
+ jid: BareJID,
) -> Result<(), RosterError> {
let iq_id = Uuid::new_v4().to_string();
let set_stanza = Stanza::Iq(Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq_id.clone(),
to: None,
r#type: IqType::Set,
@@ -399,7 +402,7 @@ pub async fn handle_delete_contact<Fs: FileStore + Clone>(
pub async fn handle_update_contact<Fs: FileStore + Clone>(
logic: &ClientLogic<Fs>,
connection: Connected,
- jid: JID,
+ jid: BareJID,
contact_update: ContactUpdate,
) -> Result<(), RosterError> {
let iq_id = Uuid::new_v4().to_string();
@@ -410,7 +413,8 @@ pub async fn handle_update_contact<Fs: FileStore + Clone>(
.map(|group| stanza::roster::Group(Some(group))),
);
let set_stanza = Stanza::Iq(Iq {
- from: Some(connection.jid().clone()),
+ // TODO: these clones could technically be avoided?
+ from: Some(connection.jid().clone().into()),
id: iq_id.clone(),
to: None,
r#type: IqType::Set,
@@ -474,7 +478,7 @@ pub async fn handle_set_status<Fs: FileStore + Clone>(
Ok(())
}
-pub async fn handle_send_message<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>, connection: Connected, jid: JID, body: Body) {
+pub async fn handle_send_message<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>, connection: Connected, jid: BareJID, body: Body) {
// upsert the chat and user the message will be delivered to. if there is a conflict, it will return whatever was there, otherwise it will return false by default.
// let have_chatted = logic.db().upsert_chat_and_user(&jid).await.unwrap_or(false);
let have_chatted = match logic.db().upsert_chat_and_user(jid.clone()).await {
@@ -490,7 +494,7 @@ pub async fn handle_send_message<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>,
let nick;
let mark_chat_as_chatted;
if have_chatted == false {
- match logic.db.read_user(logic.bare_jid.clone()).await {
+ match logic.db.read_user(logic.jid.clone()).await {
Ok(u) => {
nick = u.nick.map(|nick| Nick(nick));
mark_chat_as_chatted = true;
@@ -513,7 +517,7 @@ pub async fn handle_send_message<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>,
let timestamp = Utc::now();
let message = Message {
id,
- from: connection.jid().as_bare(),
+ from: connection.jid().to_bare(),
body: body.clone(),
timestamp,
delivery: Some(Delivery::Sending),
@@ -532,12 +536,12 @@ pub async fn handle_send_message<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>,
.await;
}
- let from = match logic.db().read_user(logic.bare_jid.clone()).await {
+ let from = match logic.db().read_user(logic.jid.clone()).await {
Ok(u) => u,
Err(e) => {
error!("{}", e);
User {
- jid: logic.bare_jid.clone(),
+ jid: logic.jid.clone(),
nick: None,
avatar: None,
}
@@ -548,7 +552,7 @@ pub async fn handle_send_message<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>,
logic
.update_sender()
.send(UpdateMessage::Message {
- to: jid.as_bare(),
+ to: jid.clone(),
message,
from,
})
@@ -556,9 +560,9 @@ pub async fn handle_send_message<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>,
// prepare the message stanza
let message_stanza = Stanza::Message(stanza::client::message::Message {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: Some(id.to_string()),
- to: Some(jid.clone()),
+ to: Some(jid.clone().into()),
// TODO: specify message type
r#type: stanza::client::message::MessageType::Chat,
// TODO: lang ?
@@ -639,7 +643,7 @@ pub async fn handle_disco_info<Fs: FileStore + Clone>(
) -> Result<Info, DiscoError> {
let id = Uuid::new_v4().to_string();
let request = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: id.clone(),
to: jid.clone(),
r#type: IqType::Get,
@@ -667,7 +671,7 @@ pub async fn handle_disco_info<Fs: FileStore + Clone>(
}) if r#type == IqType::Result || r#type == IqType::Error => {
if from == jid || {
if jid == None {
- from == Some(connection.jid().as_bare())
+ from == Some(connection.jid().to_bare().into())
} else {
false
}
@@ -694,7 +698,7 @@ pub async fn handle_disco_info<Fs: FileStore + Clone>(
}
} else {
Err(DiscoError::IncorrectEntity(
- from.unwrap_or_else(|| connection.jid().as_bare()),
+ from.unwrap_or_else(|| connection.jid().to_bare().into()),
))
}
}
@@ -710,7 +714,7 @@ pub async fn handle_disco_items<Fs: FileStore + Clone>(
) -> Result<Items, DiscoError> {
let id = Uuid::new_v4().to_string();
let request = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: id.clone(),
to: jid.clone(),
r#type: IqType::Get,
@@ -736,7 +740,7 @@ pub async fn handle_disco_items<Fs: FileStore + Clone>(
}) if r#type == IqType::Result || r#type == IqType::Error => {
if from == jid || {
if jid == None {
- from == Some(connection.jid().as_bare())
+ from == Some(connection.jid().to_bare().into())
} else {
false
}
@@ -763,7 +767,7 @@ pub async fn handle_disco_items<Fs: FileStore + Clone>(
}
} else {
Err(DiscoError::IncorrectEntity(
- from.unwrap_or_else(|| connection.jid().as_bare()),
+ from.unwrap_or_else(|| connection.jid().to_bare().into()),
))
}
}
@@ -828,7 +832,7 @@ pub async fn handle_publish_pep_item<Fs: FileStore + Clone>(
},
};
let request = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: id.clone(),
to: None,
r#type: IqType::Set,
@@ -850,7 +854,7 @@ pub async fn handle_publish_pep_item<Fs: FileStore + Clone>(
// TODO: maybe abstract a bunch of these different errors related to iqs into an iq error thing? as in like call iq.result(), get the query from inside, error otherwise.
}) if r#type == IqType::Result || r#type == IqType::Error => {
if from == None ||
- from == Some(connection.jid().as_bare())
+ from == Some(connection.jid().to_bare().into())
{
match r#type {
IqType::Result => {
@@ -870,7 +874,7 @@ pub async fn handle_publish_pep_item<Fs: FileStore + Clone>(
}
} else {
Err(PEPError::IncorrectEntity(
- from.unwrap_or_else(|| connection.jid().as_bare()),
+ from.unwrap_or_else(|| connection.jid().to_bare().into()),
))
}
}
@@ -878,10 +882,11 @@ pub async fn handle_publish_pep_item<Fs: FileStore + Clone>(
}
}
-pub async fn handle_get_pep_item<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>, connection: Connected, jid: Option<JID>, node: String, id: String) -> Result<pep::Item, PEPError> {
+pub async fn handle_get_pep_item<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>, connection: Connected, jid: Option<BareJID>, node: String, id: String) -> Result<pep::Item, PEPError> {
+ let jid = jid.map(|jid| Into::<JID>::into(jid));
let stanza_id = Uuid::new_v4().to_string();
let request = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: stanza_id.clone(),
to: jid.clone(),
r#type: IqType::Get,
@@ -909,7 +914,7 @@ pub async fn handle_get_pep_item<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>,
}) if r#type == IqType::Result || r#type == IqType::Error => {
if from == jid || {
if jid == None {
- from == Some(connection.jid().as_bare())
+ from == Some(connection.jid().to_bare().into())
} else {
false
}
@@ -955,7 +960,7 @@ pub async fn handle_get_pep_item<Fs: FileStore + Clone>(logic: &ClientLogic<Fs>,
} else {
// TODO: include expected entity
Err(PEPError::IncorrectEntity(
- from.unwrap_or_else(|| connection.jid().as_bare()),
+ from.unwrap_or_else(|| connection.jid().to_bare().into()),
))
}
}
@@ -1024,7 +1029,7 @@ pub async fn handle_delete_pep_node<Fs: FileStore + Clone>(
) -> Result<(), PEPError> {
let id = Uuid::new_v4().to_string();
let request = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: id.clone(),
to: None,
r#type: IqType::Set,
@@ -1046,7 +1051,7 @@ pub async fn handle_delete_pep_node<Fs: FileStore + Clone>(
// TODO: maybe abstract a bunch of these different errors related to iqs into an iq error thing? as in like call iq.result(), get the query from inside, error otherwise.
}) if r#type == IqType::Result || r#type == IqType::Error => {
if from == None ||
- from == Some(connection.jid().as_bare())
+ from == Some(connection.jid().to_bare().into())
{
match r#type {
IqType::Result => {
@@ -1067,7 +1072,7 @@ pub async fn handle_delete_pep_node<Fs: FileStore + Clone>(
}
} else {
Err(PEPError::IncorrectEntity(
- from.unwrap_or_else(|| connection.jid().as_bare()),
+ from.unwrap_or_else(|| connection.jid().to_bare().into()),
))
}
}
diff --git a/filamento/src/logic/process_stanza.rs b/filamento/src/logic/process_stanza.rs
index 30d0830..67b0d3f 100644
--- a/filamento/src/logic/process_stanza.rs
+++ b/filamento/src/logic/process_stanza.rs
@@ -70,7 +70,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
// TODO: proper id xep
.map(|id| Uuid::from_str(&id).unwrap_or_else(|_| Uuid::new_v4()))
.unwrap_or_else(|| Uuid::new_v4()),
- from: from.as_bare(),
+ from: from.to_bare(),
timestamp,
body: Body {
body: body.body.unwrap_or_default(),
@@ -80,31 +80,34 @@ pub async fn recv_message<Fs: FileStore + Clone>(
// TODO: process message type="error"
// save the message to the database
- match logic.db().upsert_chat_and_user(from.clone()).await {
- Ok(_) => {
- if let Err(e) = logic
- .db()
- .create_message_with_user_resource(
- message.clone(),
- from.clone(),
- from.clone(),
- )
- .await
- {
- error!("failed to create message: {}", e);
+ match logic.db().upsert_chat_and_user(from.to_bare()).await {
+ Ok(_) => match from.as_full() {
+ Ok(from) => {
+ if let Err(e) = logic
+ .db()
+ .create_message_with_user_resource(
+ message.clone(),
+ from.to_bare(),
+ from.clone(),
+ )
+ .await
+ {
+ error!("failed to create message: {}", e);
+ }
}
- }
+ Err(e) => error!("failed to create message: {}", e),
+ },
Err(e) => {
error!("failed to upsert chat and user: {}", e);
}
};
- let from_user = match logic.db().read_user(from.as_bare()).await {
+ let from_user = match logic.db().read_user(from.to_bare()).await {
Ok(u) => u,
Err(e) => {
error!("{}", e);
User {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: None,
avatar: None,
}
@@ -115,7 +118,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
logic
.update_sender()
.send(UpdateMessage::Message {
- to: from.as_bare(),
+ to: from.to_bare(),
from: from_user,
message,
})
@@ -125,13 +128,13 @@ pub async fn recv_message<Fs: FileStore + Clone>(
if let Some(nick) = stanza_message.nick {
let nick = nick.0;
if nick.is_empty() {
- match logic.db().delete_user_nick(from.as_bare()).await {
+ match logic.db().delete_user_nick(from.to_bare()).await {
Ok(changed) => {
if changed {
logic
.update_sender()
.send(UpdateMessage::NickChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: None,
})
.await;
@@ -145,7 +148,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
logic
.update_sender()
.send(UpdateMessage::NickChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: None,
})
.await;
@@ -154,7 +157,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
} else {
match logic
.db()
- .upsert_user_nick(from.as_bare(), nick.clone())
+ .upsert_user_nick(from.to_bare(), nick.clone())
.await
{
Ok(changed) => {
@@ -162,7 +165,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
logic
.update_sender()
.send(UpdateMessage::NickChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: Some(nick),
})
.await;
@@ -176,7 +179,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
logic
.update_sender()
.send(UpdateMessage::NickChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: Some(nick),
})
.await;
@@ -199,7 +202,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
if nick.is_empty() {
match logic
.db()
- .delete_user_nick(from.as_bare())
+ .delete_user_nick(from.to_bare())
.await
{
Ok(changed) => {
@@ -207,7 +210,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
logic
.update_sender()
.send(UpdateMessage::NickChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: None,
})
.await;
@@ -223,7 +226,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
logic
.update_sender()
.send(UpdateMessage::NickChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: None,
})
.await;
@@ -233,7 +236,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
match logic
.db()
.upsert_user_nick(
- from.as_bare(),
+ from.to_bare(),
nick.clone(),
)
.await
@@ -243,7 +246,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
logic
.update_sender()
.send(UpdateMessage::NickChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: Some(nick),
})
.await;
@@ -259,7 +262,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
logic
.update_sender()
.send(UpdateMessage::NickChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
nick: Some(nick),
})
.await;
@@ -294,7 +297,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
match logic
.db()
.upsert_user_avatar(
- from.as_bare(),
+ from.to_bare(),
metadata.id.clone(),
)
.await
@@ -323,7 +326,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
}) {
Ok(false) => {
// get data
- let pep_item = logic.client().get_pep_item(Some(from.as_bare()), "urn:xmpp:avatar:data".to_string(), metadata.id.clone()).await.map_err(|err| Into::<AvatarUpdateError<Fs>>::into(err))?;
+ let pep_item = logic.client().get_pep_item(Some(from.to_bare()), "urn:xmpp:avatar:data".to_string(), metadata.id.clone()).await.map_err(|err| Into::<AvatarUpdateError<Fs>>::into(err))?;
match pep_item {
crate::pep::Item::AvatarData(data) => {
let data = data.map(|data| data.data_b64).unwrap_or_default().replace("\n", "");
@@ -344,7 +347,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
.update_sender()
.send(
UpdateMessage::AvatarChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
id: Some(
metadata.id.clone(),
),
@@ -371,7 +374,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
.update_sender()
.send(
UpdateMessage::AvatarChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
id: Some(
metadata.id.clone(),
),
@@ -401,7 +404,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
// delete avatar
match logic
.db()
- .delete_user_avatar(from.as_bare())
+ .delete_user_avatar(from.to_bare())
.await
{
Ok((changed, old_avatar)) => {
@@ -419,7 +422,7 @@ pub async fn recv_message<Fs: FileStore + Clone>(
.update_sender()
.send(
UpdateMessage::AvatarChanged {
- jid: from.as_bare(),
+ jid: from.to_bare(),
id: None,
},
)
@@ -488,6 +491,7 @@ pub async fn recv_presence(
}
stanza::client::presence::PresenceType::Subscribe => {
// may get a subscription request from somebody who is not a contact!!! therefore should be its own kind of event
+ let from = from.try_into()?;
Ok(Some(UpdateMessage::SubscriptionRequest(from)))
}
stanza::client::presence::PresenceType::Unavailable => {
@@ -546,7 +550,8 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
iq: Iq,
) -> Result<Option<UpdateMessage>, IqProcessError> {
if let Some(to) = &iq.to {
- if *to == *connection.jid() {
+ // TODO: this clone could mayb b avoided
+ if *to == connection.jid().clone().into() {
} else {
return Err(IqProcessError::Iq(IqError::IncorrectAddressee(to.clone())));
}
@@ -556,7 +561,9 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
let from = iq
.from
.clone()
- .unwrap_or_else(|| connection.server().clone());
+ // TODO: maybe actually store the server in the connection again LOL
+ // .unwrap_or_else(|| connection.server().clone());
+ .unwrap_or_else(|| connection.jid().domainpart.parse().unwrap());
let id = iq.id.clone();
debug!("received iq result with id `{}` from {}", id, from);
logic
@@ -570,7 +577,8 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
let from = iq
.from
.clone()
- .unwrap_or_else(|| connection.server().clone());
+ // .unwrap_or_else(|| connection.server().clone());
+ .unwrap_or_else(|| connection.jid().domainpart.parse().unwrap());
if let Some(query) = iq.query {
match query {
stanza::client::iq::Query::DiscoInfo(query) => {
@@ -594,7 +602,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
}
Err(_e) => {
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Error,
@@ -614,7 +622,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
},
Err(_e) => {
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Error,
@@ -634,7 +642,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
}
};
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Result,
@@ -653,7 +661,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
_ => {
warn!("received unsupported iq get from {}", from);
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Error,
@@ -677,7 +685,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
} else {
info!("received malformed iq query from {}", from);
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Error,
@@ -698,7 +706,8 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
let from = iq
.from
.clone()
- .unwrap_or_else(|| connection.server().clone());
+ // .unwrap_or_else(|| connection.server().clone());
+ .unwrap_or_else(|| connection.jid().domainpart.parse().unwrap());
if let Some(query) = iq.query {
match query {
stanza::client::iq::Query::Roster(mut query) => {
@@ -725,7 +734,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
.await;
}
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Result,
@@ -751,7 +760,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
} else {
warn!("received malformed roster push");
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Error,
@@ -771,7 +780,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
_ => {
warn!("received unsupported iq set from {}", from);
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Error,
@@ -791,7 +800,7 @@ pub async fn recv_iq<Fs: FileStore + Clone>(
} else {
warn!("received malformed iq set from {}", from);
let iq = Iq {
- from: Some(connection.jid().clone()),
+ from: Some(connection.jid().clone().into()),
id: iq.id,
to: iq.from,
r#type: IqType::Error,
@@ -820,7 +829,7 @@ pub async fn process_stanza<Fs: FileStore + Clone>(
Stanza::Presence(presence) => Ok(recv_presence(presence).await?),
Stanza::Iq(iq) => Ok(recv_iq(logic, connection.clone(), iq).await?),
// unreachable, always caught by lampada
- // TODO: make cleaner than this in some way
+ // TODO: make cleaner than this in some way, by just reexporting a stanza enum from lampada ig.
Stanza::Error(error) => {
unreachable!()
}
diff --git a/filamento/src/roster.rs b/filamento/src/roster.rs
index 6b61e10..0498278 100644
--- a/filamento/src/roster.rs
+++ b/filamento/src/roster.rs
@@ -1,6 +1,6 @@
use std::{collections::HashSet, fmt::Display};
-use jid::JID;
+use jid::BareJID;
use rusqlite::{
ToSql,
types::{FromSql, ToSqlOutput, Value},
@@ -15,7 +15,7 @@ pub struct ContactUpdate {
#[cfg_attr(feature = "reactive_stores", derive(reactive_stores::Store))]
pub struct Contact {
// jid is the id used to reference everything, but not the primary key
- pub user_jid: JID,
+ pub user_jid: BareJID,
pub subscription: Subscription,
/// client user defined name
pub name: Option<String>,
diff --git a/filamento/src/user.rs b/filamento/src/user.rs
index f30933c..f962a4c 100644
--- a/filamento/src/user.rs
+++ b/filamento/src/user.rs
@@ -1,10 +1,10 @@
-use jid::JID;
+use jid::BareJID;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "reactive_stores", derive(reactive_stores::Store))]
pub struct User {
- pub jid: JID,
+ pub jid: BareJID,
pub nick: Option<String>,
pub avatar: Option<String>,
// pub cached_status_message: Option<String>,