nestjs-oauth2-server icon indicating copy to clipboard operation
nestjs-oauth2-server copied to clipboard

How do I inject dependencies into my model?

Open thalysonalexr opened this issue 4 years ago • 7 comments

How do I inject dependencies into my model? I tried it with injectable, but it looks like he totally ignores it when deco with his model decorator!??

thalysonalexr avatar Mar 12 '21 16:03 thalysonalexr

Hello @thalysonalexr , can you provide code snippets? This will better help proffer a solution.

toondaey avatar May 15 '21 08:05 toondaey

Okay, I have the following code:

@OAuth2Model()
@Injectable()
export class OAuth2ModelService implements RequestAuthenticationModel {
  constructor(private readonly configService: ConfigService) {}
}

as you can see, I'm passing the @ Injectable decorator so that the nest inject via constructor my dependency on ConfigService. I would like to use some of the environment with this module, instead of using directly with process.env as I did when implementing ... When trying to use this way, something simply causes nest to ignore ... Is there any solution for me to can use the decorator of OAuth2Model in a nest provider?

Thanks for the feedback!

thalysonalexr avatar May 15 '21 23:05 thalysonalexr

Hey! having the same problem injecting Prisma service into the model service, any ideas?

cerpinn avatar Oct 28 '21 14:10 cerpinn

Hey guys,

I think I would have to revise the lib and implement the solution. In my case I needed to inject a typeorm repository and use configService. So manually I used process.env and getRepository method.

thalysonalexr avatar Nov 13 '21 07:11 thalysonalexr

Hey guys,

I think I would have to revise the lib and implement the solution. In my case I needed to inject a typeorm repository and use configService. So manually I used process.env and getRepository method.

The problem is caused by nested modules. @OAuth2Model provider is got by reflector inside ModelProviderModule, thus we cannot import modules for it. I will try to fix it in the next week.

helsonxiao avatar Nov 14 '21 13:11 helsonxiao

Update: After digging into the codebase, I'm using this workaround.

import * as OAuth2Server from 'oauth2-server';
import { ServerOptions } from 'oauth2-server';
import {
  OAuth2ServerTokenGuard,
  OAuth2ServerAuthorizationGuard,
  OAuth2ServerAuthenticationGuard,
} from '@t00nday/nestjs-oauth2-server/dist/guards';
import { IOAuth2ServerModuleOptions } from '@t00nday/nestjs-oauth2-server/dist/interfaces';
import {
  OAUTH2_SERVER,
  OAUTH2_SERVER_MODEL_PROVIDER,
  OAUTH2_SERVER_OPTIONS_TOKEN,
} from '@t00nday/nestjs-oauth2-server/dist/oauth2-server.constants';

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from 'src/user/entities/user.entity';
import { OAuth2User } from './entities/oauth2-user.entity';
import { OAuth2Controller } from './oauth2.controller';
import { OAuth2Model } from './oauth2.model';
import { OAuth2Service } from './oauth2.service';

@Module({
  imports: [
    TypeOrmModule.forFeature([
      OAuth2User,
      User,
    ]),
  ],
  providers: [
    OAuth2Service,
    {
      provide: OAUTH2_SERVER_OPTIONS_TOKEN,
      useValue: {},
    },
    {
      provide: OAUTH2_SERVER_MODEL_PROVIDER,
      useClass: OAuth2Model,
    },
    {
      provide: OAUTH2_SERVER,
      useFactory: (
        options: IOAuth2ServerModuleOptions,
        model: ServerOptions['model'],
      ): OAuth2Server =>
        new OAuth2Server(Object.assign({}, options, { model })),
      inject: [OAUTH2_SERVER_OPTIONS_TOKEN, OAUTH2_SERVER_MODEL_PROVIDER],
    },
    OAuth2ServerTokenGuard,
    OAuth2ServerAuthorizationGuard,
    OAuth2ServerAuthenticationGuard,
  ],
  controllers: [OAuth2Controller],
})
export class OAuth2Module {}

Now, OAuth2Service is injectable in OAuth2Model.

Also, OAuth2ServerModule is no more needed in your app.module.ts because providers have been already imported above.

// just remove this line!
import { OAuth2ServerModule } from '@t00nday/nestjs-oauth2-server';

helsonxiao avatar Nov 17 '21 15:11 helsonxiao

I'd like to propose a new but breaking API for this feature.

Update: This is available on npm now. Just install it by npm install @boyuai/nestjs-oauth2-server.

How do we use it?

import { Module } from '@nestjs/common';
import { OAuth2ServerModule } from '@boyuai/nestjs-oauth2-server';
import { OAuth2Controller } from './oauth2.controller';
import { OAuth2ServiceModule } from './oauth2-service.module';
import { OAuth2Model } from './oauth2.model';

@Module({
  imports: [
    OAuth2ServiceModule,
    OAuth2ServerModule.forRoot({
      imports: [OAuth2ServiceModule], // import anything you want to use in modelClass
      modelClass: OAuth2Model,
    }),
  ],
  controllers: [OAuth2Controller],
})
export class OAuth2Module {}

And you have to implement your own OAuth2Model.

@Injectable() // We don't use `@OAuth2Model()` any more.
export class OAuth2Model
  implements RequestAuthenticationModel, AuthorizationCodeModel
{
  private readonly logger = new Logger(OAuth2Model.name);

  constructor(
    private readonly redisService: RedisService,
    private readonly oauth2Service: OAuth2Service,
  ) {}

  // ...
  // methods for oauth2 server
}

helsonxiao avatar Nov 17 '21 16:11 helsonxiao