Last active 1753037062

hyperreal's Avatar hyperreal revised this gist 1753037062. Go to revision

1 file changed, 99 insertions

proton2bw.py(file created)

@@ -0,0 +1,99 @@
1 + #!/usr/bin/env python3
2 +
3 + import json
4 + import subprocess
5 +
6 + PROTON_DATA_FILE = "/path/to/Proton Pass/data.json"
7 +
8 + bw_get_template_item = subprocess.run(
9 + ["bw", "get", "template", "item"], text=True, capture_output=True
10 + ).stdout
11 +
12 + bw_get_template_item_login = subprocess.run(
13 + ["bw", "get", "template", "item.login"], text=True, capture_output=True
14 + ).stdout
15 +
16 + bw_get_template_item_login_uri = subprocess.run(
17 + ["bw", "get", "template", "item.login.uri"], text=True, capture_output=True
18 + ).stdout
19 +
20 + bw_get_template_item_securenote = subprocess.run(
21 + ["bw", "get", "template", "item.securenote"], text=True, capture_output=True
22 + ).stdout
23 +
24 + json_bw_item = json.loads(bw_get_template_item)
25 + json_bw_item_login = json.loads(bw_get_template_item_login)
26 + json_bw_item_login_uri = json.loads(bw_get_template_item_login_uri)
27 + json_bw_item_securenote = json.loads(bw_get_template_item_securenote)
28 +
29 + with open(PROTON_DATA_FILE, "r") as outfile:
30 + proton_data = json.load(outfile)
31 +
32 + proton_vault = proton_data["vaults"]["<VAULT_ID>"]["items"]
33 +
34 + for item in proton_vault:
35 + if item["data"]["type"] == "login":
36 + json_bw_item["name"] = item["data"]["metadata"]["name"]
37 +
38 + if item["data"]["content"]["urls"]:
39 + json_bw_item_login_uri["uri"] = item["data"]["content"]["urls"][0]
40 + else:
41 + json_bw_item_login_uri["uri"] = None
42 +
43 + json_bw_item_login_uri_list = list()
44 + json_bw_item_login_uri_list.append(json_bw_item_login_uri)
45 +
46 + json_bw_item_login["username"] = item["data"]["content"]["username"]
47 + json_bw_item_login["password"] = item["data"]["content"]["password"]
48 + json_bw_item_login["totp"] = None
49 + json_bw_item_login["uris"] = json_bw_item_login_uri_list
50 + json_bw_item["login"] = json_bw_item_login
51 +
52 + bw_json = subprocess.Popen(
53 + ["echo", json.dumps(json_bw_item)], text=True, stdout=subprocess.PIPE
54 + )
55 +
56 + bw_encode = subprocess.Popen(
57 + ["bw", "encode"], text=True, stdin=bw_json.stdout, stdout=subprocess.PIPE
58 + )
59 +
60 + bw_create = subprocess.Popen(
61 + ["bw", "create", "item"], stdin=bw_encode.stdout, stdout=subprocess.PIPE
62 + )
63 +
64 + bw_json.stdout.close()
65 + bw_encode.stdout.close()
66 + output = bw_create.communicate()[0]
67 + print(output)
68 +
69 + if item["data"]["type"] == "note":
70 + json_bw_item["name"] = item["data"]["metadata"]["name"]
71 + json_bw_item["notes"] = item["data"]["metadata"]["note"]
72 + json_bw_item["type"] = 2
73 + json_bw_item["secureNote"] = json_bw_item_securenote
74 +
75 + bw_json = subprocess.Popen(
76 + ["echo", json.dumps(json_bw_item)], text=True, stdout=subprocess.PIPE
77 + )
78 + bw_encode = subprocess.Popen(
79 + ["bw", "encode"], text=True, stdin=bw_json.stdout, stdout=subprocess.PIPE
80 + )
81 + bw_create = subprocess.Popen(
82 + ["bw", "create", "item"],
83 + text=True,
84 + stdin=bw_encode.stdout,
85 + stdout=subprocess.PIPE,
86 + )
87 +
88 + bw_json.stdout.close()
89 + bw_encode.stdout.close()
90 + output = bw_create.communicate()[0]
91 + print(output)
92 +
93 +
94 + shredder_output = subprocess.run(
95 + ["shred", "-x", "-u", PROTON_DATA_FILE],
96 + text=True,
97 + capture_output=True,
98 + ).stdout
99 + print(shredder_output)
Newer Older