-1

i hope you can help me, i'm trying to build an API using inversify and inversify-express-utils. So, I already created my controllers and the API is working fine and no problems so far, but when I try to access to the httpContext property that comes from the inheritance of BaseHttpController to my controller I can't see the user details 'cause this property (httpContext) is an empty object, I already configured my custom Authentication provider like the official docs explain.

Here's my code ...

app.ts

import AuthInversifyProvider from './providers/auth-inversify.provider';

export default class Application {
  private readonly server: InversifyExpressServer;
  private readonly environment: Environment;
  private readonly rootPath = '/api/v1';

  constructor(container: Container, environment: Environment) {
    this.server = new InversifyExpressServer(container, null, {
      rootPath: this.rootPath,
    }, null, AuthInversifyProvider);
    this.environment = environment;
  }

  public initialize(): ExpressApp {
    this.server.setConfig((app) => {
      // settings
      app.set('port', this.environment.PORT);
      app.set('pkg', pkg);

      // middlewares
      app.use(morgan('dev'));
      app.use(cors());
      app.use(urlencoded({ extended: false }));
      app.use(json());

      // swagger docs...
      app.use(
        `${this.rootPath}/docs`,
        SwaggerUI.serve,
        SwaggerUI.setup(SwaggerDocsSetup)
      );
    });

    this.server.setErrorConfig((app) => {
      // Global error handling
      app.use(ErrorMiddlewareHandler);
    });

    return this.server.build();
  }
}

auth-inversify.provider.ts

/* eslint-disable max-classes-per-file */
import Interfaces from '@Interfaces/interfaces.mapping';
import IAuthService from '@Interfaces/services/iauth.service';
import IUsersService from '@Interfaces/services/iusers.service';
import { Request } from 'express';
import { inject, injectable } from 'inversify';
import { interfaces } from 'inversify-express-utils';
import { UserResponseDto } from '@Shared/dtos/users.dto';

class Principal implements interfaces.Principal {
  public details: UserResponseDto | null;
  public constructor(details: UserResponseDto | null) {
    this.details = details;
  }
  public isAuthenticated(): Promise<boolean> {
    return Promise.resolve(true);
  }
  public isResourceOwner(resourceId: unknown): Promise<boolean> {
    return Promise.resolve(resourceId === 1111);
  }
  public isInRole(role: string): Promise<boolean> {
    return Promise.resolve(role === 'admin');
  }
}

@injectable()
export default class AuthInversifyProvider implements interfaces.AuthProvider {
  @inject(Interfaces.AuthService)
  private readonly authService!: IAuthService;
  @inject(Interfaces.UsersService)
  private readonly usersSevice!: IUsersService;

  public async getUser(req: Request): Promise<interfaces.Principal> {
    try {
      const rawToken = req.headers.authorization;
      const token = rawToken?.split(' ').pop() ?? '';
      const payload = await this.authService.verifyToken(token);
      const user = this.usersSevice.getById(payload?.id ?? '');

      return new Principal(user);
    } catch (error) {
      return new Principal(null);
    }
  }
}

This is a picture for reference, it shows that the current user is being found successfully

enter image description here

My controller.

enter image description here

  • I don't have a full answer, only a suspicion. [Here](https://github.com/inversify/inversify-express-utils/blob/master/src/server.ts#L122) is the place where fake empty context is created for registration purposes, [later](https://github.com/inversify/inversify-express-utils/blob/master/src/server.ts#L256) it is replaced with real context, and then [injected](https://github.com/inversify/inversify-express-utils/blob/master/src/base_http_controller.ts#L11) into controller. Could it be that wrong container is used in the controller? E.g. two instances of `inversify`, maybe of different versions? – alx Sep 01 '22 at 20:56

1 Answers1

1

Are you instantiating your new Container with Singleton option? If yes, try using default option i.e transient rather than Singleton. I had the same problem which had an empty httpContext.