mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-09-12 21:57:19 -04:00
Account.ToString() returned "id - locale", so interpolating an account or
logging a non-destructured {Account} published the address. It now returns
the masked entry, with a DebuggerDisplay keeping the real values visible
while debugging. Nothing in the UI relied on it: both scan dialogs build
their own labels.
For structured logging, an ILogMasked type is reduced to its masked entry
by a destructuring policy, which covers the {@DebugInfo} shape most of
Libation's logging uses. And DecryptKey - the activation bytes - is now a
SecretString, so it has no plaintext for a reflective dump to find at all.
Its JSON stays the bare string it always was, so existing settings files
load unchanged.
A registered policy that nobody notices is missing protects nothing, so
the tests write through a logger built by ConfigureLogging itself rather
than a hand-made one. Deleting either registration fails them: the masked
object comes out whole, and a destructured secret renders as
{"HasValue":true} instead of its length.
The contribute guide now states the rule, since the reason for all of
this is invisible from the code alone: log files get attached to public
issues, so treat what goes in them as published.
Co-authored-by: rmcrackan <rmcrackan@gmail.com>
2.3 KiB
2.3 KiB
Contribute to Libation
We welcome contributions! Whether it's fixing bugs, adding features, or improving documentation, your help is appreciated.
Warning
Read the Development - Getting Started guide first.
Getting Started
- Fork the repository on GitHub.
- Clone your fork locally.
- Create a branch for your feature or fix:
git checkout -b feature/my-new-feature
Code Style
- Follow standard C# coding conventions.
- Ensure your code builds and runs without errors.
- Clean up any unused dependencies or imports.
Logging and secrets
We ask people to attach Log.log to public issue reports, so treat everything written there as published.
- Log
account.MaskedLogEntry, never an account's id or name.AccountCredentialStatus.FormatAccountLabelgives the unmasked label and is for dialogs shown to the account's owner only. - Never hang an
Account, anIdentity, or anything holding one off an exception. Serilog.Exceptions reflects over every public property of a logged exception and follows nested objects, so a live account on an exception publishes its address and activation bytes no matter whatToStringsays. Carry anAccountSummaryinstead. A test enforces this: seeExceptionsCannotReachAnAccount. - Remember that an exception's
Messagegets logged too, so mask anything you interpolate into one. - Wrap a new secret in
Dinah.Core.Security.SecretString, which keeps the value behindReveal()where reflection cannot find it and prints[REDACTED length=N]everywhere else. ImplementILogMaskedon a type that needs a masked identity in logs. Reveal()at the point of use, and nowhere else. Interpolating a secret into a string is not a compile error, so a redaction can end up sent over the wire in place of the real value - cover any new call site with a test.
Submitting a Pull Request
- Commit your changes with a clear message.
- Push to your fork:
git push origin feature/my-new-feature - Open a Pull Request on the main repository.
- Describe your changes and link any related issues.
Reporting Issues
If you find a bug or have a feature request, please open an issue on GitHub.