codalware-auth
Version:
Complete authentication system with enterprise security, attack protection, team workspaces, waitlist, billing, UI components, 2FA, and account recovery - production-ready in 5 minutes. Enhanced CLI with verification, rollback, and App Router scaffolding.
92 lines (71 loc) • 3.05 kB
text/typescript
// Security service that uses adapter pattern - works with any ORM
import type { Adapter } from '../adapters/types';
type CreateSecuritySettingsInput = Parameters<NonNullable<Adapter['createSecuritySettings']>>[0];
type UpdateSecuritySettingsInput = Parameters<NonNullable<Adapter['updateSecuritySettings']>>[1];
type RecordLoginAttemptInput = Parameters<NonNullable<Adapter['recordLoginAttempt']>>[0];
export class SecurityService {
constructor(private adapter: Adapter) {
if (!adapter.getSecuritySettings) {
throw new Error('Adapter does not support security features. Please ensure your adapter implements security methods.');
}
}
// Security Settings
async getSettings(tenantId: string) {
return this.adapter.getSecuritySettings!(tenantId);
}
async createSettings(data: CreateSecuritySettingsInput) {
return this.adapter.createSecuritySettings!(data);
}
async updateSettings(tenantId: string, updates: UpdateSecuritySettingsInput) {
return this.adapter.updateSecuritySettings!(tenantId, updates);
}
// Email Lists
async getEmailAllowlist(tenantId: string) {
return this.adapter.getEmailAllowlist!(tenantId);
}
async addEmailToAllowlist(data: { tenantId: string; emailOrDomain: string; description?: string }) {
return this.adapter.addEmailToAllowlist!(data);
}
async removeEmailFromAllowlist(id: string) {
return this.adapter.removeEmailFromAllowlist!(id);
}
async getEmailBlocklist(tenantId: string) {
return this.adapter.getEmailBlocklist!(tenantId);
}
async addEmailToBlocklist(data: { tenantId: string; emailOrDomain: string; description?: string }) {
return this.adapter.addEmailToBlocklist!(data);
}
async removeEmailFromBlocklist(id: string) {
return this.adapter.removeEmailFromBlocklist!(id);
}
// Login Attempts
async recordLoginAttempt(data: RecordLoginAttemptInput) {
return this.adapter.recordLoginAttempt!(data);
}
async getLoginAttempts(tenantId: string, options?: { limit?: number; offset?: number }) {
return this.adapter.getLoginAttempts!(tenantId, options);
}
// Account Lockouts
async getLockedAccounts(tenantId: string) {
return this.adapter.getLockedAccounts!(tenantId);
}
async lockAccount(data: { userId: string; tenantId: string; lockedUntil: Date; reason: string }) {
return this.adapter.lockAccount!(data);
}
async unlockAccount(id: string) {
return this.adapter.unlockAccount!(id);
}
async getAccountLockout(userId: string) {
return this.adapter.getAccountLockout!(userId);
}
}
// Export singleton instance
import { createPrismaAdapter } from '../adapters/prisma';
let securityService: SecurityService | null = null;
export function getSecurityService(adapter?: Adapter): SecurityService {
if (!securityService) {
const adapterToUse = adapter || createPrismaAdapter();
securityService = new SecurityService(adapterToUse);
}
return securityService;
}