bevy_gotrue/
builder.rs

1use ehttp::{Headers, Request};
2use serde_json::json;
3
4use crate::UserAttributes;
5
6#[derive(Clone)]
7pub struct Builder {
8    pub url: String,
9    pub headers: Headers,
10}
11
12#[derive(Clone)]
13pub enum EmailOrPhone {
14    Email(String),
15    Phone(String),
16}
17// TODO detect email by looking for @
18// if no @, assume is phone number
19
20impl Builder {
21    pub fn new(url: impl Into<String>) -> Builder {
22        Builder {
23            url: url.into(),
24            headers: Headers::new(&vec![]),
25        }
26    }
27
28    /// Add arbitrary headers to the request. For instance when you may want to connect
29    /// through an API gateway that needs an API key header.
30    pub fn insert_header(
31        &mut self,
32        header_name: impl ToString,
33        header_value: impl ToString,
34    ) -> &mut Self {
35        self.headers.insert(header_name, header_value);
36        self
37    }
38
39    /// Signs up for a new account
40    pub fn sign_up(&self, email_or_phone: EmailOrPhone, password: impl AsRef<str>) -> Request {
41        let endpoint = format!("{}/signup", self.url);
42
43        let body = match email_or_phone {
44            EmailOrPhone::Email(email) => json!({
45                "email": email,
46                "password": password.as_ref(),
47            }),
48            EmailOrPhone::Phone(phone) => json!({
49                "phone": phone,
50                "password": password.as_ref()
51            }),
52        };
53
54        Request {
55            method: "POST".to_string(),
56            url: endpoint,
57            headers: self.headers.clone(),
58            body: body.to_string().into(),
59        }
60    }
61
62    /// Signs into an existing account
63    pub fn sign_in(&self, email_or_phone: EmailOrPhone, password: impl AsRef<str>) -> Request {
64        let query_string = String::from("?grant_type=password");
65
66        let endpoint = format!("{}/token{}", self.url, query_string);
67
68        let body = match email_or_phone {
69            EmailOrPhone::Email(email) => json!({
70                "email": email,
71                "password": password.as_ref(),
72            }),
73            EmailOrPhone::Phone(phone) => json!({
74                "phone": phone,
75                "password": password.as_ref()
76            }),
77        };
78
79        Request {
80            method: "POST".to_string(),
81            url: endpoint,
82            headers: self.headers.clone(),
83            body: body.to_string().into(),
84        }
85    }
86
87    /// Sends an OTP Code and creates user if it does not exist
88    pub fn send_otp(&self, email_or_phone: EmailOrPhone, should_create_user: bool) -> Request {
89        let endpoint = format!("{}/otp", self.url);
90
91        let body = match email_or_phone {
92            EmailOrPhone::Email(email) => json!({
93                "email": email,
94                "should_create_user": should_create_user
95            }),
96            EmailOrPhone::Phone(phone) => json!({
97                "phone": phone,
98                "should_create_user": should_create_user
99            }),
100        };
101
102        Request {
103            method: "POST".to_string(),
104            url: endpoint,
105            headers: self.headers.clone(),
106            body: body.to_string().into(),
107        }
108    }
109
110    pub fn verify_otp<T: serde::Serialize>(&self, params: T) -> Request {
111        let endpoint = format!("{}/verify", self.url);
112
113        let body = serde_json::to_value(&params).unwrap();
114
115        Request {
116            method: "POST".to_string(),
117            url: endpoint,
118            headers: self.headers.clone(),
119            body: body.to_string().into(),
120        }
121    }
122
123    /// Signs the current user out
124    pub fn sign_out(&self, access_token: impl AsRef<str>) -> Request {
125        let endpoint = format!("{}/logout", self.url);
126
127        let mut headers = self.headers.clone();
128        let bearer = format!("Bearer {}", access_token.as_ref());
129        headers.insert("Authorization", bearer.as_str());
130
131        Request {
132            method: "POST".to_string(),
133            url: endpoint,
134            headers: self.headers.clone(),
135            body: Default::default(),
136        }
137    }
138
139    /// Sends password recovery email
140    pub fn reset_password_for_email(&self, email: impl AsRef<str>) -> Request {
141        let endpoint = format!("{}/recover", self.url);
142
143        let body = json!({
144            "email": email.as_ref(),
145        });
146
147        Request {
148            method: "POST".to_string(),
149            url: endpoint,
150            headers: self.headers.clone(),
151            body: body.to_string().into(),
152        }
153    }
154
155    /// Refreshes the current session by refresh token
156    pub fn refresh_access_token(&self, refresh_token: impl AsRef<str>) -> Request {
157        let endpoint = format!("{}/token?grant_type=refresh_token", self.url);
158        let body = json!({ "refresh_token": refresh_token.as_ref() });
159
160        Request {
161            method: "POST".to_string(),
162            url: endpoint,
163            headers: self.headers.clone(),
164            body: body.to_string().into(),
165        }
166    }
167
168    /// Gets a user by access token
169    pub fn get_user(&self, jwt: impl AsRef<str>) -> Request {
170        let endpoint = format!("{}/user", self.url);
171
172        let mut headers = self.headers.clone();
173        let bearer = format!("Bearer {}", jwt.as_ref());
174        headers.insert("Authorization", bearer.as_str());
175
176        Request {
177            method: "GET".to_string(),
178            url: endpoint,
179            headers: self.headers.clone(),
180            body: Default::default(),
181        }
182    }
183
184    /// Updates a user
185    pub fn update_user(&self, user: UserAttributes, jwt: impl AsRef<str>) -> Request {
186        let endpoint = format!("{}/user", self.url);
187
188        let mut headers = self.headers.clone();
189        let bearer = format!("Bearer {}", jwt.as_ref());
190        headers.insert("Authorization", bearer.as_str());
191
192        let body = json!({"email": user.email, "password": user.password, "data": user.data});
193
194        Request {
195            method: "PUT".to_string(),
196            url: endpoint,
197            headers: self.headers.clone(),
198            body: body.to_string().into(),
199        }
200    }
201
202    /// Invites a user via email
203    pub fn invite_user_by_email(&self, email: impl AsRef<str>) -> Request {
204        let endpoint = format!("{}/invite", self.url);
205
206        let body = json!({
207            "email": email.as_ref(),
208        });
209
210        Request {
211            method: "POST".to_string(),
212            url: endpoint,
213            headers: self.headers.clone(),
214            body: body.to_string().into(),
215        }
216    }
217
218    /// Lists all users based on a query string
219    pub fn list_users(&self, query_string: Option<String>) -> Request {
220        let endpoint = match query_string {
221            Some(query) => format!("{}/admin/users{}", self.url, query),
222            None => format!("{}/admin/users", self.url),
223        };
224
225        Request {
226            method: "GET".to_string(),
227            url: endpoint,
228            headers: self.headers.clone(),
229            body: Default::default(),
230        }
231    }
232
233    /// Gets a user by id
234    pub fn get_user_by_id(&self, user_id: impl AsRef<str>) -> Request {
235        let endpoint = format!("{}/admin/users/{}", self.url, user_id.as_ref());
236
237        Request {
238            method: "GET".to_string(),
239            url: endpoint,
240            headers: self.headers.clone(),
241            body: Default::default(),
242        }
243    }
244
245    /// Creates a user
246    pub fn create_user<T: serde::Serialize>(&self, user: T) -> Request {
247        let endpoint = format!("{}/admin/users", self.url);
248
249        let body = serde_json::to_value(&user).unwrap();
250
251        Request {
252            method: "POST".to_string(),
253            url: endpoint,
254            headers: self.headers.clone(),
255            body: body.to_string().into(),
256        }
257    }
258
259    /// Updates a user by id
260    pub fn update_user_by_id<T: serde::Serialize>(&self, id: impl AsRef<str>, user: T) -> Request {
261        let endpoint = format!("{}/admin/users/{}", self.url, id.as_ref());
262
263        let body = serde_json::to_value(&user).unwrap();
264        Request {
265            method: "PUT".to_string(),
266            url: endpoint,
267            headers: self.headers.clone(),
268            body: body.to_string().into(),
269        }
270    }
271
272    /// Deletes a user by id
273    pub fn delete_user(&self, user_id: impl AsRef<str>) -> Request {
274        let endpoint = format!("{}/admin/users/{}", self.url, user_id.as_ref());
275
276        Request {
277            method: "DELETE".to_string(),
278            url: endpoint,
279            headers: self.headers.clone(),
280            body: Default::default(),
281        }
282    }
283}