// SPDX-License-Identifier: Apache-2.0
// Copyright 2024-2026 Vorion LLC
/**
 * Security Alerting System - Type Definitions
 *
 * Comprehensive type definitions for security alerting including:
 * - Alert severity and channel enums
 * - Security alert structures
 * - Alert rules and conditions
 * - Configuration interfaces
 *
 * @packageDocumentation
 * @module security/alerting/types
 */
import { z } from 'zod';
// =============================================================================
// Enums
// =============================================================================
/**
 * Alert severity levels
 */
export const AlertSeverity = {
    CRITICAL: 'critical', // Immediate response required - active breach
    HIGH: 'high', // Urgent response - high-risk security event
    MEDIUM: 'medium', // Timely response - security concern
    LOW: 'low', // Informational - worth noting
    INFO: 'info', // Debug/audit information
};
export const alertSeveritySchema = z.nativeEnum(AlertSeverity);
/**
 * Alert delivery channels
 */
export const AlertChannel = {
    SLACK: 'slack', // Slack webhook integration
    PAGERDUTY: 'pagerduty', // PagerDuty events API
    EMAIL: 'email', // Email notification
    WEBHOOK: 'webhook', // Generic webhook
    SNS: 'sns', // AWS SNS for scalable delivery
};
export const alertChannelSchema = z.nativeEnum(AlertChannel);
/**
 * Types of security events that can trigger alerts
 */
export const SecurityEventType = {
    // Authentication events
    BRUTE_FORCE: 'brute_force',
    CREDENTIAL_STUFFING: 'credential_stuffing',
    ACCOUNT_LOCKOUT: 'account_lockout',
    SUSPICIOUS_LOGIN: 'suspicious_login',
    SESSION_HIJACK: 'session_hijack',
    MFA_BYPASS_ATTEMPT: 'mfa_bypass_attempt',
    // Authorization events
    PRIVILEGE_ESCALATION: 'privilege_escalation',
    UNAUTHORIZED_ACCESS: 'unauthorized_access',
    PERMISSION_DENIED_SPIKE: 'permission_denied_spike',
    // API security events
    API_KEY_ABUSE: 'api_key_abuse',
    RATE_LIMIT_EXCEEDED: 'rate_limit_exceeded',
    INVALID_TOKEN: 'invalid_token',
    TOKEN_REVOKED: 'token_revoked',
    // Anomaly events
    UNUSUAL_ACCESS_PATTERN: 'unusual_access_pattern',
    IMPOSSIBLE_TRAVEL: 'impossible_travel',
    NEW_DEVICE_LOGIN: 'new_device_login',
    UNUSUAL_TIME_ACCESS: 'unusual_time_access',
    // Configuration events
    SECURITY_CONFIG_CHANGE: 'security_config_change',
    ADMIN_ACTION: 'admin_action',
    KEY_ROTATION: 'key_rotation',
    POLICY_VIOLATION: 'policy_violation',
    // Data security events
    DATA_EXFILTRATION: 'data_exfiltration',
    INJECTION_ATTEMPT: 'injection_attempt',
    XSS_ATTEMPT: 'xss_attempt',
    // System events
    CERTIFICATE_EXPIRY: 'certificate_expiry',
    SECRET_EXPOSED: 'secret_exposed',
    VULNERABILITY_DETECTED: 'vulnerability_detected',
    // Incident events
    INCIDENT_CREATED: 'incident_created',
    INCIDENT_ESCALATED: 'incident_escalated',
    // Custom event type
    CUSTOM: 'custom',
};
export const securityEventTypeSchema = z.nativeEnum(SecurityEventType);
export const alertContextSchema = z.object({
    userId: z.string().optional(),
    tenantId: z.string().optional(),
    ipAddress: z.string().optional(),
    userAgent: z.string().optional(),
    location: z.object({
        country: z.string().optional(),
        city: z.string().optional(),
        latitude: z.number().optional(),
        longitude: z.number().optional(),
    }).optional(),
    resource: z.string().optional(),
    requestId: z.string().optional(),
    sessionId: z.string().optional(),
    metadata: z.record(z.unknown()).optional(),
});
export const securityAlertSchema = z.object({
    id: z.string().uuid(),
    severity: alertSeveritySchema,
    type: securityEventTypeSchema,
    message: z.string().min(1),
    title: z.string().min(1).max(255),
    context: alertContextSchema,
    timestamp: z.coerce.date(),
    fingerprint: z.string().min(1),
    source: z.string().min(1),
    suggestedActions: z.array(z.string()).optional(),
    relatedAlerts: z.array(z.string().uuid()).optional(),
    acknowledged: z.boolean().default(false),
    acknowledgedBy: z.string().optional(),
    acknowledgedAt: z.coerce.date().optional(),
    resolved: z.boolean().default(false),
    resolutionNotes: z.string().optional(),
    tags: z.array(z.string()).optional(),
});
export const createAlertInputSchema = z.object({
    severity: alertSeveritySchema,
    type: securityEventTypeSchema,
    message: z.string().min(1),
    title: z.string().min(1).max(255),
    context: alertContextSchema,
    source: z.string().min(1),
    suggestedActions: z.array(z.string()).optional(),
    tags: z.array(z.string()).optional(),
});
// =============================================================================
// Alert Rule Interface
// =============================================================================
/**
 * Condition operators for alert rules
 */
