Search code examples
javascripttypescriptnestjsbackend

nest can't resolve depencies of the authService (jwtService)


I don't understand i got this error: [Nest] 1276 - 25/04/2024 19:39:31 ERROR [ExceptionHandler] Nest can't resolve dependencies of the AuthService (?, JwtService). Please make sure that the argument UsersService at index [0] is available in the AuthModule context.

Potential solutions:

  • Is AuthModule a valid NestJS module?
  • If UsersService is a provider, is it part of the current AuthModule?
  • If UsersService is exported from a separate @Module, is that module imported within AuthModule?

but i don't understand cause i got the same code running fine in another project here my file:

authModule:

import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UsersModule } from 'src/modules/users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    UsersModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '24h' },
    }),
  ],
  controllers: [AuthController, LocalStrategy, JwtStrategy],
  providers: [AuthService],
})
export class AuthModule {}

appModule:

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import config from 'config';
import { UsersModule } from './modules/users/users.module';
import { ConfigModule } from '@nestjs/config';
import { AuthModule } from './auth/auth.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true, // no need to import into other modules
    }),
    MongooseModule.forRoot(config.get('mongoDbUrl'), {
      w: 1,
    }),
    UsersModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

userModule:

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from '../../shared/schema/user';

@Module({
  imports: [
    MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
  ],
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}

authService:

import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcrypt';
import { UsersService } from 'src/modules/users/Users.service';
import { User } from 'src/shared/schema/user';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService,
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOneByUsername(username);
    if (user && user.password === pass) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async signin(user: User): Promise<any> {
    const foundUser = await this.usersService.userGet(user.email);
    if (foundUser) {
      const { password } = foundUser;
      if (bcrypt.compare(user.password, password)) {
        const payload = { email: user.email };
        return {
          accessToken: this.jwtService.sign(payload),
        };
      }
      return new HttpException(
        'email ou mot de passe incorrect',
        HttpStatus.UNAUTHORIZED,
      );
    }
    return new HttpException(
      'email ou mot de passe incorrect',
      HttpStatus.UNAUTHORIZED,
    );
  }

  async login(user: any) {
    const payload = { username: user.username, userId: user.id };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}

i don't get why nest don't resolve the jwtService.


Solution

  • Change the import statement in the auth.service file from Users.service to users.service. The casing is important, as they are treated as separate files, and thus have their own instanceof due to the way JS realms work.

    From (incorrect)

    import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
    import { JwtService } from '@nestjs/jwt';
    import * as bcrypt from 'bcrypt';
    import { UsersService } from 'src/modules/users/Users.service';
    import { User } from 'src/shared/schema/user';
    

    To (correct)

    import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
    import { JwtService } from '@nestjs/jwt';
    import * as bcrypt from 'bcrypt';
    import { UsersService } from 'src/modules/users/users.service';
    import { User } from 'src/shared/schema/user';
    

    It's a subtle change, but an important one. There's an option in the Typescript compiler config to enforce consistent file casing, which is helpful to turn on