v3.1.0
Added
- KeePass2/KeePassXC native TOTP migration -- entries that store TOTP in the
TimeOtp-*custom fields (rather than theotpfield) now migrate to
Bitwarden'slogin.totp. All four KeePass secret encodings are supported
(TimeOtp-SecretUTF-8,-Hex,-Base32,-Base64), and non-default
TimeOtp-Length/-Period/-Algorithmsettings are emitted as a full
otpauth://URI so Bitwarden generates correct codes instead of silently
defaulting to 6 digits / 30 s / SHA-1. A default-config Base32 secret still
migrates as a bare secret;entry.otpkeeps precedence when both are present.
Logic lives in a new pure, unit-testedkp2bw/otp.pymodule.
Fixed
- Lossy/leaky TOTP fallback -- the initial
TimeOtp-Secret-Base32fallback
dropped non-default OTP configuration (producing wrong 2FA codes), ignored the
other three secret encodings, and stripped the Base32 secret from custom
fields even when it was not the value migrated. Secrets are now removed from
custom fields only when actually folded intologin.totp; any OTP secret left
behind (HOTP, an undecodable value, or one shadowed byentry.otp) is
preserved as a hidden custom field rather than dropped or exposed. - Silent HOTP loss -- counter-based HOTP (
HmacOtp-Secret*) has no
time-based target in Bitwarden. It is now reported with a warning and its
secret kept as a hidden field, instead of silently becoming a visible
plaintext custom field.
What's Changed
- feat: lossless KeePass TOTP/HOTP migration by @kjanat in #15 — thanks @Eryniox for the original implementation in #12 🙏
Full Changelog: v3.0.1...v3.1.0