lukeautry / tsoa

Build OpenAPI-compliant REST APIs using TypeScript and Node
MIT License
3.48k stars 498 forks source link

Make express request injectable #1616

Closed sourceful-mia closed 2 months ago

sourceful-mia commented 5 months ago

Sorting

Expected Behavior

I am looking to get the user claims from my JWT so that I can get user id & name. I'd like to make this available everywhere as an injectable service, to avoid every controller route having to worry about passing the request down, and reduce the amount of parameters that need to go through every function.

Possible Solution

I've tried to create a UserService where I inject the request, but it doesn't work:

import { Request } from "tsoa";
import { provide } from "inversify-binding-decorators";
import express from "express";
import { Buffer } from "buffer";

export type User = {
  id: string;
  name: string;
}

@provide(UserService)
export class UserService {
  constructor(@Request() private request: express.Request) {
  }

  async getCurrentUser(): Promise<User> {
    const authHeader = this.request.headers.authorization;
    const jwt = authHeader?.split(" ")[1];

    const claims = Buffer.from(jwt?.split(".")[1] ?? "", "base64").toString();

    return JSON.parse(claims);
  }
}

A couple of other ideas:

I really like tsoa and how it reduces the amount of (req, res) => {} functions in regular express servers, so I'm keen to avoid having to do this again with this library πŸ˜„

github-actions[bot] commented 5 months ago

Hello there sourceful-mia πŸ‘‹

Thank you for opening your very first issue in this project.

We will try to get back to you as soon as we can.πŸ‘€

github-actions[bot] commented 4 months ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

midoelhawy commented 4 months ago

Hi @sourceful-mia

you need to define a new Request interface like and use a express or tsoa middleware to intercept the request and inject what you want :

import { Request } from 'express'
export interface baseHttpRequest extends Request {
  jwtUser?: IUser | null
  clientIp?: string
  deviceType?: string
  appVersion?: string // for andriod or IOS app version
  userAgent?: string
...
  middlewaresData?: {
    article?: IArticle // For example
  }
}

And next you can replce your @Request() private request by @Request() private baseHttpRequest

github-actions[bot] commented 3 months ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days