Comments (3)
Yeah, this is definitely something I have been wanting to support this for a while now, and with the recent foundational improvements this may be a bit easier to implement.
Short-term solution
For right now, one option you have is to not use the default formatter (formatInline
), but to use formatShort
instead. The difference is that using formatShort
will not echo back the input at all, and just describe where the validation error happened within that object. It's a different experience, but it would solve your problem more immediately. See these docs: https://decoders.cc/#formatting-error-messsages
More robust actual solution
Ideas for a future release to further support this:
- Allow for a
sensitive()
decoder, which would allow you to write your object decoder like this:This is not really an actual decoder in the classic sense, but it would get recognized and treated specially by the object family of decoders, to ensure the default formatter would avoid echoing back content that should get masked. Imagine an error output like this:object({ username: string, password: sensitive(string), })
{ "username": 123, ^^^ Must be string "password": ************, }
- Also, maybe it's a good idea to let the default formatter (
formatInline
) recognize the most common field name patterns in practice and simply always treat those values as sensitive, i.e. field names containingpassword
,passwd
,token
, etc. That may be more secure by default. Echoing back values for keys with those names is never a good idea anyway.
Maybe you have some ideas for how to shape those APIs yourself? Would love to hear them!
from decoders.
I haven't thought a lot yet about what I think an ideal API for this would be, but I will say the idea of adding certain keys to a redaction blacklist makes me uneasy, honestly. If someone wants to actually render one of those in the error message, does that require a separate API for re-enabling those, or are you just stuck with the redaction and there's nothing you can do about it? And where is the line drawn for what makes a 'common' field that often has sensitive data? Is that going to keep expanding if people open issues about 'hey, I printed sensitive field <x> into my logs and then my system got compromised'? And adding any fields to this sort of list would be a breaking change every time.
A sensitive()
decoder seems nice, but the fact that that logic needs to live within the object()
et al decoders feels a bit messy. You're not really able to take advantage of tree-shaking nicely in that case, because everyone would have to pay for the possibility that they might have a sensitive()
within their object()
whether they actually did or not. It also seems to mess with the API. Either sensitive()
would need some secret backchannel way to convey its presence to object()
etc. that is inaccessible to users, or else there would need to be a whole new mechanism for decoders to pass additional metadata around, which also doesn't feel great to me.
I'd probably learn towards three additional redacting variants of object()
/exact()
/inexact()
, although I'm not sure what a nice API would look like for those.
from decoders.
"I haven't thought a lot yet about what I think an ideal API for this would be, but I will say the idea of adding certain keys to a redaction blacklist makes me uneasy, honestly. […] Is that going to keep expanding if people open issues"
Yep, this would be a massive downside, and I don't really like it either.
"A
sensitive()
decoder seems nice, but the fact that that logic needs to live within theobject()
et al decoders feels a bit messy. […] Eithersensitive()
would need some secret backchannel way to convey its presence toobject()
etc."
Edge cases pop up quickly once you start thinking about it.
For example, should this construct even be allowed or not? Does it even make sense?
either(sensitive(string), whatever) // Can you compose this thing?
I don't think so. This example illustrates that sensitive()
isn't really a Decoder itself in the strict sense, as it isn't freely composable. Instead, it serves as an "instruction" to object()
et al to construct their error messages in a slightly different way than the default. Therefore it should only be allowed at the "top level" of an object definition.
object({
username: string,
password: nullable(sensitive(string)), // ❌ Not allowed
password: sensitive(nullable(string)), // ✅ Allowed
});
Another API to convey the exact same information would be to add a second config param to object()
et al:
object(
{
username: string,
password: string,
},
{ mask: ["password"] }, // Slightly less DRY alternative, because you have to repeat the field name here
);
from decoders.
Related Issues (20)
- Question: Type intersection composition HOT 2
- Decoder for object with specified key HOT 3
- Required types HOT 6
- Dispatch does not work when the field differentiating which decoder to use has a non-string value HOT 1
- Decoder with constants is throwing an exception. TypeError: (0 , _Result.Ok) is not a function HOT 5
- Typescript error with required properties HOT 9
- [Bug] Builtin composite decoders cannot take decoders with non-`unknown` input types HOT 8
- WeakGuard in 2.x HOT 3
- Migration help needed: .map to .transform HOT 3
- Export Annotation and Formatting function from package HOT 1
- Composing `lazy` and `either` can become slow. HOT 3
- Package requires nodejs 10 or newer, but this is not documented. HOT 2
- Decoding nested serialized JSON HOT 1
- Unwrap Error Message from Guard HOT 2
- Type is not inferred correctly from a dynamically created decoder with generics HOT 4
- Union type is not inferred correctly from either decoder HOT 1
- Ability to filter out incorrect items during array decoding HOT 6
- URL decoder does not accept URLs with / in the query part HOT 2
- Missing field in `inexact` doc HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from decoders.