Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error deserializing PublicKeyCredential from JsValue #48

Open
Ben-Lichtman opened this issue Sep 22, 2024 · 3 comments
Open

Error deserializing PublicKeyCredential from JsValue #48

Ben-Lichtman opened this issue Sep 22, 2024 · 3 comments

Comments

@Ben-Lichtman
Copy link

Ben-Lichtman commented Sep 22, 2024

Trying to implement webauthn on the browser, which includes deserializing the browser's response to the message into a passkey_types::webauthn::CreatedPublicKeyCredential / passkey_types::webauthn::PublicKeyCredential, however it seems that the raw_id field of PublicKeyCredential is allowed to be {} when returned from the browser, which causes the deserialization to return an error.

let promise = window()
  .navigator()
  .credentials()
  .create_with_options(&creation_options)
  .map_err(Error::JsError)?;

let cred_jsvalue = JsFuture::from(promise).await.map_err(Error::JsError)?;

let cred = web_sys::PublicKeyCredential::from(cred_jsvalue);

let cred = <JsValue as JsValueSerdeExt>::into_serde::<
passkey_types::webauthn::CreatedPublicKeyCredential,
>(&cred)
.unwrap();
panicked at app/src/webauthn.rs:82:6:
called `Result::unwrap()` on an `Err` value: Error("invalid type: map, expected A vector of bytes or a base46(url) encoded string", line: 1, column: 41)
@Progdrasil
Copy link
Collaborator

Progdrasil commented Sep 23, 2024

Hi @Ben-Lichtman, the issue here is the use of ArrayBuffer by the webauthn types which is readonly memory. When trying to serialize to JSON it will automatically "drop" the value and replace it with an empty object. To get around this you need to either re-map the array buffer to an array or a base64url string. OR remap it directly from the web_sys/js_sys types. Perhaps wasm_bindgen_serde could help with this but I haven't tested it.

I would like to one day build wasm dedicated library for the passkey crates, but thats a fairly heavy lift that I currently don't really have time for. We alway welcome contributions.

@Ben-Lichtman
Copy link
Author

@Progdrasil I'm a little confused - isn't the deserialization though JsValueSerdeExt (via gloo) designed to do exactly that (remap from the web_sys type into your PublicKeyCredential type)?

It would make sense to me that the answer would be to change the Deserialize implementation on Bytes to handle visit_map?

Please let me know if I'm misunderstanding.

@Progdrasil
Copy link
Collaborator

JsValueSerdeExt does not. It uses the JSON.stringify method internally which transforms it to an empty map. See this JSFiddle as an example. Implementing visit_map will not help since the value will be lost by stringifying the array buffer and that map will be empty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants