ui: Send locked status to templates.

This commit is contained in:
tecnovert 2022-11-18 23:31:52 +02:00
parent 391f6ffe80
commit 6e5c54b447
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
7 changed files with 129 additions and 38 deletions

View file

@ -246,6 +246,8 @@ class BasicSwap(BaseApp):
self._keep_notifications = self.settings.get('keep_notifications', 50)
self._show_notifications = self.settings.get('show_notifications', 10)
self._notifications_cache = {}
self._is_encrypted = None
self._is_locked = None
# TODO: Adjust ranges
self.min_delay_event = self.settings.get('min_delay_event', 10)
@ -743,7 +745,7 @@ class BasicSwap(BaseApp):
if self.coin_clients[c]['connection_type'] == 'rpc':
yield c
def changeWalletPasswords(self, old_password, new_password):
def changeWalletPasswords(self, old_password, new_password, coin=None):
# Only the main wallet password is changed for monero, avoid issues by preventing until active swaps are complete
if len(self.swaps_in_progress) > 0:
raise ValueError('Can\'t change passwords while swaps are in progress')
@ -751,8 +753,13 @@ class BasicSwap(BaseApp):
if old_password == new_password:
raise ValueError('Passwords must differ')
# Unlock all wallets to ensure they all have the same password.
if len(new_password) < 4:
raise ValueError('New password is too short')
# Unlock wallets to ensure they all have the same password.
for c in self.activeCoins():
if coin and c != coin:
continue
ci = self.ci(c)
try:
ci.unlockWallet(old_password)
@ -760,15 +767,29 @@ class BasicSwap(BaseApp):
raise ValueError('Failed to unlock {}'.format(ci.coin_name()))
for c in self.activeCoins():
if coin and c != coin:
continue
self.ci(c).changeWalletPassword(old_password, new_password)
def unlockWallets(self, password):
for c in self.activeCoins():
self.ci(c).unlockWallet(password)
# Update cached state
if coin is None or coin == Coins.PART:
self._is_encrypted, self._is_locked = self.ci(Coins.PART).isWalletEncryptedLocked()
def lockWallets(self):
def unlockWallets(self, password, coin=None):
for c in self.activeCoins():
if coin and c != coin:
continue
self.ci(c).unlockWallet(password)
if c == Coins.PART:
self._is_locked = False
def lockWallets(self, coin=None):
for c in self.activeCoins():
if coin and c != coin:
continue
self.ci(c).lockWallet()
if c == Coins.PART:
self._is_locked = True
def initialiseWallet(self, coin_type, raise_errors=False):
if coin_type == Coins.PART:
@ -6059,6 +6080,11 @@ class BasicSwap(BaseApp):
return {'Error': 'Not Initialised'}
return self._network.get_info()
def getLockedState(self):
if self._is_encrypted is None or self._is_locked is None:
self._is_encrypted, self._is_locked = self.ci(Coins.PART).isWalletEncryptedLocked()
return self._is_encrypted, self._is_locked
def lookupRates(self, coin_from, coin_to, output_array=False):
self.log.debug('lookupRates {}, {}'.format(coin_from, coin_to))

View file

@ -150,6 +150,10 @@ class HttpHandler(BaseHTTPRequestHandler):
self.server.session_tokens['shutdown'] = shutdown_token
args_dict['shutdown_token'] = shutdown_token
encrypted, locked = swap_client.getLockedState()
args_dict['encrypted'] = encrypted
args_dict['locked'] = locked
if self.server.msg_id_counter >= 0x7FFFFFFF:
self.server.msg_id_counter = 0

View file

@ -1302,6 +1302,12 @@ class BTCInterface(CoinInterface):
return True
return False
def isWalletEncryptedLocked(self):
wallet_info = self.rpc_callback('getwalletinfo')
encrypted = 'unlocked_until' in wallet_info
locked = encrypted and wallet_info['unlocked_until'] <= 0
return encrypted, locked
def changeWalletPassword(self, old_password, new_password):
self._log.info('changeWalletPassword - {}'.format(self.ticker()))
if old_password == '':

View file

@ -454,7 +454,7 @@ def js_setpassword(self, url_split, post_string, is_json):
coin = getCoinType(get_data_entry(post_data, 'coin'))
if coin in (Coins.PART_ANON, Coins.PART_BLIND):
raise ValueError('Invalid coin.')
swap_client.ci(coin).changeWalletPassword(old_password, new_password)
swap_client.changeWalletPasswords(old_password, new_password, coin)
return bytes(json.dumps({'success': True}), 'UTF-8')
# Set password for all coins
@ -472,7 +472,7 @@ def js_unlock(self, url_split, post_string, is_json):
coin = getCoinType(str(get_data_entry(post_data, 'coin')))
if coin in (Coins.PART_ANON, Coins.PART_BLIND):
raise ValueError('Invalid coin.')
swap_client.ci(coin).unlockWallet(password)
swap_client.unlockWallets(password, coin)
return bytes(json.dumps({'success': True}), 'UTF-8')
swap_client.unlockWallets(password)
@ -487,7 +487,7 @@ def js_lock(self, url_split, post_string, is_json):
coin = getCoinType(get_data_entry(post_data, 'coin'))
if coin in (Coins.PART_ANON, Coins.PART_BLIND):
raise ValueError('Invalid coin.')
swap_client.ci(coin).lockWallet()
swap_client.lockWallets(coin)
return bytes(json.dumps({'success': True}), 'UTF-8')
swap_client.lockWallets()

