fix: use JavaScript for base64 decoding to avoid UTF-8 encoding issues (65 bytes expected)

This commit is contained in:
spinline
2026-02-06 01:17:01 +03:00
parent cd2a398b15
commit 68b517a336

View File

@@ -527,6 +527,7 @@ pub async fn subscribe_to_push_notifications() {
} }
/// Helper to convert URL-safe base64 string to Uint8Array /// Helper to convert URL-safe base64 string to Uint8Array
/// Uses JavaScript to properly decode binary data (avoids UTF-8 encoding issues)
fn url_base64_to_uint8array(base64_string: &str) -> Result<js_sys::Uint8Array, JsValue> { fn url_base64_to_uint8array(base64_string: &str) -> Result<js_sys::Uint8Array, JsValue> {
// Add padding // Add padding
let padding = (4 - (base64_string.len() % 4)) % 4; let padding = (4 - (base64_string.len() % 4)) % 4;
@@ -536,15 +537,24 @@ fn url_base64_to_uint8array(base64_string: &str) -> Result<js_sys::Uint8Array, J
// Replace URL-safe characters // Replace URL-safe characters
let standard_base64 = padded.replace('-', "+").replace('_', "/"); let standard_base64 = padded.replace('-', "+").replace('_', "/");
// Decode base64 // Decode using JavaScript to avoid UTF-8 encoding issues
let window = web_sys::window().ok_or_else(|| JsValue::from_str("no window"))?; // Create a JavaScript function to decode the base64 and convert to Uint8Array
let decoded = window.atob(&standard_base64)?; let js_code = format!(
r#"
(function() {{
const binaryString = atob('{}');
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {{
bytes[i] = binaryString.charCodeAt(i);
}}
return bytes;
}})()
"#,
standard_base64
);
// Convert to Uint8Array let result = js_sys::eval(&js_code)?;
let array = js_sys::Uint8Array::new_with_length(decoded.len() as u32); let array = result.dyn_into::<js_sys::Uint8Array>()?;
for (i, byte) in decoded.bytes().enumerate() {
array.set_index(i as u32, byte);
}
Ok(array) Ok(array)
} }