2026-02-10 15:31:31 +00:00
|
|
|
import { logger } from '../../logger.js';
|
|
|
|
|
import { SecurityLogger, SecurityLogLevel, SecurityEventType } from '../../security/index.js';
|
2026-02-10 20:30:43 +00:00
|
|
|
import { RustSecurityBridge } from '../../security/classes.rustsecuritybridge.js';
|
2025-10-24 08:09:29 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Result of a DKIM verification
|
|
|
|
|
*/
|
|
|
|
|
export interface IDkimVerificationResult {
|
|
|
|
|
isValid: boolean;
|
|
|
|
|
domain?: string;
|
|
|
|
|
selector?: string;
|
|
|
|
|
status?: string;
|
|
|
|
|
details?: any;
|
|
|
|
|
errorMessage?: string;
|
|
|
|
|
signatureFields?: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-02-10 20:30:43 +00:00
|
|
|
* DKIM verifier — delegates to the Rust security bridge.
|
2025-10-24 08:09:29 +00:00
|
|
|
*/
|
|
|
|
|
export class DKIMVerifier {
|
2026-02-10 20:30:43 +00:00
|
|
|
constructor() {}
|
2025-10-24 08:09:29 +00:00
|
|
|
|
|
|
|
|
/**
|
2026-02-10 20:30:43 +00:00
|
|
|
* Verify DKIM signature for an email via Rust bridge
|
2025-10-24 08:09:29 +00:00
|
|
|
*/
|
|
|
|
|
public async verify(
|
|
|
|
|
emailData: string,
|
|
|
|
|
options: {
|
|
|
|
|
useCache?: boolean;
|
|
|
|
|
returnDetails?: boolean;
|
|
|
|
|
} = {}
|
|
|
|
|
): Promise<IDkimVerificationResult> {
|
|
|
|
|
try {
|
2026-02-10 20:30:43 +00:00
|
|
|
const bridge = RustSecurityBridge.getInstance();
|
|
|
|
|
const results = await bridge.verifyDkim(emailData);
|
|
|
|
|
const first = results[0];
|
|
|
|
|
|
|
|
|
|
const result: IDkimVerificationResult = {
|
|
|
|
|
isValid: first?.is_valid ?? false,
|
|
|
|
|
domain: first?.domain ?? undefined,
|
|
|
|
|
selector: first?.selector ?? undefined,
|
|
|
|
|
status: first?.status ?? 'none',
|
|
|
|
|
details: options.returnDetails ? results : undefined,
|
|
|
|
|
};
|
2025-10-24 08:09:29 +00:00
|
|
|
|
2026-02-10 20:30:43 +00:00
|
|
|
SecurityLogger.getInstance().logEvent({
|
|
|
|
|
level: result.isValid ? SecurityLogLevel.INFO : SecurityLogLevel.WARN,
|
|
|
|
|
type: SecurityEventType.DKIM,
|
|
|
|
|
message: `DKIM verification ${result.isValid ? 'passed' : 'failed'} for domain ${result.domain || 'unknown'}`,
|
|
|
|
|
details: { selector: result.selector, status: result.status },
|
|
|
|
|
domain: result.domain || 'unknown',
|
|
|
|
|
success: result.isValid
|
|
|
|
|
});
|
2025-10-24 08:09:29 +00:00
|
|
|
|
2026-02-10 20:30:43 +00:00
|
|
|
logger.log(result.isValid ? 'info' : 'warn',
|
|
|
|
|
`DKIM verification: ${result.status} for domain ${result.domain || 'unknown'}`);
|
2025-10-24 08:09:29 +00:00
|
|
|
|
2026-02-10 20:30:43 +00:00
|
|
|
return result;
|
2025-10-24 08:09:29 +00:00
|
|
|
} catch (error) {
|
2026-02-10 20:30:43 +00:00
|
|
|
logger.log('error', `DKIM verification failed: ${error.message}`);
|
|
|
|
|
|
2025-10-24 08:09:29 +00:00
|
|
|
SecurityLogger.getInstance().logEvent({
|
|
|
|
|
level: SecurityLogLevel.ERROR,
|
|
|
|
|
type: SecurityEventType.DKIM,
|
2026-02-10 20:30:43 +00:00
|
|
|
message: `DKIM verification error`,
|
2025-10-24 08:09:29 +00:00
|
|
|
details: { error: error.message },
|
|
|
|
|
success: false
|
|
|
|
|
});
|
2026-02-10 20:30:43 +00:00
|
|
|
|
2025-10-24 08:09:29 +00:00
|
|
|
return {
|
|
|
|
|
isValid: false,
|
|
|
|
|
status: 'temperror',
|
2026-02-10 20:30:43 +00:00
|
|
|
errorMessage: `Verification error: ${error.message}`
|
2025-10-24 08:09:29 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-10 20:30:43 +00:00
|
|
|
/** No-op — Rust bridge handles its own caching */
|
|
|
|
|
public clearCache(): void {}
|
|
|
|
|
|
|
|
|
|
/** Always 0 — cache is managed by the Rust side */
|
2025-10-24 08:09:29 +00:00
|
|
|
public getCacheSize(): number {
|
2026-02-10 20:30:43 +00:00
|
|
|
return 0;
|
2025-10-24 08:09:29 +00:00
|
|
|
}
|
2026-02-10 20:30:43 +00:00
|
|
|
}
|