View file

@ -23,7 +23,7 @@
<svg width="6" height="15" viewBox="0 0 6 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.34 0.671999L2.076 14.1H0.732L3.984 0.671999H5.34Z" fill="#BBC3CF"></path>
</svg>
</li>
</li>
<li>
<a class="flex font-medium text-xs text-coolGray-500 hover:text-coolGray-700" href="/changepassword">Change Password</a>
</li>
@ -70,19 +70,55 @@
<tr class="bg-white border-t hover:bg-gray-50">
<td class="py-4 pl-5 pr-5 bold">Old Password</td>
<td td class="py-4 pr-5 w-2/3">
<input class="w-full aappearance-none bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 w-full block p-2.5" type="text" name="oldpassword">
<div class="relative w-full">
<div class="absolute inset-y-0 right-0 flex items-center px-2">
<input class="hidden js-password-toggle" id="toggle-old" type="checkbox" />
<label class="px-2 py-1 text-sm text-gray-600 font-mono cursor-pointer js-password-label" for="toggle-old" id="input-old-label">
<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24">
<g fill="#8896ab">
<path d="M23.444,10.239C21.905,8.062,17.708,3,12,3S2.1,8.062.555,10.24a3.058,3.058,0,0,0,0,3.52h0C2.1,15.938,6.292,21,12,21s9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z" fill="#8896ab"></path>
</g>
</svg>
</label>
</div>
<input class="w-full aappearance-none bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 w-full block p-2.5" type="password" name="oldpassword" id="input-old">
</div>
</td>
</tr>
<tr class="bg-white border-t hover:bg-gray-50">
<td class="py-4 pl-5 pr-5 bold">New Password</td>
<td td class="py-4 pr-5 w-2/3">
<input class="w-full aappearance-none bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 w-full block p-2.5" type="text" name="newpassword">
<div class="relative w-full">
<div class="absolute inset-y-0 right-0 flex items-center px-2">
<input class="hidden js-password-toggle" id="toggle-new" type="checkbox" />
<label class="px-2 py-1 text-sm text-gray-600 font-mono cursor-pointer js-password-label" for="toggle-new" id="input-new-label">
<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24">
<g fill="#8896ab">
<path d="M23.444,10.239C21.905,8.062,17.708,3,12,3S2.1,8.062.555,10.24a3.058,3.058,0,0,0,0,3.52h0C2.1,15.938,6.292,21,12,21s9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z" fill="#8896ab"></path>
</g>
</svg>
</label>
</div>
<input class="w-full aappearance-none bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 w-full block p-2.5" type="password" name="newpassword" id="input-new">
</div>
</td>
</tr>
<tr class="bg-white border-t hover:bg-gray-50">
<td class="py-4 pl-5 pr-5 bold">Confirm Password</td>
<td td class="py-4 pr-5 w-2/3">
<input class="w-full aappearance-none bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 w-full block p-2.5" type="text" name="confirmpassword">
<div class="relative w-full">
<div class="absolute inset-y-0 right-0 flex items-center px-2">
<input class="hidden js-password-toggle" id="toggle-conf" type="checkbox" />
<label class="px-2 py-1 text-sm text-gray-600 font-mono cursor-pointer js-password-label" for="toggle-conf" id="input-confirm-label">
<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24">
<g fill="#8896ab">
<path d="M23.444,10.239C21.905,8.062,17.708,3,12,3S2.1,8.062.555,10.24a3.058,3.058,0,0,0,0,3.52h0C2.1,15.938,6.292,21,12,21s9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z" fill="#8896ab"></path>
</g>
</svg>
</label>
</div>
<input class="w-full aappearance-none bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 w-full block p-2.5" type="password" name="confirmpassword" id="input-confirm">
</div>
</td>
</tr>
</table>
@ -111,5 +147,32 @@
</div>
</section>
{% include 'footer.html' %}
<script>
function togglePassword(event) {
let input_name = 'input-new';
if (event.target.id == 'toggle-old') {
input_name = 'input-old';
} else
if (event.target.id == 'toggle-conf') {
input_name = 'input-confirm';
}
const password = document.getElementById(input_name),
passwordLabel = document.getElementById(input_name + '-label');
if (password.type === 'password') {
password.type = 'text';
passwordLabel.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24"><g fill="#8896ab"><path d="M23.444,10.239a22.936,22.936,0,0,0-2.492-2.948l-4.021,4.021A5.026,5.026,0,0,1,17,12a5,5,0,0,1-5,5,5.026,5.026,0,0,1-.688-.069L8.055,20.188A10.286,10.286,0,0,0,12,21c5.708,0,9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239Z" fill="#8896ab"></path><path d="M12,3C6.292,3,2.1,8.062.555,10.24a3.058,3.058,0,0,0,0,3.52h0a21.272,21.272,0,0,0,4.784,4.9l3.124-3.124a5,5,0,0,1,7.071-7.072L8.464,15.536l10.2-10.2A11.484,11.484,0,0,0,12,3Z" fill="#8896ab"></path><path data-color="color-2" d="M1,24a1,1,0,0,1-.707-1.707l22-22a1,1,0,0,1,1.414,1.414l-22,22A1,1,0,0,1,1,24Z"></path></g></svg>';
} else {
password.type = 'password';
passwordLabel.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 24 24"><g fill="#8896ab" ><path d="M23.444,10.239C21.905,8.062,17.708,3,12,3S2.1,8.062.555,10.24a3.058,3.058,0,0,0,0,3.52h0C2.1,15.938,6.292,21,12,21s9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z" fill="#8896ab"></path></g></svg>';
}
password.focus();
}
const toggles = ["toggle-old", "toggle-new", "toggle-conf"]
toggles.forEach(function (toggle_id, index) {
document.getElementById(toggle_id).addEventListener('change', togglePassword, false);
});
</script>
</body>
</html>
</html>

