@diagramers/api
Version:
Diagramers API - A comprehensive Node.js API template with TypeScript, Firebase Functions, and Socket.io
165 lines (137 loc) • 5.54 kB
text/typescript
import { BasePlugin, PluginMetadata, PluginConfig, PluginContext, PluginHealth, PluginMetrics } from '../../plugins/base/plugin';
import { BaseAuthProvider } from './providers/base-auth-provider';
import { InternalAuthProvider } from './providers/internal-auth-provider';
import { FirebaseAuthProvider } from './providers/firebase-auth-provider';
import { OAuthProvider } from './providers/oauth-provider';
import { SMSAuthProvider } from './providers/sms-auth-provider';
import { EmailAuthProvider } from './providers/email-auth-provider';
import { AuthConfig } from '../../core/config/interfaces';
export class AuthModule extends BasePlugin {
private providers: Map<string, BaseAuthProvider> = new Map();
private activeProvider: string = 'internal';
constructor(config: PluginConfig, context: PluginContext) {
const metadata: PluginMetadata = {
name: 'auth',
version: '1.0.0',
description: 'Multi-provider authentication module',
author: 'Diagramers Team'
};
super(metadata, config, context);
}
async initialize(): Promise<void> {
const authConfig = this.context.config.auth as AuthConfig;
// Initialize internal auth provider
if (authConfig.providers.internal) {
const internalProvider = new InternalAuthProvider(authConfig);
this.providers.set('internal', internalProvider);
}
// Initialize Firebase auth provider
if (authConfig.providers.firebase.enabled) {
const firebaseProvider = new FirebaseAuthProvider(authConfig.providers.firebase);
this.providers.set('firebase', firebaseProvider);
}
// Initialize OAuth providers
if (authConfig.providers.oauth.enabled) {
for (const [providerName, providerConfig] of Object.entries(authConfig.providers.oauth.providers)) {
if ((providerConfig as any).enabled) {
const oauthProvider = new OAuthProvider(providerName, providerConfig);
this.providers.set(providerName, oauthProvider);
}
}
}
// Initialize SMS auth provider
if (authConfig.providers.sms.enabled) {
const smsProvider = new SMSAuthProvider(authConfig.providers.sms);
this.providers.set('sms', smsProvider);
}
// Initialize Email auth provider
if (authConfig.providers.email.enabled) {
const emailProvider = new EmailAuthProvider(authConfig.providers.email);
this.providers.set('email', emailProvider);
}
this.context.logger.info(`[AuthModule] Initialized ${this.providers.size} auth providers`);
}
async start(): Promise<void> {
// Start all providers
for (const [name, provider] of this.providers) {
await provider.initialize();
this.context.logger.info(`[AuthModule] Started auth provider: ${name}`);
}
}
async stop(): Promise<void> {
// Stop all providers
for (const [name, provider] of this.providers) {
await provider.cleanup();
this.context.logger.info(`[AuthModule] Stopped auth provider: ${name}`);
}
}
async getHealth(): Promise<PluginHealth> {
const providerHealth = {};
let overallStatus: 'healthy' | 'unhealthy' | 'degraded' = 'healthy';
for (const [name, provider] of this.providers) {
try {
const health = await provider.getHealth();
providerHealth[name] = health;
if (health.status === 'unhealthy') {
overallStatus = 'unhealthy';
} else if (health.status === 'degraded' && overallStatus !== 'unhealthy') {
overallStatus = 'degraded';
}
} catch (error) {
providerHealth[name] = { status: 'unhealthy', error: error.message };
overallStatus = 'unhealthy';
}
}
return {
status: overallStatus,
details: { providers: providerHealth },
timestamp: new Date()
};
}
async getMetrics(): Promise<PluginMetrics> {
const metrics = {
totalProviders: this.providers.size,
activeProviders: 0,
totalAuthentications: 0
};
for (const provider of this.providers.values()) {
const providerMetrics = await provider.getMetrics();
metrics.activeProviders += providerMetrics.isActive ? 1 : 0;
metrics.totalAuthentications += providerMetrics.totalAuthentications || 0;
}
return {
name: this.metadata.name,
metrics,
timestamp: new Date()
};
}
// Auth module specific methods
getProvider(name: string): BaseAuthProvider | undefined {
return this.providers.get(name);
}
getActiveProvider(): BaseAuthProvider | undefined {
return this.providers.get(this.activeProvider);
}
setActiveProvider(name: string): void {
if (this.providers.has(name)) {
this.activeProvider = name;
this.context.logger.info(`[AuthModule] Active provider changed to: ${name}`);
} else {
throw new Error(`Auth provider not found: ${name}`);
}
}
async authenticate(credentials: any, provider?: string): Promise<any> {
const authProvider = provider ? this.getProvider(provider) : this.getActiveProvider();
if (!authProvider) {
throw new Error('No authentication provider available');
}
return await authProvider.authenticate(credentials);
}
async validateToken(token: string, provider?: string): Promise<any> {
const authProvider = provider ? this.getProvider(provider) : this.getActiveProvider();
if (!authProvider) {
throw new Error('No authentication provider available');
}
return await authProvider.validateToken(token);
}
}