@catalystlabs/firebase-ecosystem
v0.1.0
Published
A comprehensive authentication and service ecosystem built on Firebase with exceptional developer experience
Maintainers
Readme
Firebase Auth Ecosystem
A comprehensive authentication and service ecosystem built on Firebase, designed to provide exceptional developer experience with powerful features out of the box.
Overview
This ecosystem consists of four interconnected libraries that work seamlessly together:
- 🔐 Auth Library - Complete authentication solution with Firebase
- 📧 Email Library - Simple yet powerful email service
- 🔔 Notifications Library - Multi-channel notification system
- 📝 Audit Logging Library - Comprehensive activity tracking
Why Use This Ecosystem?
The Problem
Building authentication, email, notifications, and audit logging from scratch is time-consuming and error-prone. Existing solutions often require complex configurations, lack integration, or don't provide the developer experience modern applications demand.
The Solution
This ecosystem provides:
- One-line operations for complex tasks
- Seamless integration between all libraries
- Type-safe throughout with full TypeScript support
- Exceptional DX with intuitive APIs
- Production-ready with security best practices
- Highly customizable while maintaining simplicity
Quick Start
1. Automated Setup (Recommended)
Use our CLI tool to set up your project with all necessary files and configurations:
# Run the setup wizard
npx @catalystlabs/firebase-ecosystem fb-eco-setup
# This will create:
# - .env.local with all required environment variables
# - Firebase configuration files (firebase.json, firestore.rules, etc.)
# - middleware.ts for Next.js auth protection
# - Example components showing usage2. Install the Package
# Using bun (recommended)
bun add @catalystlabs/firebase-ecosystem
# Using npm
npm install @catalystlabs/firebase-ecosystem
# Using yarn
yarn add @catalystlabs/firebase-ecosystem3. Configure Environment Variables
Fill in your Firebase configuration in .env.local:
# Firebase Configuration (from Firebase Console)
NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-auth-domain
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-storage-bucket
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your-sender-id
NEXT_PUBLIC_FIREBASE_APP_ID=your-app-id
# Firebase Admin SDK (for server-side operations)
FIREBASE_ADMIN_PROJECT_ID=your-project-id
FIREBASE_ADMIN_CLIENT_EMAIL=your-service-account-email
FIREBASE_ADMIN_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
# Optional: Email Provider
EMAIL_PROVIDER=resend
RESEND_API_KEY=your-resend-api-key
# Optional: Audit Logging with ClickHouse
AUDIT_STORAGE=clickhouse
CLICKHOUSE_HOST=http://localhost:8123
CLICKHOUSE_DATABASE=audit_logs4. Optional: Database Setup
If using ClickHouse for audit logging:
# Generate ClickHouse setup script
npx @catalystlabs/firebase-ecosystem fb-eco-setup init-clickhouse
# Apply the generated SQL script
clickhouse-client < clickhouse-setup.sql5. Create Initial Admin User
# Generate admin creation script
npx @catalystlabs/firebase-ecosystem fb-eco-setup create-admin
# Run the script with your admin credentials
node scripts/create-admin.js [email protected] SecurePassword123!Library Overview
🔐 Auth Library
Complete authentication solution with user management, invitations, roles, and permissions.
// One-line user invitation with role
await auth.inviteUser({
email: '[email protected]',
role: 'editor',
department: 'marketing',
sendEmail: true
});
// Simple permission checks
if (user.hasRole('admin')) {
// Admin-only code
}📧 Email Library
Dead-simple email sending with templates, batch operations, and automatic footer injection.
// Send a templated email
await email.send({
to: '[email protected]',
template: 'welcome',
data: { name: 'John' }
});
// Batch emails with personalization
await email.sendBatch({
template: 'newsletter',
recipients: subscribers.map(sub => ({
to: sub.email,
data: { name: sub.name }
}))
});🔔 Notifications Library
Multi-channel notifications with toast, bell, push, and email support.
// Show a notification with progress
notifications.show({
title: 'Upload in progress',
progress: { value: 45, label: 'Uploading...' },
avatar: { src: user.photoURL }
});
// Update notification dynamically
notifications.update(id, {
progress: { value: 100 },
status: { type: 'completed' }
});Full Notifications Documentation →
📝 Audit Logging Library
Track all user actions with automatic context capture and powerful querying.
// Log an action
await audit.log({
action: 'document.update',
resource: 'documents/123',
metadata: { changes: diff }
});
// Query audit logs
const logs = await audit.query({
actor: userId,
action: 'document.*',
timeRange: { start: lastWeek }
});Integration Example
Here's how all libraries work together:
// User accepts an invitation
const { user } = await auth.acceptInvitation(token);
// Send welcome email
await email.send({
to: user.email,
template: 'welcome',
data: { name: user.displayName }
});
// Show success notification
notifications.show({
title: 'Welcome aboard!',
message: 'Your account has been created',
type: 'success'
});
// Log the event
await audit.log({
action: 'user.invitation.accepted',
actor: user.uid,
metadata: { invitationId: token }
});Roles, Permissions & User Metadata
Understanding the Auth System
The auth library uses Firebase Custom Claims to manage roles, permissions, and user metadata. This provides a secure, token-based authorization system.
User Structure
interface User {
// Firebase Auth fields
uid: string;
email: string;
displayName?: string;
photoURL?: string;
// Custom claims (stored in JWT token)
role?: 'admin' | 'editor' | 'viewer' | string;
permissions?: string[];
department?: string;
// Additional metadata (stored in Firestore)
metadata?: {
firstName?: string;
lastName?: string;
phoneNumber?: string;
address?: string;
preferences?: Record<string, any>;
onboardingCompleted?: boolean;
[key: string]: any;
};
}Setting Up Roles and Permissions
1. Define Your Role Hierarchy
// lib/auth/config/roles.ts
export const ROLES = {
ADMIN: 'admin',
MANAGER: 'manager',
EDITOR: 'editor',
VIEWER: 'viewer',
} as const;
export const ROLE_PERMISSIONS = {
[ROLES.ADMIN]: [
'users.*', // All user operations
'content.*', // All content operations
'settings.*', // All settings
'audit.read', // View audit logs
],
[ROLES.MANAGER]: [
'users.read',
'users.update',
'content.*',
'invites.create',
],
[ROLES.EDITOR]: [
'content.create',
'content.update',
'content.read',
],
[ROLES.VIEWER]: [
'content.read',
],
};2. Assign Roles During User Creation
// When inviting a user
await auth.inviteUser({
email: '[email protected]',
role: 'editor',
department: 'marketing',
permissions: ['content.create', 'content.update'],
metadata: {
firstName: 'Jane',
lastName: 'Doe',
managerId: currentUser.uid,
}
});
// When creating user programmatically (server-side)
const user = await admin.auth().createUser({
email: '[email protected]',
password: 'temporaryPassword',
});
await admin.auth().setCustomUserClaims(user.uid, {
role: 'manager',
department: 'sales',
permissions: ROLE_PERMISSIONS.manager,
});3. Check Permissions in Your App
// Using hooks
const { user, hasRole, hasPermission } = useAuth();
// Check single role
if (hasRole('admin')) {
// Show admin UI
}
// Check multiple roles
if (hasRole(['admin', 'manager'])) {
// Show management UI
}
// Check specific permission
if (hasPermission('users.create')) {
// Show create user button
}
// Using components
<RequireRole role="admin">
<AdminDashboard />
</RequireRole>
<RequirePermission permission="content.edit">
<EditButton />
</RequirePermission>Managing User Metadata
1. Update User Profile
// Update custom claims (server-side only)
await admin.auth().setCustomUserClaims(uid, {
role: 'manager',
department: 'engineering',
});
// Update Firestore metadata (client or server)
await updateUserMetadata(user.uid, {
firstName: 'John',
lastName: 'Smith',
preferences: {
theme: 'dark',
notifications: true,
},
onboardingCompleted: true,
});2. Extend User Metadata
// Define your app-specific metadata
interface AppUserMetadata {
// Profile
firstName: string;
lastName: string;
phoneNumber?: string;
// Organization
teamId?: string;
managerId?: string;
officeLocation?: string;
// Preferences
preferences: {
theme: 'light' | 'dark';
language: string;
timezone: string;
emailNotifications: boolean;
};
// App-specific
onboardingStep?: number;
lastActiveProject?: string;
subscription?: {
plan: 'free' | 'pro' | 'enterprise';
validUntil: Date;
};
}
// Use with type safety
const { user } = useAuth<AppUserMetadata>();
console.log(user.metadata?.subscription?.plan);Security Rules for Roles
The setup script creates Firestore rules that respect roles:
// firestore.rules
function hasRole(role) {
return request.auth.token.role == role;
}
function hasPermission(permission) {
return permission in request.auth.token.permissions;
}
// Only admins can read all users
match /users/{userId} {
allow read: if request.auth.uid == userId || hasRole('admin');
allow write: if request.auth.uid == userId || hasPermission('users.update');
}Best Practices
- Use Custom Claims Sparingly: Limited to 1000 bytes total
- Store Large Data in Firestore: Use metadata for extensive user data
- Cache Permissions: The auth library caches claims automatically
- Validate Server-Side: Always verify permissions on the server
- Audit Changes: All permission changes are automatically logged
Architecture
firebase-auth-ecosystem/
├── lib/
│ ├── auth/ # Authentication library
│ ├── email/ # Email service library
│ ├── notifications/ # Notification system
│ └── audit/ # Audit logging library
├── app/ # Next.js application
├── components/ # Shared UI components
└── docs/ # DocumentationFeatures
🔐 Authentication
- User registration and login
- Social authentication providers
- Magic link authentication
- User invitations with pre-assigned roles
- Role-based access control (RBAC)
- Department-based permissions
- Custom claims and permissions
- Session management
- Account linking
- Multiple email providers (Resend, SendGrid, SES)
- Template management with variables
- Batch sending with personalization
- Automatic footer injection (HIPAA, unsubscribe)
- Email scheduling
- Delivery tracking
- Error handling and retries
🔔 Notifications
- Toast notifications
- Notification center (bell icon)
- Push notifications
- Email notifications
- Real-time updates
- Progress indicators
- Status tracking
- Custom avatars and badges
- Action buttons
📝 Audit Logging
- Automatic action tracking
- Actor identification
- Resource tracking
- Metadata storage
- Time-based queries
- Action pattern matching
- Compliance reporting
- Data retention policies
Security
- Authentication: Firebase Authentication with custom claims
- Authorization: Role-based and permission-based access control
- Data Protection: Automatic PII redaction in logs
- Compliance: HIPAA-compliant email footers and audit trails
- Best Practices: Security headers, CSRF protection, rate limiting
Performance
- Tree-shaking: Import only what you need
- Lazy Loading: Components load on demand
- Caching: Smart caching for user data and permissions
- Batch Operations: Efficient bulk operations
- Real-time: WebSocket connections for live updates
Development Scripts
Build and dev scripts
bun dev– start dev serverbun build– bundle application for productionbun analyze– analyzes application bundle
Testing scripts
bun typecheck– checks TypeScript typesbun lint– runs ESLintbun test– runs all tests
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
MIT License - see LICENSE for details.
Support
Built with ❤️ using Next.js, Firebase, and Mantine UI
