@advantev/multiauth
v1.2.0
Published
Multi-provider authentication package for NestJS with Firebase, Auth0, Cognito support
Readme
NestJS Auth Provider
A flexible, multi-provider authentication package for NestJS applications. Currently supports Firebase Authentication with plans to add Auth0, AWS Cognito, and Okta.
Features
- 🔥 Firebase Authentication support
- 🎯 Type-safe with TypeScript
- 🔌 Easy to extend with new providers
- 🛡️ Built-in guards and decorators
- 📦 Minimal dependencies
- ✅ Fully tested
Installation
npm install @advantev/multiauth firebase-adminQuick Start
1. Configure in your module
import { Module } from '@nestjs/common';
import { AuthProviderModule, AuthProviderType } from '@advantev/multiauth';
@Module({
imports: [
AuthProviderModule.forRoot({
provider: AuthProviderType.FIREBASE,
config: {
serviceAccount: {
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
},
databaseURL: process.env.FIREBASE_DATABASE_URL,
},
}),
],
})
export class AppModule {}2. Use in your service
import { Injectable } from '@nestjs/common';
import { InjectAuthProvider, IAuthProvider } from '@advantev/multiauth';
@Injectable()
export class AuthService {
constructor(
@InjectAuthProvider()
private readonly authProvider: IAuthProvider,
) {}
async registerUser(email: string, password: string) {
const user = await this.authProvider.signUp(email, password, {
sendVerificationEmail: true,
});
// Your database operations
await this.saveUserToDatabase(user);
return user;
}
async loginUser(email: string, password: string) {
const session = await this.authProvider.signIn(email, password);
// Your database operations
await this.updateLastLogin(session.user.uid);
return session;
}
async changeUserPassword(userId: string, newPassword: string) {
const success = await this.authProvider.updatePassword(userId, newPassword);
if (success) {
// Optionally revoke refresh tokens for security
await this.authProvider.revokeRefreshTokens(userId);
// Your database operations
await this.logPasswordChange(userId);
}
return success;
}
private async saveUserToDatabase(user: any) {
// Your DB logic here
}
private async updateLastLogin(userId: string) {
// Your DB logic here
}
private async logPasswordChange(userId: string) {
// Your DB logic here
}
}3. Protect routes with guard
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@advantev/multiauth';
@Controller('profile')
@UseGuards(AuthGuard)
export class ProfileController {
@Get()
getProfile() {
return { message: 'Protected route' };
}
}API Reference
IAuthProvider Interface
All methods available:
signUp(email, password, options?)- Register new usersignIn(email, password, options?)- Authenticate usersignOut(userId)- Sign out userverifyToken(token, options?)- Verify JWT tokenrefreshToken(refreshToken)- Refresh expired tokengetUserById(userId)- Get user by IDgetUserByEmail(email)- Get user by emailgetUserByPhoneNumber(phoneNumber)- Get user by phone numberupdateUser(userId, updates)- Update user profileupdatePassword(userId, newPassword)- Update user password (Firebase only)deleteUser(userId)- Delete user accountsendPasswordResetEmail(email, options?)- Send password resetsendEmailVerification(userId)- Send email verificationsetCustomClaims(userId, claims)- Set custom claimsrevokeRefreshTokens(userId)- Revoke all refresh tokens
Password Management
Update Password (Firebase only)
Update a user's password directly using their user ID:
async updatePassword(userId: string, newPassword: string): Promise<boolean>Example:
// In your controller or service
const success = await this.authProvider.updatePassword('user-id-123', 'newSecurePass123');
if (success) {
console.log('Password updated successfully');
// For security, revoke all refresh tokens
await this.authProvider.revokeRefreshTokens('user-id-123');
} else {
console.log('User not found');
}Returns:
true- Password updated successfullyfalse- User not found
Throws:
AuthException- If operation fails for reasons other than user not found
Security Best Practices:
- Always validate the new password meets your security requirements before calling this method
- Consider requiring re-authentication before allowing password changes
- Revoke refresh tokens after password update to force re-login
- Log password changes for audit purposes
- Consider sending a notification email to the user
Note: This method is currently only available for Firebase provider. Other providers (Auth0, Cognito, etc.) may handle password updates differently through their respective SDKs.
Environment Variables
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=your-client-email
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
FIREBASE_DATABASE_URL=https://your-project.firebaseio.comError Handling
The package provides standardized exceptions:
import {
AuthException,
InvalidCredentialsException,
UserNotFoundException,
TokenExpiredException
} from '@advantev/multiauth';
try {
await this.authProvider.signIn(email, password);
} catch (error) {
if (error instanceof InvalidCredentialsException) {
// Handle invalid credentials
}
}Async Configuration
For dynamic configuration:
AuthProviderModule.forRootAsync({
useFactory: async (configService: ConfigService) => ({
provider: AuthProviderType.FIREBASE,
config: {
serviceAccount: {
projectId: configService.get('FIREBASE_PROJECT_ID'),
clientEmail: configService.get('FIREBASE_CLIENT_EMAIL'),
privateKey: configService.get('FIREBASE_PRIVATE_KEY'),
},
},
}),
inject: [ConfigService],
})Testing
# Unit tests
npm test
# Integration tests
npm run test:integration
# Coverage
npm run test:covRoadmap
- [x] Firebase Authentication
- [x] Password update functionality
- [ ] Auth0 Integration
- [ ] AWS Cognito Integration
- [ ] Okta Integration
- [ ] Social OAuth providers
- [ ] Multi-factor authentication
- [ ] Rate limiting
- [ ] Session management
License
MIT
