// SPDX-License-Identifier: Apache-2.0
// Copyright 2024-2026 Vorion LLC
/**
 * Anomaly Detection Types
 *
 * Type definitions for the rule-based anomaly detection engine.
 * Provides interfaces for detecting suspicious patterns including:
 * - Impossible travel (geographic anomalies)
 * - Unusual access times (temporal anomalies)
 * - Volume spikes (behavioral anomalies)
 * - New device access
 * - Authentication failure spikes
 * - Privilege probing attempts
 *
 * @packageDocumentation
 * @module security/anomaly/types
 */
import { z } from 'zod';
// =============================================================================
// Anomaly Types
// =============================================================================
/**
 * Types of anomalies that can be detected
 */
export const AnomalyType = {
    IMPOSSIBLE_TRAVEL: 'impossible-travel',
    UNUSUAL_TIME: 'unusual-time',
    VOLUME_SPIKE: 'volume-spike',
    NEW_DEVICE: 'new-device',
    FAILED_AUTH_SPIKE: 'failed-auth-spike',
    PRIVILEGE_PROBE: 'privilege-probe',
};
export const anomalyTypeSchema = z.nativeEnum(AnomalyType);
/**
 * Severity levels for detected anomalies
 */
export const AnomalySeverity = {
    LOW: 'low',
    MEDIUM: 'medium',
    HIGH: 'high',
    CRITICAL: 'critical',
};
export const anomalySeveritySchema = z.nativeEnum(AnomalySeverity);
export const indicatorSchema = z.object({
    type: z.string().min(1),
    description: z.string().min(1),
    value: z.union([z.string(), z.number(), z.boolean()]),
    weight: z.number().min(0).max(100),
});
export const anomalySchema = z.object({
    id: z.string().uuid(),
    timestamp: z.coerce.date(),
    type: anomalyTypeSchema,
    severity: anomalySeveritySchema,
    confidence: z.number().min(0).max(100),
    userId: z.string().optional(),
    tenantId: z.string().optional(),
    ipAddress: z.string().optional(),
    description: z.string().min(1),
    indicators: z.array(indicatorSchema),
    suggestedActions: z.array(z.string()),
    metadata: z.record(z.unknown()).optional(),
});
export const anomalyDetectorConfigSchema = z.object({
    enabled: z.boolean().default(true),
    detectors: z.array(z.string()).default(['geographic', 'temporal', 'volume']),
    alertThreshold: z.number().min(0).max(100).default(70),
    learningPeriodDays: z.number().int().positive().default(14),
    autoBlock: z.boolean().default(false),
    autoBlockThreshold: z.number().min(0).max(100).default(90),
    redisKeyPrefix: z.string().default('vorion:anomaly:'),
});
/**
 * Default configuration values
 */
