mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-09 06:46:10 +01:00
feature: Provide Text Authenticator Key during 2FA in addition to QR code
This commit is contained in:
@@ -154,6 +154,32 @@ app.controller('modifyUser', function ($scope, $http) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.copySecretKey = function() {
|
||||||
|
if ($scope.secretKey) {
|
||||||
|
// Create a temporary textarea element
|
||||||
|
var tempTextarea = document.createElement('textarea');
|
||||||
|
tempTextarea.value = $scope.secretKey;
|
||||||
|
tempTextarea.style.position = 'fixed';
|
||||||
|
tempTextarea.style.opacity = '0';
|
||||||
|
document.body.appendChild(tempTextarea);
|
||||||
|
|
||||||
|
// Select and copy the text
|
||||||
|
tempTextarea.select();
|
||||||
|
tempTextarea.setSelectionRange(0, 99999); // For mobile devices
|
||||||
|
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
// Show success feedback (you can add a toast notification here if available)
|
||||||
|
alert('Secret key copied to clipboard!');
|
||||||
|
} catch (err) {
|
||||||
|
alert('Failed to copy secret key. Please copy it manually.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the temporary element
|
||||||
|
document.body.removeChild(tempTextarea);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
$scope.fetchUserDetails = function () {
|
$scope.fetchUserDetails = function () {
|
||||||
|
|
||||||
@@ -192,6 +218,12 @@ app.controller('modifyUser', function ($scope, $http) {
|
|||||||
$scope.currentSecurityLevel = userDetails.securityLevel;
|
$scope.currentSecurityLevel = userDetails.securityLevel;
|
||||||
$scope.twofa = Boolean(userDetails.twofa);
|
$scope.twofa = Boolean(userDetails.twofa);
|
||||||
|
|
||||||
|
// Format secret key with spaces for better readability
|
||||||
|
if (userDetails.secretKey) {
|
||||||
|
$scope.secretKey = userDetails.secretKey;
|
||||||
|
$scope.formattedSecretKey = userDetails.secretKey.match(/.{1,4}/g).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
qrCode.set({
|
qrCode.set({
|
||||||
value: userDetails.otpauth
|
value: userDetails.otpauth
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -286,6 +286,18 @@
|
|||||||
<div style="max-width:220px;">
|
<div style="max-width:220px;">
|
||||||
<canvas id="qr"></canvas>
|
<canvas id="qr"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-3">
|
||||||
|
<p class="help-text mb-2">{% trans "Or manually enter this key:" %}</p>
|
||||||
|
<div class="input-group" style="max-width:350px;">
|
||||||
|
<input type="text" class="form-control" ng-model="formattedSecretKey" readonly style="font-family: monospace; font-size: 14px;">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-outline-secondary" type="button" ng-click="copySecretKey()" title="{% trans 'Copy to clipboard' %}">
|
||||||
|
<i class="fa fa-copy"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted mt-1 d-block">{% trans "Enter this key in your authenticator app if you cannot scan QR codes." %}</small>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" style="margin-top: 2rem;">
|
<div class="form-group" style="margin-top: 2rem;">
|
||||||
|
|||||||
@@ -310,7 +310,8 @@ def fetchUserDetails(request):
|
|||||||
"websitesLimit": websitesLimit,
|
"websitesLimit": websitesLimit,
|
||||||
"securityLevel": SecurityLevel(user.securityLevel).name,
|
"securityLevel": SecurityLevel(user.securityLevel).name,
|
||||||
"otpauth": otpauth,
|
"otpauth": otpauth,
|
||||||
'twofa': user.twoFA
|
'twofa': user.twoFA,
|
||||||
|
'secretKey': user.secretKey
|
||||||
}
|
}
|
||||||
|
|
||||||
data_ret = {'fetchStatus': 1, 'error_message': 'None', "userDetails": userDetails}
|
data_ret = {'fetchStatus': 1, 'error_message': 'None', "userDetails": userDetails}
|
||||||
|
|||||||
Reference in New Issue
Block a user