A reusable **authentication and authorization** package for NestJS applications with isolated database support. This package provides a complete auth system with its own dedicated database connection, allowing you to reuse authentication across multiple a
npm install @evara-group/guardUserRole)
AuthGuard for route protection
RolesGuard for role-based authorization
@Roles() decorator for easy role checking
@AuthUser() decorator for easy access to authenticated user
bash
npm install @evara-group/guard
or
pnpm add @evara-group/guard
or
yarn add @evara-group/guard
`
---
šļø Architecture
This package uses a named TypeORM connection (AUTH_DATABASE_CONNECTION) to ensure complete isolation from your application's database. This means:
- ā
Your app can have its own database connection
- ā
The auth package uses a separate, dedicated database for users
- ā
No conflicts between connections
- ā
Easy to reuse across multiple applications
$3
The package follows the same architecture pattern as dms-new-backend-nestjs:
1. AuthorizationGuardModule - Unified entry point that:
- Configures TypeORM connection for the auth database (named connection)
- Loads UserModule (simple module for user management)
- Loads AuthModule (simple module for authentication)
2. UserModule - Simple module that:
- Uses TypeOrmModule.forFeature([User], AUTH_DATABASE_CONNECTION)
- Provides UserService for CRUD operations
- Exports UserService and TypeOrmModule
3. AuthModule - Simple module that:
- Imports UserModule directly
- Configures JWT using JwtModule.registerAsync() with ConfigService
- Provides AuthService and JwtStrategy
- Exports AuthService
This architecture ensures:
- ā
Clear separation of concerns
- ā
Proper dependency resolution
- ā
Simple, maintainable code structure
- ā
Follows NestJS best practices
---
š Usage
$3
In your app.module.ts:
`typescript
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { TypeOrmModule } from "@nestjs/typeorm";
import { AuthorizationGuardModule } from "@evara-group/guard";
@Module({
imports: [
// Global configuration
ConfigModule.forRoot({
isGlobal: true,
envFilePath: [".env"],
}),
// Your application database connection (for business entities)
TypeOrmModule.forRootAsync({
// Your app database configuration
// ...
}),
// Authorization Guard Module - Unified module that configures auth database and loads UserModule & AuthModule
AuthorizationGuardModule.forRoot({
database: {
name: process.env.AUTH_DATABASE_NAME || "auth_db",
host: process.env.AUTH_DATABASE_HOST || "localhost",
port: Number(process.env.AUTH_DATABASE_PORT || "5432"),
user: process.env.AUTH_DATABASE_USER || "postgres",
password: process.env.AUTH_DATABASE_PASSWORD || "postgres",
ssl: process.env.AUTH_DATABASE_SSL === "true" || false,
},
jwtSecret: process.env.JWT_SECRET || "your-secret-key",
expiresIn: "7d", // Optional, defaults to '7d'
}),
// Your other modules...
],
})
export class AppModule {}
`
$3
Create a .env file:
`env
Auth Database Configuration
AUTH_DATABASE_NAME=auth_db
AUTH_DATABASE_HOST=localhost
AUTH_DATABASE_PORT=5432
AUTH_DATABASE_USER=postgres
AUTH_DATABASE_PASSWORD=postgres
AUTH_DATABASE_SSL=false
JWT Configuration
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
`
$3
`typescript
import { Controller, Get } from "@nestjs/common";
import { AuthGuard, RolesGuard, Roles, AuthUser } from "@evara-group/guard";
import { UseGuards } from "@nestjs/common";
import { UserDTO } from "@evara-group/guard";
@Controller("protected")
@UseGuards(AuthGuard, RolesGuard)
export class ProtectedController {
@Get("profile")
@Roles("user", "admin") // Allow both user and admin roles
getProfile(@AuthUser() user: UserDTO) {
return {
message: Hello ${user.email},
user: user,
};
}
@Get("admin-only")
@Roles("admin") // Only admin can access
adminOnly() {
return { message: "Admin area" };
}
}
`
$3
`typescript
import { Injectable } from "@nestjs/common";
import { AuthService } from "@evara-group/guard";
@Injectable()
export class MyService {
constructor(private readonly authService: AuthService) {}
async login(email: string, password: string) {
return this.authService.login({ email, password });
}
}
`
$3
`typescript
import { Injectable } from "@nestjs/common";
import { UserService } from "@evara-group/guard";
@Injectable()
export class MyService {
constructor(private readonly userService: UserService) {}
async getUserById(id: number) {
return this.userService.findById(id);
}
async createUser(userData: CreateUserDTO) {
return this.userService.save(userData);
}
}
`
---
š Database Setup
$3
The package requires a separate PostgreSQL database for authentication. Create it:
`sql
CREATE DATABASE auth_db;
`
$3
The package uses TypeORM entities. You'll need to:
1. Option 1: Use TypeORM migrations (recommended)
- Generate migration from the User entity
- Run migrations on your auth database
2. Option 2: Use synchronize (development only)
- Modify AuthorizationGuardModule.forRoot() to set synchronize: true in the TypeORM config (NOT recommended for production)
$3
The package includes a User entity with the following fields:
- id - Primary key
- email - Unique email address
- password - Hashed password
- username - Optional username
- activated - Account activation status
- imageUrl - Optional profile image URL
- role - User role (enum: UserRole)
- resetPasswordRequest - Password reset flag
- createdAt, updatedAt, deletedAt - Timestamps
- createdBy, updatedBy, deletedBy - Audit fields
---
šÆ API Reference
$3
#### AuthorizationGuardModule.forRoot(options: GuardModuleOptions)
Unified module that configures the TypeORM connection for the auth database and loads both UserModule and AuthModule. This is the recommended way to use the package.
Options:
- database - Database configuration object
- name - Database name
- host - Database host
- port - Database port (number)
- user - Database user
- password - Database password
- ssl - Enable SSL (optional, boolean)
- jwtSecret - JWT secret key (required)
- expiresIn - Token expiration time (optional, default: '7d')
Architecture:
The module follows the same pattern as dms-new-backend-nestjs:
1. Configures TypeORM connection first (with named connection AUTH_DATABASE_CONNECTION)
2. Loads UserModule (simple module that uses the configured TypeORM connection)
3. Loads AuthModule (simple module that imports UserModule and configures JWT)
This ensures proper dependency resolution and follows NestJS best practices.
$3
#### AuthGuard
Protects routes requiring authentication. Validates JWT tokens.
#### RolesGuard
Checks user roles against route requirements. Must be used with @Roles() decorator.
$3
#### @Roles(...roles: string[])
Specifies which roles can access a route.
#### @AuthUser()
Extracts the authenticated user from the request.
$3
#### AuthService
- login(dto: AuthLoginDTO) - Authenticate user and return JWT token
- validateUser(payload: JwtPayload) - Validate user from JWT payload
#### UserService
- findById(id: number) - Find user by ID
- findByFields(options) - Find user by custom criteria
- save(userDTO, creator?, updatePassword?) - Create or update user
- update(userDTO, updater?) - Update user
- delete(userDTO) - Delete user
- findAndCount(options) - Find users with pagination
---
š Multiple Applications Setup
This package is designed to be reused across multiple applications. Each application can:
1. Share the same auth database - All apps authenticate against the same user database
2. Have separate application databases - Each app has its own business data
Example setup:
`
Application A (E-commerce)
āāā Auth Database (shared) ā Users from @evara-group/guard
āāā App Database A ā Products, Orders, etc.
Application B (CMS)
āāā Auth Database (shared) ā Users from @evara-group/guard
āāā App Database B ā Articles, Pages, etc.
`
Both applications use the same AuthorizationGuardModule.forRoot() configuration pointing to the same auth database, but each has its own application database.
---
š ļø Development
$3
`bash
pnpm build
`
$3
`bash
pnpm test
`
---
š Notes
- The package uses a named TypeORM connection (AUTH_DATABASE_CONNECTION) to avoid conflicts
- Never set synchronize: true` in production