UNPKG

bauth-js

Version:

A Node.js authentication library for API requests via remote authentication service using Bearer tokens. Compatible with Express and NestJS.

489 lines (362 loc) 9.8 kB
# bauth-js A Node.js authentication library for API requests via remote authentication service using Bearer tokens. Compatible with Express and NestJS. ## Features - 🔐 **Bearer Token Authentication** - Validate tokens against remote authentication service - 🚀 **Express Middleware** - Easy integration with Express.js applications - 🦅 **NestJS Guard** - Native support for NestJS applications - ⚡ **Lightweight** - Minimal dependencies, fast performance - 🔧 **Configurable** - Customizable token extraction and error handling - 📝 **TypeScript** - Full TypeScript support with type definitions ## Installation ```bash npm install bauth-js ``` ### CLI Tool The package includes a CLI tool for easy setup and configuration: ```bash # Install globally for CLI access npm install -g bauth-js # Or use npx npx bauth-js --help ``` ## Quick Start ### Basic Usage ```typescript import { BAuth } from 'bauth-js'; const auth = new BAuth({ endpoint: 'https://auth.example.com' }); // Authenticate with a token const result = await auth.authenticate('your-bearer-token'); if (result.valid) { console.log('User:', result.user); } else { console.log('Error:', result.error); } ``` ### Express.js Integration ```typescript import express from 'express'; import { bauth } from 'bauth-js'; const app = express(); // Apply authentication middleware app.use('/api', bauth({ endpoint: 'https://auth.example.com' })); // Protected route app.get('/api/profile', (req, res) => { // req.user contains the authenticated user data res.json({ user: req.user }); }); ``` ### NestJS Integration ```typescript import { Controller, Get, UseGuards } from '@nestjs/common'; import { BAuthGuard, CurrentUser } from 'bauth-js'; @Controller('api') @UseGuards(BAuthGuard, { endpoint: 'https://auth.example.com' }) export class ApiController { @Get('profile') getProfile(@CurrentUser() user: any) { return { user }; } } ``` ## API Reference ### BAuth Class The core authentication class for validating tokens and retrieving user information. #### Constructor ```typescript new BAuth(config: BAuthConfig) ``` **Config Options:** - `endpoint` (required): The base URL of your authentication service - `timeout` (optional): Request timeout in milliseconds (default: 10000) - `headers` (optional): Additional headers to send with requests #### Methods ##### `setToken(token: string): void` Set the Bearer token for authentication. ##### `getToken(): string | null` Get the current token. ##### `validate(): Promise<ValidationResponse>` Validate if the current token is valid by calling `/auth/validate` endpoint. ##### `user(): Promise<AuthResponse>` Get authenticated user information by calling `/users/me` endpoint. ##### `authenticate(token: string): Promise<AuthResponse>` Set token and get user info in one call. ##### `static withToken(token: string, config: BAuthConfig): BAuth` Create a new instance with a pre-set token. ### Express Middleware #### `bauth(config: BAuthConfig)` Basic middleware function for Express applications. ```typescript import { bauth } from 'bauth-js'; app.use('/api', bauth({ endpoint: 'https://auth.example.com' })); ``` #### `createBAuthMiddleware(options: BAuthExpressOptions)` Advanced middleware with additional options. ```typescript import { createBAuthMiddleware } from 'bauth-js'; const middleware = createBAuthMiddleware({ endpoint: 'https://auth.example.com', userProperty: 'authUser', // Custom property name onUnauthorized: (req, res, next) => { // Custom unauthorized handling res.status(401).json({ message: 'Access denied' }); }, tokenExtractor: (req) => { // Custom token extraction logic return req.headers['x-api-key']; } }); app.use('/api', middleware); ``` **Options:** - `endpoint` (required): Authentication service endpoint - `userProperty` (optional): Property name to attach user data (default: 'user') - `onUnauthorized` (optional): Custom unauthorized handler - `tokenExtractor` (optional): Custom function to extract token from request - `timeout` (optional): Request timeout - `headers` (optional): Additional headers ### NestJS Guard #### `BAuthGuard` Authentication guard for NestJS applications. ```typescript import { BAuthGuard } from 'bauth-js'; @UseGuards(BAuthGuard, { endpoint: 'https://auth.example.com' }) export class ProtectedController {} ``` #### `UseBAuth` Decorator Decorator to mark routes that require authentication. ```typescript import { UseBAuth } from 'bauth-js'; @Controller('api') export class ApiController { @Get('profile') @UseBAuth({ endpoint: 'https://auth.example.com' }) getProfile() { return { message: 'Protected route' }; } } ``` #### `CurrentUser` Decorator Decorator to inject the authenticated user. ```typescript import { CurrentUser } from 'bauth-js'; @Get('profile') getProfile(@CurrentUser() user: any) { return { user }; } ``` #### `createBAuthGuard(options: BAuthNestOptions)` Factory function to create a custom guard. ```typescript import { createBAuthGuard } from 'bauth-js'; const CustomAuthGuard = createBAuthGuard({ endpoint: 'https://auth.example.com', userProperty: 'authUser' }); @UseGuards(CustomAuthGuard) export class CustomController {} ``` ## Configuration ### Environment Variables Set your authentication service endpoint: ```bash BAUTH_ENDPOINT=https://auth.example.com ``` ### Configuration File Create a configuration file for your application: ```typescript // config/auth.ts export const authConfig = { endpoint: process.env.BAUTH_ENDPOINT || 'https://auth.example.com', timeout: 15000, headers: { 'User-Agent': 'MyApp/1.0' } }; ``` ## Error Handling The library provides comprehensive error handling: ```typescript try { const result = await auth.authenticate(token); if (result.valid) { // Handle successful authentication } else { // Handle authentication failure console.error(result.error); } } catch (error) { // Handle unexpected errors console.error('Authentication error:', error); } ``` ## Custom Token Extraction You can customize how tokens are extracted from requests: ```typescript // Extract from custom header const customExtractor = (req: Request) => { return req.headers['x-auth-token'] || null; }; // Extract from query parameter const queryExtractor = (req: Request) => { return req.query.token as string || null; }; // Extract from cookie const cookieExtractor = (req: Request) => { return req.cookies.authToken || null; }; ``` ## Examples ### Express.js Application ```typescript import express from 'express'; import { createBAuthMiddleware } from 'bauth-js'; const app = express(); // Global authentication middleware app.use('/api', createBAuthMiddleware({ endpoint: 'https://auth.example.com', onUnauthorized: (req, res) => { res.status(401).json({ error: 'Authentication required', code: 'AUTH_REQUIRED' }); } })); // Protected routes app.get('/api/profile', (req, res) => { res.json({ message: 'Profile data', user: req.user }); }); app.get('/api/settings', (req, res) => { res.json({ message: 'User settings', user: req.user }); }); app.listen(3000, () => { console.log('Server running on port 3000'); }); ``` ### NestJS Application ```typescript import { Module } from '@nestjs/common'; import { APP_GUARD } from '@nestjs/core'; import { BAuthGuard } from 'bauth-js'; @Module({ providers: [ { provide: APP_GUARD, useClass: BAuthGuard, }, ], }) export class AuthModule {} // Controller with authentication @Controller('api') @UseGuards(BAuthGuard, { endpoint: 'https://auth.example.com' }) export class ApiController { @Get('profile') getProfile(@CurrentUser() user: any) { return { user }; } @Post('update') updateProfile(@CurrentUser() user: any, @Body() data: any) { return { message: 'Profile updated', user, data }; } } ``` ### Standalone Usage ```typescript import { BAuth } from 'bauth-js'; class AuthService { private auth: BAuth; constructor() { this.auth = new BAuth({ endpoint: 'https://auth.example.com', timeout: 15000 }); } async validateUser(token: string) { const result = await this.auth.authenticate(token); if (result.valid) { return { success: true, user: result.user }; } else { return { success: false, error: result.error }; } } async refreshUser(token: string) { this.auth.setToken(token); return this.auth.user(); } } ``` ## CLI Commands The `bauth-js` CLI tool provides several commands to help you get started: ### Test Authentication Endpoint ```bash bauth-js test -e https://auth.example.com bauth-js test -e https://auth.example.com -t your-bearer-token ``` ### Generate Configuration Files ```bash # Express.js middleware configuration bauth-js generate:express -e https://auth.example.com # NestJS guard configuration bauth-js generate:nest -e https://auth.example.com # Environment configuration bauth-js generate:env -e https://auth.example.com # Package.json scripts bauth-js generate:scripts ``` ### Interactive Setup ```bash bauth-js setup ``` ## Testing Run the test suite: ```bash npm test ``` Run tests in watch mode: ```bash npm run test:watch ``` ## Building Build the library: ```bash npm run build ``` Development build with watch mode: ```bash npm run dev ``` ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests for new functionality 5. Ensure all tests pass 6. Submit a pull request ## License MIT License - see LICENSE file for details. ## Support For support and questions, please open an issue on GitHub.