#How can i extend the `nestjs jwt` service to add purpose validation?

3 messages · Page 1 of 1 (latest)

lethal garnet
#

How can i extend the @nestjs/jwt service to add purpose validation?

jwt.module.ts

import { Module } from '@nestjs/common';
import { JwtModule as NestJwtModule } from '@nestjs/jwt';
import { JwtService } from './jwt.service';

@Module({
  controllers: [],
  exports: [JwtService],
  imports: [NestJwtModule.register({ secret: 'secret-test' })],
  providers: [JwtService],
})
export class JwtModule {}

jwt.service.ts

import { Injectable } from '@nestjs/common';
import { JwtService as NestJwtService, JwtSignOptions } from '@nestjs/jwt';

@Injectable()
export class JwtService extends NestJwtService {
  async signPurpose<T = object>(purpose: string, payload: T, options?: JwtSignOptions): Promise<string> {
    return this.signAsync(
      {
        purpose,
        ...payload,
      },
      options,
    );
  }

  async verifyPurpose<T = object>(purpose: string, token: string): Promise<T> {
    const payload = await this.verifyAsync(token);

    if (payload.purpose !== purpose) {
      throw new Error('Invalid purpose');
    }

    return payload;
  }
}

Now i want to access the jwtservice (example in my main.ts file):

  const tokenA = await app.get(JwtService).signPurpose('auth.2fa', {
    userId: 'abc',
  });

  const tokenB = await app.get(JwtService).signPurpose('auth.session', {
    userId: 'abc',
  });

  console.log(tokenA, tokenB);

But the JWT service still wants me to set a secretOrPrivateKey.

Error: secretOrPrivateKey must have a value
supple token
#

I would use composition instead of inheritance. Basically, do what you did, but instead of extending, inject the original JwtService throught constructor and instead of this.sign, use this.jwtSerive.sign. By puttin a service in providers, nest will instantiate it, but the JwtService itself must be instantiated using the JwtModule to use the settings passed to it.

lethal garnet
#

Thanks! I'll try that out 🙂