Skip to content

Commit

Permalink
fix(webauthn): resolve missing identifier bug
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Mar 11, 2022
1 parent 686c9ba commit 93a1ae4
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
[
{
"attributes": {
"disabled": false,
"name": "identifier",
"node_type": "input",
"type": "hidden"
},
"group": "default",
"messages": [],
"meta": {},
"type": "input"
},
{
"attributes": {
"disabled": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
"ui": {
"method": "POST",
"nodes": [
{
"type": "input",
"group": "default",
"attributes": {
"name": "identifier",
"type": "hidden",
"required": true,
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {}
},
{
"type": "input",
"group": "default",
Expand Down Expand Up @@ -58,19 +71,6 @@
},
"messages": [],
"meta": {}
},
{
"type": "input",
"group": "default",
"attributes": {
"name": "identifier",
"type": "hidden",
"required": true,
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {}
}
],
"messages": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
"ui": {
"method": "POST",
"nodes": [
{
"type": "input",
"group": "default",
"attributes": {
"name": "identifier",
"type": "hidden",
"required": true,
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {}
},
{
"type": "input",
"group": "default",
Expand Down Expand Up @@ -58,19 +71,6 @@
},
"messages": [],
"meta": {}
},
{
"type": "input",
"group": "default",
"attributes": {
"name": "identifier",
"type": "hidden",
"required": true,
"disabled": false,
"node_type": "input"
},
"messages": [],
"meta": {}
}
],
"messages": [
Expand Down
4 changes: 4 additions & 0 deletions selfservice/strategy/webauthn/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ func (s *Strategy) populateLoginMethod(r *http.Request, sr *login.Flow, i *ident
return errors.WithStack(err)
}

if len(cred.Identifiers) > 0 {
sr.UI.SetNode(node.NewInputField("identifier", cred.Identifiers[0], node.DefaultGroup, node.InputAttributeTypeHidden))
}

sr.UI.SetCSRF(s.d.GenerateCSRFToken(r))
sr.UI.Nodes.Upsert(NewWebAuthnScript(urlx.AppendPaths(s.d.Config(r.Context()).SelfPublicURL(), webAuthnRoute).String(), jsOnLoad))
sr.UI.SetNode(NewWebAuthnLoginTrigger(string(injectWebAuthnOptions)).
Expand Down
12 changes: 7 additions & 5 deletions selfservice/strategy/webauthn/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,14 +458,16 @@ func TestCompleteLogin(t *testing.T) {

apiClient := testhelpers.NewHTTPClientWithIdentitySessionToken(t, reg, id)
f := testhelpers.InitializeLoginFlowViaBrowser(t, apiClient, publicTS, false, true, testhelpers.InitFlowWithAAL(identity.AuthenticatorAssuranceLevel2))
assert.Equal(t, gjson.GetBytes(id.Traits, "subject").String(), f.Ui.Nodes[0].Attributes.UiNodeInputAttributes.Value)
testhelpers.SnapshotTExcept(t, f.Ui.Nodes, []string{
"0.attributes.value",
"1.attributes.onclick",
"1.attributes.onload",
"3.attributes.src",
"3.attributes.nonce",
"1.attributes.value",
"2.attributes.onclick",
"2.attributes.onload",
"4.attributes.src",
"4.attributes.nonce",
})
ensureReplacement(t, "1", f.Ui, "allowCredentials")
ensureReplacement(t, "2", f.Ui, "allowCredentials")
})

t.Run("case=webauthn payload is not set when identity has no webauthn", func(t *testing.T) {
Expand Down
19 changes: 19 additions & 0 deletions test/e2e/cypress/integration/profiles/mfa/webauthn.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,25 @@ context('2FA WebAuthn', () => {
cy.expectSettingsSaved()
cy.get('*[name="webauthn_remove"]').should('exist')

// Login without refresh
cy.login({ email, password })
cy.visit(login + '?aal=aal2')
cy.location().should((loc) => {
expect(loc.href).to.include('/login')
})

cy.get('*[name="webauthn_login_trigger"]').should('have.length', 1)
cy.clickWebAuthButton('login')
cy.location().should((loc) => {
expect(loc.href).to.not.include('/login')
})

cy.getSession({
expectAal: 'aal2',
expectMethods: ['password', 'webauthn']
})

// Login with refresh
cy.visit(login + '?aal=aal2&refresh=true')
cy.location().should((loc) => {
expect(loc.href).to.include('/login')
Expand Down

0 comments on commit 93a1ae4

Please sign in to comment.