273 lines
13 KiB
HTML
273 lines
13 KiB
HTML
|
|
{% extends "base.html" %}
|
||
|
|
|
||
|
|
{% block content %}
|
||
|
|
<div class="modal fade-in" id="add-ssh-key-modal">
|
||
|
|
<div class="modal-ux-header cyan darken-2 white-text">
|
||
|
|
<h2>Add SSH Public Key</h2>
|
||
|
|
</div>
|
||
|
|
<div class="modal-content modal-ux">
|
||
|
|
<form>
|
||
|
|
<div class="row">
|
||
|
|
<div class="input-field">
|
||
|
|
<i class="material-icons prefix">vpn_key</i>
|
||
|
|
<textarea class="materialize-textarea" id="ssh-pub-key" style="height: 200px;"></textarea>
|
||
|
|
<label for="ssh-pub-key">SSH public key</label>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="row">
|
||
|
|
<div class="modal-footer">
|
||
|
|
<button id="btn-add-ssh-key" class="btn waves-effect waves-light right modal-close" onclick="add_ssh_key()" type="button">Submit<i class="material-icons right">send</i></button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="modal fade-in" id="remove-ssh-key-modal">
|
||
|
|
<div class="modal-ux-header cyan darken-2 white-text">
|
||
|
|
<h2>Confirm SSH Key Removal</h2>
|
||
|
|
</div>
|
||
|
|
<div class="modal-content modal-ux row">
|
||
|
|
<p>Are you sure you want to remove this ssh public key?</p>
|
||
|
|
<div class="modal-footer">
|
||
|
|
<button id="btn-confirm-ssh-key-remove" class="btn waves-effect waves-light red modal-close" type="button">Remove</button>
|
||
|
|
<button id="btn-confirm-ssh-key-remove" class="btn waves-effect waves-light modal-close" type="button">Cancel</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="modal fade-in" id="change-password-modal">
|
||
|
|
<div class="modal-ux-header cyan darken-2 white-text">
|
||
|
|
<h2>Change Password</h2>
|
||
|
|
</div>
|
||
|
|
<div class="modal-ux modal-content">
|
||
|
|
<form>
|
||
|
|
<div class="input-field row">
|
||
|
|
<i class="material-icons prefix">password</i>
|
||
|
|
<input id="old-password" type="password" required>
|
||
|
|
<label for="old-password">Password</label>
|
||
|
|
</div>
|
||
|
|
<div class="input-field row">
|
||
|
|
<i class="material-icons prefix">password</i>
|
||
|
|
<input id="new-password" type="password" required>
|
||
|
|
<label for="new-password">New Password</label>
|
||
|
|
</div>
|
||
|
|
<div class="input-field row">
|
||
|
|
<i class="material-icons prefix">password</i>
|
||
|
|
<input id="confirm-password" type="password" required>
|
||
|
|
<label for="confirm-password">Confirm Password</label>
|
||
|
|
</div>
|
||
|
|
<div class="modal-footer row">
|
||
|
|
<button class="btn waves-effect waves-light modal-close" type="button">Cancel</button>
|
||
|
|
<button id="btn-change-password" class="btn waves-effect waves-light" type="button" onclick="change_password()">Submit<i class="material-icons right">send</i></button>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="wrapper">
|
||
|
|
<div id="profile-page-header" class="card">
|
||
|
|
<div class="card-content">
|
||
|
|
<div class="row">
|
||
|
|
<div class="col s12 center-align">
|
||
|
|
<h1 class="card-title grey-text text-darken-4"><i class="material-icons prefix">account_circle</i>{{ current_user.name }}</h1>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div id="profile-page-content" class="row">
|
||
|
|
<div class="col s12">
|
||
|
|
<ul class="collapsible popout white" data-collapsible="accordion">
|
||
|
|
<li>
|
||
|
|
<div class="collapsible-header"><i class="material-icons prefix">account_circle</i>Contact Info</div>
|
||
|
|
<div class="collapsible-body">
|
||
|
|
<ul class="collection">
|
||
|
|
<li class="collection-item">
|
||
|
|
<i class="material-icons">phone_android</i>
|
||
|
|
<span class="title">Phone</span>
|
||
|
|
<div class="input-field">
|
||
|
|
<input id="mobile-phone" value="{{ current_user.phone }}" disabled>
|
||
|
|
</div>
|
||
|
|
<button id="blank" class="btn hiddendiv" type="buton"></button>
|
||
|
|
<button id="cancel-new-phone" class="btn hiddendiv" type="button" onclick="cancel_edit_phone()">Cancel</button>
|
||
|
|
<button id="save-new-phone" class="btn hiddendiv" type="button" onclick="update_phone()">Save<i class="material-icons right">send</i></button>
|
||
|
|
<a id="phone-edit" href="#" onclick="edit_phone()"><i class="material-icons">edit</i></a>
|
||
|
|
</li>
|
||
|
|
<li class="collection-item">
|
||
|
|
<i class="material-icons">email</i>
|
||
|
|
<span class="title">Email</span>
|
||
|
|
<p>{{ current_user.email }}</p>
|
||
|
|
</li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
</li>
|
||
|
|
<li>
|
||
|
|
<div class="collapsible-header"><i class="material-icons prefix">lock</i>Credentials</div>
|
||
|
|
<div class="collapsible-body">
|
||
|
|
<ul class="collection">
|
||
|
|
<li class="collection-item">
|
||
|
|
<i class="material-icons prefix">vpn_key</i>
|
||
|
|
<span class="title">SSH Public Keys</span>
|
||
|
|
{% for pub_key in current_user.ssh_pub_keys %}
|
||
|
|
<div class="row">
|
||
|
|
<div class="col s11">
|
||
|
|
<div class="input-field">
|
||
|
|
<textarea class="materialize-textarea" id="pub-key{{ loop.index0 }}" style="height: 150px;" disabled>{{ pub_key }}</textarea>
|
||
|
|
<label for="pub-key-{{ loop.index0 }}">Public Key {{ loop.index0 + 1 }}:</label>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="col s1">
|
||
|
|
<a class="right modal-trigger" href="#remove-ssh-key-modal" onclick="del_ssh_key('{{ pub_key }}')">
|
||
|
|
<i class="material-icons red-text">remove</i>
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="divider"></div>
|
||
|
|
{% endfor %}
|
||
|
|
<div clas="row">
|
||
|
|
<p>Add public key <a class="modal-trigger right" href="#add-ssh-key-modal"><i class="material-icons">add</i></a></p>
|
||
|
|
</div>
|
||
|
|
</li>
|
||
|
|
<li class="collection-item">
|
||
|
|
<i class="material-icons">password</i>
|
||
|
|
<span class="title"><a class="modal-trigger" href="#change-password-modal">Change Password</a></span>
|
||
|
|
</li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
</li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<script>
|
||
|
|
$(document).ready(function() {
|
||
|
|
$('.modal').modal();
|
||
|
|
});
|
||
|
|
|
||
|
|
function add_ssh_key() {
|
||
|
|
let ssh_key = $("#ssh-pub-key").val();
|
||
|
|
|
||
|
|
console.log(ssh_key);
|
||
|
|
|
||
|
|
$.ajax({
|
||
|
|
url: "{{ url_for('auth.add_ssh_pub_key') }}",
|
||
|
|
type: "POST",
|
||
|
|
dataType: "json",
|
||
|
|
contentType: "application/json",
|
||
|
|
data: JSON.stringify({"pubkey": ssh_key}),
|
||
|
|
success: function(data, status) { window.location.reload(); },
|
||
|
|
complete: function(xhr, textStatus) {
|
||
|
|
if (xhr.status === 400) {
|
||
|
|
let message = xhr.responseJSON.error;
|
||
|
|
if (message === "INVALID_KEY") {
|
||
|
|
message = "Invalid SSH key given (does not conform to openSSH format)."
|
||
|
|
}
|
||
|
|
M.toast({html: '<span>' + message + '</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">×</button>'});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function del_ssh_key(key_to_del) {
|
||
|
|
console.log(key_to_del);
|
||
|
|
$('#btn-confirm-ssh-key-remove').click(function () {
|
||
|
|
$.ajax({
|
||
|
|
url: "{{ url_for('auth.add_ssh_pub_key') }}",
|
||
|
|
type: "DELETE",
|
||
|
|
dataType: "json",
|
||
|
|
contentType: "application/json",
|
||
|
|
data: JSON.stringify({"pubkey": key_to_del}),
|
||
|
|
success: function(data, status) { window.location.reload(); }
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function cancel_edit_phone() {
|
||
|
|
let phone_field = $("#mobile-phone");
|
||
|
|
let phone_save_btn = $("#save-new-phone");
|
||
|
|
let phone_cancel_btn = $("#cancel-new-phone");
|
||
|
|
let phone_edit_icon = $("#phone-edit");
|
||
|
|
// Allow the field to be edited and show save the button
|
||
|
|
phone_field.prop("disabled", true);
|
||
|
|
phone_save_btn.addClass("hiddendiv");
|
||
|
|
phone_cancel_btn.addClass("hiddendiv");
|
||
|
|
phone_edit_icon.removeClass("hiddendiv");
|
||
|
|
phone_field.value("{{ current_user.phone }}");
|
||
|
|
}
|
||
|
|
|
||
|
|
function update_phone() {
|
||
|
|
let phone_field = $("#mobile-phone");
|
||
|
|
let phone_save_btn = $("#save-new-phone");
|
||
|
|
let phone_cancel_btn = $("#cancel-new-phone");
|
||
|
|
let phone_edit_icon = $("#phone-edit");
|
||
|
|
// Allow the field to be edited and show save the button
|
||
|
|
phone_field.prop("disabled", true);
|
||
|
|
phone_save_btn.addClass("hiddendiv");
|
||
|
|
phone_cancel_btn.addClass("hiddendiv");
|
||
|
|
phone_edit_icon.removeClass("hiddendiv");
|
||
|
|
$.ajax({
|
||
|
|
url: "{{ url_for('auth.update_phone') }}",
|
||
|
|
type: "POST",
|
||
|
|
dataType: "json",
|
||
|
|
contentType: "application/json",
|
||
|
|
data: JSON.stringify({"phone_number": phone_field.val()}),
|
||
|
|
success: function(data, status) {
|
||
|
|
M.toast({html: '<span>Phone number updated</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">×</button>'});
|
||
|
|
},
|
||
|
|
complete: function(xhr, textStatus) {
|
||
|
|
if (xhr.status === 400) {
|
||
|
|
let message = xhr.responseJSON.error;
|
||
|
|
M.toast({html: '<span>' + message + '</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">×</button>'});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
function edit_phone() {
|
||
|
|
let phone_field = $("#mobile-phone");
|
||
|
|
let phone_save_btn = $("#save-new-phone");
|
||
|
|
let phone_cancel_btn = $("#cancel-new-phone");
|
||
|
|
let phone_edit_icon = $("#phone-edit");
|
||
|
|
// Allow the field to be edited and show save the button
|
||
|
|
phone_field.prop("disabled", false);
|
||
|
|
phone_save_btn.removeClass("hiddendiv");
|
||
|
|
phone_cancel_btn.removeClass("hiddendiv");
|
||
|
|
phone_edit_icon.addClass("hiddendiv");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
function change_password() {
|
||
|
|
let old_pass = $("#old-password");
|
||
|
|
let new_pass = $("#new-password");
|
||
|
|
let confirm_pass = $("#confirm-password");
|
||
|
|
|
||
|
|
if (new_pass.val() !== confirm_pass.val()) {
|
||
|
|
new_pass.addClass('invalid');
|
||
|
|
new_pass.addClass('active');
|
||
|
|
confirm_pass.addClass('invalid');
|
||
|
|
confirm_pass.addClass('active');
|
||
|
|
M.toast({html: '<span>Passwords do not match</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">×</button>'});
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
$.ajax({
|
||
|
|
url: "{{ url_for('auth.change_passwd') }}",
|
||
|
|
type: "POST",
|
||
|
|
dataType: "json",
|
||
|
|
contentType: "application/json",
|
||
|
|
data: JSON.stringify({"passwd": old_pass.val(), "new_passwd": new_pass.val()}),
|
||
|
|
success: function(data, status) {
|
||
|
|
window.location.reload();
|
||
|
|
},
|
||
|
|
complete: function(xhr, textStatus) {
|
||
|
|
console.log(xhr.status);
|
||
|
|
if (xhr.status === 405) {
|
||
|
|
old_pass.addClass('invalid');
|
||
|
|
old_pass.addClass('invalid');
|
||
|
|
M.toast({html: '<span>Password is incorrect</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">×</button>'});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
{% endblock %}
|