I've been struggling with this for longer than I care to admit. I am simply trying to register a new device using WebAutn. I've tried at least two different examples and have examined lots of different code. I seem to be doing everything right... but no matter what I do I keep getting the same unhelpful exception. I've scoured the web and no one else seems to be getting this exception so I really have no idea what is wrong?
In short on line newCredential = await navigator.credentials.create({publicKey: options}); I am getting this error: "exception:TypeError: Failed to execute 'create' on 'CredentialsContainer': The provided value '2' is not a valid enum value of type AttestationConveyancePreference."
Here are the PublicKeyCredentialCreationOptions are returned and that I am submitting: NOTE: Both the challenge and user.id are populated but since they are ArrayBuffer()'s they do not print.
{
"rp": {
"id": "someserver",
"name": "IB-Fido2",
"icon": null
},
"user": {
"name": "fred@someserver.com",
"id": {},
"displayName": "Fred Sampson"
},
"challenge": {},
"pubKeyCredParams": [
{
"type": 0,
"alg": -7
},
{
"type": 0,
"alg": -257
},
{
"type": 0,
"alg": -37
},
{
"type": 0,
"alg": -35
},
{
"type": 0,
"alg": -258
},
{
"type": 0,
"alg": -38
},
{
"type": 0,
"alg": -36
},
{
"type": 0,
"alg": -259
},
{
"type": 0,
"alg": -39
}
],
"timeout": 60000,
"attestation": 0,
"authenticatorSelection": {
"requireResidentKey": false,
"userVerification": 1
},
"excludeCredentials": [],
"extensions": null,
"status": "ok",
"errorMessage": ""
}
Any help or suggestions would be GREATLY appreciated!
UPDATE: Have been serializing/ deserializing objects for a while... but almost always for C# and not JavaScript... thus I was not aware of JavaScripts String Enum until I came across this issue. I saw that this was a conversion error but had mistakenly thought the Fido2NetLib had to be returning the needed object since no one else was reporting an error with it.
Thankfully Newtonsoft.Json already had extensions to do this coversion really easily which I discovered from here.
Thus in the end I had to serialize the object with StringEnumConverter() then Deserialize it back into a custom class I created from the json which was the exact same thing but with String Enum values. I needed to do it that way because passing the Json to Blazor.Interop was not working... it needed an actual object. In the end I am sure there is a cleaner way to do the conversion with String Enum's but wanting to move forward I am rolling with it for now. See:
string url = string.Format("{0}{1}", Endpoints.UsersFidoOptions, userId);
var options = await userRepository.FidoOptions(url);
if (options != null)
{
if (options.Status != "ok")
{
//Error Message
}
else
{
try
{
// Serialize returned options: NOTE: String Enum Converter necessary as this object has JavaScript String Enum's
string json = JsonConvert.SerializeObject(options, new Newtonsoft.Json.Converters.StringEnumConverter());
// Next Deserialize into Custom Object to Compensate for String Enum's
var pubKey = Newtonsoft.Json.JsonConvert.DeserializeObject<PublicKey>(json);
// Now Serialize the Public Key for Session Storage
string pkJson = JsonConvert.SerializeObject(pubKey, new Newtonsoft.Json.Converters.StringEnumConverter());
await sessionStorage.SetItemAsync<string>("fido2.attestationOptions", pkJson);
await jsRuntime.InvokeVoidAsync("blazorInterop.registerOptions", pubKey);
}
catch (JSException e)
{
string err = e.Message;
}
}
}