You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
4.5 KiB
164 lines
4.5 KiB
use std::{error::Error, fmt::Display, time::Duration};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::api::FastInsidersApi;
|
|
|
|
#[cfg(client)]
|
|
#[derive(Serialize)]
|
|
pub struct UserLoginBody {
|
|
pub name: String,
|
|
pub password: String,
|
|
}
|
|
|
|
#[cfg(client)]
|
|
#[derive(Serialize)]
|
|
pub struct UserRegisterBody {
|
|
pub name: String,
|
|
pub email: String,
|
|
pub password: String,
|
|
}
|
|
|
|
#[cfg(client)]
|
|
type Response = reqwasm::http::Response;
|
|
|
|
#[cfg(client)]
|
|
#[derive(Deserialize)]
|
|
struct LoginResponse {
|
|
pub token: String,
|
|
}
|
|
|
|
#[cfg(client)]
|
|
#[derive(Debug, Deserialize)]
|
|
pub enum LoginError {
|
|
Unknown,
|
|
InvalidCredentials,
|
|
InternalServer(String),
|
|
Server(String),
|
|
UserNotFound(String),
|
|
}
|
|
|
|
#[cfg(client)]
|
|
#[derive(Deserialize)]
|
|
struct ErrorBody {
|
|
error: String,
|
|
}
|
|
|
|
#[cfg(client)]
|
|
impl Display for LoginError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::Unknown => {
|
|
write!(f, "There was an unknown error while trying to log you in.").to_owned()
|
|
}
|
|
Self::InternalServer(e) => write!(f, "Internal server error: {}", e),
|
|
Self::Server(e) => write!(f, "There was an error completing the request {}", e),
|
|
Self::InvalidCredentials => write!(f, "Invalid username or password"),
|
|
Self::UserNotFound(e) => write!(f, "{e}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(client)]
|
|
impl Error for LoginError {}
|
|
|
|
#[cfg(client)]
|
|
#[derive(Debug, Deserialize)]
|
|
pub enum RegisterError {
|
|
Unknown,
|
|
InternalServer(String),
|
|
Server(String),
|
|
Conflict(String),
|
|
}
|
|
|
|
#[cfg(client)]
|
|
impl Display for RegisterError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::Unknown => {
|
|
write!(f, "There was an unknown error while trying to log you in.").to_owned()
|
|
}
|
|
Self::InternalServer(e) => write!(f, "Internal server error: {}", e),
|
|
Self::Server(e) => write!(f, "There was an error completing the request {}", e),
|
|
Self::Conflict(e) => write!(f, "{e}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(client)]
|
|
impl Error for RegisterError {}
|
|
|
|
#[cfg(client)]
|
|
pub fn set_token_cookie(token: &str) {
|
|
use wasm_cookies::CookieOptions;
|
|
let cookie_options = CookieOptions::default()
|
|
.secure()
|
|
.with_same_site(wasm_cookies::SameSite::Strict)
|
|
.expires_after(Duration::from_secs(60 * 60 * 24 * 5)); // 5 days
|
|
|
|
wasm_cookies::set("token", token, &cookie_options);
|
|
}
|
|
|
|
#[cfg(client)]
|
|
impl FastInsidersApi {
|
|
pub async fn login(&self, body: &UserLoginBody) -> Result<(), LoginError> {
|
|
let route = &format!("{}/user/login", self.url);
|
|
|
|
let resp = reqwasm::http::Request::post(route)
|
|
.header("Content-type", "application/json")
|
|
.body(serde_json::to_string(&body).unwrap())
|
|
.send()
|
|
.await
|
|
.map_err(|e| LoginError::Server(e.to_string()))?;
|
|
|
|
if resp.status() == 200 {
|
|
if let Ok(data) = resp.json::<LoginResponse>().await {
|
|
set_token_cookie(&data.token);
|
|
return Ok(());
|
|
} else {
|
|
panic!();
|
|
}
|
|
}
|
|
|
|
match resp.status() {
|
|
401 => return Err(LoginError::InvalidCredentials),
|
|
500 => {
|
|
let error = resp.json::<ErrorBody>().await.unwrap().error;
|
|
return Err(LoginError::InternalServer(error));
|
|
}
|
|
404 => {
|
|
let error = resp.json::<ErrorBody>().await.unwrap().error;
|
|
return Err(LoginError::UserNotFound(error));
|
|
}
|
|
_ => return Err(LoginError::Unknown),
|
|
}
|
|
}
|
|
|
|
pub async fn register(&self, body: &UserRegisterBody) -> Result<(), RegisterError> {
|
|
let route = &format!("{}/user/register", self.url);
|
|
|
|
use wasm_cookies::CookieOptions;
|
|
let resp = reqwasm::http::Request::post(route)
|
|
.header("Content-type", "application/json")
|
|
.body(serde_json::to_string(&body).unwrap())
|
|
.send()
|
|
.await
|
|
.map_err(|e| RegisterError::Server(e.to_string()))?;
|
|
|
|
if resp.status() == 200 {
|
|
return Ok(());
|
|
}
|
|
|
|
if resp.status() == 500 {
|
|
let error = resp.json::<ErrorBody>().await.unwrap().error;
|
|
return Err(RegisterError::InternalServer(error));
|
|
}
|
|
|
|
if resp.status() == 409 {
|
|
let error = resp.json::<ErrorBody>().await.unwrap().error;
|
|
return Err(RegisterError::Conflict(error));
|
|
}
|
|
Err(RegisterError::Unknown)
|
|
}
|
|
}
|