npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ux-common-lib-test

v0.0.2

Published

unifyedx-common-lib is a Node.js module that provides authentication functionality for UnifyedX microservices. Check package.json for nestjs dependency.

Downloads

34

Readme

unifyedx-common-lib

unifyedx-common-lib is a Node.js module that provides authentication functionality for UnifyedX microservices. Check package.json for nestjs dependency.

Installation

npm install unifyedx-common-lib

Usage

unifyedx-common-lib provides certain utility functions and components which can be used across all unifyed products.

UnifyedAuthCheckGuard

A nestjs guard named UnifyedAuthCheckGuard that can be used to check if a user is authenticated before allowing access to API routes.

To enable the guard, import and add it to the APP_GUARD providers in your main module (app.module.ts):

import { UnifyedAuthCheckGuard } from 'unifyedx-common-lib';

{
  provide: APP_GUARD,
  useClass: UnifyedAuthCheckGuard,
},

This will check for a valid user in the following ways:

Check request header for Bearer token. Use that token to look up for an authenticated user in redis cache If no user found, throw Unauthorized error To skip authentication for specific routes, decorate the class or method with the @Public() decorator. This decorator is also provided in the common library.

Usage of the pubilc decorator is shown below.

import { Public } from 'unifyedx-common-lib';

@Controller()
export class PublicController {

  @Public()
  @Get()
  publicMethod() {
  }

}

IP Inject Middleware and IP Check Gurad (UnifyedIPGuard, UnifyedIpInjectMiddleware)

unifyedx-common-lib provides an IP inject middleare and and IP Check guard which can be included in your project as shown below. Both should be used in conjuction. UnifyedIpInjectMiddleware will set the client ip in the request which can later be used by the UnifyedIPGuard to permit of deny access to API routes.

import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { UnifyedIPGuard, UnifyedIpInjectMiddleware } from 'unifyedx-common-lib';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './modules/config/config.module';
import { TenantModule } from './modules/tenant/tenant.module';
import { APP_GUARD } from '@nestjs/core';

@Module({
  imports: [ConfigModule, TenantModule],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_GUARD,
      useClass: UnifyedIPGuard,
    },
  ],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(UnifyedIpInjectMiddleware).forRoutes('*');
  }
}

If a class or method to be protected using the IP guard then set the metadata and pass the allowed IPs as shown below. (comma separated and without spaces)

import { Controller, Get, SetMetadata } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @SetMetadata('allowed-ips', '127.0.0.1,192.168.0.1') // Specify allowed IPs
  findAll() {
    return 'This action returns all items';
  }
}

OR

import { Controller, Get, SetMetadata } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @AllowedIPs('127.0.0.1,192.168.0.1') // Specify allowed IPs
  findAll() {
    return 'This action returns all items';
  }
}

Pub Sub Service Using redis (RedisPubSubService)

unifyedx-common-lib provides an service class for publishing and subscribing to redis channels. This can be included in your project as shown below

import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';
import { RedisPubSubService } from 'unifyed-common-lib';
import { Public } from './decorators';

@Controller()
@Public()
export class AppController {
  constructor(
    private readonly pubSubService: RedisPubSubService,
  ) {}

  @Get('/publish/:channel/:message')
  publish(
    @Param('channel') channel: string,
    @Param('message') message: string,
  ): string {
    this.pubSubService.publish(channel, message);
    return `published message: ${message} to channel ${channel}`;
  }

  @Get('/subscribe/:channel')
  subscribe(@Param('channel') channel: string): string {
    this.pubSubService.subscribe(channel, (message) => {
      console.log(`Received message from channel ${channel}: ${message}`);
    });
    return `subscribed to channel ${channel}`;
  }
}

Unifyed Dynamic Logger (UnifyedLogger)

Dynamic logger should be used in all the unifyed products . This allows the logger to be configured at runtime and can be used to log messages with different log levels.

UnifyedLogger is exported as a provider and can be injected into the constructor of any class just like any other provider.

UnifyedLogger listener should also be registered in the main module as shown below. This will ensure that the logger changes are consumed by the logger listener.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UnifyedAuthCheckGuard } from './guards/auth.check.guard';
import { ConfigModule } from '@nestjs/config';
import { UnifyedLoggerListener } from 'unifyed-common-lib';

@Module({
  imports: [ConfigModule.forRoot()],
  controllers: [AppController],
  providers: [
    AppService,
    UnifyedLoggerListener
  ],
})
export class AppModule {}

Example usage of UnifyedLogger

import { Controller, Get, Param } from '@nestjs/common';
import { UnifyedLogger } from 'unifyed-common-lib';

@Controller()
@Public()
export class AppController {
  constructor(
    private readonly logger: UnifyedLogger
  ) {}

  @Get('/publish/:channel/:message')
  publish(
    @Param('channel') channel: string,
    @Param('message') message: string,
  ): string {
    this.logger.verbose(
      `Publishing message: ${message} to channel: ${channel}`,
      AppController.name,
    );
    this.logger.debug(
      `Publishing message: ${message} to channel: ${channel}`,
      AppController.name,
    );
    this.logger.log(
      `Publishing message: ${message} to channel: ${channel}`,
      AppController.name,
    );
    this.logger.warn(
      `Publishing message: ${message} to channel: ${channel}`,
      AppController.name,
    );
    this.logger.error(
      `Publishing message: ${message} to channel: ${channel}`,
      AppController.name,
    );
    return `published message: ${message} to channel ${channel}`;
  }

}

