use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation};
use serde::{Deserialize, Serialize};
use std::{
env,
error::Error,
io,
ops::Add,
time::{SystemTime, UNIX_EPOCH},
};
use uuid::Uuid;
pub struct Cookie {}
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
sub: String,
name: String,
email: String,
iat: u64,
exp: u64,
}
pub struct Users {
pub name: String,
pub email: String,
pub exp: u64,
}
impl Cookie {
pub fn encode(secret: String, claims: Users) -> Result<String, Box<dyn Error>> {
let secret = env::var(secret);
let claim = Claims {
sub: Uuid::new_v4().to_string(),
name: claims.name,
email: claims.email,
iat: SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs(),
exp: SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
.add(claims.exp),
};
match secret {
Ok(secret) => {
let encode_key = EncodingKey::from_secret(secret.as_bytes());
let encode = encode(&Header::default(), &claim, &encode_key);
match encode {
Ok(ecoded_cookie) => {
Ok(ecoded_cookie)
}
Err(err) => Err(Box::new(io::Error::new(
io::ErrorKind::InvalidData,
err.to_string(),
))),
}
}
Err(err) => Err(Box::new(io::Error::new(
io::ErrorKind::InvalidData,
err.to_string(),
))),
}
}
pub fn decode(secret: String, cookie: String) -> Result<TokenData<Claims>, Box<dyn Error>> {
let secret = env::var(secret);
match secret {
Ok(secret) => {
let decode_key = DecodingKey::from_secret(secret.as_bytes());
let encode = decode(
&cookie,
&decode_key,
&Validation::new(jsonwebtoken::Algorithm::HS256),
);
match encode {
Ok(encode) => Ok(encode),
Err(err) => Err(Box::new(io::Error::new(
io::ErrorKind::InvalidData,
err.to_string(),
))),
}
}
Err(err) => Err(Box::new(io::Error::new(
io::ErrorKind::InvalidData,
err.to_string(),
))),
}
}
}