#![forbid(non_ascii_idents)] #![allow(clippy::nonstandard_macro_braces)] use chrono::prelude::*; use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::fmt; pub mod opaque; /// The messages for the 3-step OPAQUE and simple login process. pub mod login { use super::{types::UserId, *}; #[derive(Serialize, Deserialize, Clone)] pub struct ServerData { pub username: UserId, pub server_login: opaque::server::login::ServerLogin, } #[derive(Serialize, Deserialize, Clone)] pub struct ClientLoginStartRequest { pub username: UserId, pub login_start_request: opaque::server::login::CredentialRequest, } #[derive(Serialize, Deserialize, Clone)] pub struct ServerLoginStartResponse { /// Base64, encrypted ServerData to be passed back to the server. pub server_data: String, pub credential_response: opaque::client::login::CredentialResponse, } #[derive(Serialize, Deserialize, Clone)] pub struct ClientLoginFinishRequest { /// Encrypted ServerData from the previous step. pub server_data: String, pub credential_finalization: opaque::client::login::CredentialFinalization, } #[derive(Serialize, Deserialize, Clone)] pub struct ClientSimpleLoginRequest { pub username: UserId, pub password: String, } impl fmt::Debug for ClientSimpleLoginRequest { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ClientSimpleLoginRequest") .field("username", &self.username.as_str()) .field("password", &"***********") .finish() } } #[derive(Serialize, Deserialize, Clone)] pub struct ServerLoginResponse { pub token: String, #[serde(rename = "refreshToken", skip_serializing_if = "Option::is_none")] pub refresh_token: Option, } } /// The messages for the 3-step OPAQUE registration process. /// It is used to reset a user's password. pub mod registration { use super::{types::UserId, *}; #[derive(Serialize, Deserialize, Clone)] pub struct ServerData { pub username: UserId, } #[derive(Serialize, Deserialize, Clone)] pub struct ClientRegistrationStartRequest { pub username: UserId, pub registration_start_request: opaque::server::registration::RegistrationRequest, } #[derive(Serialize, Deserialize, Clone)] pub struct ServerRegistrationStartResponse { /// Base64, encrypted ServerData to be passed back to the server. pub server_data: String, pub registration_response: opaque::client::registration::RegistrationResponse, } #[derive(Serialize, Deserialize, Clone)] pub struct ClientRegistrationFinishRequest { /// Encrypted ServerData from the previous step. pub server_data: String, pub registration_upload: opaque::server::registration::RegistrationUpload, } } /// The messages for the 3-step OPAQUE registration process. /// It is used to reset a user's password. pub mod password_reset { use super::*; #[derive(Serialize, Deserialize, Clone)] pub struct ServerPasswordResetResponse { #[serde(rename = "userId")] pub user_id: String, pub token: String, } } pub mod types { use serde::{Deserialize, Serialize}; #[cfg(feature = "sea_orm")] use sea_orm::{DbErr, DeriveValueType, QueryResult, TryFromU64, Value}; #[derive( PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Default, Hash, Serialize, Deserialize, )] #[cfg_attr(feature = "sea_orm", derive(DeriveValueType))] #[serde(from = "String")] pub struct CaseInsensitiveString(String); impl CaseInsensitiveString { pub fn new(s: &str) -> Self { Self(s.to_ascii_lowercase()) } pub fn as_str(&self) -> &str { self.0.as_str() } pub fn into_string(self) -> String { self.0 } } impl From for CaseInsensitiveString { fn from(mut s: String) -> Self { s.make_ascii_lowercase(); Self(s) } } impl From<&String> for CaseInsensitiveString { fn from(s: &String) -> Self { Self::new(s.as_str()) } } impl From<&str> for CaseInsensitiveString { fn from(s: &str) -> Self { Self::new(s) } } #[derive( PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Default, Hash, Serialize, Deserialize, )] #[cfg_attr(feature = "sea_orm", derive(DeriveValueType))] #[serde(from = "CaseInsensitiveString")] pub struct UserId(CaseInsensitiveString); impl UserId { pub fn new(s: &str) -> Self { s.into() } pub fn as_str(&self) -> &str { self.0.as_str() } pub fn into_string(self) -> String { self.0.into_string() } } impl From for UserId where T: Into, { fn from(s: T) -> Self { Self(s.into()) } } impl std::fmt::Display for UserId { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.0.as_str()) } } #[cfg(feature = "sea_orm")] impl From<&UserId> for Value { fn from(user_id: &UserId) -> Self { user_id.as_str().into() } } #[cfg(feature = "sea_orm")] impl TryFromU64 for UserId { fn try_from_u64(_n: u64) -> Result { Err(DbErr::ConvertFromU64( "UserId cannot be constructed from u64", )) } } } #[derive(Clone, Serialize, Deserialize)] pub struct JWTClaims { pub exp: DateTime, pub iat: DateTime, pub user: String, pub groups: HashSet, }