~martijnbraam/public-inbox

numberstation: Update TOTP codes when they are expired v1 APPLIED

~skv: 1
 Update TOTP codes when they are expired

 2 files changed, 25 insertions(+), 14 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~martijnbraam/public-inbox/patches/39319/mbox | git am -3
Learn more about email & git

[PATCH numberstation] Update TOTP codes when they are expired Export this patch

From: Andrey Skvortsov <andrej.skvortzov@gmail.com>

If system is suspended, then after resume TOTP are not updated until
'period' seconds are left in the wakeup state. During this time shown
TOTP codes are wrong, because they are calculated base on the
timestamp before system was suspended.
---
 numberstation/otpurl.py | 15 ++++++++++++++-
 numberstation/window.py | 24 +++++++++++-------------
 2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/numberstation/otpurl.py b/numberstation/otpurl.py
index 628e3f0..701d100 100644
--- a/numberstation/otpurl.py
+++ b/numberstation/otpurl.py
@@ -46,7 +46,9 @@ class OTPUrl:
    def get_token(self):
        if self.type == 'totp':
            totp = pyotp.TOTP(self.secret, interval=self.period, digits=self.digits, digest=self.digest)
            return totp.now(), totp.interval - datetime.now().timestamp() % totp.interval
            base_timestamp = totp.interval * int(datetime.now().timestamp() / totp.interval)
            valid_until = datetime.fromtimestamp(base_timestamp + totp.interval)
            return totp.now(), valid_until
        elif self.type == 'hotp':
            hotp = pyotp.HOTP(self.secret, digits=self.digits, digest=self.digest, initial_count=self.initial_count)
            return hotp.at(0), None
@@ -54,6 +56,17 @@ class OTPUrl:
            sys.stderr.write("Unknown key format '{}'\n".format(self.type))
            return None, None

    def get_validity(self):
        """Returns floating value in the range 0.0-1.0
        described how long generated code will be valid
        relative to update period
        """
        if self.type == 'totp':
            secs_left = self.period - datetime.now().timestamp() % self.period
            return 1.0 * secs_left / self.period
        else:
            return None

    def get_url(self):
        properties = {
            'secret': self.secret,
diff --git a/numberstation/window.py b/numberstation/window.py
index 5dda4c9..eb14310 100644
--- a/numberstation/window.py
+++ b/numberstation/window.py
@@ -1,4 +1,5 @@
from base64 import b32decode
from datetime import datetime
from collections import namedtuple

import keyring
@@ -128,7 +129,7 @@ class NumberstationWindow:
            self.save_keyring()

    def update_code_label(self, label, progressbar, token):
        code, validity = token.get_token()
        code, valid_until = token.get_token()
        if code is None:
            return
        user_code = code
@@ -144,23 +145,20 @@ class NumberstationWindow:
        else:
            label.set_label(user_code)
        label.paste_code = paste_code
        if validity:
            progressbar.validity = int(validity)
        if valid_until:
            progressbar.valid_until = valid_until
        else:
            if progressbar:
                progressbar.validity = None
                progressbar.valid_until = None

    def update_codes(self):
        GLib.timeout_add(1000, self.update_codes)
        for timer in self.timers:
            if timer.validity is None:
            if timer.valid_until is None:
                continue
            timer.validity -= 1
            if timer.validity < 1:
                timer.validity = int(timer.period)
            if timer.valid_until < datetime.now():
                self.update_code_label(timer.display, timer, timer.token)

            timer.set_fraction(1.0 / timer.period * timer.validity)
            timer.set_fraction(timer.token.get_validity())

    def on_long_press(self, gesture, x, y, *args):
        eb = gesture.eb
@@ -249,12 +247,12 @@ class NumberstationWindow:

            timer.token = token
            timer.display = code
            if not hasattr(timer, 'validity'):
            if not hasattr(timer, 'valid_until'):
                continue
            if timer.validity is not None:
            if timer.valid_until is not None:
                timer.show()
                timer.set_no_show_all(False)
                timer.set_fraction(1.0 / token.period * timer.validity)
                timer.set_fraction(token.get_validity())
            else:
                timer.hide()
                timer.set_no_show_all(True)
-- 
2.34.7
Hi Martijn,

do you have any feedback on the patch? Is there anything I could
possibly do to get it merged?