diff --git a/Cargo.toml b/Cargo.toml
index 4aa2058..f5e5b7a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -57,7 +57,7 @@ uuid = { version = "1.6.1", features = ["serde"] }
tower-http = { version = "0.4.0", features = ["cors", "fs"], optional = true }
serde = { version = "1.0.192", features = ["derive"] }
url = { version = "2.4.1", features = ["serde"] }
-reqwest = { version = "0.11.22", features = ["json"] }
+reqwest = { version = "0.11.22", features = ["json", "cookies"] }
log = "0.4"
tracing = "0.1.40"
once_cell = "1.18.0"
@@ -68,7 +68,6 @@ time = "0.3.31"
[dev-dependencies]
pretty_assertions = "1.4.0"
-reqwest = { version = "0.11.22", features = ["cookies"] }
[package.metadata.leptos]
output-name = "ibis"
diff --git a/Trunk.toml b/Trunk.toml
index 101f859..10005a7 100644
--- a/Trunk.toml
+++ b/Trunk.toml
@@ -3,4 +3,4 @@ filehash = false
target = "assets/index.html"
[[proxy]]
-backend = "http://[::1]:8131"
+backend = "http://127.0.0.1:8131"
diff --git a/src/backend/api/user.rs b/src/backend/api/user.rs
index 9b0788a..9598c03 100644
--- a/src/backend/api/user.rs
+++ b/src/backend/api/user.rs
@@ -91,6 +91,7 @@ fn create_cookie(jwt: String, data: &Data) -> Cookie<'static> {
.same_site(SameSite::Strict)
.path("/")
.http_only(true)
+ .secure(true)
.expires(Expiration::DateTime(
OffsetDateTime::now_utc() + Duration::weeks(52),
))
diff --git a/src/frontend/api.rs b/src/frontend/api.rs
index f8d2363..60b3a39 100644
--- a/src/frontend/api.rs
+++ b/src/frontend/api.rs
@@ -6,13 +6,10 @@ use crate::common::{DbArticle, GetArticleData};
use crate::common::{DbInstance, FollowInstance, InstanceView, SearchArticleData};
use crate::frontend::error::MyResult;
use anyhow::anyhow;
-use once_cell::sync::Lazy;
use reqwest::{Client, RequestBuilder, StatusCode};
use serde::{Deserialize, Serialize};
use url::Url;
-pub static CLIENT: Lazy = Lazy::new(Client::new);
-
#[derive(Clone)]
pub struct ApiClient {
client: Client,
@@ -116,8 +113,9 @@ impl ApiClient {
let resolve_form = ResolveObject {
id: Url::parse(&format!("http://{}", follow_instance))?,
};
- let instance_resolved: DbInstance =
- get_query(&self.hostname, "instance/resolve", Some(resolve_form)).await?;
+ let instance_resolved: DbInstance = self
+ .get_query("instance/resolve", Some(resolve_form))
+ .await?;
// send follow
let follow_form = FollowInstance {
@@ -170,35 +168,29 @@ impl ApiClient {
pub async fn resolve_article(&self, id: Url) -> MyResult {
let resolve_object = ResolveObject { id };
- get_query(&self.hostname, "article/resolve", Some(resolve_object)).await
+ self.get_query("article/resolve", Some(resolve_object))
+ .await
}
pub async fn resolve_instance(&self, id: Url) -> MyResult {
let resolve_object = ResolveObject { id };
- get_query(&self.hostname, "instance/resolve", Some(resolve_object)).await
+ self.get_query("instance/resolve", Some(resolve_object))
+ .await
}
}
-async fn get_query(hostname: &str, endpoint: &str, query: Option) -> MyResult
+async fn handle_json_res(#[allow(unused_mut)] mut req: RequestBuilder) -> MyResult
where
T: for<'de> Deserialize<'de>,
- R: Serialize,
{
- let mut req = CLIENT.get(format!("http://{}/api/v1/{}", hostname, endpoint));
- if let Some(query) = query {
- req = req.query(&query);
+ #[cfg(not(feature = "ssr"))]
+ {
+ req = req.fetch_credentials_include();
}
- handle_json_res::(req).await
-}
-
-async fn handle_json_res(req: RequestBuilder) -> MyResult
-where
- T: for<'de> Deserialize<'de>,
-{
let res = req.send().await?;
let status = res.status();
let text = res.text().await?;
- if status == reqwest::StatusCode::OK {
+ if status == StatusCode::OK {
Ok(serde_json::from_str(&text).map_err(|e| anyhow!("Json error on {text}: {e}"))?)
} else {
Err(anyhow!("API error: {text}").into())
diff --git a/src/frontend/app.rs b/src/frontend/app.rs
index 45ea374..aa723a4 100644
--- a/src/frontend/app.rs
+++ b/src/frontend/app.rs
@@ -43,10 +43,9 @@ impl GlobalState {
create_local_resource(
move || (),
|_| async move {
- if let Ok(my_profile) = GlobalState::api_client().my_profile().await {
- expect_context::>()
- .update(|state| state.my_profile = Some(my_profile.clone()))
- };
+ let my_profile = GlobalState::api_client().my_profile().await.ok();
+ expect_context::>()
+ .update(|state| state.my_profile = my_profile.clone());
},
);
}
@@ -54,7 +53,7 @@ impl GlobalState {
#[component]
pub fn App() -> impl IntoView {
- let backend_hostname = "localhost:8080".to_string();
+ let backend_hostname = "127.0.0.1:8080".to_string();
provide_meta_context();
let backend_hostname = GlobalState {
diff --git a/src/frontend/components/nav.rs b/src/frontend/components/nav.rs
index b12ef71..5eb4a25 100644
--- a/src/frontend/components/nav.rs
+++ b/src/frontend/components/nav.rs
@@ -6,6 +6,12 @@ use leptos_router::*;
#[component]
pub fn Nav() -> impl IntoView {
let global_state = use_context::>().unwrap();
+ let logout_action = create_action(move |_| async move {
+ GlobalState::api_client().logout().await.unwrap();
+ expect_context::>()
+ .get_untracked()
+ .update_my_profile();
+ });
view! {
@@ -40,14 +42,3 @@ pub fn Nav() -> impl IntoView {
}
}
-
-fn do_logout() {
- dbg!("do logout");
- create_action(move |()| async move {
- dbg!("run logout action");
- GlobalState::api_client().logout().await.unwrap();
- expect_context::>()
- .get()
- .update_my_profile();
- });
-}
diff --git a/src/frontend/pages/article.rs b/src/frontend/pages/article.rs
index b95d364..5abdab6 100644
--- a/src/frontend/pages/article.rs
+++ b/src/frontend/pages/article.rs
@@ -26,12 +26,19 @@ pub fn Article() -> impl IntoView {
},
);
+ let global_state = use_context::>().unwrap();
+ let (count, set_count) = create_signal(0);
view! {
{move || article.get().map(|article|
view! {
{article.article.title}
+
+ Edit {move || count.get()}
+
{article.article.text}
})}
diff --git a/src/main.rs b/src/main.rs
index 40089c1..31b8ea8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,7 +8,7 @@ pub async fn main() -> ibis_lib::backend::error::MyResult<()> {
.filter_module("ibis", LevelFilter::Info)
.init();
let database_url = "postgres://ibis:password@localhost:5432/ibis";
- ibis_lib::backend::start("localhost:8131", database_url).await?;
+ ibis_lib::backend::start("127.0.0.1:8131", database_url).await?;
Ok(())
}
diff --git a/tests/common.rs b/tests/common.rs
index d192609..1fbafe8 100644
--- a/tests/common.rs
+++ b/tests/common.rs
@@ -115,16 +115,7 @@ impl IbisInstance {
username: username.to_string(),
password: "hunter2".to_string(),
};
- // use a separate http client for each backend instance, with cookie store for auth
- // how to pass the client/hostname to api client methods?
- // probably create a struct ApiClient(hostname, client) with all api methods in impl
- // TODO: seems that cookie isnt being stored? or maybe wrong hostname?
- let jar = Arc::new(Jar::default());
- let client = ClientBuilder::new()
- .cookie_store(true)
- .cookie_provider(jar.clone())
- .build()
- .unwrap();
+ let client = ClientBuilder::new().cookie_store(true).build().unwrap();
let api_client = ApiClient::new(client, hostname.clone());
api_client.register(form).await.unwrap();
Self {