BasicOIDC/templates/settings/add_webauthn_page.html

87 lines
3.2 KiB
HTML

{% extends "base_settings_page.html" %}
{% block content %}
<div style="max-width: 700px;">
<p>In order to continue, please click on the "Start Enrollment" button, insert your security key and approve the
registration request.</p>
<div class="form-group">
<label for="inputKeyName" class="form-label mt-4">Key name</label>
<input type="text" class="form-control" id="inputKeyName"
placeholder="Device / Authenticator app name"
value="Security key" minlength="1" required/>
<small class="form-text text-muted">Please give a name to your key to identify it more easily later.</small>
<div class="invalid-feedback">Please give a name to this security key</div>
</div>
<input type="button" class="btn btn-primary" value="Start enrollment" onclick="startEnrollment()"
style="margin-top: 20px;"/>
<script src="/assets/js/base64_lib.js"></script>
<script>
const OPAQUE_STATE = "{{ opaque_state }}";
const REGISTRATION_CHALLENGE = JSON.parse(decodeURIComponent("{{ challenge_json }}"));
// Decode data
REGISTRATION_CHALLENGE.publicKey.challenge = base64NoPaddingToUint8Array(
REGISTRATION_CHALLENGE.publicKey.challenge
);
REGISTRATION_CHALLENGE.publicKey.user.id = base64NoPaddingToUint8Array(
REGISTRATION_CHALLENGE.publicKey.user.id
);
async function startEnrollment() {
try {
const factorNameInput = document.getElementById("inputKeyName");
factorNameInput.classList.remove("is-invalid");
if (factorNameInput.value.length === 0) {
factorNameInput.classList.add("is-invalid");
return;
}
const cred = await navigator.credentials.create(REGISTRATION_CHALLENGE);
// Encode data that needs to be encoded
const credential_res = {
id: cred.id,
rawId: ArrayBufferToBase64(cred.rawId),
type: cred.type,
response: {
attestationObject: ArrayBufferToBase64(
cred.response.attestationObject
),
clientDataJSON: ArrayBufferToBase64(
cred.response.clientDataJSON
),
},
};
const res = await fetch("/settings/api/two_factor/save_webauthn_factor", {
method: "post",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
opaque_state: OPAQUE_STATE,
factor_name: factorNameInput.value,
credential: credential_res,
})
});
let text = await res.text();
alert(text);
if (res.status == 200)
location.href = "/settings/two_factors";
} catch(e) {
console.error(e);
alert("Failed enrollment, please try again!");
}
}
</script>
</div>
{% endblock content %}