use base64::Engine;
pub fn firebase_uid_from_id_token(token: &str) -> Option<String> {
let payload_segment = token.split('.').nth(1)?.trim();
if payload_segment.is_empty() {
return None;
}
let mut padded = payload_segment.to_string();
let remainder = padded.len() % 4;
if remainder != 0 {
padded.push_str(&"=".repeat(4 - remainder));
}
let decoded = base64::engine::general_purpose::URL_SAFE_NO_PAD
.decode(payload_segment)
.or_else(|_| base64::engine::general_purpose::URL_SAFE.decode(&padded))
.ok()?;
let json: serde_json::Value = serde_json::from_slice(&decoded).ok()?;
json.get("sub")
.or_else(|| json.get("user_id"))
.and_then(|value| value.as_str())
.map(str::to_string)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn firebase_uid_from_id_token_reads_sub_claim() {
let token = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.\
eyJzdWIiOiJ1c2VyLWFiYy0xMjMiLCJhdWQiOiJ0ZXN0In0.\
signature";
assert_eq!(
firebase_uid_from_id_token(token).as_deref(),
Some("user-abc-123"),
);
}
}