mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2025-01-18 17:15:13 +01:00
UI updates
This commit is contained in:
parent
09342c9743
commit
65c9ad9caf
@ -7899,7 +7899,7 @@ a.badge-dark.focus {
|
||||
display: block;
|
||||
padding: 0.75rem 1.25rem;
|
||||
margin-bottom: -1px;
|
||||
background-color: var(--select-bg);
|
||||
background-color: var(--outline);
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
|
||||
|
30
app/frontend/static/assets/css/mfa.css
Normal file
30
app/frontend/static/assets/css/mfa.css
Normal file
@ -0,0 +1,30 @@
|
||||
.bootbox-custom-layout {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.bootbox-custom-layout .left-panel {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bootbox-custom-layout .right-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.bootbox-custom-layout .qr-code {
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
/* Adjust as needed */
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.bootbox-custom-layout .list-group {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.bootbox .modal-dialog {
|
||||
max-width: 900px;
|
||||
/* Wider modal */
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
{% block title %}Crafty Controller - {{ translate('userConfig', 'editTOTP', data['lang']) }}{% end %}
|
||||
|
||||
{% block content %}
|
||||
<link href="/static/assets/css/mfa.css" rel="stylesheet">
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Page Title Header Starts-->
|
||||
@ -54,7 +55,9 @@
|
||||
<h4 class="card-title"><i class="fas fa-key"></i> {{ translate('otp',
|
||||
'otpTitle',
|
||||
data['lang']) }}</h4>
|
||||
<div><button class="btn btn-primary" id="createButton"><i
|
||||
<div><button class="btn btn-primary" id="createButton" data-backup-codes="{{
|
||||
translate('otp', 'backupCodes', data['lang']) }}" data-backup-codes-max="{{
|
||||
translate('otp', 'backupCodesMax', data['lang']) }}"><i
|
||||
class="fas fa-plus-circle"></i>
|
||||
{{
|
||||
translate('otp', 'newOTP', data['lang']) }}</button></div>
|
||||
@ -129,17 +132,37 @@
|
||||
|
||||
// Function to create the modal response content
|
||||
function createResponseDiv(data) {
|
||||
let backupcodes = ``;
|
||||
let backupcodes = `<ul class="list-group">`;
|
||||
data["backup_codes"].forEach(element => {
|
||||
backupcodes += `<li>${element}</li>`;
|
||||
backupcodes += `<li class="list-group-item">${element}</li>`;
|
||||
});
|
||||
backupcodes += `</ul>`
|
||||
if (data["backup_codes"].length == 0) {
|
||||
backupcodes = `<div style="text-align: center; color: grey;">
|
||||
${$("#createButton").data("backup-codes-max")}
|
||||
</div>`
|
||||
}
|
||||
|
||||
const contentHTML = `
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div id="qrcode"></div>
|
||||
<span id="secret">${data["otp"]["totp_secret"]}</span>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<ul id="backupcodes">${backupcodes}</ul>
|
||||
<div class="bootbox-custom-layout row">
|
||||
<div class="left-panel col-md-6 col-12 d-flex flex-column align-items-center justify-content-center">
|
||||
<div id="qrcode" class="mb-3"></div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item" id="secret">${data["otp"]["totp_secret"]}</li>
|
||||
<ul>
|
||||
|
||||
<!-- Input and Verify button inline -->
|
||||
<div class="d-flex align-items-center mt-3">
|
||||
<input type="text" class="form-control me-2" placeholder="Enter code">
|
||||
<button class="btn btn-primary">Verify</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-panel col-md-6 col-12">
|
||||
<h4>${$("#createButton").data("backup-codes")}</h4>
|
||||
<ul class="list-group">
|
||||
${backupcodes}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
let responseDIV = document.createElement("div");
|
||||
@ -173,17 +196,20 @@
|
||||
let resdiv = createResponseDiv(responseData.data);
|
||||
bootbox.dialog({
|
||||
title: 'Your TOTP QR Code',
|
||||
size: "large",
|
||||
closeButton: false,
|
||||
message: resdiv, // Display the generated QR code
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'Close',
|
||||
className: 'btn-secondary',
|
||||
className: 'bb-close-button',
|
||||
callback: function () {
|
||||
// Optional: Any cleanup logic
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
$(`.bb-close-button`).prop("disabled", true);
|
||||
|
||||
// Generate the QR Code with the TOTP secret, user name, and issuer
|
||||
generateTotpQrCode(responseData.data["otp"]["totp_secret"], responseData.data["otp"]["user"]["username"], "CraftyController");
|
||||
|
@ -112,7 +112,7 @@
|
||||
</div>
|
||||
<select required class="form-control form-control-lg select-css" id="2fa-type" name="type">
|
||||
<option value="totp">{{ translate('login', 'totpSelect', data['lang']) }}</option>
|
||||
<option value="backupCode">{{ translate('login', 'backupCodeTitle', data['lang']) }}</option>
|
||||
<option value="backup_code">{{ translate('login', 'backupCodeTitle', data['lang']) }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -206,10 +206,11 @@
|
||||
"password": formDataObject.password,
|
||||
}
|
||||
if (formDataObject.totp != "") {
|
||||
let key = $("#2fa-type").val();
|
||||
body = {
|
||||
"username": formDataObject.username,
|
||||
"password": formDataObject.password,
|
||||
"totp": formDataObject.totp,
|
||||
[key]: formDataObject.totp,
|
||||
}
|
||||
}
|
||||
let res = await fetch(`/api/v2/auth/login/`, {
|
||||
|
@ -263,6 +263,8 @@
|
||||
"no": "No",
|
||||
"2faCreate": "Add New 2FA Method",
|
||||
"backupCodes": "New 2FA method created. Please copy your backup codes.",
|
||||
"backupCodesMax": "A maximum of 6 back codes has already been reached.",
|
||||
"saveWarn": "Make sure to save these backup codes or you could lose access",
|
||||
"confirm2FA": "Please Confirm Authenticator Code",
|
||||
"otpTitle": "2FA Methods",
|
||||
"newOTP": "Add New 2 Factor Auth"
|
||||
@ -698,6 +700,7 @@
|
||||
"otpReq": "TOTP is required for super users. You cannot remove your only TOTP method."
|
||||
},
|
||||
"validators": {
|
||||
"2FAerror": "2 Factor code must be 6 digits (i.e. 000000) or a backup code of 16 characters separated every 4 by - (i.e. ABCD-EFGH-IJKL-MNOP)",
|
||||
"backupName": "Backup name must be a string and a minimum length of 3.",
|
||||
"enumErr": "failed validating. Acceptable data includes: ",
|
||||
"filesPageLen": "length must be greater than 1 for property",
|
||||
|
Loading…
x
Reference in New Issue
Block a user