dummy_json_rs/
auth.rs

1//! Auth module
2//! The auth endpoint provides details about the user authentication and authorization and refresh
3//! tokens.
4//!
5//! https://dummyjson.com/docs/auth
6
7use crate::{DummyJsonClient, API_BASE_URL};
8use once_cell::sync::Lazy;
9use serde::{Deserialize, Serialize};
10use serde_json::json;
11
12static AUTH_BASE_URL: Lazy<String> = Lazy::new(|| format!("{}/auth", API_BASE_URL));
13
14/// Login request payload
15#[derive(Serialize)]
16pub struct LoginRequest {
17	pub username: String,
18	pub password: String,
19	#[serde(rename = "expiresInMins")]
20	pub expires_in_mins: Option<u32>,
21}
22
23/// Login response
24#[derive(Deserialize, Debug)]
25pub struct LoginResponse {
26	pub id: u32,
27	pub username: String,
28	pub email: String,
29	#[serde(rename = "firstName")]
30	pub first_name: String,
31	#[serde(rename = "lastName")]
32	pub last_name: String,
33	pub gender: String,
34	pub image: String,
35	/// JWT accessToken (for backward compatibility) in response and cookies
36	#[serde(rename = "accessToken")]
37	pub access_token: String,
38	/// refreshToken in response and cookies
39	#[serde(rename = "refreshToken")]
40	pub refresh_token: String,
41}
42
43#[derive(Serialize, Deserialize, Debug)]
44pub struct User {
45	pub id: u32,
46	#[serde(flatten)]
47	pub other_fields: AddUserPayload,
48}
49
50#[derive(Serialize, Deserialize, Debug, Default)]
51pub struct AddUserPayload {
52	#[serde(rename = "firstName")]
53	pub first_name: Option<String>,
54	#[serde(rename = "lastName")]
55	pub last_name: Option<String>,
56	#[serde(rename = "maidenName")]
57	pub maiden_name: Option<String>,
58	pub age: Option<u8>,
59	pub gender: Option<String>,
60	pub email: Option<String>,
61	pub phone: Option<String>,
62	pub username: Option<String>,
63	pub password: Option<String>,
64	#[serde(rename = "birthDate")]
65	pub birth_date: Option<String>,
66	pub image: Option<String>,
67	#[serde(rename = "bloodGroup")]
68	pub blood_group: Option<String>,
69	pub height: Option<f32>,
70	pub weight: Option<f32>,
71	#[serde(rename = "eyeColor")]
72	pub eye_color: Option<String>,
73	pub hair: Option<Hair>,
74	// TODO: Add other fields
75}
76#[derive(Serialize, Deserialize, Debug)]
77pub struct Hair {
78	pub color: String,
79	#[serde(rename = "type")]
80	pub r#type: String,
81}
82
83/// Refresh response
84#[derive(Deserialize, Debug)]
85pub struct RefreshResponse {
86	#[serde(rename = "accessToken")]
87	pub access_token: String,
88	#[serde(rename = "refreshToken")]
89	pub refresh_token: String,
90}
91
92impl DummyJsonClient {
93	/// Login to the dummyjson API
94	pub async fn login(
95		&self,
96		username: &str,
97		password: &str,
98		expires_in_mins: Option<u32>,
99	) -> Result<LoginResponse, reqwest::Error> {
100		let payload: LoginRequest = LoginRequest {
101			username: username.to_string(),
102			password: password.to_string(),
103			expires_in_mins,
104		};
105
106		let url = format!("{}/login", AUTH_BASE_URL.as_str());
107		let response = self.client.post(url).json(&payload).send().await?;
108		response.json().await
109	}
110
111	/// Get the current user
112	pub async fn get_user(&self, access_token: &str) -> Result<User, reqwest::Error> {
113		let url = format!("{}/me", AUTH_BASE_URL.as_str());
114		let response = self
115			.client
116			.get(url)
117			.header("Authorization", format!("Bearer {}", access_token))
118			.send()
119			.await?;
120		response.json().await
121	}
122
123	/// Refresh the auth session
124	pub async fn refresh_auth_session(
125		&self,
126		refresh_token: &str,
127		expires_in_mins: u32,
128	) -> Result<RefreshResponse, reqwest::Error> {
129		let payload = json!({
130			"refreshToken": refresh_token,
131			"expiresInMins": expires_in_mins,
132		});
133
134		let url = format!("{}/refresh", AUTH_BASE_URL.as_str());
135		let response = self.client.post(url).json(&payload).send().await?;
136		response.json().await
137	}
138}