basic-password-manager 0.4.1__tar.gz → 0.4.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/PKG-INFO +23 -8
  2. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/README.md +22 -7
  3. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/basic_password_manager.egg-info/PKG-INFO +23 -8
  4. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/cli.py +9 -1
  5. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/tui.py +27 -9
  6. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pyproject.toml +1 -1
  7. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/LICENSE +0 -0
  8. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/basic_password_manager.egg-info/SOURCES.txt +0 -0
  9. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/basic_password_manager.egg-info/dependency_links.txt +0 -0
  10. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/basic_password_manager.egg-info/entry_points.txt +0 -0
  11. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/basic_password_manager.egg-info/requires.txt +0 -0
  12. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/basic_password_manager.egg-info/top_level.txt +0 -0
  13. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/__init__.py +0 -0
  14. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/crypto.py +0 -0
  15. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/logo.py +0 -0
  16. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/mobile.py +0 -0
  17. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/vault.py +0 -0
  18. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/web/argon2.umd.min.js +0 -0
  19. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/pw_manager/web/page.html +0 -0
  20. {basic_password_manager-0.4.1 → basic_password_manager-0.4.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-password-manager
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: The Paladin — a local encrypted password manager that lives in your terminal
5
5
  License-Expression: MIT
6
6
  Project-URL: Repository, https://github.com/Daisentaur/password-manager
@@ -138,12 +138,25 @@ install. The page opens in whatever TUI theme you had set when you generated
138
138
  the QR, knight and all (it won't follow later theme changes — scan again for
139
139
  that).
140
140
 
141
- Have your own domain? `paladin mobile --url https://vault.you.dev` serves at
142
- your subdomain instead of a random tunnel, so a bookmark keeps working (the
143
- path rotates every 30 days on its own). It serves on `127.0.0.1:8787` by
144
- default — point your reverse proxy or named tunnel there. Set
145
- `PALADIN_MOBILE_URL` (and optionally `PALADIN_MOBILE_PORT`) and plain
146
- `paladin mobile` uses it.
141
+ ### Want it at your own subdomain?
142
+
143
+ By default every session gets a fresh random URL. If you own a domain and
144
+ want the QR to always point at *your* address instead, set one variable:
145
+
146
+ ```bash
147
+ export PALADIN_MOBILE_URL=https://passwords.yourdomain.com # in your ~/.bashrc
148
+ ```
149
+
150
+ and point that subdomain at `127.0.0.1:8787` through whatever you already
151
+ use (reverse proxy, named tunnel — `PALADIN_MOBILE_PORT` changes the port).
152
+ From then on plain `paladin mobile` serves at your subdomain, every time, so
153
+ a phone bookmark keeps working.
154
+
155
+ To be clear about what this does and doesn't change: a session still only
156
+ lives while `paladin mobile` is running — closing it still ends access, and
157
+ the secret path at the end of the URL still expires every 30 days (your
158
+ bookmark needs refreshing then, on purpose). The only difference is that
159
+ every new session opens at *your* address instead of a random one.
147
160
 
148
161
  The one thing crossing the internet is the encrypted blob, which is useless
149
162
  without the master password that never leaves your phone. The tunnel provider
@@ -251,7 +264,9 @@ and restore from a backup.
251
264
  unexpected.
252
265
 
253
266
  **Password prints instead of copying** — no clipboard tool found. Install
254
- one: `sudo apt install wl-clipboard` (Wayland) or `xclip` (X11).
267
+ one: `sudo apt install wl-clipboard` (Wayland) or `xclip` (X11). This is a
268
+ Linux-only situation — macOS (`pbcopy`) and Windows (`clip`) have theirs
269
+ built in and are used automatically.
255
270
 
256
271
  **Unlock feels slow (~1s)** — that's Argon2 doing its job. The delay *is*
257
272
  the brute-force resistance. Per command, not per keystroke.
@@ -122,12 +122,25 @@ install. The page opens in whatever TUI theme you had set when you generated
122
122
  the QR, knight and all (it won't follow later theme changes — scan again for
123
123
  that).
124
124
 
125
- Have your own domain? `paladin mobile --url https://vault.you.dev` serves at
126
- your subdomain instead of a random tunnel, so a bookmark keeps working (the
127
- path rotates every 30 days on its own). It serves on `127.0.0.1:8787` by
128
- default — point your reverse proxy or named tunnel there. Set
129
- `PALADIN_MOBILE_URL` (and optionally `PALADIN_MOBILE_PORT`) and plain
130
- `paladin mobile` uses it.
125
+ ### Want it at your own subdomain?
126
+
127
+ By default every session gets a fresh random URL. If you own a domain and
128
+ want the QR to always point at *your* address instead, set one variable:
129
+
130
+ ```bash
131
+ export PALADIN_MOBILE_URL=https://passwords.yourdomain.com # in your ~/.bashrc
132
+ ```
133
+
134
+ and point that subdomain at `127.0.0.1:8787` through whatever you already
135
+ use (reverse proxy, named tunnel — `PALADIN_MOBILE_PORT` changes the port).
136
+ From then on plain `paladin mobile` serves at your subdomain, every time, so
137
+ a phone bookmark keeps working.
138
+
139
+ To be clear about what this does and doesn't change: a session still only
140
+ lives while `paladin mobile` is running — closing it still ends access, and
141
+ the secret path at the end of the URL still expires every 30 days (your
142
+ bookmark needs refreshing then, on purpose). The only difference is that
143
+ every new session opens at *your* address instead of a random one.
131
144
 
132
145
  The one thing crossing the internet is the encrypted blob, which is useless
133
146
  without the master password that never leaves your phone. The tunnel provider
@@ -235,7 +248,9 @@ and restore from a backup.
235
248
  unexpected.
236
249
 
237
250
  **Password prints instead of copying** — no clipboard tool found. Install
238
- one: `sudo apt install wl-clipboard` (Wayland) or `xclip` (X11).
251
+ one: `sudo apt install wl-clipboard` (Wayland) or `xclip` (X11). This is a
252
+ Linux-only situation — macOS (`pbcopy`) and Windows (`clip`) have theirs
253
+ built in and are used automatically.
239
254
 
240
255
  **Unlock feels slow (~1s)** — that's Argon2 doing its job. The delay *is*
241
256
  the brute-force resistance. Per command, not per keystroke.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-password-manager
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: The Paladin — a local encrypted password manager that lives in your terminal
5
5
  License-Expression: MIT
6
6
  Project-URL: Repository, https://github.com/Daisentaur/password-manager
@@ -138,12 +138,25 @@ install. The page opens in whatever TUI theme you had set when you generated
138
138
  the QR, knight and all (it won't follow later theme changes — scan again for
139
139
  that).
140
140
 
141
- Have your own domain? `paladin mobile --url https://vault.you.dev` serves at
142
- your subdomain instead of a random tunnel, so a bookmark keeps working (the
143
- path rotates every 30 days on its own). It serves on `127.0.0.1:8787` by
144
- default — point your reverse proxy or named tunnel there. Set
145
- `PALADIN_MOBILE_URL` (and optionally `PALADIN_MOBILE_PORT`) and plain
146
- `paladin mobile` uses it.
141
+ ### Want it at your own subdomain?
142
+
143
+ By default every session gets a fresh random URL. If you own a domain and
144
+ want the QR to always point at *your* address instead, set one variable:
145
+
146
+ ```bash
147
+ export PALADIN_MOBILE_URL=https://passwords.yourdomain.com # in your ~/.bashrc
148
+ ```
149
+
150
+ and point that subdomain at `127.0.0.1:8787` through whatever you already
151
+ use (reverse proxy, named tunnel — `PALADIN_MOBILE_PORT` changes the port).
152
+ From then on plain `paladin mobile` serves at your subdomain, every time, so
153
+ a phone bookmark keeps working.
154
+
155
+ To be clear about what this does and doesn't change: a session still only
156
+ lives while `paladin mobile` is running — closing it still ends access, and
157
+ the secret path at the end of the URL still expires every 30 days (your
158
+ bookmark needs refreshing then, on purpose). The only difference is that
159
+ every new session opens at *your* address instead of a random one.
147
160
 
148
161
  The one thing crossing the internet is the encrypted blob, which is useless
149
162
  without the master password that never leaves your phone. The tunnel provider
@@ -251,7 +264,9 @@ and restore from a backup.
251
264
  unexpected.
252
265
 
253
266
  **Password prints instead of copying** — no clipboard tool found. Install
254
- one: `sudo apt install wl-clipboard` (Wayland) or `xclip` (X11).
267
+ one: `sudo apt install wl-clipboard` (Wayland) or `xclip` (X11). This is a
268
+ Linux-only situation — macOS (`pbcopy`) and Windows (`clip`) have theirs
269
+ built in and are used automatically.
255
270
 
256
271
  **Unlock feels slow (~1s)** — that's Argon2 doing its job. The delay *is*
257
272
  the brute-force resistance. Per command, not per keystroke.
@@ -25,7 +25,15 @@ def generate(length: int = 20) -> str:
25
25
 
26
26
  def to_clipboard(text: str) -> bool:
27
27
  # ponytail: no auto-clear timer; clear manually or copy something else over it
28
- for cmd in (["wl-copy"], ["xclip", "-selection", "clipboard"], ["xsel", "-b"]):
28
+ # linux needs a tool installed; macOS (pbcopy) and Windows (clip) ship theirs
29
+ for cmd in (
30
+ ["wl-copy"],
31
+ ["xclip", "-selection", "clipboard"],
32
+ ["xsel", "-b"],
33
+ ["pbcopy"],
34
+ ["clip"],
35
+ ["clip.exe"], # windows tool as seen from inside WSL
36
+ ):
29
37
  if shutil.which(cmd[0]):
30
38
  subprocess.run(cmd, input=text.encode(), check=True)
31
39
  return True
@@ -160,9 +160,10 @@ class ImportModal(ModalScreen):
160
160
  self.dismiss(os.path.expanduser(event.value.strip()))
161
161
 
162
162
 
163
- def _qr_text(url: str, primary: str) -> Text:
163
+ def _qr_text(url: str, primary: str) -> tuple[Text, int]:
164
164
  """The QR as half-block art: theme-colored modules on white, darkened
165
- until cameras can read it (contrast beats style, but we can have both)."""
165
+ until cameras can read it. Returns (text, width_in_cells) — the caller
166
+ must give the widget exactly that width: a wrapped QR is a dead QR."""
166
167
  import qrcode
167
168
 
168
169
  r, g, b = logo._hex_rgb(primary)
@@ -176,12 +177,12 @@ def _qr_text(url: str, primary: str) -> Text:
176
177
  matrix = qr.get_matrix()
177
178
  if len(matrix) % 2:
178
179
  matrix.append([False] * len(matrix[0]))
179
- text = Text()
180
+ text = Text(no_wrap=True)
180
181
  for top, bottom in zip(matrix[::2], matrix[1::2]):
181
182
  for t, btm in zip(top, bottom):
182
183
  text.append("▀", Style(color=dark if t else light, bgcolor=dark if btm else light))
183
184
  text.append("\n")
184
- return text
185
+ return text, len(matrix[0])
185
186
 
186
187
 
187
188
  class MobileModal(ModalScreen):
@@ -199,6 +200,7 @@ class MobileModal(ModalScreen):
199
200
  with Vertical(classes="modal-box", id="mobile-box"):
200
201
  yield Label("open on phone", classes="modal-title")
201
202
  yield Static("creating your secure link…", id="qr")
203
+ yield Static("", id="mobile-url")
202
204
  yield Static("", id="mobile-status")
203
205
  yield Static("esc ends the session", classes="modal-hint")
204
206
 
@@ -217,9 +219,19 @@ class MobileModal(ModalScreen):
217
219
  self.query_one("#qr", Static).update, f"couldn't start: {e}"
218
220
  )
219
221
  return
220
- qr = _qr_text(url, self.app.current_theme.primary)
221
- qr.append(f"\n{url}", Style(color=self.app.current_theme.primary))
222
- self.app.call_from_thread(self.query_one("#qr", Static).update, qr)
222
+ self.app.call_from_thread(self._show_qr, url)
223
+
224
+ def _show_qr(self, url: str) -> None:
225
+ qr, width = _qr_text(url, self.app.current_theme.primary)
226
+ widget = self.query_one("#qr", Static)
227
+ widget.update(qr)
228
+ # pin every width to the QR's real size — auto-layout wrapping a QR
229
+ # scrambles the modules and kills scannability
230
+ widget.styles.width = width
231
+ for wid in ("#mobile-url", "#mobile-status"):
232
+ self.query_one(wid, Static).styles.width = width
233
+ self.query_one("#mobile-box").styles.width = width + 6 # padding + border
234
+ self.query_one("#mobile-url", Static).update(url)
223
235
 
224
236
  def _on_fetch(self) -> None:
225
237
  self.app.call_from_thread(
@@ -369,7 +381,10 @@ class MainScreen(Screen):
369
381
  if to_clipboard(self.app.entries[name]["pw"]):
370
382
  self.notify(f"password for '{name}' copied", severity="information")
371
383
  else:
372
- self.notify("no clipboard tool (install wl-clipboard)", severity="error")
384
+ self.notify(
385
+ "no clipboard tool found (on Linux: install wl-clipboard)",
386
+ severity="error",
387
+ )
373
388
 
374
389
  def action_new(self) -> None:
375
390
  def done(entry: dict | None) -> None:
@@ -514,7 +529,10 @@ class PwApp(App):
514
529
  }
515
530
  #mobile-box {
516
531
  width: auto;
517
- max-width: 90%;
532
+ }
533
+ #mobile-url {
534
+ color: $text-muted;
535
+ margin-top: 1;
518
536
  }
519
537
  .modal-title {
520
538
  color: $primary;
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "basic-password-manager"
7
- version = "0.4.1"
7
+ version = "0.4.3"
8
8
  description = "The Paladin — a local encrypted password manager that lives in your terminal"
9
9
  readme = "README.md"
10
10
  license = "MIT"