small_jwt 1.1.0

Simple and small JWT libary
Documentation
//! Encode function home.

use crate::{Result, utils, Header};

/// Encodes Header and payload into JWT.
///
/// # Usage
/// ```
/// #[derive(Debug, serde::Serialize)]
/// pub struct Claims {
///     pub user: String,
/// }
///
/// let header = small_jwt::Header::default();
///
/// let claims = Claims {
///     user: String::from("username"),
/// };
///
/// let key = b"test";
///
/// let token = small_jwt::encode(&header, &claims, key);
/// ```
pub fn encode<P>(
    header: &Header,
    payload: &P,
    secret_key: &[u8],
) -> Result<String>
where
    P: serde::Serialize
{
    let sign = header.alg.sign_fn();
    let header_encoded = utils::to_json_b64(header)?;
    let payload_encoded = utils::to_json_b64(payload)?;

    let unsigned_jwt = format!("{header_encoded}.{payload_encoded}");

    let signature = sign(unsigned_jwt.as_bytes(), secret_key)?;
    let signature_encoded = utils::to_b64(&signature);

    Ok(format!("{}.{}", unsigned_jwt, signature_encoded))
}

#[cfg(test)]
mod tests {
    use super::*;

    // INFO:
    // - For token testing: https://jwt.io/

    #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Claims {
        pub user: String,
        pub age: u16,
        pub is_admin: bool,
    }

    const SECRET_KEY: &[u8] = b"super_secret_key";

    #[test]
    fn encode_success() {
        let header = Header::default();
        
        let data = Claims {
            user: String::from("username"),
            age: 128,
            is_admin: true,
        };

        let token = encode(&header, &data, SECRET_KEY);

        assert!(token.is_ok(), "Should be ok");
        assert_eq!("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidXNlcm5hbWUiLCJhZ2UiOjEyOCwiaXNfYWRtaW4iOnRydWV9.3dTbG3tFs2QBcxkxmpxnRzPdCi-fpe9YzoLWX-lBBl0", token.unwrap());
    }
}