dynamic_token/
to_key.rs

1use crate::auth_options::AuthOptions;
2use crate::{utils::*, MAX_API_KEY_OFFSET};
3use simple_string_patterns::StripCharacters;
4
5/// Generate a time-sensitive dynamic key from a shared API key as defined in the options
6/// the current millisecond timestamp (encoded, split and injected)
7/// some random characters and an optional uuid that can be decoded and used for additional authentication
8pub fn to_dynamic_key(options: &AuthOptions, uuid_opt: Option<&str>) -> String {  
9  let ts = milliseconds_now(); 
10  let ts_list = i64_to_base_36(ts).unwrap_or("".to_string()).chars().rev().collect::<String>();
11  let ts_list_36 = base_36_str_to_u64(&ts_list[..1]).unwrap_or(0);
12  let is_under = ts_list_36 < usize::MAX as u64;
13  let offset = if is_under { (ts_list_36 as usize % MAX_API_KEY_OFFSET) + 2 } else { 0 };
14  let mut parts: Vec<String> = vec![];
15
16  let merged_list = [&ts_list.as_str()[..offset], options.key(), &ts_list.as_str()[offset..]].concat();
17  let rand_separator = rand_char_as_string(&options.rand_chars());
18  let base_str = [merged_list, rand_int_36(3)].join(&rand_separator);
19  parts.push(base_str);
20  if let Some(uuid) = uuid_opt {     
21    if let Some(uid_str) = hex_string_to_base36_parts(&uuid.strip_non_alphanum()) {
22      let rand_int_str = rand_int_36(3);
23      let rand_separator = rand_char_as_string(&options.rand_chars());
24      let uid_part = [uid_str, rand_int_str].join(&rand_separator);
25      parts.push(uid_part);
26    }
27  }
28  let key_str = parts.join("__");
29  encode_base64(&key_str)
30}