export const ConditionOperator = {
    EQUALS: 'equals',
    NOT_EQUALS: 'not_equals',
    GREATER_THAN: 'greater_than',
    LESS_THAN: 'less_than',
    GREATER_THAN_OR_EQUALS: 'greater_than_or_equals',
    LESS_THAN_OR_EQUALS: 'less_than_or_equals',
    CONTAINS: 'contains',
    NOT_CONTAINS: 'not_contains',
    MATCHES: 'matches', // Regex match
    IN: 'in', // Value in array
    NOT_IN: 'not_in',
};
export const conditionOperatorSchema = z.nativeEnum(ConditionOperator);
export const alertConditionSchema = z.object({
    field: z.string().min(1),
    operator: conditionOperatorSchema,
    value: z.unknown(),
});
export const alertThresholdSchema = z.object({
    count: z.number().int().positive(),
    windowSeconds: z.number().int().positive(),
    groupBy: z.string().optional(),
});
export const channelConfigSchema = z.object({
    channel: alertChannelSchema,
    config: z.record(z.unknown()),
    severityFilter: z.array(alertSeveritySchema).optional(),
    activeHours: z.object({
        start: z.number().int().min(0).max(23),
        end: z.number().int().min(0).max(23),
    }).optional(),
    rateLimit: z.number().int().positive().optional(),
});
export const alertRuleSchema = z.object({
    id: z.string().min(1),
    name: z.string().min(1).max(255),
    description: z.string().optional(),
    enabled: z.boolean().default(true),
    eventTypes: z.array(securityEventTypeSchema).min(1),
    conditions: z.array(alertConditionSchema).optional(),
    threshold: alertThresholdSchema.optional(),
    channels: z.array(channelConfigSchema).min(1),
    cooldownSeconds: z.number().int().nonnegative().default(300),
    severity: alertSeveritySchema,
    tags: z.array(z.string()).optional(),
    priority: z.number().int().default(0),
    stopOnMatch: z.boolean().default(false),
    messageTemplate: z.string().optional(),
    titleTemplate: z.string().optional(),
});
export const maintenanceWindowSchema = z.object({
    id: z.string().uuid(),
    name: z.string().min(1).max(255),
    startTime: z.coerce.date(),
    endTime: z.coerce.date(),
    suppressedEventTypes: z.array(securityEventTypeSchema).optional(),
    suppressedSeverities: z.array(alertSeveritySchema).optional(),
    suppressAll: z.boolean().default(false),
    reason: z.string().optional(),
    createdBy: z.string().min(1),
});
export const escalationPolicySchema = z.object({
    id: z.string().min(1),
    name: z.string().min(1).max(255),
    severities: z.array(alertSeveritySchema).min(1),
    levels: z.array(z.object({
        afterMinutes: z.number().int().positive(),
        channels: z.array(channelConfigSchema).min(1),
        message: z.string().optional(),
    })).min(1),
    escalateOnNoAcknowledge: z.boolean().default(true),
    escalateOnNoResolve: z.boolean().default(true),
});
export const alertConfigSchema = z.object({
    enabled: z.boolean().default(true),
    rules: z.array(alertRuleSchema).default([]),
    defaultChannels: z.array(channelConfigSchema).default([]),
    escalationPolicies: z.array(escalationPolicySchema).default([]),
    maintenanceWindows: z.array(maintenanceWindowSchema).default([]),
    deduplicationWindowSeconds: z.number().int().positive().default(300),
    redisKeyPrefix: z.string().default('vorion:alerting:'),
    defaultCooldownSeconds: z.number().int().nonnegative().default(300),
    channelSettings: z.object({
        slack: z.object({
            webhookUrl: z.string().url(),
            defaultChannel: z.string().optional(),
            username: z.string().optional(),
            iconEmoji: z.string().optional(),
        }).optional(),
        pagerduty: z.object({
            routingKey: z.string().min(1),
            apiUrl: z.string().url().optional(),
        }).optional(),
        email: z.object({
            from: z.string().email(),
            host: z.string().min(1),
            port: z.number().int().positive(),
            secure: z.boolean(),
            auth: z.object({
                user: z.string().min(1),
                pass: z.string().min(1),
            }).optional(),
            defaultRecipients: z.array(z.string().email()).optional(),
        }).optional(),
        webhook: z.object({
            defaultUrl: z.string().url().optional(),
            headers: z.record(z.string()).optional(),
            timeout: z.number().int().positive().optional(),
        }).optional(),
        sns: z.object({
            region: z.string().min(1),
            topicArn: z.string().optional(),
            accessKeyId: z.string().optional(),
            secretAccessKey: z.string().optional(),
        }).optional(),
    }).default({}),
});
// =============================================================================
// Default Configuration
// =============================================================================
/**
 * Default alerting configuration
 */
export const DEFAULT_ALERT_CONFIG = {
    enabled: true,
    rules: [],
    defaultChannels: [],
    escalationPolicies: [],
    maintenanceWindows: [],
    deduplicationWindowSeconds: 300,
    redisKeyPrefix: 'vorion:alerting:',
    defaultCooldownSeconds: 300,
    channelSettings: {},
};
export const alertDeliveryResultSchema = z.object({
    channel: alertChannelSchema,
    success: z.boolean(),
    messageId: z.string().optional(),
    error: z.string().optional(),
    timestamp: z.coerce.date(),
    retryCount: z.number().int().nonnegative(),
});
//# sourceMappingURL=types.js.map