Multitenant Connection Middleware (MultiTenantConnectionMiddleware)

A middleware that injects the appropriate database connection for a multi-tenant application.

  • It retrieves the tenant identifier from the request hostname, fetches the tenant configuration from an API,
  • and then sets the appropriate database connection on the request object.

Example usage is shown below.

import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { UnifyedAuthCheckGuard } from 'unifyed-common-lib';
import { RedisPubSubService } from 'unifyed-common-lib';
import { UnifyedLogger } from 'unifyed-common-lib';
import { UnifyedLoggerListener } from 'unifyed-common-lib';
import { UnifyedTenantConnectionInjectMiddleware } from 'unifyed-common-lib';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRootAsync({
      useFactory: async () => ({
        uri: `mongodb://root:admin2008@localhost:27017/UNIFYEX_MASTER?authSource=admin&readPreference=primary&ssl=false&minPoolSize=50&maxPoolSize=500`
      })
    })
  ],
  controllers: [],
  providers: [
    RedisPubSubService,
    UnifyedLogger,
    UnifyedLoggerListener,
    {
      provide: APP_GUARD,
      useClass: UnifyedAuthCheckGuard
    }
  ]
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(UnifyedTenantConnectionInjectMiddleware).forRoutes('*');
  }
}

Multitenant Model Provider (UnifyedModelProvider)

Provides a factory function that creates a Mongoose model provider dynamically based on the given model name and schema.The provider is registered with the tenant connection and pagination is enabled on the model schema before returning the model.

Example usage is shown below.

import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { UnifyedTenantConnectionInjectMiddleware } from 'unifyed-common-lib';
import { MongooseModule } from '@nestjs/mongoose';
import { UnifyedModelProvider } from 'unifyed-common-lib';

@Module({
  imports: [
    MongooseModule.forRootAsync({
      useFactory: async () => ({
        uri: `mongodb://root:admin2008@localhost:27017/UNIFYEX_MASTER?authSource=admin&readPreference=primary&ssl=false&minPoolSize=50&maxPoolSize=500`
      })
    })
  ],
  controllers: [AppController],
  providers: [
    AppService,
    UnifyedModelProvider.forFeature(Test.name, TestSchema),
  ]
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(UnifyedTenantConnectionInjectMiddleware).forRoutes('*');
  }
}

Person Record (Unifyed Person Record)

Exposes a DTO which is used to store person record data.

/**
 * Represents a person record in the Unifyed system.
 *
 * @param userId - The unique identifier for the person.
 * @param firstName - The person's first name.
 * @param lastName - The person's last name.
 * @param phone - The person's phone number.
 * @param address - The person's address.
 * @param preferredName - The person's preferred name (optional).
 * @param preferredPronouns - The person's preferred pronouns (optional).
 * @param personalEmail - The person's personal email address (optional).
 * @param officialEmail - The person's official email address (optional).
 * @param dob - The person's date of birth (optional).
 * @param unifyedRoles - The person's Unifyed roles (optional).
 * @param identityRoles - The person's identity roles (optional).
 * @param additionalAttributes - Additional attributes for the person (optional).
 * @param backgroundInfo - Background information about the person (optional).
 * @param education - Information about the person's education (optional).
 *
 * @author Ranjith Madhavan
 * @since 11 June 2024
 */

export class UnifyedPersonRecord {
  constructor(
    public userId: string,
    public firstName?: string,
    public lastName?: string,
    public phone?: string,
    public address?: string,
    public preferredName?: string,
    public preferredPronouns?: string,
    public personalEmail?: string,
    public officialEmail?: string,
    public dob?: Date,
    public unifyedRoles?: string[],
    public identityRoles?: string[],
    public additionalAttributes?: Record<string, any>,
    public backgroundInfo?: {
      homeTownOrCity?: string;
      highSchool?: string;
    },
    public education?: {
      classOf?: string;
      housingStatus?: 'On Campus' | 'Off Campus' | 'None';
      pgOccupationConsiderations?: string[];
    }
  ) {}
}

Exception Filter (Unifyed Global Exception Filer)

Usage: In main.ts use this as global filter

async function bootstrap() {
  process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
  dotenv.config();
  const app = await NestFactory.create(AppModule, {
    logger:
      configuration().app.NODE_ENV === 'development'
        ? ['log', 'debug', 'error', 'verbose', 'warn']
        : ['error', 'warn', 'log'],
  });
  app.enableCors();
  app.useGlobalPipes(new ValidationPipe());
  app.setGlobalPrefix(configuration().app.apiGlobalPrefix);
  //app.useGlobalInterceptors(new CustomCacheInterceptor(app.get(Reflector)));
  app.useGlobalFilters(new UnifyedGlobalExceptionHandlerFilter());
  await setupSwagger(app);
  app.use(cookieParser());
  await app.listen(configuration().app.port);
  logger.log(
    `Server running on http://localhost:${configuration().app.port}/api`,
  );
}