Skip to content

Latest commit

 

History

History
158 lines (121 loc) · 4.86 KB

File metadata and controls

158 lines (121 loc) · 4.86 KB

Providers

This directory contains providers contributing additional bindings, for example custom sequence actions.

Overview

A provider is a class that provides a value() function. This function is called Context when another entity requests a value to be injected.

Basic Usage

These are the optional bindings that can be used to extend the functionality of this service.

BEARER_TOKEN_VERIFIER

This provides a function that is used to verify the Bearer Token for endpoints using the Bearer Token authentication.

Implementation for this can be seen here;

CODEREADER_PROVIDER

This provides a function that can process the authorization code (used in KeyCloak and Google Oauth authentications) before being verified. This can be used to decrypt a code or to retrieve it from Cache/Redis.

Sample implementation -

export class CodeReaderProvider
    implements Provider<CodeReaderFn> {
    constructor(
        @repository(CodeRepository)
        private readonly codeRepo: CodeRepository
    ) { }

    value(): CodeReaderFn {
        return async (token) => {
            let codeModel = await this.codeRepo.get(token);
            if (!codeModel?.code) {
                return token;
            }
            await this.codeRepo.delete(token);
            return codeModel.code
        }
    }
}

Here CodeRepository is a Redis Repository, implementation for such a key pair repository can be seen here.

CODEWRITER_PROVIDER

This provides a function that can process the authorization code before it is passed to the client, it can be used to store the token in a cache and pass only a key, or to encrypt the token.

Sample implementation -

export class CodeWriterProvider
    implements Provider<CodeWriterFn> {
    constructor(
        @repository(CodeRepository)
        private readonly codeRepo: CodeRepository
    ) { }

    value(): CodeWriterFn {
        return async (token) => {
            let key = uuidv4();
            await this.codeRepo.set(key, {code: token});
            return key;
        }
    }
}

Here CodeRepository is a Redis Repository, implementation for such a key pair repository can be seen here.

uuidv4 is function to from this.

PRE_LOCAL_SIGNUP_PROVIDER

This provides a function that creates the object stored in the JWT token for signup requests.

Sample implementation for this can be seen here

LOCAL_SIGNUP_PROVIDER

This provides a function that gets the data from the signup token and is responsible for performing all tasks required to signup a user. You can also find an implementation of this provider in auth-basic-example.

Sample implementation -

export class LocalSignupProvider
  implements
    Provider<UserSignupFn<UserSignupDto, {userId: string | undefined}>> {
  constructor(
    @service(UserService)
    private readonly userService: UserService,
  ) {}

  value(): UserSignupFn<UserSignupDto, {userId: string | undefined}> {
    return async (model: UserSignupDto, tokenInfo?: AnyObject) => {
      if (!model.userData) {
        throw new HttpErrors.BadRequest('userData missing');
      }
      if (tokenInfo?.email && model.email === tokenInfo.email) {
        await this.userService.updateUser(model.userData, model.email);
      } else {
        throw new HttpErrors.BadRequest('Invalid Email');
      }
    };
  }
}

BEARER_SIGNUP_VERIFY_PROVIDER

The provider for this key is used to verify a signup token generated by the signup endpoint.

    this.bind(VerifyBindings.BEARER_SIGNUP_VERIFY_PROVIDER).toProvider(
      SignupBearerVerifyProvider,
    );
export class SignupBearerVerifyProvider
  implements Provider<VerifyFunction.BearerFn<UserInviteDto>> {
  constructor(
  ) {}

  value(): VerifyFunction.BearerFn<UserInviteDto> {
    return async (token: string) => {
      let result: UserInviteDto;
      try {
        result = verify(token, process.env.JWT_SECRET as string, {
          issuer: process.env.JWT_ISSUER,
        }) as UserInviteDto;
      } catch (error) {
        throw new HttpErrors.Unauthorized('TokenExpired');
      }
      if (await this.userOpsService.checkUserSignedUp(result.email)) {
        throw new HttpErrors.Forbidden('TokenAlreadyUsed');
      }
      return result;
    };
  }
}

Related Resources

You can check out the following resource to learn more about providers, components, sequences, and binding keys.