Skip to content

Commit 23afd5b

Browse files
nipunn1313Convex, Inc.
authored andcommitted
Fix randomization of device authorization token ID (#40608)
GitOrigin-RevId: fb6263359068264baf90646e631b59d3d6d2b236
1 parent 7645706 commit 23afd5b

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

crates/common/src/utils.rs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{
55
sync::LazyLock,
66
};
77

8+
use rand;
89
use regex::Regex;
910
pub use value::utils::{
1011
display_map,
@@ -33,20 +34,31 @@ static NAME_NUMBER_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(.*) \((\
3334

3435
/// "Increment" a string.
3536
/// E.g. `Foo` becomes `Foo (1)`, and `Foo (1)` becomes `Foo (2)`.
37+
/// If amt is None, uses 8 random hex characters instead.
3638
/// Useful for strings (team names, device names) remain unique.
37-
pub fn increment_name(name: &str, amt: u64) -> String {
38-
if let Some(number) = NAME_NUMBER_RE
39-
.captures(name)
40-
.and_then(|c| c.get(2))
41-
.and_then(|m| m.as_str().parse::<u64>().ok())
42-
{
43-
NAME_NUMBER_RE
44-
.replace(name, |caps: &regex::Captures| {
45-
format!("{} ({})", &caps[1], number + amt)
46-
})
47-
.into()
48-
} else {
49-
format!("{name} ({amt})")
39+
pub fn increment_name(name: &str, amt: Option<u64>) -> String {
40+
match amt {
41+
Some(amt) => {
42+
if let Some(number) = NAME_NUMBER_RE
43+
.captures(name)
44+
.and_then(|c| c.get(2))
45+
.and_then(|m| m.as_str().parse::<u64>().ok())
46+
{
47+
NAME_NUMBER_RE
48+
.replace(name, |caps: &regex::Captures| {
49+
format!("{} ({})", &caps[1], number + amt)
50+
})
51+
.into()
52+
} else {
53+
format!("{name} ({amt})")
54+
}
55+
},
56+
None => {
57+
let hex_suffix: String = (0..8)
58+
.map(|_| format!("{:x}", rand::random::<u8>() % 16))
59+
.collect();
60+
format!("{name} ({hex_suffix})")
61+
},
5062
}
5163
}
5264

@@ -72,9 +84,17 @@ fn test_increment_name() {
7284
("Foo (a)", "Foo (a) (1)"),
7385
];
7486
for (test, expected) in cases {
75-
assert_eq!(increment_name(test, 1), expected);
87+
assert_eq!(increment_name(test, Some(1)), expected);
7688
}
7789

78-
assert_eq!(increment_name("Foo", 50), "Foo (50)");
79-
assert_eq!(increment_name("Foo (20)", 50), "Foo (70)");
90+
assert_eq!(increment_name("Foo", Some(50)), "Foo (50)");
91+
assert_eq!(increment_name("Foo (20)", Some(50)), "Foo (70)");
92+
93+
// Test None case - should generate 8 hex characters
94+
let result = increment_name("Test", None);
95+
assert!(result.starts_with("Test ("));
96+
assert!(result.ends_with(")"));
97+
let hex_part = &result[6..result.len() - 1]; // Extract hex part between "Test (" and ")"
98+
assert_eq!(hex_part.len(), 8);
99+
assert!(hex_part.chars().all(|c| c.is_ascii_hexdigit()));
80100
}

0 commit comments

Comments
 (0)