0

im making a middleware from a node api, to check if the user is logged in, and im sending a jwt token

this is the class and the function

export class Auth {
    async isAuthenticatedClient(req: Request, res: Response) {
        const { token } = req.cookies

        if (!token) {
            res.status(401).send({
                message: "Faça login para acessar esse conteúdo"
            })
        }

        const decoded = jwt.verify(token, "sgjlskdfghajhdfghsd");
        req.client = await prisma.client.findUnique({ decoded.id });
    }
}

its returning two errors:

Property 'client' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
Argument of type '{ decoded: string | jwt.JwtPayload; "": any; }' is not assignable to parameter of type '{ rejectOnNotFound?: RejectOnNotFound | undefined; select?: ClientSelect | null | undefined; include?: ClientInclude | null | undefined; where: ClientWhereUniqueInput; }'.
  Object literal may only specify known properties, and 'decoded' does not exist in type '{ rejectOnNotFound?: RejectOnNotFound | undefined; select?: ClientSelect | null | undefined; include?: ClientInclude | null | undefined; where: ClientWhereUniqueInput; }'.

im using a js api to base myself, and the type of client should be any, and decoded should be jwt.Jwt & jwt.JwtPayload & void

EDIT: i created two interfaces and its not getting any error in the class, but in the routes the following line:


router.route('/teste').get(authController.teste, authMiddleware.isAuthenticatedClient) // this route only gets a simples request just to test the middleware

these are the two interfaces that i created:

export interface GetClientAuthInfoRequest extends Request {
    client: Client | null// or any other type
}

interface JwtPayload {
    id: string
}

export type Client = {
    name: string
    email: string
    password: string
}

the error is the following:

No overload matches this call.
  The last overload gave the following error.
    Argument of type '(req: GetClientAuthInfoRequest, res: Response<any, Record<string, any>>) => Promise<void>' is not assignable to parameter of type 'RequestHandlerParams<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
      Type '(req: GetClientAuthInfoRequest, res: Response<any, Record<string, any>>) => Promise<void>' is not assignable to type 'RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
        Types of parameters 'req' and 'req' are incompatible.
          Property 'client' is missing in type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' but required in type 'GetClientAuthInfoRequest'.ts(2769)
Express.type.ts(4, 5): 'client' is declared here.
index.d.ts(222, 5): The last overload is declared here.

1 Answers1

0

The first error is because client isn't defined on the Request type from Express, you can solve it like this based on this other question Typescript Error: Property 'user' does not exist on type 'Request'

import { Request } from "express"
export interface clientRequest extends Request {
  client: string
}

for the second error you could try with { id: decoded.id } or where { id: decoded.id }

EDIT

Replace Request with GetClientAuthInfoRequest

export class Auth {
  async isAuthenticatedClient(
    req = GetClientAuthInfoRequest,
    res = Response,
    next
  ) {
    const { token } = req.cookies;

    if (!token) {
      return res.status(500).send({
        msg: "Faça login para acessar esse conteúdo",
      });
    }
    next();
    try {
      const decoded = jwt.verify(token, "sgjlskdfghajhdfghsd");
      req.client = await prisma.client.findUnique({ id: decoded.id });
    } catch (error) {
      return res.status(401).send({
        msg: "Error",
      });
    }
  }
}
René
  • 101
  • 2
  • 5
  • it is returing "type 'Client | null' is not assignable to type 'string'. Type 'null' is not assignable to type 'string'" and for the decoded is returning "Property 'id' does not exist on type 'string | JwtPayload'. Property 'id' does not exist on type 'string'". – Pedro Souza Apr 19 '23 at 23:02
  • For the 'Client | null' error you could use `any` and then print on console and see what values you get and why they don't match, for the second one you can do type casting, adding `as string` to decoded: `const decoded = jwt.verify() as string;`, as well as adding `if` to check that your data isn't empty, example`if(!client)` – René Apr 19 '23 at 23:24
  • im getting a new error, im gonna edit the question – Pedro Souza Apr 19 '23 at 23:26
  • Edited my answer as well. – René Apr 19 '23 at 23:47
  • i made your changes and also uses as JwtPayload for the decoded variable and it stopped to getting error in the middleware file, but its getting the error in the route (that i specified in the post) – Pedro Souza Apr 19 '23 at 23:49
  • Maybe `authController.teste` is doing something with the request, try using `GetClientAuthInfoRequest` or create a similar interface with another name for teste. – René Apr 19 '23 at 23:58
  • the error is in the auth middleware, i tried to use just the middleware and its returning the same error, and i think its because the interfaces, especially in the express interface. – Pedro Souza Apr 20 '23 at 00:23
  • The error is in the sequence, it should be route, middleware and controller: `router.route('/teste').get(authMiddleware.isAuthenticatedClient,authController.teste)` – René Apr 20 '23 at 00:33
  • its getting the same error @René – Pedro Souza Apr 20 '23 at 00:37
  • Can you shared the authController.teste code? Anyways you were executing the controller before the middleware, it was accessed before doing the validations. Now it validates and gives access if successful – René Apr 20 '23 at 00:43
  • is the following: ` async teste(req: Request, res: Response) { res.send({ message: 'teste' }) }` – Pedro Souza Apr 20 '23 at 00:51
  • Maybe it is the way the interfaces were declared, looked for other examples and it seems that this should work: [Extend Express Request object using Typescript](https://stackoverflow.com/a/58788706/13049325) yet it seems that there are many ways to do it and not all of them work as expected. – René Apr 20 '23 at 01:04
  • aparently when i use namespace in the interface it works in the route, but the import in the middleware goes wrong – Pedro Souza Apr 20 '23 at 01:09
  • How are you importing it? – René Apr 20 '23 at 01:24
  • `import { GetClientAuthInfoRequest } from '../types/Express.types';` – Pedro Souza Apr 20 '23 at 01:26
  • Try with `import GetClientAuthInfoRequest from '../types/Express.types'` or try declaring as `declare global { interface GetClientAuthInfoRequest {} }` – René Apr 20 '23 at 01:41
  • im getting the sam error – Pedro Souza Apr 20 '23 at 01:49
  • Which error? Same one as before? – René Apr 20 '23 at 02:04
  • same, the error in the post, i tried to change but every time some error solves, another comes, i dont know that much about interfaces and types – Pedro Souza Apr 20 '23 at 02:31
  • Looks like the same problem you have was solved here [Cannot extend express request](https://stackoverflow.com/a/63603545/13049325) – René Apr 20 '23 at 05:18