Skip to content

Commit 2ca11a8

Browse files
feat(dioxus): add query params (#333)
1 parent 5cfdcfe commit 2ca11a8

14 files changed

Lines changed: 95 additions & 38 deletions

File tree

Cargo.lock

Lines changed: 17 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/shield/src/shield.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,16 @@ impl<U: User> Shield<U> {
139139
}
140140
}
141141

142+
provider_forms.sort_by(|a, b| a.id.cmp(&b.id));
143+
142144
method_forms.push(ActionMethodForm {
143145
id: method_id.clone(),
144146
provider_forms,
145147
});
146148
}
147149

150+
method_forms.sort_by(|a, b| a.id.cmp(&b.id));
151+
148152
Ok(ActionForms {
149153
id: action_id.to_owned(),
150154
name: action_name.unwrap_or(action_id.to_owned()),

packages/integrations/shield-dioxus/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ server = ["dioxus/server"]
1515
anyhow.workspace = true
1616
dioxus = { workspace = true, features = ["fullstack", "router"] }
1717
serde_json.workspace = true
18+
serde_qs = "1.0.0"
1819
shield.workspace = true
1920
tracing.workspace = true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
mod integration;
2+
mod query;
23
mod router;
34
mod routes;
45
mod style;
56

67
pub use integration::*;
8+
pub use query::*;
79
pub use router::*;
810
pub use routes::call;
911
pub use style::*;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use std::{collections::HashMap, ops::Deref};
2+
3+
#[derive(Clone, Debug)]
4+
pub struct Query(HashMap<String, String>);
5+
6+
impl Query {
7+
pub fn parse(query: &str) -> Self {
8+
Self(serde_qs::from_str::<HashMap<String, String>>(query).unwrap_or_default())
9+
}
10+
}
11+
12+
impl Deref for Query {
13+
type Target = HashMap<String, String>;
14+
15+
fn deref(&self) -> &Self::Target {
16+
&self.0
17+
}
18+
}

packages/integrations/shield-dioxus/src/router.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::routes::Action;
44

55
#[derive(Clone, Debug, PartialEq, Routable)]
66
pub enum ShieldRouter {
7-
#[route("", Action)]
8-
ActionIndex,
9-
#[route("/:action_id")]
10-
Action { action_id: String },
7+
#[route("?:..query", Action)]
8+
ActionIndex { query: String },
9+
#[route("/:action_id?:..query")]
10+
Action { action_id: String, query: String },
1111
}

packages/integrations/shield-dioxus/src/routes/action.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ use dioxus::prelude::*;
22
use serde_json::Value;
33
use shield::{ActionForms, ResponseType};
44

5-
use crate::ErasedDioxusStyle;
5+
use crate::{query::Query, style::ErasedDioxusStyle};
66

77
#[derive(Clone, PartialEq, Props)]
88
pub struct ActionProps {
99
#[props(default = "index".to_owned())]
1010
action_id: String,
11+
query: String,
1112
}
1213

1314
#[component]
@@ -22,6 +23,8 @@ pub fn Action(props: ActionProps) -> Element {
2223
let response_read = response.read();
2324
let response = response_read.as_ref().unwrap();
2425

26+
use_context_provider(|| Query::parse(&props.query));
27+
2528
match response {
2629
Ok(forms) => style.render(forms),
2730
Err(err) => rsx! { "{err}" },

packages/methods/shield-email/src/actions/sign_in.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,24 +97,19 @@ impl<U: User + 'static> Action<EmailProvider, ()> for EmailSignInAction<U> {
9797
.map_err(|err| ShieldError::Validation(err.to_string()))?;
9898

9999
let token = Alphanumeric.sample_string(&mut rand::rng(), 32);
100-
let expires_at = Utc::now() + self.options.expires_in;
101100

102101
let email_auth_token = self
103102
.storage
104103
.create_email_auth_token(CreateEmailAuthToken {
105104
email: data.email.to_lowercase(),
106105
token: hash_token(&token, &self.options.secret),
107-
expired_at: expires_at.into(),
106+
expired_at: (Utc::now() + self.options.expires_in).into(),
108107
})
109108
.await?;
110109

111110
self.options
112111
.sender
113-
.send(
114-
&email_auth_token.email,
115-
&email_auth_token.token,
116-
email_auth_token.expired_at,
117-
)
112+
.send(&email_auth_token.email, &token, email_auth_token.expired_at)
118113
.await?;
119114

120115
Ok(Response::new(ResponseType::Default).session_action(SessionAction::unauthenticate()))

packages/methods/shield-email/src/actions/sign_in_callback.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use chrono::Utc;
55
use serde::Deserialize;
66
use shield::{
77
Action, ActionMethod, CreateEmailAddress, CreateUser, Form, Input, InputType, InputTypeEmail,
8-
InputTypeSubmit, InputValue, MethodSession, Request, Response, ResponseType, SessionAction,
9-
ShieldError, SignInCallbackAction, User, erased_action,
8+
InputTypeSubmit, InputTypeText, InputValue, MethodSession, Request, Response, ResponseType,
9+
SessionAction, ShieldError, SignInCallbackAction, User, erased_action,
1010
};
1111

1212
use crate::{
@@ -51,7 +51,7 @@ impl<U: User + 'static> Action<EmailProvider, ()> for EmailSignInCallbackAction<
5151
}
5252

5353
fn method(&self) -> ActionMethod {
54-
ActionMethod::Get
54+
ActionMethod::Post
5555
}
5656

5757
fn condition(
@@ -74,19 +74,23 @@ impl<U: User + 'static> Action<EmailProvider, ()> for EmailSignInCallbackAction<
7474
required: Some(true),
7575
..Default::default()
7676
}),
77-
value: None,
77+
value: Some(InputValue::Query {
78+
key: "email".to_owned(),
79+
}),
7880
addon_start: None,
7981
addon_end: None,
8082
},
8183
Input {
8284
name: "token".to_owned(),
8385
label: Some("Token".to_owned()),
84-
r#type: InputType::Email(InputTypeEmail {
86+
r#type: InputType::Text(InputTypeText {
8587
placeholder: Some("Token".to_owned()),
8688
required: Some(true),
8789
..Default::default()
8890
}),
89-
value: None,
91+
value: Some(InputValue::Query {
92+
key: "token".to_owned(),
93+
}),
9094
addon_start: None,
9195
addon_end: None,
9296
},
@@ -147,7 +151,10 @@ impl<U: User + 'static> Action<EmailProvider, ()> for EmailSignInCallbackAction<
147151
}
148152
};
149153

150-
Ok(Response::new(ResponseType::Default).session_action(SessionAction::authenticate(user)))
154+
Ok(Response::new(ResponseType::Redirect(
155+
self.options.sign_in_redirect.clone(),
156+
))
157+
.session_action(SessionAction::authenticate(user)))
151158
}
152159
}
153160

packages/methods/shield-email/src/options.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use secrecy::SecretString;
77
use crate::sender::Sender;
88

99
#[derive(Builder, Clone)]
10-
#[builder(state_mod(vis = "pub(crate)"))]
10+
#[builder(on(String, into), state_mod(vis = "pub(crate)"))]
1111
pub struct EmailOptions {
1212
#[builder(into)]
1313
pub(crate) secret: SecretString,
@@ -17,4 +17,7 @@ pub struct EmailOptions {
1717

1818
#[builder(default = TimeDelta::minutes(10))]
1919
pub(crate) expires_in: TimeDelta,
20+
21+
#[builder(default = "/")]
22+
pub(crate) sign_in_redirect: String,
2023
}

0 commit comments

Comments
 (0)