export const DEFAULT_ANOMALY_DETECTOR_CONFIG = {
    enabled: true,
    detectors: ['geographic', 'temporal', 'volume'],
    alertThreshold: 70,
    learningPeriodDays: 14,
    autoBlock: false,
    autoBlockThreshold: 90,
    redisKeyPrefix: 'vorion:anomaly:',
};
export const geoLocationSchema = z.object({
    latitude: z.number().min(-90).max(90),
    longitude: z.number().min(-180).max(180),
    countryCode: z.string().length(2).optional(),
    city: z.string().optional(),
    region: z.string().optional(),
    timezone: z.string().optional(),
});
export const geographicDetectorConfigSchema = z.object({
    maxTravelSpeedKmh: z.number().positive().default(1200),
    minDistanceKm: z.number().positive().default(100),
    highRiskCountries: z.array(z.string().length(2)).default([]),
    flagVpnUsage: z.boolean().default(true),
});
export const DEFAULT_GEOGRAPHIC_DETECTOR_CONFIG = {
    maxTravelSpeedKmh: 1200, // Faster than commercial aviation (~900 km/h) with buffer
    minDistanceKm: 100,
    highRiskCountries: [],
    flagVpnUsage: true,
};
export const temporalDetectorConfigSchema = z.object({
    normalHoursStart: z.number().int().min(0).max(23).default(6),
    normalHoursEnd: z.number().int().min(0).max(23).default(22),
    normalDays: z.array(z.number().int().min(0).max(6)).default([1, 2, 3, 4, 5]),
    learnUserPatterns: z.boolean().default(true),
    minEventsForBaseline: z.number().int().positive().default(20),
});
export const DEFAULT_TEMPORAL_DETECTOR_CONFIG = {
    normalHoursStart: 6, // 6 AM
    normalHoursEnd: 22, // 10 PM
    normalDays: [1, 2, 3, 4, 5], // Monday through Friday
    learnUserPatterns: true,
    minEventsForBaseline: 20,
};
export const userAccessPatternSchema = z.object({
    userId: z.string().min(1),
    hourHistogram: z.array(z.number()).length(24),
    dayHistogram: z.array(z.number()).length(7),
    totalEvents: z.number().int().nonnegative(),
    lastUpdated: z.coerce.date(),
});
export const volumeDetectorConfigSchema = z.object({
    windowMinutes: z.number().int().positive().default(5),
    spikeThresholdStdDev: z.number().positive().default(3),
    absoluteMaxRequests: z.number().int().positive().default(1000),
    trackPerUser: z.boolean().default(true),
    trackPerIp: z.boolean().default(true),
    trackPerEndpoint: z.boolean().default(false),
});
export const DEFAULT_VOLUME_DETECTOR_CONFIG = {
    windowMinutes: 5,
    spikeThresholdStdDev: 3,
    absoluteMaxRequests: 1000,
    trackPerUser: true,
    trackPerIp: true,
    trackPerEndpoint: false,
};
export const volumeBaselineSchema = z.object({
    identifier: z.string().min(1),
    identifierType: z.enum(['user', 'ip', 'endpoint']),
    mean: z.number().nonnegative(),
    stdDev: z.number().nonnegative(),
    sampleCount: z.number().int().nonnegative(),
    lastUpdated: z.coerce.date(),
});
export const securityEventSchema = z.object({
    eventId: z.string().min(1),
    timestamp: z.coerce.date(),
    eventType: z.string().min(1),
    userId: z.string().optional(),
    tenantId: z.string().optional(),
    ipAddress: z.string().min(1),
    userAgent: z.string().optional(),
    location: geoLocationSchema.optional(),
    resource: z.string().optional(),
    method: z.string().optional(),
    success: z.boolean(),
    failureReason: z.string().optional(),
    deviceFingerprint: z.string().optional(),
    metadata: z.record(z.unknown()).optional(),
});
export const detectionResultSchema = z.object({
    detectorName: z.string().min(1),
    anomalyDetected: z.boolean(),
    confidence: z.number().min(0).max(100).optional(),
    severity: anomalySeveritySchema.optional(),
    description: z.string().optional(),
    indicators: z.array(indicatorSchema),
    suggestedActions: z.array(z.string()),
    durationMs: z.number().nonnegative(),
    error: z.string().optional(),
});
export const aggregatedDetectionResultSchema = z.object({
    event: securityEventSchema,
    detectorResults: z.array(detectionResultSchema),
    anomalies: z.array(anomalySchema),
    totalDurationMs: z.number().nonnegative(),
    analyzedAt: z.coerce.date(),
});
export const anomalyAlertSchema = z.object({
    alertId: z.string().uuid(),
    anomaly: anomalySchema,
    status: z.enum(['open', 'acknowledged', 'resolved', 'dismissed']),
    createdAt: z.coerce.date(),
    updatedAt: z.coerce.date(),
    handledBy: z.string().optional(),
    notes: z.string().optional(),
    autoActionTaken: z.boolean(),
    autoActionDescription: z.string().optional(),
});
//# sourceMappingURL=types.js.map