No description
|
Some checks failed
Build and Publish / build-and-publish (push) Failing after 56s
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| .githooks | ||
| src | ||
| .gitignore | ||
| eslint.config.js | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
@lilith/nestjs-auth
NestJS shared authentication utilities with JWT support, guards, and decorators.
Features
- JWT Guard: Passport-based JWT authentication guard
- Public Decorator: Mark routes as publicly accessible
- CurrentUser Decorator: Extract authenticated user from request
- Module Configuration: Flexible JWT configuration options
Installation
pnpm add @lilith/nestjs-auth
Peer Dependencies
pnpm add @nestjs/common @nestjs/core @nestjs/jwt @nestjs/passport passport passport-jwt
Quick Start
import { Module } from '@nestjs/common';
import { AuthModule } from '@lilith/nestjs-auth';
@Module({
imports: [
AuthModule.register({
jwtSecret: process.env.JWT_SECRET,
jwtExpiresIn: '1h',
}),
],
})
export class AppModule {}
Configuration
Sync Configuration
AuthModule.register({
jwtSecret: 'your-secret-key',
jwtExpiresIn: '1h',
jwtIssuer: 'my-app',
});
Async Configuration
AuthModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
jwtSecret: config.get('JWT_SECRET'),
jwtExpiresIn: config.get('JWT_EXPIRES_IN'),
}),
});
Decorators
@Public()
Mark a route as publicly accessible (bypasses JWT guard):
import { Controller, Get } from '@nestjs/common';
import { Public } from '@lilith/nestjs-auth';
@Controller('api')
export class ApiController {
@Get('public')
@Public()
publicEndpoint() {
return { message: 'This is public' };
}
@Get('protected')
protectedEndpoint() {
return { message: 'This requires authentication' };
}
}
@CurrentUser()
Extract the authenticated user from the request:
import { Controller, Get } from '@nestjs/common';
import { CurrentUser, AuthenticatedUser } from '@lilith/nestjs-auth';
@Controller('api')
export class ApiController {
@Get('profile')
getProfile(@CurrentUser() user: AuthenticatedUser) {
return {
id: user.sub,
email: user.email,
};
}
// Get specific property
@Get('user-id')
getUserId(@CurrentUser('sub') userId: string) {
return { userId };
}
}
Guards
JwtAuthGuard
Apply JWT authentication to routes or controllers:
import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from '@lilith/nestjs-auth';
@Controller('api')
@UseGuards(JwtAuthGuard)
export class ApiController {
@Get('data')
getData() {
return { data: 'protected' };
}
}
Global Guard
Apply JWT authentication globally:
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { JwtAuthGuard, AuthModule } from '@lilith/nestjs-auth';
@Module({
imports: [AuthModule.register({ ... })],
providers: [
{
provide: APP_GUARD,
useClass: JwtAuthGuard,
},
],
})
export class AppModule {}
With global guard, use @Public() to opt-out specific routes.
Types
AuthenticatedUser
interface AuthenticatedUser {
sub: string; // Subject (user ID)
email?: string; // User email
roles?: string[]; // User roles
[key: string]: unknown; // Additional claims
}
AuthModuleOptions
interface AuthModuleOptions {
jwtSecret: string;
jwtExpiresIn?: string; // e.g., '1h', '7d'
jwtIssuer?: string;
jwtAudience?: string;
}
Exports
// Decorators
export { Public, IS_PUBLIC_KEY } from './decorators/public.decorator';
export { CurrentUser, type AuthenticatedUser } from './decorators/current-user.decorator';
// Guards
export { JwtAuthGuard } from './guards/jwt-auth.guard';
// Module
export { AuthModule, type AuthModuleOptions, type AuthModuleAsyncOptions } from './auth.module';
License
MIT