From e43793aec930322d3d94a086497a85f5b4c2d89a Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Fri, 3 Dec 2021 10:04:29 +0000 Subject: [PATCH] add a export tool helper --- tools/export.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tools/export.py diff --git a/tools/export.py b/tools/export.py new file mode 100644 index 0000000..1733da4 --- /dev/null +++ b/tools/export.py @@ -0,0 +1,74 @@ +""" +Simple script to retrieve your accounts in case your system is broken: + +Update the db_path variable to point to the database and +the output one to where you want the file to be saved + +the resulted file can be re-imported by any application accepting FreeOTP like backups +which are a otp URI per line +""" + +import sqlite3 +from gi import require_version + +require_version("Secret", "1") +from gi.repository import Secret + + +db_path = "/home/bilelmoussaoui/.var/app/com.belmoussaoui.Authenticator/data/authenticator/authenticator.db" +output = "/home/bilelmoussaoui/output.text" + + +db = sqlite3.connect(db_path) + +accounts = db.execute( + """ + SELECT * FROM accounts + INNER JOIN providers ON accounts.provider_id = providers.id + """ +).fetchall() + +service = Secret.Service.get_sync(Secret.ServiceFlags.NONE, None) +service.load_collections_sync(None) +collections = service.get_collections() +service.unlock_sync(collections, None) + +default_collection = list(filter(lambda x: x.get_label() == "Login", collections))[0] + + +def get_token(token_id): + + item = default_collection.search_sync( + None, + { + "type": "token", + "application": "com.belmoussaoui.Authenticator", + "token_id": token_id, + }, + Secret.SearchFlags.NONE, + None, + )[0] + item.load_secret_sync(None) + + return item.get_secret().get_text() + + +accounts_otp_uri = [] + +for account in accounts: + token_id = account[3] + token = get_token(token_id) + method = account[-1] + + uri = f"otpauth://{method}/{account[1]}?secret={token}&issuer={account[6]}&algorithm={account[-2]}&digits={account[-5]}" + + if method == "totp": + uri += f"&period={account[-4]}" + else: + uri += f"&counter={account[-3]}" + uri += "\n" + + accounts_otp_uri.append(uri) + +with open(output, "w") as f: + f.writelines(accounts_otp_uri)