Skip to main content

uselesskey_token/
lib.rs

1#![forbid(unsafe_code)]
2
3//! Token fixtures built on `uselesskey-core`.
4//!
5//! This crate generates realistic test-token shapes without committing
6//! secret-looking blobs to version control.
7//!
8//! Most users should depend on the [`uselesskey`](https://crates.io/crates/uselesskey)
9//! facade crate, which re-exports this crate's types behind the `token` feature flag.
10//!
11//! Supported token kinds:
12//! - API key style tokens (`uk_test_<base62>`)
13//! - Opaque bearer tokens (base64url)
14//! - OAuth-style JWT access tokens (`header.payload.signature`)
15//! - Scanner-safe negative token shapes for validator error paths
16//!
17//! # Examples
18//!
19//! ```
20//! use uselesskey_core::Factory;
21//! use uselesskey_token::{NegativeToken, TokenFactoryExt, TokenSpec};
22//!
23//! let fx = Factory::random();
24//! let tok = fx.token("api-key", TokenSpec::api_key());
25//! let value = tok.value();
26//! assert!(!value.is_empty());
27//!
28//! let near_miss = tok.negative_value(NegativeToken::NearMissApiKey);
29//! assert!(!near_miss.starts_with("uk_test_"));
30//! ```
31//!
32//! # Deterministic Mode
33//!
34//! Use deterministic mode for reproducible test fixtures:
35//!
36//! ```
37//! use uselesskey_core::{Factory, Seed};
38//! use uselesskey_token::{TokenFactoryExt, TokenSpec};
39//!
40//! let seed = Seed::from_env_value("test-seed").unwrap();
41//! let fx = Factory::deterministic(seed);
42//!
43//! // Same seed + label + spec = same token
44//! let t1 = fx.token("billing", TokenSpec::api_key());
45//! let t2 = fx.token("billing", TokenSpec::api_key());
46//! assert_eq!(t1.value(), t2.value());
47//!
48//! // Different labels produce different tokens
49//! let t3 = fx.token("other", TokenSpec::api_key());
50//! assert_ne!(t1.value(), t3.value());
51//! ```
52
53#[doc(hidden)]
54pub mod srp;
55mod token;
56
57pub use srp::shape::NegativeToken;
58pub use srp::spec::TokenSpec;
59pub use token::{DOMAIN_TOKEN_FIXTURE, TokenFactoryExt, TokenFixture};