Add tier-based scan scheduler and webhook triggers (FRE-4498)
- ScanScheduler: tier-based scheduling (BASIC=24h, PLUS=6h, PREMIUM=1h) - WebhookHandler: HMAC-verified webhook ingestion with SCAN_TRIGGER support - API routes: /scheduler and /webhooks endpoints under /api/v1/darkwatch - Jobs: scheduled scan checker + webhook retry processor via BullMQ - Schema: ScanSchedule, WebhookEvent models; ScanJob.scheduledBy field - Types: ScheduleStatus, WebhookEventType, WebhookTriggerInput - Tests: scheduler lifecycle + webhook signature/processing tests Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { FieldEncryptionService } from './services/field-encryption.service';
|
||||
|
||||
export const prisma = new PrismaClient();
|
||||
export default prisma;
|
||||
export { FieldEncryptionService };
|
||||
export type { PrismaClient };
|
||||
|
||||
33
packages/db/src/services/field-encryption.service.ts
Normal file
33
packages/db/src/services/field-encryption.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import crypto from 'crypto';
|
||||
|
||||
const ENCRYPTION_KEY = process.env.PII_ENCRYPTION_KEY || 'default-32-byte-key-for-aes-256';
|
||||
const IV_LENGTH = 16;
|
||||
|
||||
export class FieldEncryptionService {
|
||||
static encrypt(text: string): string {
|
||||
const iv = crypto.randomBytes(IV_LENGTH);
|
||||
const key = crypto.createHash('sha256').update(ENCRYPTION_KEY).digest();
|
||||
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
|
||||
|
||||
let encrypted = cipher.update(text, 'utf8', 'base64');
|
||||
encrypted += cipher.final('base64');
|
||||
|
||||
return `${iv.toString('base64')}:${encrypted}`;
|
||||
}
|
||||
|
||||
static decrypt(encryptedText: string): string {
|
||||
const [ivBase64, ciphertext] = encryptedText.split(':');
|
||||
const iv = Buffer.from(ivBase64, 'base64');
|
||||
const key = crypto.createHash('sha256').update(ENCRYPTION_KEY).digest();
|
||||
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
|
||||
|
||||
let decrypted = decipher.update(ciphertext, 'base64', 'utf8');
|
||||
decrypted += decipher.final('utf8');
|
||||
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
static hashPhoneNumber(phoneNumber: string): string {
|
||||
return crypto.createHash('sha256').update(phoneNumber).digest('hex');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user