View file

@ -290,11 +290,10 @@
</ul>
<!-- dev mode icons on/off -->
{% endif %}
{% if debug_mode == true %}
<!-- if wallets locked -->
<!-- <ul class="xl:flex hidden">
<li>
{% if encrypted == true %}
<ul class="xl:flex"><li>
{% if locked == true %}
<div data-tooltip-target="tooltip-locked-wallets" class="ml-5 flex items-center text-gray-50 hover:text-gray-100 text-sm">
<svg class="text-gray-500 w-5 h-5 mr-3" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><g stroke-linecap="round" stroke-width="2" fill="none" stroke="#2ad167" stroke-linejoin="round"><rect x="3" y="11" width="18" height="12" rx="2"></rect><circle cx="12" cy="17" r="2" stroke="#2ad167"></circle><path d="M17,7V6a4.951,4.951,0,0,0-4.9-5H12A4.951,4.951,0,0,0,7,5.9V7" stroke="#2ad167"></path></g></svg>
<span data-tooltip-target="tooltip-locked-wallets" ></span> </div>
@ -302,19 +301,18 @@
<div id="tooltip-locked-wallets" role="tooltip" class="inline-block absolute invisible z-10 py-2 px-3 text-sm font-medium text-white bg-blue-500 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip">
<p>Wallets locked </p>
<p> </p> </div>
</li>
</ul>
<ul class="xl:flex hidden">
<li>
{% else %}
<a href='/lock'>
<div data-tooltip-target="tooltip-unlocked-wallets" class="ml-5 flex items-center text-gray-50 hover:text-gray-100 text-sm">
<svg class="text-gray-500 w-5 h-5 mr-3" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><g stroke-linecap="round" stroke-width="2" fill="none" stroke="#f80b0b" stroke-linejoin="round"><rect x="3" y="11" width="18" height="12"></rect><circle cx="12" cy="17" r="2" stroke="#f80b0b"></circle><path data-cap="butt" d="M17,6a4.951,4.951,0,0,0-4.9-5H12A4.951,4.951,0,0,0,7,5.9V11"></path></g></svg>
<svg class="text-gray-500 w-5 h-5 mr-3" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><g stroke-linecap="round" stroke-width="2" fill="none" stroke="#f80b0b" stroke-linejoin="round"><rect x="3" y="11" width="18" height="12"></rect><circle cx="12" cy="17" r="2" stroke="#f80b0b"></circle><path data-cap="butt" d="M17,6a4.951,4.951,0,0,0-4.9-5H12A4.951,4.951,0,0,0,7,5.9V11"></path></g></svg>
<span data-tooltip-target="tooltip-unlocked-wallets" ></span> </div>
<div class="tooltip-arrow" data-popper-arrow></div>
<div id="tooltip-unlocked-wallets" role="tooltip" class="inline-block absolute invisible z-10 py-2 px-3 text-sm font-medium text-white bg-blue-500 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip">
<p>Wallets unlocked </p>
<p> </p> </div>
</li>
</ul> -->
</a>
{% endif %}
</li></ul>
{% endif %}
{% if use_tor_proxy == true %}
<!-- tor -->
@ -650,7 +648,7 @@
</nav>
</div>
<!-- mobile sidebar -->
</section>
</section>
{% if ws_url %}
<script>
var ws = new WebSocket("{{ ws_url }}"),
@ -687,4 +685,4 @@
element.parentNode.parentNode.removeChild(element.parentNode);
}
</script>
{% endif %}
{% endif %}

View file

@ -76,13 +76,7 @@ def page_lock(self, url_split, post_string):
swap_client.checkSystemStatus()
swap_client.lockWallets()
messages = []
err_messages = []
template = server.env.get_template('info.html')
return self.render_template(template, {
'messages': messages,
'err_messages': err_messages,
'message_str': 'Wallets locked'
})
self.send_response(302)
self.send_header('Location', '/')
self.end_headers()
return bytes()