auth0 / express-jwt

connect/express middleware that validates a JsonWebToken (JWT) and set the req.user with the attributes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bring TypeScript Types In-House

shellscape opened this issue · comments

Describe the problem you'd like to have solved

It's nice to have something in the way of typing in @types/express-jwt but the types there are lacking, they do funky things that are generally a bad idea, and they track behind project development.

There are three issues still open, of which the oldest is 3 years old: #270 #233 #215

Describe the ideal solution

Bring the types in-house, into this repo and release them as part of the package with each version. Surely auth0 has enough expertise in TypeScript between the auth0 and okta orgs to be able to support this. It's not a heavy lift. Alternatively, convert the small amount of JS in this repo to TS and let TS generate the types for you.

As an experiment, I was able to convert this project to TS in less than two hours. Maybe that'll help the middle management plan for something like that. If you're open to community contribution to that extent, I'll be able to share my rewrite as a PR.

Alternatives and current work-arounds

The current alternative is quite frankly, lacking severely, and there's really no reason for it.

Additional context

Thanks for the heads up. I can see the problems about the way the current type is extending express's Request globally but I am wondering what's the best way to do it. Assume we convert this repository to typescript

Do you have or know about any other middleware lib written in typescript that extend the request object?

All examples I found do something very similar:

I think the other complication we have is that the user property can be changed.

Would you rather leave to the consumer of the library? ie creating a custom type extending Request on each project

Thank you very much for the feedback

One thing we could do is to export a generic type to make it easier for implementors like this:

export type ExperssJwtRequest<PropertyName extends string> =
  express.Request & { [P in PropertyName]: jwt.JwtPayload }

Then:

Screen Shot 2022-03-16 at 11 46 14

this wouldn't work for things like requestProperty: 'auth.token'...

I think the other complication we have is that the user property can be changed.

Honestly I wouldn't even bother with allowing the name of the user property to be changed. Are there any metrics for people actually using that feature? A package like this should be prescriptive imho, and specify that a property is the source of truth, whether that property name be jwt, user, auth, etc. It always struck me as one of those configuration options that was a solution looking for a problem. If users needed to alias that, it could be accomplished with simple additional middleware. In larger open source projects, if there isn't a need for a configuration or option by a significant portion of the userbase, we offer workarounds and alternative recipes to accomplish a thing.

I can see the problems about the way the current type is extending express's Request globally but I am wondering what's the best way to do it.

I tend to take the "don't mess with globals" approach, the same mantra as not messing with builtin prototypes. I'd much rather specify a separate request (like ExpressJwtRequest) that extends the base type/interface and specify that in code. Providing a Handler type that extends the base type will go a long way to reduce the need to use the request type frequently as well, now that we have solid introspection. Extending the base express types is black box magic, and you need to know that's being done in order to understand why a new property exists. I'm not a fan of black box/magic in code.

I agree with you, thanks for this feedback. I will send a PR today

this my PR, it will be great if you can provide feedback there. Thank you very much

#274

Fixed in v7