- Python 97.2%
- Roff 1.6%
- Makefile 0.7%
- Nix 0.5%
gen_otp() required secret, period and digits to all be present in an
otpauth:// URL and returned an empty string otherwise. Bitwarden keeps the
TOTP field as it was entered, so three perfectly normal values produced no
code at all and no error: a bare base32 key (what pasting a key stores), an
otpauth:// URL from a QR code that omits the optional parameters, and a
steam:// URL. {TOTP} typed nothing and "TOTP: ******" in the view menu
yielded an empty selection.
Split the parsing into otp_params() and make everything but the secret
optional, falling back to the RFC 6238 defaults. Handle the two
non-otpauth forms, strip the spacing Bitwarden preserves in a key, and
return an empty string rather than propagating binascii.Error or a
ValueError from an algorithm hashlib doesn't know. The debug log line
carries only the exception, never the field value.
edit_totp() prefilled the secret with query_string["secret"][0], which
raised KeyError on any entry whose TOTP was a bare secret. Route it through
otp_params() so an unreadable value just prefills nothing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|---|---|---|
| .claude | ||
| .github/workflows | ||
| bwm | ||
| docs | ||
| tests | ||
| .gitignore | ||
| bwm.1 | ||
| bwm.1.md | ||
| CLAUDE.md | ||
| config.ini.example | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
Bitwarden-menu
Dmenu/Rofi frontend for managing Bitwarden vaults. Uses the Bitwarden CLI tool to interact with the Bitwarden database.
This project is not associated with the Bitwarden project nor 8bit Solutions LLC.
Installation
pip install --user bitwarden-menu[autotype]
Ensure ~/.local/bin is in your $PATH. Run bwm and enter your database
path, keyfile path, and password.
Drop the [autotype] extra to install without pynput.
NOTE: Initial login to some servers, including vault.bitwarden.com, will
require the client_secret from your account settings page. Ensure this is in
your clipboard and ready to paste prior to first run. Once logged in for the
first time, you will not need this value again.
For full installation documention see the [installation docs][docs/install.md].
Full Documentation
Installation - Configuration - Usage
Requirements
- Python 3.10+
- Bitwarden CLI. Ensure the
bwcommand is in$PATH - Xdg
The rest is only needed for the interactive (launcher) mode:
- Pynput (
pip install bitwarden-menu[autotype]), or one of the alternate type libraries below - Dmenu, Rofi, Wofi or Bemenu
- xsel or wl-copy
- (optional) Pinentry.
- (optional) xdotool, ydotool(>= 1.0.0)/wtype (for Wayland).
Features
- Supports multiple bitwarden.com and self-hosted Vaultwarden accounts. Accounts can be switched on the fly.
- Auto-type username and/or password on selection. Select to clipboard if desired (clipboard clears after 30 sec on X11 or after 1 paste on Wayland).
- Supports login with 2FA code from Authenticator(TOTP), Email, or Yubikey.
- Background process allows selectable time-out for locking the database.
- Use a custom Keepass 2.x style auto-type sequence.
- Type, view or edit any field.
- Open the URL in the default web browser.
- Non U.S. English keyboard languages and layouts supported via xdotool or ydotool/wtype (for Wayland).
- Edit notes using terminal or gui editor.
- Add and Delete entries
- Rename, move, delete and add folders and collections
- Move any item to or from an organization, including support for multiple collections.
- Hide selected folders from the default and 'View/Type Individual entries' views.
- Configure the characters and groups of characters used during password generation.
- Optional Pinentry support for secure passphrase entry.
- Add, edit and type TOTP codes.
- Offline use: an already logged in vault can be unlocked, viewed and typed without a network connection.
- Output any field(s) to stdout with
--show, usable as a CLI-only password manager with no launcher or GUI installed. Works headless, including the initial login and 2FA. - Runs as a background daemon, so a vault is unlocked once rather than on every
lookup.
--foregroundkeeps it attached for troubleshooting.
License
- MIT
Usage
bwm [-h] [-V] [-v VAULT] [-l LOGIN] [-k] [-a AUTOTYPE] [-C] [-c CONFIGPATH] [-s SEARCH] [-f FIELD] [-F]
- Run
bwmor bind to keystroke combination. - Enter account URL on first run.
- Start typing to match entries.
- Configure ~/.config/bwm/config.ini as desired.
- More detailed usage information.
- Screencast (Using Bemenu on Sway):
Tests
Run tests using pytest:
# Using make (creates venv automatically)
make test
# With coverage report
make test-cov
# Or install and run directly
pip install .[test]
pytest
Development
-
To install bitwarden-menu in a venv:
make -
Build man page from Markdown source:
make man -
The version is hardcoded in
bwm/__init__.py(make versionorbwm -V). Anything else needing a version number reads from there. -
Using
hatch:hatch shell: provies venv with editable installation.hatch build&&hatch publish: build and publish to Pypi.
-
Using
nix:nix develop: Provides development shell with all dependencies.make testandhatch build/publishwork as usual.
-
GitHub Action will upload to TestPyPi on each push to
main. To create a GitHub and PyPi release, runmake release VERSION=x.y.z(no leadingv; the tag gets one). It bumps__version__, updates and rebuilds the man page, commits, and opens an editor for the annotated tag, prefilled with the version as the subject and one bullet per commit since the last tag.<tag name on first line, prefilled> * Release note 1 * Release note 2 * ...Then push the commit and tag:
git push origin main --follow-tags. The GitHub Action fails the build if a pushed tag does not match__version__, so nothing mismatched can reach PyPi.
Planned features
- Notifications for syncing status (e.g. when a sync is complete)
