use crate::auth::session::{hash, random_token};
use crate::config::Config;
use crate::error::AppError;
pub const KEY_PREFIX: &str = "cdo_";
pub const DISPLAY_PREFIX_LEN: usize = 12;
const KEY_LEN: usize = KEY_PREFIX.len() + 43;
pub struct NewKey {
pub plaintext: String,
pub hash: Vec<u8>,
pub prefix: String,
}
pub fn generate() -> NewKey {
let plaintext = format!("{KEY_PREFIX}{}", random_token());
NewKey {
hash: hash_key(&plaintext),
prefix: plaintext.chars().take(DISPLAY_PREFIX_LEN).collect(),
plaintext,
}
}
pub fn hash_key(key: &str) -> Vec<u8> {
hash(key)
}
pub fn is_well_formed(key: &str) -> bool {
key.len() == KEY_LEN
&& key.starts_with(KEY_PREFIX)
&& key[KEY_PREFIX.len()..]
.bytes()
.all(|b| b.is_ascii_alphanumeric() || b == b'-' || b == b'_')
}
pub fn mcp_url(config: &Config) -> Result<String, AppError> {
Ok(config
.base_url
.join("mcp")
.map_err(AppError::internal)?
.to_string())
}
pub fn claude_command(mcp_url: &str, key: &str) -> String {
format!(
"claude mcp add --transport http codoseo {mcp_url} --header \"Authorization: Bearer {key}\""
)
}
pub fn mcp_servers_json(mcp_url: &str, key: &str) -> String {
format!(
"{{\n \"mcpServers\": {{\n \"codoseo\": {{\n \"type\": \"http\",\n \
\"url\": \"{mcp_url}\",\n \"headers\": {{\n \
\"Authorization\": \"Bearer {key}\"\n }}\n }}\n }}\n}}"
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_json_snippet_is_valid_and_carries_the_url_and_the_bearer_key() {
let key = "cdo_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
let json = mcp_servers_json("https://codoseo.com/mcp", key);
let v: serde_json::Value = serde_json::from_str(&json).expect("valid JSON");
let server = &v["mcpServers"]["codoseo"];
assert_eq!(server["type"], "http");
assert_eq!(server["url"], "https://codoseo.com/mcp");
assert_eq!(server["headers"]["Authorization"], format!("Bearer {key}"));
assert!(json.find("\"type\"").unwrap() < json.find("\"url\"").unwrap());
assert!(json.find("\"url\"").unwrap() < json.find("\"headers\"").unwrap());
}
#[test]
fn the_claude_command_names_the_url_and_the_bearer_key() {
assert_eq!(
claude_command("https://codoseo.com/mcp", "cdo_x"),
"claude mcp add --transport http codoseo https://codoseo.com/mcp --header \"Authorization: Bearer cdo_x\""
);
}
#[test]
fn a_key_is_cdo_and_43_url_safe_characters() {
let key = generate();
assert!(key.plaintext.starts_with("cdo_"));
assert_eq!(key.plaintext.len(), 4 + 43);
assert!(is_well_formed(&key.plaintext));
}
#[test]
fn the_hash_is_sha256_of_the_whole_key_and_the_prefix_its_first_12_characters() {
let key = generate();
assert_eq!(key.hash, hash_key(&key.plaintext));
assert_eq!(key.hash.len(), 32);
assert_eq!(key.prefix, key.plaintext[..12]);
}
#[test]
fn keys_do_not_repeat() {
assert_ne!(generate().plaintext, generate().plaintext);
assert_ne!(generate().hash, generate().hash);
}
#[test]
fn malformed_keys_are_not_well_formed() {
for bad in [
"",
"cdo_",
"cdo_short",
"xyz_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"cdo_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"cdo_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
"cdo_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+",
] {
assert!(!is_well_formed(bad), "{bad:?}");
}
assert!(is_well_formed(
"cdo_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
));
}
}