pub const SECRET_PREFIXES: &[&str] = &[
"sk-",
"sk_live_",
"sk_test_",
"AKIA",
"ghp_",
"gho_",
"-----BEGIN",
"xoxb-",
"xoxp-",
"AIza",
"ya29.",
"glpat-",
"hf_",
"npm_",
"dckr_pat_",
];
pub const PATH_PREFIXES: &[&str] = &["/home/", "/Users/", "/root/", "/tmp/", "/var/"];
pub const BEARER_TOKEN_PATTERN: &str = r"(?i)(Authorization:\s*Bearer\s+)\S+";
pub const JWT_PATTERN: &str = r"eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*";
#[cfg(test)]
mod tests {
use regex::Regex;
use super::*;
#[test]
fn bearer_pattern_compiles_and_matches() {
let re = Regex::new(BEARER_TOKEN_PATTERN).unwrap();
assert!(re.is_match("Authorization: Bearer abc.def.ghi"));
}
#[test]
fn jwt_pattern_compiles_and_matches() {
let re = Regex::new(JWT_PATTERN).unwrap();
assert!(re.is_match("eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIn0.sig"));
}
#[test]
fn jwt_pattern_matches_alg_none_empty_signature() {
let re = Regex::new(JWT_PATTERN).unwrap();
assert!(re.is_match("eyJhbGciOiJub25lIn0.eyJzdWIiOiJ1c2VyIn0."));
}
#[test]
fn secret_prefixes_build_valid_escaped_regex_alternation() {
let pattern = SECRET_PREFIXES
.iter()
.map(|p| regex::escape(p))
.collect::<Vec<_>>()
.join("|");
let full = format!("(?:{pattern})[^\\s]*");
let re = Regex::new(&full).expect("alternation built from SECRET_PREFIXES must compile");
assert!(re.is_match("sk-abc123"));
assert!(re.is_match("ya29.a0AfH6"));
}
#[test]
fn path_prefixes_build_valid_regex_alternation() {
let pattern = PATH_PREFIXES.join("|");
let full = format!("(?:{pattern})[^\\s]*");
let re = Regex::new(&full).expect("alternation built from PATH_PREFIXES must compile");
assert!(re.is_match("/home/user/file"));
}
}