forked from GithubBackups/healthchecks
Improve the "add security key" UX, require sudo mode
This commit is contained in:
parent
e3aedd3b03
commit
2c3286c280
@ -22,6 +22,7 @@ from fido2.server import Fido2Server
|
|||||||
from fido2.webauthn import PublicKeyCredentialRpEntity
|
from fido2.webauthn import PublicKeyCredentialRpEntity
|
||||||
from fido2 import cbor
|
from fido2 import cbor
|
||||||
from hc.accounts import forms
|
from hc.accounts import forms
|
||||||
|
from hc.accounts.decorators import require_sudo_mode
|
||||||
from hc.accounts.models import Credential, Profile, Project, Member
|
from hc.accounts.models import Credential, Profile, Project, Member
|
||||||
from hc.api.models import Channel, Check, TokenBucket
|
from hc.api.models import Channel, Check, TokenBucket
|
||||||
from hc.lib.date import choose_next_report_date
|
from hc.lib.date import choose_next_report_date
|
||||||
@ -552,6 +553,7 @@ def _verify_origin(aaa):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@require_sudo_mode
|
||||||
def add_credential(request):
|
def add_credential(request):
|
||||||
rp = PublicKeyCredentialRpEntity("localhost", "Healthchecks")
|
rp = PublicKeyCredentialRpEntity("localhost", "Healthchecks")
|
||||||
# FIXME use HTTPS, remove the verify_origin hack
|
# FIXME use HTTPS, remove the verify_origin hack
|
||||||
|
8
static/css/add_credential.css
Normal file
8
static/css/add_credential.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#add-credential-waiting .spinner {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#add-credential-error-text {
|
||||||
|
font-family: "Lucida Console", Monaco, monospace;
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
@ -3,23 +3,34 @@ $(function() {
|
|||||||
var optionsBytes = Uint8Array.from(atob(form.dataset.options), c => c.charCodeAt(0));
|
var optionsBytes = Uint8Array.from(atob(form.dataset.options), c => c.charCodeAt(0));
|
||||||
// cbor.js expects ArrayBuffer as input when decoding
|
// cbor.js expects ArrayBuffer as input when decoding
|
||||||
var options = CBOR.decode(optionsBytes.buffer);
|
var options = CBOR.decode(optionsBytes.buffer);
|
||||||
console.log("decoded options:", options);
|
|
||||||
|
|
||||||
function b64(arraybuffer) {
|
function b64(arraybuffer) {
|
||||||
return btoa(String.fromCharCode.apply(null, new Uint8Array(arraybuffer)));
|
return btoa(String.fromCharCode.apply(null, new Uint8Array(arraybuffer)));
|
||||||
}
|
}
|
||||||
|
|
||||||
navigator.credentials.create(options).then(function(attestation) {
|
function requestCredentials() {
|
||||||
console.log("got attestation: ", attestation);
|
// Hide error & success messages, show the "waiting" message
|
||||||
|
$("#name-next").addClass("hide");
|
||||||
|
$("#add-credential-waiting").removeClass("hide");
|
||||||
|
$("#add-credential-error").addClass("hide");
|
||||||
|
$("#add-credential-success").addClass("hide");
|
||||||
|
|
||||||
$("#attestation_object").val(b64(attestation.response.attestationObject));
|
navigator.credentials.create(options).then(function(attestation) {
|
||||||
$("#client_data_json").val(b64(attestation.response.clientDataJSON));
|
$("#attestation_object").val(b64(attestation.response.attestationObject));
|
||||||
console.log("form updated, all is well");
|
$("#client_data_json").val(b64(attestation.response.clientDataJSON));
|
||||||
|
|
||||||
|
// Show the success message and save button
|
||||||
|
$("#add-credential-waiting").addClass("hide");
|
||||||
|
$("#add-credential-success").removeClass("hide");
|
||||||
|
}).catch(function(err) {
|
||||||
|
// Show the error message
|
||||||
|
$("#add-credential-waiting").addClass("hide");
|
||||||
|
$("#add-credential-error-text").text(err);
|
||||||
|
$("#add-credential-error").removeClass("hide");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#name-next").click(requestCredentials);
|
||||||
|
$("#retry").click(requestCredentials);
|
||||||
|
|
||||||
$("#add-credential-submit").prop("disabled", "");
|
|
||||||
$("#add-credential-success").removeClass("hide");
|
|
||||||
}).catch(function(err) {
|
|
||||||
$("#add-credential-error span").text(err);
|
|
||||||
$("#add-credential-error").removeClass("hide");
|
|
||||||
});
|
|
||||||
});
|
});
|
@ -1,5 +1,5 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load compress static %}
|
{% load compress static hc_extras %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
@ -11,7 +11,7 @@
|
|||||||
data-options="{{ options }}"
|
data-options="{{ options }}"
|
||||||
method="post"
|
method="post"
|
||||||
encrypt="multipart/form-data">
|
encrypt="multipart/form-data">
|
||||||
<h1>Add Credential</h1>
|
<h1>Add Security Key</h1>
|
||||||
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input id="attestation_object" type="hidden" name="attestation_object">
|
<input id="attestation_object" type="hidden" name="attestation_object">
|
||||||
@ -25,23 +25,56 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group text-right">
|
||||||
|
<button
|
||||||
|
id="name-next"
|
||||||
|
class="btn btn-default" type="button">
|
||||||
|
Confirm Name and Continue
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="add-credential-waiting" class="hide">
|
||||||
|
<h2>Waiting for security key</h2>
|
||||||
|
<p>
|
||||||
|
Follow your browser's steps to register your security key
|
||||||
|
with {% site_name %}.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="spinner started">
|
||||||
|
<div class="d1"></div>
|
||||||
|
<div class="d2"></div>
|
||||||
|
<div class="d3"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="add-credential-error" class="alert alert-danger hide">
|
<div id="add-credential-error" class="alert alert-danger hide">
|
||||||
<strong>Something went wrong.</strong>
|
<p>
|
||||||
<span></span>
|
<strong>Something went wrong.</strong>
|
||||||
|
</p>
|
||||||
|
<p id="add-credential-error-text"></p>
|
||||||
|
|
||||||
|
<div class="text-right">
|
||||||
|
<button id="retry" type="button" class="btn btn-danger">
|
||||||
|
Try Again
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="add-credential-success" class="alert alert-success hide">
|
<div id="add-credential-success" class="hide">
|
||||||
<strong>Success!</strong>
|
<div class="alert alert-success">
|
||||||
Credential acquired.
|
<strong>Success!</strong>
|
||||||
|
Credential acquired.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group text-right">
|
||||||
|
<input
|
||||||
|
id="add-credential-submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="submit"
|
||||||
|
name=""
|
||||||
|
value="Save Security Key">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<input
|
|
||||||
id="add-credential-submit"
|
|
||||||
class="btn btn-default pull-right"
|
|
||||||
type="submit"
|
|
||||||
name=""
|
|
||||||
value="Save Credential" disabled>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
<link rel="stylesheet" href="{% static 'css/bootstrap-select.min.css' %}" type="text/css">
|
<link rel="stylesheet" href="{% static 'css/bootstrap-select.min.css' %}" type="text/css">
|
||||||
<link rel="stylesheet" href="{% static 'css/selectize.hc.css' %}" type="text/css">
|
<link rel="stylesheet" href="{% static 'css/selectize.hc.css' %}" type="text/css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{% static 'css/add_credential.css' %}" type="text/css">
|
||||||
<link rel="stylesheet" href="{% static 'css/add_project_modal.css' %}" type="text/css">
|
<link rel="stylesheet" href="{% static 'css/add_project_modal.css' %}" type="text/css">
|
||||||
<link rel="stylesheet" href="{% static 'css/add_pushover.css' %}" type="text/css">
|
<link rel="stylesheet" href="{% static 'css/add_pushover.css' %}" type="text/css">
|
||||||
<link rel="stylesheet" href="{% static 'css/webhook_form.css' %}" type="text/css">
|
<link rel="stylesheet" href="{% static 'css/webhook_form.css' %}" type="text/css">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user