From 5befe1ed3a51281eab34b9b32d5695251f91bb4e Mon Sep 17 00:00:00 2001 From: Danilo Reyes Date: Thu, 8 May 2025 20:13:54 -0600 Subject: [PATCH] u2f check + new path for clean_watch --- flake.lock | 27 ------------ src/scripts/clean-watch.sh | 4 +- src/scripts/u2f_check.py | 85 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 29 deletions(-) delete mode 100644 flake.lock create mode 100644 src/scripts/u2f_check.py diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 516826d..0000000 --- a/flake.lock +++ /dev/null @@ -1,27 +0,0 @@ -{ - "nodes": { - "nixpkgs": { - "locked": { - "lastModified": 1746183838, - "narHash": "sha256-kwaaguGkAqTZ1oK0yXeQ3ayYjs8u/W7eEfrFpFfIDFA=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "bf3287dac860542719fe7554e21e686108716879", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-24.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/src/scripts/clean-watch.sh b/src/scripts/clean-watch.sh index 1388880..322aaf6 100644 --- a/src/scripts/clean-watch.sh +++ b/src/scripts/clean-watch.sh @@ -2,8 +2,8 @@ #! nix-shell -i bash -p bash gnome.zenity firefox # Path to the list file -LIST_PATH="/srv/miniserver/jawz/.config/jawz/lists/jawz/watch.txt" -KEPT_LINKS_PATH="/srv/miniserver/jawz/.config/jawz/lists/jawz/kept_links.txt" +LIST_PATH="/srv/server/jawz/.config/jawz/lists/jawz/watch.txt" +KEPT_LINKS_PATH="/srv/server/jawz/.config/jawz/lists/jawz/kept_links.txt" # Check if the list file exists if [[ ! -f $LIST_PATH ]]; then diff --git a/src/scripts/u2f_check.py b/src/scripts/u2f_check.py new file mode 100644 index 0000000..20ed5b4 --- /dev/null +++ b/src/scripts/u2f_check.py @@ -0,0 +1,85 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i python3 -p python3 python3Packages.tldextract python3Packages.requests +import csv +import sys +import requests +import tldextract +from typing import Set + + +def extract_root_domain(url_or_host: str) -> str | None: + if not url_or_host: + return None + + parts = [p.strip() for p in url_or_host.split(",")] + web_part = next((p for p in parts if p.startswith("http")), parts[0]) + + ext = tldextract.extract(web_part) + if ext.domain and ext.suffix: + return f"{ext.domain}.{ext.suffix}".lower().strip() + return None + + +def load_fido2_supported() -> Set[str]: + resp = requests.get("https://api.2fa.directory/v4/u2f.json") + resp.raise_for_status() + + raw_supported = resp.json() + root_domains = { + extract_root_domain(domain) + for domain in raw_supported.keys() + if extract_root_domain(domain) is not None + } + return root_domains + + +def process_csv( + csv_filename: str, fido2_supported: Set[str] +) -> tuple[list[str], list[str]]: + supported = [] + unsupported = [] + + with open(csv_filename, newline="") as f: + reader = csv.DictReader(f) + for row in reader: + name = row.get("name", "").strip() + url = row.get("login_uri", "").strip() + domain = extract_root_domain(url) + + if not domain: + print(f"[DEBUG] domain=None for entry {name!r} (uri={url!r})") + unsupported.append(name) + continue + + if domain in fido2_supported: + supported.append(name) + else: + unsupported.append(name) + + return supported, unsupported + + +def export_to_org( + supported: list[str], unsupported: list[str], output_filename: str +) -> None: + with open(output_filename, "w") as f: + f.write("* FIDO2 Setup Tracker\n") + f.write("** ✅ Supported Accounts\n") + for entry in sorted(set(supported)): + f.write(f"- [ ] {entry}\n") + f.write("\n** ❌ Unsupported / To Double-Check\n") + for entry in sorted(set(unsupported)): + f.write(f"- [ ] {entry}\n") + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python check_fido2_compat.py ") + sys.exit(1) + + csv_file = sys.argv[1] + supported_sites = load_fido2_supported() + supported, unsupported = process_csv(csv_file, supported_sites) + export_to_org(supported, unsupported, "fido2_tracker.org") + + print("Done! Output written to fido2_tracker.org")