mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-08 22:36:12 +01:00
feature: Provide Text Authenticator Key during 2FA in addition to QR code
This commit is contained in:
@@ -153,6 +153,32 @@ app.controller('modifyUser', function ($scope, $http) {
|
||||
$scope.qrHidden = true;
|
||||
}
|
||||
};
|
||||
|
||||
$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 () {
|
||||
@@ -191,6 +217,12 @@ app.controller('modifyUser', function ($scope, $http) {
|
||||
$scope.securityLevel = userDetails.securityLevel;
|
||||
$scope.currentSecurityLevel = userDetails.securityLevel;
|
||||
$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({
|
||||
value: userDetails.otpauth
|
||||
|
||||
@@ -286,6 +286,18 @@
|
||||
<div style="max-width:220px;">
|
||||
<canvas id="qr"></canvas>
|
||||
</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 class="form-group" style="margin-top: 2rem;">
|
||||
|
||||
@@ -310,7 +310,8 @@ def fetchUserDetails(request):
|
||||
"websitesLimit": websitesLimit,
|
||||
"securityLevel": SecurityLevel(user.securityLevel).name,
|
||||
"otpauth": otpauth,
|
||||
'twofa': user.twoFA
|
||||
'twofa': user.twoFA,
|
||||
'secretKey': user.secretKey
|
||||
}
|
||||
|
||||
data_ret = {'fetchStatus': 1, 'error_message': 'None', "userDetails": userDetails}
|
||||
|
||||
Reference in New Issue
Block a user