mirror of
https://github.com/ysoftdevs/oauth-playground-server.git
synced 2026-04-19 07:09:47 +02:00
Merge branch 'master' of https://github.com/ysoftdevs/oauth-playground-server
This commit is contained in:
@@ -79,7 +79,7 @@ public class MyWebAuthnSetup implements WebAuthnUserProvider {
|
|||||||
}
|
}
|
||||||
// returning (or duplicate) user with new credential -> reject,
|
// returning (or duplicate) user with new credential -> reject,
|
||||||
// as we do not provide a means to register additional credentials yet
|
// as we do not provide a means to register additional credentials yet
|
||||||
return Uni.createFrom().failure(new Throwable("Duplicate user"));
|
return Uni.createFrom().failure(new Throwable("Duplicate user: " + authenticator.getUserName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,41 +15,14 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||||
<script charset="UTF-8" src="/js/webauthn-debug.js" type="text/javascript"></script>
|
<script charset="UTF-8" src="/js/webauthn-debug.js" type="text/javascript"></script>
|
||||||
<style>
|
<style>
|
||||||
.container {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto auto auto;
|
.code {
|
||||||
|
white-space: pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
button, input {
|
.step {
|
||||||
margin: 5px 0;
|
display: none;
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav > ul {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav > ul > li {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav > ul > li > a {
|
|
||||||
display: block;
|
|
||||||
color: white;
|
|
||||||
text-align: center;
|
|
||||||
padding: 14px 16px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav > ul > li > a:hover {
|
|
||||||
background-color: #111;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -57,55 +30,45 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<input id="userName" placeholder="User name"/><br/>
|
<input id="userName" placeholder="User name"/><br/>
|
||||||
<button id="login">Login</button>
|
<button class="nextBtn" id="login">Login</button>
|
||||||
<button id="register">Register</button>
|
<button class="nextBtn" id="register">Register</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="trace"></div>
|
<div class="container step" id="server1-request">
|
||||||
|
The interaction starts with an AJAX call.
|
||||||
<div class="container" id="server1">
|
<div class="code">POST <span id="server1-url"></span>
|
||||||
<div id="server1-call"></div>
|
<div id="server1-call"></div>
|
||||||
<div id="server1-response"></div>
|
</div>
|
||||||
|
<button class="nextBtn">Request challenge</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container" id="navigator">
|
<div class="container step" id="server1-response">
|
||||||
<div id="navigator-call"></div>
|
The server prepares a challenge for the browser to sign.
|
||||||
<div id="navigator-response"></div>
|
<div class="code" id="server1-response-body"></div>
|
||||||
|
<button class="nextBtn">Continue</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container" id="server2">
|
<div class="container step" id="navigator-request">
|
||||||
<div id="server2-call"></div>
|
The challenge is passed to the browser call:
|
||||||
<div id="server2-response"></div>
|
<div class="code" id="navigator-call"></div>
|
||||||
|
<button class="nextBtn">Call Webauthn API</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container step" id="navigator-response">
|
||||||
|
Which responds:
|
||||||
|
<div class="code" id="navigator-response-body"></div>
|
||||||
|
The <strong>response.clientDataJSON</strong> are base64 encoded:
|
||||||
|
<div class="code" id="navigator-clientDataJSON"></div>
|
||||||
|
<button class="nextBtn">Finish the interaction</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="result"></div>
|
<div id="result"></div>
|
||||||
|
<div id="trace"></div>
|
||||||
|
|
||||||
<form action="#" method="POST">
|
<form action="#" method="POST">
|
||||||
<input id="webAuthnId" name="webAuthnId" placeholder="webAuthnId"/><br/>
|
<input name="sessionId" type="hidden" value="somesessionid">
|
||||||
<input id="webAuthnRawId" name="webAuthnRawId" placeholder="webAuthnRawId"/><br/>
|
<div id="form-generated"></div>
|
||||||
<input id="webAuthnResponseAttestationObject" name="webAuthnResponseAttestationObject"
|
|
||||||
placeholder="webAuthnResponseAttestationObject"/><br/>
|
|
||||||
<input id="webAuthnResponseClientDataJSON" name="webAuthnResponseClientDataJSON"
|
|
||||||
placeholder="webAuthnResponseClientDataJSON"/><br/>
|
|
||||||
<div id="webAuthnResponseClientDataJSONJson"></div>
|
|
||||||
<br/>
|
|
||||||
<input id="webAuthnResponseAuthenticatorData" name="webAuthnResponseAuthenticatorData"
|
|
||||||
placeholder="webAuthnResponseAuthenticatorData"/><br/>
|
|
||||||
<div id="webAuthnResponseAuthenticatorDataJson"></div>
|
|
||||||
<br/>
|
|
||||||
<input id="webAuthnResponseSignature" name="webAuthnResponseSignature"
|
|
||||||
placeholder="webAuthnResponseSignature"/><br/>
|
|
||||||
<div id="webAuthnResponseSignatureJson"></div>
|
|
||||||
<br/>
|
|
||||||
<input id="webAuthnResponseUserHandle" name="webAuthnResponseUserHandle"
|
|
||||||
placeholder="webAuthnResponseUserHandle"/><br/>
|
|
||||||
<div id="webAuthnResponseUserHandleJson"></div>
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<input id="webAuthnType" name="webAuthnType" placeholder="webAuthnType"/><br/>
|
|
||||||
<button formaction="/webauthn/register" type="submit">Finish registration</button>
|
|
||||||
<button formaction="/webauthn/login" type="submit">Finish login</button>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@@ -117,39 +80,113 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillOrHideFormField(id, value) {
|
|
||||||
let el = document.getElementById(id);
|
|
||||||
if (!el) throw "No element #" + id;
|
|
||||||
el.value = value;
|
|
||||||
if (value !== undefined) {
|
|
||||||
el.style.display = "";
|
|
||||||
} else {
|
|
||||||
//el.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fillOrHideJsonField(id, value) {
|
|
||||||
let el = document.getElementById(id);
|
|
||||||
if (!el) throw "No element #" + id;
|
|
||||||
if (value !== undefined) {
|
|
||||||
el.style.display = "";
|
|
||||||
el.innerHTML = tryDecodeBase64(value);
|
|
||||||
} else {
|
|
||||||
el.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function tracer(stage, params) {
|
function tracer(stage, params) {
|
||||||
console.log(stage, params)
|
console.log(stage, params)
|
||||||
|
|
||||||
|
switch (stage) {
|
||||||
|
case "register-request":
|
||||||
|
return traceRegisterRequest(params);
|
||||||
|
case "register-response":
|
||||||
|
return traceRegisterResponse(params);
|
||||||
|
case "credentials-create-request":
|
||||||
|
return traceCredentialsCreateRequest(params);
|
||||||
|
case "credentials-create-response":
|
||||||
|
return traceCredentialsCreateResponse(params);
|
||||||
|
case "login-request":
|
||||||
|
return traceLoginRequest(params);
|
||||||
|
case "login-response":
|
||||||
|
return traceLoginResponse(params);
|
||||||
|
case "credentials-get-request":
|
||||||
|
return traceCredentialsGetRequest(params);
|
||||||
|
case "credentials-get-response":
|
||||||
|
return traceCredentialsGetResponse(params);
|
||||||
|
default:
|
||||||
|
return traceGeneric(stage, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function continueButton(where, result) {
|
||||||
|
const button = $("button", $(where)).show();
|
||||||
|
if (button.length) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
button.click(() => {
|
||||||
|
resolve(result);
|
||||||
|
$(button).hide();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceRegisterRequest(params) {
|
||||||
|
$(".step").hide();
|
||||||
|
$("#server1-request").show();
|
||||||
|
$("#server1-url").html(params.url)
|
||||||
|
$("#server1-call").html(JSON.stringify(params.body, null, 2));
|
||||||
|
return continueButton("#server1-request", params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceRegisterResponse(params) {
|
||||||
|
$("#server1-response").show();
|
||||||
|
$("#server1-response-body").html(JSON.stringify(params, null, 2));
|
||||||
|
return continueButton("#server1-response", params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceLoginRequest(params) {
|
||||||
|
$(".step").hide();
|
||||||
|
$("#server1-request").show();
|
||||||
|
$("#server1-url").html(params.url)
|
||||||
|
$("#server1-call").html(JSON.stringify(params.body, null, 2));
|
||||||
|
return continueButton("#server1-request", params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceLoginResponse(params) {
|
||||||
|
$("#server1-response").show();
|
||||||
|
$("#server1-response-body").html(JSON.stringify(params, null, 2));
|
||||||
|
return continueButton("#server1-response", params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceCredentialsCreateRequest(challenge) {
|
||||||
|
$("#navigator-request").show();
|
||||||
|
$("#navigator-call").html("navigator.credentials.create({ publicKey: ... });");
|
||||||
|
return continueButton("#navigator-request", challenge);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceCredentialsCreateResponse(response) {
|
||||||
|
$("#navigator-response").show();
|
||||||
|
$("#navigator-response-body").html(JSON.stringify(response, null, 2));
|
||||||
|
$("#navigator-clientDataJSON").html(JSON.stringify(JSON.parse(tryDecodeBase64(response.response.clientDataJSON)), null, 2));
|
||||||
|
return continueButton("#navigator-response", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceCredentialsGetRequest(challenge) {
|
||||||
|
$("#navigator-request").show();
|
||||||
|
$("#navigator-call").html("navigator.credentials.get({ publicKey: ... });");
|
||||||
|
return continueButton("#navigator-request", challenge);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceCredentialsGetResponse(response) {
|
||||||
|
$("#navigator-response").show();
|
||||||
|
$("#navigator-response-body").html(JSON.stringify(response, null, 2));
|
||||||
|
$("#navigator-clientDataJSON").html(JSON.stringify(JSON.parse(tryDecodeBase64(response.response.clientDataJSON)), null, 2));
|
||||||
|
return continueButton("#navigator-response", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
function traceGeneric(stage, params) {
|
||||||
const content = JSON.stringify(params);
|
const content = JSON.stringify(params);
|
||||||
const trace = $("<div class='container'></div>").attr("id", stage).html(content).appendTo("#trace");
|
const trace = $("<div class='container'></div>").attr("id", stage).html(content).appendTo("#trace");
|
||||||
const button = $("<button>Continue</button>").appendTo(trace)
|
return continueButton(trace, params);
|
||||||
return new Promise((resolve, reject) => {
|
}
|
||||||
button.click(() => {
|
|
||||||
resolve(params);
|
function form(action, fields) {
|
||||||
$(button).remove();
|
const $form = $("form").attr("action", action);
|
||||||
});
|
const $fields = $("#form-generated", $form).empty()
|
||||||
});
|
for ([key, value] of Object.entries(fields)) {
|
||||||
|
console.log(key);
|
||||||
|
$("<input type='hidden'>").attr("name", key).val(value).appendTo($fields)
|
||||||
|
}
|
||||||
|
$form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
const webAuthn = new WebAuthn({
|
const webAuthn = new WebAuthn({
|
||||||
@@ -170,24 +207,15 @@
|
|||||||
result.replaceChildren();
|
result.replaceChildren();
|
||||||
webAuthn.loginOnly({name: userName})
|
webAuthn.loginOnly({name: userName})
|
||||||
.then(body => {
|
.then(body => {
|
||||||
// store the registration JSON in form elements
|
form("/webauthn/login", {
|
||||||
fillOrHideFormField('webAuthnId', body.id);
|
'webAuthnId': body.id,
|
||||||
fillOrHideFormField('webAuthnRawId', body.rawId);
|
'webAuthnRawId': body.rawId,
|
||||||
fillOrHideFormField('webAuthnResponseClientDataJSON', body.response.clientDataJSON);
|
'webAuthnResponseClientDataJSON': body.response.clientDataJSON,
|
||||||
fillOrHideJsonField('webAuthnResponseClientDataJSONJson', body.response.clientDataJSON);
|
'webAuthnResponseAuthenticatorData': body.response.authenticatorData,
|
||||||
fillOrHideFormField('webAuthnResponseAuthenticatorData', body.response.authenticatorData);
|
'webAuthnResponseSignature': body.response.signature,
|
||||||
fillOrHideFormField('webAuthnResponseSignature', body.response.signature);
|
'webAuthnResponseUserHandle': body.response.userHandle,
|
||||||
fillOrHideFormField('webAuthnResponseUserHandle', body.response.userHandle);
|
'webAuthnType': body.type
|
||||||
fillOrHideFormField('webAuthnType', body.type);
|
});
|
||||||
|
|
||||||
|
|
||||||
// document.getElementById('webAuthnId').value = body.id;
|
|
||||||
// document.getElementById('webAuthnRawId').value = body.rawId;
|
|
||||||
// document.getElementById('webAuthnResponseClientDataJSON').value = body.response.clientDataJSON;
|
|
||||||
// document.getElementById('webAuthnResponseAuthenticatorData').value = body.response.authenticatorData;
|
|
||||||
// document.getElementById('webAuthnResponseSignature').value = body.response.signature;
|
|
||||||
// document.getElementById('webAuthnResponseUserHandle').value = body.response.userHandle;
|
|
||||||
// document.getElementById('webAuthnType').value = body.type;
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
result.append("Login failed: " + err);
|
result.append("Login failed: " + err);
|
||||||
@@ -207,14 +235,13 @@
|
|||||||
|
|
||||||
webAuthn.registerOnly({name: userName, displayName: userName /*firstName + " " + lastName*/})
|
webAuthn.registerOnly({name: userName, displayName: userName /*firstName + " " + lastName*/})
|
||||||
.then(body => {
|
.then(body => {
|
||||||
// store the registration JSON in form elements
|
form("/webauthn/register", {
|
||||||
fillOrHideFormField('webAuthnId', body.id);
|
'webAuthnId': body.id,
|
||||||
fillOrHideFormField('webAuthnRawId', body.rawId);
|
'webAuthnRawId': body.rawId,
|
||||||
fillOrHideFormField('webAuthnResponseAttestationObject', body.response.attestationObject);
|
'webAuthnResponseAttestationObject': body.response.attestationObject,
|
||||||
fillOrHideFormField('webAuthnResponseClientDataJSON', body.response.clientDataJSON);
|
'webAuthnResponseClientDataJSON': body.response.clientDataJSON,
|
||||||
fillOrHideJsonField('webAuthnResponseClientDataJSONJson', body.response.clientDataJSON);
|
'webAuthnType': body.type
|
||||||
fillOrHideFormField('webAuthnType', body.type);
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
result.append("Registration failed: " + err);
|
result.append("Registration failed: " + err);
|
||||||
|
|||||||
@@ -112,9 +112,23 @@
|
|||||||
return Promise.resolve(params);
|
return Promise.resolve(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
this._debugFetch = function (stage, input, init) {
|
this._debugPostJson = function (stage, url, body) {
|
||||||
return this.debuggingFunction(stage + "-request", {input: input, init: init})
|
return this.debuggingFunction(stage + "-request", {url: url, body: body})
|
||||||
.then(params => fetch(params.input, params.init))
|
.then(params => fetch(params.url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(params.body)
|
||||||
|
}))
|
||||||
|
.then(res => {
|
||||||
|
if (res.status >= 200 && res.status < 300) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new Error(res.statusText);
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
.then(resp => this.debuggingFunction(stage + "-response", resp));
|
.then(resp => this.debuggingFunction(stage + "-response", resp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,21 +148,7 @@
|
|||||||
if (!self.registerPath) {
|
if (!self.registerPath) {
|
||||||
return Promise.reject('Register path missing form the initial configuration!');
|
return Promise.reject('Register path missing form the initial configuration!');
|
||||||
}
|
}
|
||||||
return self._debugFetch("register", self.registerPath, {
|
return self._debugPostJson("register", self.registerPath, user || {})
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(user || {})
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
if (res.status === 200) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
throw new Error(res.statusText);
|
|
||||||
})
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(res => {
|
.then(res => {
|
||||||
res.challenge = base64ToBuffer(res.challenge);
|
res.challenge = base64ToBuffer(res.challenge);
|
||||||
res.user.id = base64ToBuffer(res.user.id);
|
res.user.id = base64ToBuffer(res.user.id);
|
||||||
@@ -159,8 +159,7 @@
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.then(res => self._debugAround("credentials-create", x => navigator.credentials.create(x), {publicKey: res}))
|
.then(res => self._debugAround("credentials-create", x => navigator.credentials.create(x).then(credential => {
|
||||||
.then(credential => {
|
|
||||||
return {
|
return {
|
||||||
id: credential.id,
|
id: credential.id,
|
||||||
rawId: bufferToBase64(credential.rawId),
|
rawId: bufferToBase64(credential.rawId),
|
||||||
@@ -170,49 +169,22 @@
|
|||||||
},
|
},
|
||||||
type: credential.type
|
type: credential.type
|
||||||
};
|
};
|
||||||
});
|
}), {publicKey: res}));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WebAuthn.prototype.register = function (user) {
|
WebAuthn.prototype.register = function (user) {
|
||||||
const self = this;
|
const self = this;
|
||||||
return self.registerOnly(user)
|
return self.registerOnly(user)
|
||||||
.then(body => {
|
.then(body => {
|
||||||
return self._debugFetch("register-callback", self.registerCallbackPath, {
|
return self._debugPostJson("register-callback", self.registerCallbackPath, body)
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
if (res.status >= 200 && res.status < 300) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
throw new Error(res.statusText);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
WebAuthn.prototype.login = function (user) {
|
WebAuthn.prototype.login = function (user) {
|
||||||
const self = this;
|
const self = this;
|
||||||
return self.loginOnly(user)
|
return self.loginOnly(user)
|
||||||
.then(body => {
|
.then(body => self._debugPostJson("login-callback", self.loginCallbackPath, body))
|
||||||
return self._debugFetch("login-callback", self.loginCallbackPath, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
if (res.status >= 200 && res.status < 300) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
throw new Error(res.statusText);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WebAuthn.prototype.loginOnly = function (user) {
|
WebAuthn.prototype.loginOnly = function (user) {
|
||||||
@@ -220,21 +192,7 @@
|
|||||||
if (!self.loginPath) {
|
if (!self.loginPath) {
|
||||||
return Promise.reject('Login path missing from the initial configuration!');
|
return Promise.reject('Login path missing from the initial configuration!');
|
||||||
}
|
}
|
||||||
return self._debugFetch("login", self.loginPath, {
|
return self._debugPostJson("login", self.loginPath, user)
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(user)
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
if (res.status === 200) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
throw new Error(res.statusText);
|
|
||||||
})
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(res => {
|
.then(res => {
|
||||||
res.challenge = base64ToBuffer(res.challenge);
|
res.challenge = base64ToBuffer(res.challenge);
|
||||||
if (res.allowCredentials) {
|
if (res.allowCredentials) {
|
||||||
@@ -244,8 +202,7 @@
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.then(res => self._debugAround("credentials-get", x => navigator.credentials.get(x), {publicKey: res}))
|
.then(res => self._debugAround("credentials-get", x => navigator.credentials.get(x).then(credential => {
|
||||||
.then(credential => {
|
|
||||||
return {
|
return {
|
||||||
id: credential.id,
|
id: credential.id,
|
||||||
rawId: bufferToBase64(credential.rawId),
|
rawId: bufferToBase64(credential.rawId),
|
||||||
@@ -257,7 +214,8 @@
|
|||||||
},
|
},
|
||||||
type: credential.type
|
type: credential.type
|
||||||
};
|
};
|
||||||
})
|
}), {publicKey: res}))
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return WebAuthn;
|
return WebAuthn;
|
||||||
|
|||||||
Reference in New Issue
Block a user