mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 07:18:47 +00:00
Add TOTP viewer window
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import time
|
||||||
|
|
||||||
import toga
|
import toga
|
||||||
from toga.style import Pack
|
from toga.style import Pack
|
||||||
from toga.style.pack import COLUMN, ROW
|
from toga.style.pack import COLUMN, ROW
|
||||||
|
|
||||||
from seedpass.core.manager import PasswordManager
|
|
||||||
from seedpass.core.entry_types import EntryType
|
from seedpass.core.entry_types import EntryType
|
||||||
import time
|
from seedpass.core.manager import PasswordManager
|
||||||
|
from seedpass.core.totp import TotpManager
|
||||||
|
|
||||||
from seedpass.core.api import (
|
from seedpass.core.api import (
|
||||||
VaultService,
|
VaultService,
|
||||||
@@ -95,12 +98,14 @@ class MainWindow(toga.Window):
|
|||||||
edit_button = toga.Button("Edit", on_press=self.edit_entry)
|
edit_button = toga.Button("Edit", on_press=self.edit_entry)
|
||||||
search_button = toga.Button("Search", on_press=self.search_entries)
|
search_button = toga.Button("Search", on_press=self.search_entries)
|
||||||
relay_button = toga.Button("Relays", on_press=self.manage_relays)
|
relay_button = toga.Button("Relays", on_press=self.manage_relays)
|
||||||
|
totp_button = toga.Button("TOTP", on_press=self.show_totp_codes)
|
||||||
|
|
||||||
button_box = toga.Box(style=Pack(direction=ROW, padding_top=5))
|
button_box = toga.Box(style=Pack(direction=ROW, padding_top=5))
|
||||||
button_box.add(add_button)
|
button_box.add(add_button)
|
||||||
button_box.add(edit_button)
|
button_box.add(edit_button)
|
||||||
button_box.add(search_button)
|
button_box.add(search_button)
|
||||||
button_box.add(relay_button)
|
button_box.add(relay_button)
|
||||||
|
button_box.add(totp_button)
|
||||||
|
|
||||||
self.status = toga.Label("Last sync: never", style=Pack(padding_top=5))
|
self.status = toga.Label("Last sync: never", style=Pack(padding_top=5))
|
||||||
|
|
||||||
@@ -148,6 +153,10 @@ class MainWindow(toga.Window):
|
|||||||
dlg = RelayManagerDialog(self, self.nostr)
|
dlg = RelayManagerDialog(self, self.nostr)
|
||||||
dlg.show()
|
dlg.show()
|
||||||
|
|
||||||
|
def show_totp_codes(self, widget: toga.Widget) -> None:
|
||||||
|
win = TotpViewerWindow(self.controller, self.entries)
|
||||||
|
win.show()
|
||||||
|
|
||||||
# --- PubSub callbacks -------------------------------------------------
|
# --- PubSub callbacks -------------------------------------------------
|
||||||
def sync_started(self, *args: object, **kwargs: object) -> None:
|
def sync_started(self, *args: object, **kwargs: object) -> None:
|
||||||
self.status.text = "Syncing..."
|
self.status.text = "Syncing..."
|
||||||
@@ -282,6 +291,47 @@ class SearchDialog(toga.Window):
|
|||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
|
||||||
|
class TotpViewerWindow(toga.Window):
|
||||||
|
"""Window displaying active TOTP codes."""
|
||||||
|
|
||||||
|
def __init__(self, controller: SeedPassApp, entries: EntryService) -> None:
|
||||||
|
super().__init__("TOTP Codes", on_close=self.cleanup)
|
||||||
|
self.controller = controller
|
||||||
|
self.entries = entries
|
||||||
|
|
||||||
|
self.table = toga.Table(
|
||||||
|
headings=["Label", "Code", "Seconds"],
|
||||||
|
style=Pack(flex=1),
|
||||||
|
)
|
||||||
|
|
||||||
|
box = toga.Box(style=Pack(direction=COLUMN, padding=20))
|
||||||
|
box.add(self.table)
|
||||||
|
self.content = box
|
||||||
|
|
||||||
|
self._running = True
|
||||||
|
self.controller.loop.create_task(self._update_loop())
|
||||||
|
self.refresh_codes()
|
||||||
|
|
||||||
|
async def _update_loop(self) -> None:
|
||||||
|
while self._running:
|
||||||
|
self.refresh_codes()
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
def refresh_codes(self) -> None:
|
||||||
|
self.table.data = []
|
||||||
|
for idx, label, *_rest in self.entries.list_entries(
|
||||||
|
filter_kind=EntryType.TOTP.value
|
||||||
|
):
|
||||||
|
entry = self.entries.retrieve_entry(idx)
|
||||||
|
code = self.entries.get_totp_code(idx)
|
||||||
|
period = int(entry.get("period", 30)) if entry else 30
|
||||||
|
remaining = TotpManager.time_remaining(period)
|
||||||
|
self.table.data.append((label, code, remaining))
|
||||||
|
|
||||||
|
def cleanup(self, *args: object, **kwargs: object) -> None:
|
||||||
|
self._running = False
|
||||||
|
|
||||||
|
|
||||||
class RelayManagerDialog(toga.Window):
|
class RelayManagerDialog(toga.Window):
|
||||||
"""Dialog for managing relay URLs."""
|
"""Dialog for managing relay URLs."""
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user