use chrono::{DateTime, Utc};
use ulid::Ulid;
mod device;
mod session;
mod sso_login;
pub use self::{
device::Device,
session::{CompatSession, CompatSessionState},
sso_login::{CompatSsoLogin, CompatSsoLoginState},
};
use crate::InvalidTransitionError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CompatAccessToken {
pub id: Ulid,
pub session_id: Ulid,
pub token: String,
pub created_at: DateTime<Utc>,
pub expires_at: Option<DateTime<Utc>>,
}
impl CompatAccessToken {
#[must_use]
pub fn is_valid(&self, now: DateTime<Utc>) -> bool {
if let Some(expires_at) = self.expires_at {
expires_at > now
} else {
true
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub enum CompatRefreshTokenState {
#[default]
Valid,
Consumed {
consumed_at: DateTime<Utc>,
},
}
impl CompatRefreshTokenState {
#[must_use]
pub fn is_valid(&self) -> bool {
matches!(self, Self::Valid)
}
#[must_use]
pub fn is_consumed(&self) -> bool {
matches!(self, Self::Consumed { .. })
}
pub fn consume(self, consumed_at: DateTime<Utc>) -> Result<Self, InvalidTransitionError> {
match self {
Self::Valid => Ok(Self::Consumed { consumed_at }),
Self::Consumed { .. } => Err(InvalidTransitionError),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CompatRefreshToken {
pub id: Ulid,
pub state: CompatRefreshTokenState,
pub session_id: Ulid,
pub access_token_id: Ulid,
pub token: String,
pub created_at: DateTime<Utc>,
}
impl std::ops::Deref for CompatRefreshToken {
type Target = CompatRefreshTokenState;
fn deref(&self) -> &Self::Target {
&self.state
}
}
impl CompatRefreshToken {
pub fn consume(mut self, consumed_at: DateTime<Utc>) -> Result<Self, InvalidTransitionError> {
self.state = self.state.consume(consumed_at)?;
Ok(self)
}
}