|
|
|
|
@@ -12,6 +12,21 @@ from subprocess import run, DEVNULL
|
|
|
|
|
|
|
|
|
|
home = environ.get('HOME')
|
|
|
|
|
|
|
|
|
|
def parse_totp(totp: str) -> None|str:
|
|
|
|
|
try:
|
|
|
|
|
# Attempt to parse the TOTP URI
|
|
|
|
|
totp = pyotp.parse_uri(totp).now()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
try:
|
|
|
|
|
# Attempt to create a TOTP object using the TOTP function
|
|
|
|
|
totp = pyotp.TOTP(totp).now()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
# Return False if both attempts fail
|
|
|
|
|
totp = None
|
|
|
|
|
return totp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_lock() -> bool:
|
|
|
|
|
check = run(['bw', 'unlock', '--check'], stdout=DEVNULL, stderr=DEVNULL)
|
|
|
|
|
|
|
|
|
|
@@ -37,15 +52,19 @@ def get_password(search_string: Annotated[str, typer.Argument(help="The term to
|
|
|
|
|
|
|
|
|
|
items = json.loads(list_items_cmd.stdout)
|
|
|
|
|
|
|
|
|
|
search_string_lower = search_string.lower()
|
|
|
|
|
# Filtering the list based on the search string
|
|
|
|
|
filtered_list = [
|
|
|
|
|
d for d in items if any(
|
|
|
|
|
search_string in str(value) for key, value in d.items()
|
|
|
|
|
d for d in items
|
|
|
|
|
if d.get('type') == 1 and ( # Only passwords
|
|
|
|
|
any(
|
|
|
|
|
search_string_lower in str(value).lower() for key, value in d.items()
|
|
|
|
|
if key != 'login' # Exclude the 'login' key entirely
|
|
|
|
|
) or (
|
|
|
|
|
'login' in d and (
|
|
|
|
|
search_string in str(d['login'].get('username', '')) or
|
|
|
|
|
search_string in str(d['login'].get('password', ''))
|
|
|
|
|
search_string_lower in str(d['login'].get('username', '')).lower() or
|
|
|
|
|
search_string_lower in str(d['login'].get('password', '')).lower()
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
]
|
|
|
|
|
@@ -54,7 +73,12 @@ def get_password(search_string: Annotated[str, typer.Argument(help="The term to
|
|
|
|
|
|
|
|
|
|
if len(filtered_list) > 1:
|
|
|
|
|
for item_index, item in enumerate(filtered_list):
|
|
|
|
|
choices.append(questionary.Choice(f"{item['name']} ({item['login']['username']})", item_index))
|
|
|
|
|
if item.get('login') and item['login'].get('username'):
|
|
|
|
|
username = f" ({item['login']['username']})"
|
|
|
|
|
else:
|
|
|
|
|
username = ""
|
|
|
|
|
|
|
|
|
|
choices.append(questionary.Choice(f"{item['name']}{username}", item_index))
|
|
|
|
|
|
|
|
|
|
chosen_index = questionary.select("Select item", choices, use_shortcuts=True).ask()
|
|
|
|
|
elif len(filtered_list) == 1:
|
|
|
|
|
@@ -73,9 +97,9 @@ def get_password(search_string: Annotated[str, typer.Argument(help="The term to
|
|
|
|
|
|
|
|
|
|
print(f"username\t: {filtered_list[chosen_index]['login']['username']}")
|
|
|
|
|
print(f"password\t: \033[34m\033[44m{filtered_list[chosen_index]['login']['password']}\033[0m")
|
|
|
|
|
if filtered_list[chosen_index]['login']['totp']:
|
|
|
|
|
totp = pyotp.parse_uri(filtered_list[chosen_index]['login']['totp'])
|
|
|
|
|
print(f"TOTP\t\t: {totp.now()}")
|
|
|
|
|
if filtered_list[chosen_index]['login']['totp'] and parse_totp(filtered_list[chosen_index]['login']['totp']):
|
|
|
|
|
totp = parse_totp(filtered_list[chosen_index]['login']['totp'])
|
|
|
|
|
print(f"TOTP\t\t: {totp}")
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
import pyperclip
|
|
|
|
|
|