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
Markdown
# 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.