Skip to content

Commit

Permalink
fix(webauthn): support react-based webauth
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Oct 19, 2021
1 parent c31915d commit b6123b4
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "csrf_token",
"required": true,
"type": "hidden",
"value": "OWt1cWhvMnpqZzgyc2x3OGdmaHVoZzFhbmV6Y3BnemI="
"value": "Yms2cmo1NTA2OWFub3F3dHI2NHcxNnd2MTNsNzhocTk="
},
"group": "default",
"messages": [],
Expand All @@ -16,8 +16,8 @@
"attributes": {
"disabled": false,
"name": "webauthn_login_trigger",
"onclick": "// noinspection JSAnnotator\nreturn (function (e) {\n if (e.value) {\n return true\n }\n\n if (!window.PublicKeyCredential) {\n alert('This browser does not support WebAuthn!');\n return false;\n }\n\n function bufferDecode(value) {\n return Uint8Array.from(atob(value), c =\u003e c.charCodeAt(0));\n }\n\n function bufferEncode(value) {\n return btoa(String.fromCharCode.apply(null, new Uint8Array(value)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n }\n\n const opt = {\"publicKey\":{\"challenge\":\"qjoy5ND5aFxdRfAv3gken1zF/aw70BMqIwxit2W/wdE=\",\"timeout\":60000,\"rpId\":\"localhost\",\"allowCredentials\":[{\"type\":\"public-key\",\"id\":\"Zm9vZm9v\"},{\"type\":\"public-key\",\"id\":\"YmFyYmFy\"}]}}\n opt.publicKey.challenge = bufferDecode(opt.publicKey.challenge);\n opt.publicKey.allowCredentials = opt.publicKey.allowCredentials.map(function (value) {\n return {\n ...value,\n id: bufferDecode(value.id)\n }\n });\n\n navigator.credentials.get(opt).then(function (credential) {\n const val = JSON.stringify({\n id: credential.id,\n rawId: bufferEncode(credential.rawId),\n type: credential.type,\n response: {\n authenticatorData: bufferEncode(credential.response.authenticatorData),\n clientDataJSON: bufferEncode(credential.response.clientDataJSON),\n signature: bufferEncode(credential.response.signature),\n userHandle: bufferEncode(credential.response.userHandle),\n },\n })\n console.log('setting value!', val)\n document.querySelector('input[name=\"webauthn_login\"]').value = val\n\n console.log('Submitting!')\n e.closest('form').submit()\n console.log('Done!')\n }).catch((err) =\u003e {\n alert(err)\n })\n\n return false\n})(this)\n",
"type": "submit",
"onclick": "if (!window.PublicKeyCredential) {\n alert('This browser does not support WebAuthn!');\n} else {\n function bufferDecode(value) {\n return Uint8Array.from(atob(value), c =\u003e c.charCodeAt(0));\n }\n\n function bufferEncode(value) {\n return btoa(String.fromCharCode.apply(null, new Uint8Array(value)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n }\n\n const opt = {\"publicKey\":{\"challenge\":\"EjcLNulRLiiAvumMXEwUWT+CDYtnsRpznIBlC2/Ljwo=\",\"timeout\":60000,\"rpId\":\"localhost\",\"allowCredentials\":[{\"type\":\"public-key\",\"id\":\"Zm9vZm9v\"},{\"type\":\"public-key\",\"id\":\"YmFyYmFy\"}],\"userVerification\":\"discouraged\"}}\n opt.publicKey.challenge = bufferDecode(opt.publicKey.challenge);\n opt.publicKey.allowCredentials = opt.publicKey.allowCredentials.map(function (value) {\n return {\n ...value,\n id: bufferDecode(value.id)\n }\n });\n\n navigator.credentials.get(opt).then(function (credential) {\n document.querySelector('*[name=\"webauthn_login\"]').value = JSON.stringify({\n id: credential.id,\n rawId: bufferEncode(credential.rawId),\n type: credential.type,\n response: {\n authenticatorData: bufferEncode(credential.response.authenticatorData),\n clientDataJSON: bufferEncode(credential.response.clientDataJSON),\n signature: bufferEncode(credential.response.signature),\n userHandle: bufferEncode(credential.response.userHandle),\n },\n })\n\n document.querySelector('*[name=\"webauthn_login_trigger\"]').closest('form').submit()\n }).catch((err) =\u003e {\n alert(err)\n })\n}\n",
"type": "button",
"value": ""
},
"group": "webauthn",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "csrf_token",
"required": true,
"type": "hidden",
"value": "OWt1cWhvMnpqZzgyc2x3OGdmaHVoZzFhbmV6Y3BnemI="
"value": "Yms2cmo1NTA2OWFub3F3dHI2NHcxNnd2MTNsNzhocTk="
},
"group": "default",
"messages": [],
Expand Down Expand Up @@ -78,8 +78,8 @@
"attributes": {
"disabled": false,
"name": "webauthn_register_trigger",
"onclick": "// noinspection JSAnnotator\nreturn (function (e) {\n if (e.value) {\n return true\n }\n\n if (!window.PublicKeyCredential) {\n alert('This browser does not support WebAuthn!');\n return false;\n }\n\n function bufferDecode(value) {\n return Uint8Array.from(atob(value), c =\u003e c.charCodeAt(0));\n }\n\n function bufferEncode(value) {\n return btoa(String.fromCharCode.apply(null, new Uint8Array(value)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n }\n\n const opt = {\"publicKey\":{\"challenge\":\"Dfm/AnBY/jD3LbMqILM5HBpsrWRMzlFloxsoy2RVobE=\",\"rp\":{\"name\":\"Ory Corp\",\"id\":\"localhost\"},\"user\":{\"name\":\"placeholder\",\"icon\":\"https://via.placeholder.com/128\",\"displayName\":\"placeholder\",\"id\":\"b3tjRYN0QMqE1zEikQMMVQ==\"},\"pubKeyCredParams\":[{\"type\":\"public-key\",\"alg\":-7},{\"type\":\"public-key\",\"alg\":-35},{\"type\":\"public-key\",\"alg\":-36},{\"type\":\"public-key\",\"alg\":-257},{\"type\":\"public-key\",\"alg\":-258},{\"type\":\"public-key\",\"alg\":-259},{\"type\":\"public-key\",\"alg\":-37},{\"type\":\"public-key\",\"alg\":-38},{\"type\":\"public-key\",\"alg\":-39},{\"type\":\"public-key\",\"alg\":-8}],\"authenticatorSelection\":{\"requireResidentKey\":false,\"userVerification\":\"preferred\"},\"timeout\":60000}}\n opt.publicKey.user.id = bufferDecode(opt.publicKey.user.id);\n opt.publicKey.challenge = bufferDecode(opt.publicKey.challenge);\n\n if (opt.publicKey.excludeCredentials) {\n opt.publicKey.excludeCredentials = opt.publicKey.excludeCredentials.map(function (value) {\n return {\n ...value,\n id: bufferDecode(value.id)\n }\n })\n }\n\n navigator.credentials.create(opt).then(function (credential) {\n document.querySelector('input[name=\"webauthn_register\"]').value = JSON.stringify({\n id: credential.id,\n rawId: bufferEncode(credential.rawId),\n type: credential.type,\n response: {\n attestationObject: bufferEncode(credential.response.attestationObject),\n clientDataJSON: bufferEncode(credential.response.clientDataJSON),\n },\n })\n\n console.log('Submitting!')\n e.closest('form').submit()\n console.log('Done!')\n }).catch((err) =\u003e {\n alert(err)\n })\n\n return false\n})(this)\n",
"type": "submit",
"onclick": "// noinspection JSAnnotator\nif (!window.PublicKeyCredential) {\n alert('This browser does not support WebAuthn!');\n} else {\n function bufferDecode(value) {\n return Uint8Array.from(atob(value), c =\u003e c.charCodeAt(0));\n }\n\n function bufferEncode(value) {\n return btoa(String.fromCharCode.apply(null, new Uint8Array(value)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n }\n\n const opt = {\"publicKey\":{\"challenge\":\"shAe3iabHLxQreNmyjIaj9P0Uk4fTCbALzuHKph3KAI=\",\"rp\":{\"name\":\"Ory Corp\",\"id\":\"localhost\"},\"user\":{\"name\":\"placeholder\",\"icon\":\"https://via.placeholder.com/128\",\"displayName\":\"placeholder\",\"id\":\"804bqWslQ3OcrP7e+pAlIA==\"},\"pubKeyCredParams\":[{\"type\":\"public-key\",\"alg\":-7},{\"type\":\"public-key\",\"alg\":-35},{\"type\":\"public-key\",\"alg\":-36},{\"type\":\"public-key\",\"alg\":-257},{\"type\":\"public-key\",\"alg\":-258},{\"type\":\"public-key\",\"alg\":-259},{\"type\":\"public-key\",\"alg\":-37},{\"type\":\"public-key\",\"alg\":-38},{\"type\":\"public-key\",\"alg\":-39},{\"type\":\"public-key\",\"alg\":-8}],\"authenticatorSelection\":{\"requireResidentKey\":false,\"userVerification\":\"preferred\"},\"timeout\":60000}}\n opt.publicKey.user.id = bufferDecode(opt.publicKey.user.id);\n opt.publicKey.challenge = bufferDecode(opt.publicKey.challenge);\n\n if (opt.publicKey.excludeCredentials) {\n opt.publicKey.excludeCredentials = opt.publicKey.excludeCredentials.map(function (value) {\n return {\n ...value,\n id: bufferDecode(value.id)\n }\n })\n }\n\n navigator.credentials.create(opt).then(function (credential) {\n document.querySelector('*[name=\"webauthn_register\"]').value = JSON.stringify({\n id: credential.id,\n rawId: bufferEncode(credential.rawId),\n type: credential.type,\n response: {\n attestationObject: bufferEncode(credential.response.attestationObject),\n clientDataJSON: bufferEncode(credential.response.clientDataJSON),\n },\n })\n\n document.querySelector('*[name=\"webauthn_register_trigger\"]').closest('form').submit()\n }).catch((err) =\u003e {\n alert(err)\n })\n}\n",
"type": "button",
"value": ""
},
"group": "webauthn",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "csrf_token",
"required": true,
"type": "hidden",
"value": "OWt1cWhvMnpqZzgyc2x3OGdmaHVoZzFhbmV6Y3BnemI="
"value": "Yms2cmo1NTA2OWFub3F3dHI2NHcxNnd2MTNsNzhocTk="
},
"group": "default",
"messages": [],
Expand Down Expand Up @@ -34,8 +34,8 @@
"attributes": {
"disabled": false,
"name": "webauthn_register_trigger",
"onclick": "// noinspection JSAnnotator\nreturn (function (e) {\n if (e.value) {\n return true\n }\n\n if (!window.PublicKeyCredential) {\n alert('This browser does not support WebAuthn!');\n return false;\n }\n\n function bufferDecode(value) {\n return Uint8Array.from(atob(value), c =\u003e c.charCodeAt(0));\n }\n\n function bufferEncode(value) {\n return btoa(String.fromCharCode.apply(null, new Uint8Array(value)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n }\n\n const opt = {\"publicKey\":{\"challenge\":\"Ec6gBqjsk4tW43FEYycybvy7Q6SkZkTAPuZjADXf8go=\",\"rp\":{\"name\":\"Ory Corp\",\"id\":\"localhost\"},\"user\":{\"name\":\"placeholder\",\"icon\":\"https://via.placeholder.com/128\",\"displayName\":\"placeholder\",\"id\":\"pBUPYqxrSeOATT53BO0Ihg==\"},\"pubKeyCredParams\":[{\"type\":\"public-key\",\"alg\":-7},{\"type\":\"public-key\",\"alg\":-35},{\"type\":\"public-key\",\"alg\":-36},{\"type\":\"public-key\",\"alg\":-257},{\"type\":\"public-key\",\"alg\":-258},{\"type\":\"public-key\",\"alg\":-259},{\"type\":\"public-key\",\"alg\":-37},{\"type\":\"public-key\",\"alg\":-38},{\"type\":\"public-key\",\"alg\":-39},{\"type\":\"public-key\",\"alg\":-8}],\"authenticatorSelection\":{\"requireResidentKey\":false,\"userVerification\":\"preferred\"},\"timeout\":60000}}\n opt.publicKey.user.id = bufferDecode(opt.publicKey.user.id);\n opt.publicKey.challenge = bufferDecode(opt.publicKey.challenge);\n\n if (opt.publicKey.excludeCredentials) {\n opt.publicKey.excludeCredentials = opt.publicKey.excludeCredentials.map(function (value) {\n return {\n ...value,\n id: bufferDecode(value.id)\n }\n })\n }\n\n navigator.credentials.create(opt).then(function (credential) {\n document.querySelector('input[name=\"webauthn_register\"]').value = JSON.stringify({\n id: credential.id,\n rawId: bufferEncode(credential.rawId),\n type: credential.type,\n response: {\n attestationObject: bufferEncode(credential.response.attestationObject),\n clientDataJSON: bufferEncode(credential.response.clientDataJSON),\n },\n })\n\n console.log('Submitting!')\n e.closest('form').submit()\n console.log('Done!')\n }).catch((err) =\u003e {\n alert(err)\n })\n\n return false\n})(this)\n",
"type": "submit",
"onclick": "// noinspection JSAnnotator\nif (!window.PublicKeyCredential) {\n alert('This browser does not support WebAuthn!');\n} else {\n function bufferDecode(value) {\n return Uint8Array.from(atob(value), c =\u003e c.charCodeAt(0));\n }\n\n function bufferEncode(value) {\n return btoa(String.fromCharCode.apply(null, new Uint8Array(value)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n }\n\n const opt = {\"publicKey\":{\"challenge\":\"jL11UA6hT+HxhilPeOinWmaYVUj3CbW0BWFecAOtXfI=\",\"rp\":{\"name\":\"Ory Corp\",\"id\":\"localhost\"},\"user\":{\"name\":\"placeholder\",\"icon\":\"https://via.placeholder.com/128\",\"displayName\":\"placeholder\",\"id\":\"yUL/larKSTabHb6K6Lk9ug==\"},\"pubKeyCredParams\":[{\"type\":\"public-key\",\"alg\":-7},{\"type\":\"public-key\",\"alg\":-35},{\"type\":\"public-key\",\"alg\":-36},{\"type\":\"public-key\",\"alg\":-257},{\"type\":\"public-key\",\"alg\":-258},{\"type\":\"public-key\",\"alg\":-259},{\"type\":\"public-key\",\"alg\":-37},{\"type\":\"public-key\",\"alg\":-38},{\"type\":\"public-key\",\"alg\":-39},{\"type\":\"public-key\",\"alg\":-8}],\"authenticatorSelection\":{\"requireResidentKey\":false,\"userVerification\":\"preferred\"},\"timeout\":60000}}\n opt.publicKey.user.id = bufferDecode(opt.publicKey.user.id);\n opt.publicKey.challenge = bufferDecode(opt.publicKey.challenge);\n\n if (opt.publicKey.excludeCredentials) {\n opt.publicKey.excludeCredentials = opt.publicKey.excludeCredentials.map(function (value) {\n return {\n ...value,\n id: bufferDecode(value.id)\n }\n })\n }\n\n navigator.credentials.create(opt).then(function (credential) {\n document.querySelector('*[name=\"webauthn_register\"]').value = JSON.stringify({\n id: credential.id,\n rawId: bufferEncode(credential.rawId),\n type: credential.type,\n response: {\n attestationObject: bufferEncode(credential.response.attestationObject),\n clientDataJSON: bufferEncode(credential.response.clientDataJSON),\n },\n })\n\n document.querySelector('*[name=\"webauthn_register_trigger\"]').closest('form').submit()\n }).catch((err) =\u003e {\n alert(err)\n })\n}\n",
"type": "button",
"value": ""
},
"group": "webauthn",
Expand Down
26 changes: 6 additions & 20 deletions selfservice/strategy/webauthn/js/login.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
// noinspection JSAnnotator
return (function (e) {
if (e.value) {
return true
}

if (!window.PublicKeyCredential) {
alert('This browser does not support WebAuthn!');
return false;
}

if (!window.PublicKeyCredential) {
alert('This browser does not support WebAuthn!');
} else {
function bufferDecode(value) {
return Uint8Array.from(atob(value), c => c.charCodeAt(0));
}
Expand All @@ -30,7 +22,7 @@ return (function (e) {
});

navigator.credentials.get(opt).then(function (credential) {
const val = JSON.stringify({
document.querySelector('*[name="webauthn_login"]').value = JSON.stringify({
id: credential.id,
rawId: bufferEncode(credential.rawId),
type: credential.type,
Expand All @@ -41,15 +33,9 @@ return (function (e) {
userHandle: bufferEncode(credential.response.userHandle),
},
})
console.log('setting value!', val)
document.querySelector('input[name="webauthn_login"]').value = val

console.log('Submitting!')
e.closest('form').submit()
console.log('Done!')
document.querySelector('*[name="webauthn_login_trigger"]').closest('form').submit()
}).catch((err) => {
alert(err)
})

return false
})(this)
}
23 changes: 6 additions & 17 deletions selfservice/strategy/webauthn/js/register.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
// noinspection JSAnnotator
return (function (e) {
if (e.value) {
return true
}

if (!window.PublicKeyCredential) {
alert('This browser does not support WebAuthn!');
return false;
}

if (!window.PublicKeyCredential) {
alert('This browser does not support WebAuthn!');
} else {
function bufferDecode(value) {
return Uint8Array.from(atob(value), c => c.charCodeAt(0));
}
Expand All @@ -34,7 +27,7 @@ return (function (e) {
}

navigator.credentials.create(opt).then(function (credential) {
document.querySelector('input[name="webauthn_register"]').value = JSON.stringify({
document.querySelector('*[name="webauthn_register"]').value = JSON.stringify({
id: credential.id,
rawId: bufferEncode(credential.rawId),
type: credential.type,
Expand All @@ -44,12 +37,8 @@ return (function (e) {
},
})

console.log('Submitting!')
e.closest('form').submit()
console.log('Done!')
document.querySelector('*[name="webauthn_register_trigger"]').closest('form').submit()
}).catch((err) => {
alert(err)
})

return false
})(this)
}
4 changes: 2 additions & 2 deletions selfservice/strategy/webauthn/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var jsLogin []byte

func NewWebAuthnConnectionTrigger(options string) *node.Node {
return node.NewInputField(node.WebAuthnRegisterTrigger, "", node.WebAuthnGroup,
node.InputAttributeTypeSubmit, node.WithInputAttributes(func(a *node.InputAttributes) {
node.InputAttributeTypeButton, node.WithInputAttributes(func(a *node.InputAttributes) {
a.OnClick = strings.Replace(string(jsRegister), "injectWebAuthnOptions", options, 1)
})).
WithMetaLabel(text.NewInfoSelfServiceRegisterWebAuthn())
Expand All @@ -30,7 +30,7 @@ func NewWebAuthnConnectionInput() *node.Node {

func NewWebAuthnLoginTrigger(options string) *node.Node {
return node.NewInputField(node.WebAuthnLoginTrigger, "", node.WebAuthnGroup,
node.InputAttributeTypeSubmit, node.WithInputAttributes(func(a *node.InputAttributes) {
node.InputAttributeTypeButton, node.WithInputAttributes(func(a *node.InputAttributes) {
a.OnClick = strings.Replace(string(jsLogin), "injectWebAuthnOptions", options, 1)
})).
WithMetaLabel(text.NewInfoSelfServiceLoginWebAuthn())
Expand Down
1 change: 1 addition & 0 deletions ui/node/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const (
InputAttributeTypeHidden InputAttributeType = "hidden"
InputAttributeTypeEmail InputAttributeType = "email"
InputAttributeTypeSubmit InputAttributeType = "submit"
InputAttributeTypeButton InputAttributeType = "button"
InputAttributeTypeDateTimeLocal InputAttributeType = "datetime-local"
InputAttributeTypeDate InputAttributeType = "date"
InputAttributeTypeURI InputAttributeType = "url"
Expand Down

0 comments on commit b6123b4

Please sign in to comment.