feat: Update WebAuthn credential handling with modern browser standards

This commit is contained in:
Prad Nukala 2024-12-09 15:12:16 -05:00
parent e572d7a626
commit 98bdf92d70
2 changed files with 29 additions and 7 deletions

View File

@ -43,6 +43,11 @@ templ passkeyDropzone(addr string, userHandle string, challenge string) {
</sl-button>
}
script base64URLEncode(buffer) {
const base64 = btoa(String.fromCharCode(...new Uint8Array(buffer)));
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
script createPasskey(userId string, userHandle string, challenge string) {
const publicKey = {
challenge: Uint8Array.from(challenge, (c) => c.charCodeAt(0)),
@ -81,10 +86,16 @@ navigator.credentials
.create({ publicKey })
.then((newCredentialInfo) => {
// Convert credential to base64 string
// Convert the credential data to a proper format
const credentialJSON = JSON.stringify({
CredentialID: Array.from(new Uint8Array(newCredentialInfo.rawId)),
Type: newCredentialInfo.type,
Transport: newCredentialInfo.response.getTransports ? newCredentialInfo.response.getTransports() : []
id: base64URLEncode(newCredentialInfo.rawId),
type: newCredentialInfo.type,
authenticatorAttachment: newCredentialInfo.authenticatorAttachment,
clientExtensionResults: newCredentialInfo.getClientExtensionResults(),
response: {
attestationObject: base64URLEncode(newCredentialInfo.response.attestationObject),
clientDataJSON: base64URLEncode(newCredentialInfo.response.clientDataJSON)
}
});
document.getElementById('credential-data').value = btoa(credentialJSON);
document.getElementById('passkey-form').submit();

View File

@ -50,16 +50,27 @@ func HandleRegisterFinish(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "invalid credential encoding")
}
// Unmarshal credential
var cred protocol.CredentialDescriptor
// Unmarshal the complete credential
var cred struct {
ID string `json:"id"`
Type string `json:"type"`
AuthenticatorAttachment string `json:"authenticatorAttachment"`
ClientExtensionResults map[string]interface{} `json:"clientExtensionResults"`
Response struct {
AttestationObject string `json:"attestationObject"`
ClientDataJSON string `json:"clientDataJSON"`
} `json:"response"`
}
if err := json.Unmarshal(credJSON, &cred); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "invalid credential format")
}
// Log credential details
fmt.Printf("Credential ID: %v\n", cred.CredentialID)
fmt.Printf("Credential ID: %s\n", cred.ID)
fmt.Printf("Credential Type: %s\n", cred.Type)
fmt.Printf("Transport: %v\n", cred.Transport)
fmt.Printf("Authenticator Attachment: %s\n", cred.AuthenticatorAttachment)
fmt.Printf("Attestation Object Length: %d\n", len(cred.Response.AttestationObject))
fmt.Printf("Client Data JSON Length: %d\n", len(cred.Response.ClientDataJSON))
return response.TemplEcho(c, register.LoadingVaultView())
}