diff --git a/packages/api/src/routes/removebrokers.routes.ts b/packages/api/src/routes/removebrokers.routes.ts index 13077de..5f8403c 100644 --- a/packages/api/src/routes/removebrokers.routes.ts +++ b/packages/api/src/routes/removebrokers.routes.ts @@ -1,6 +1,6 @@ import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'; import { prisma } from '@shieldai/db'; -import { RemovalStatus, Severity } from '@shieldai/types'; +import { RemovalStatus, Severity, AlertCategory, EntityTypes } from '@shieldai/types'; import { removeBrokersService, removeBrokersScheduler, @@ -144,13 +144,13 @@ export async function removebrokersRoutes(fastify: FastifyInstance) { userId: (request as AuthRequest).user!.id, brokerName: listing.brokerName, brokerId: listing.brokerId, - category: 'INFO_BROKER_LISTING' as any, + category: AlertCategory.INFO_BROKER_LISTING, severity: Severity.MEDIUM, title: `Personal listing found on ${listing.brokerName}`, description: `Your personal information was found on ${listing.brokerName} (${listing.brokerId}). Consider submitting a removal request.`, entities: [ - { type: 'USER_ID' as any, value: (request as AuthRequest).user!.id }, - ], + { type: EntityTypes.USER_ID, value: (request as AuthRequest).user!.id }, + ], metadata: { url: listing.url }, }); } catch { @@ -319,7 +319,7 @@ export async function removebrokersRoutes(fastify: FastifyInstance) { return reply.send({ request: { id: req.id, - status: 'cancelled', + status: RemovalStatus.REJECTED, }, }); } catch (error) { @@ -335,6 +335,10 @@ export async function removebrokersRoutes(fastify: FastifyInstance) { return reply.code(401).send({ error: 'User not authenticated' }); } + if (authReq.user.role !== 'admin' && authReq.user.role !== 'support') { + return reply.code(403).send({ error: 'Admin access required' }); + } + try { const results = await removeBrokersService.processPendingRequests(); diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index bc4f825..df0ba4b 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -38,8 +38,6 @@ model User { correlationGroups CorrelationGroup[] securityReports SecurityReport[] analysisJobs AnalysisJob[] - removalRequests RemovalRequest[] - brokerListings BrokerListing[] // Audit createdAt DateTime @default(now()) @@ -578,6 +576,7 @@ enum NormalizedAlertSeverity { enum CorrelationStatus { ACTIVE RESOLVED + FALSE_POSITIVE } model NormalizedAlert { @@ -816,29 +815,29 @@ model PropertyChange { // ============================================ enum BrokerCategory { - people_search - background_check - public_records - reverse_lookup - social_media + PEOPLE_SEARCH + BACKGROUND_CHECK + PUBLIC_RECORDS + REVERSE_LOOKUP + SOCIAL_MEDIA } enum RemovalMethod { - automated - manual_form - email - phone - mail - none + AUTOMATED + MANUAL_FORM + EMAIL + PHONE + MAIL + NONE } enum RemovalStatus { - pending - submitted - in_progress - completed - failed - rejected + PENDING + SUBMITTED + IN_PROGRESS + COMPLETED + FAILED + REJECTED } model InfoBroker { @@ -867,7 +866,7 @@ model RemovalRequest { id String @id @default(uuid()) subscriptionId String brokerId String - status RemovalStatus @default(pending) + status RemovalStatus @default(PENDING) personalInfo Json // { fullName, email?, phone?, address?, dob? } method RemovalMethod attempts Int @default(0) @@ -879,6 +878,8 @@ model RemovalRequest { metadata Json? // Broker response data, tracking info broker InfoBroker @relation(fields: [brokerId], references: [id]) + subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade) + brokerListings BrokerListing[] createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt @@ -902,6 +903,7 @@ model BrokerListing { removedAt DateTime? removalRequest RemovalRequest? @relation(fields: [removalRequestId], references: [id]) + subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade) scannedAt DateTime @default(now()) createdAt DateTime @default(now()) diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index b94fb52..b3f7d27 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -27,6 +27,7 @@ export const AlertSource = { SPAMSHIELD: "SPAMSHIELD", VOICEPRINT: "VOICEPRINT", CALL_ANALYSIS: "CALL_ANALYSIS", + HOME_TITLE: "HOME_TITLE", INFO_BROKER: "INFO_BROKER", } as const; export type AlertSource = (typeof AlertSource)[keyof typeof AlertSource]; @@ -375,6 +376,15 @@ export interface SecurityReportOutput { // Info Broker Removal Types // ============================================ +export const BrokerCategory = { + PEOPLE_SEARCH: "PEOPLE_SEARCH", + BACKGROUND_CHECK: "BACKGROUND_CHECK", + PUBLIC_RECORDS: "PUBLIC_RECORDS", + REVERSE_LOOKUP: "REVERSE_LOOKUP", + SOCIAL_MEDIA: "SOCIAL_MEDIA", +} as const; +export type BrokerCategory = (typeof BrokerCategory)[keyof typeof BrokerCategory]; + export const BrokerStatus = { ACTIVE: "ACTIVE", INACTIVE: "INACTIVE", diff --git a/services/removebrokers/src/RemoveBrokersService.ts b/services/removebrokers/src/RemoveBrokersService.ts index a608181..aceb973 100644 --- a/services/removebrokers/src/RemoveBrokersService.ts +++ b/services/removebrokers/src/RemoveBrokersService.ts @@ -138,7 +138,7 @@ export class RemoveBrokersService { const job: RemovalJob = { requestId: request.id, brokerId: request.brokerId, - brokerName: request.brokerId, + brokerName: getBrokerById(request.brokerId)?.name || request.brokerId, personalInfo: request.personalInfo as PersonalInfo, method: request.method, attempt: request.attempts + 1, diff --git a/services/removebrokers/src/brokerRegistry.ts b/services/removebrokers/src/brokerRegistry.ts index 0f5eaab..cd45bed 100644 --- a/services/removebrokers/src/brokerRegistry.ts +++ b/services/removebrokers/src/brokerRegistry.ts @@ -1,4 +1,4 @@ -import { RemovalMethod } from "@shieldai/types"; +import { RemovalMethod, BrokerCategory } from "@shieldai/types"; import type { BrokerEntry } from "./types"; export const BROKER_REGISTRY: BrokerEntry[] = [ @@ -6,7 +6,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "whitepages", name: "Whitepages", domain: "whitepages.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://www.whitepages.com/optout", requiresAccount: false, @@ -18,7 +18,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "spokeo", name: "Spokeo", domain: "spokeo.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://www.spokeo.com/privacy/removal-request", requiresAccount: false, @@ -30,7 +30,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "truepeoplesearch", name: "TruePeopleSearch", domain: "truepeoplesearch.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.AUTOMATED, removalUrl: "https://www.truepeoplesearch.com/remove-your-info", requiresAccount: false, @@ -42,7 +42,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "peoplefinders", name: "PeopleFinders", domain: "peoplefinders.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://www.peoplefinders.com/privacy-policy", requiresAccount: false, @@ -54,7 +54,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "thatsmth", name: "That's Them", domain: "thatsmth.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.AUTOMATED, removalUrl: "https://thatsmth.com/opt-out", requiresAccount: false, @@ -66,7 +66,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "fastpeoplesearch", name: "FastPeopleSearch", domain: "fastpeoplesearch.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.AUTOMATED, removalUrl: "https://www.fastpeoplesearch.com/opt-out", requiresAccount: false, @@ -78,7 +78,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "backgroundcheck", name: "BackgroundCheck", domain: "backgroundcheck.com", - category: "background_check", + category: BrokerCategory.BACKGROUND_CHECK, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://www.backgroundcheck.com/removal", requiresAccount: false, @@ -90,7 +90,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "freepeopledirectory", name: "Free People Directory", domain: "freepeopledirectory.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.AUTOMATED, removalUrl: "https://freepeopledirectory.com/optout", requiresAccount: false, @@ -102,7 +102,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "radaris", name: "Radaris", domain: "radaris.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.EMAIL, removalUrl: undefined, requiresAccount: false, @@ -114,7 +114,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "zynda", name: "Zynda", domain: "zynda.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://zynda.com/opt-out", requiresAccount: false, @@ -126,7 +126,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "addressinator", name: "Addressinator", domain: "addressinator.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://addressinator.com/opt-out", requiresAccount: false, @@ -135,10 +135,10 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ isActive: true, }, { - id: "familytree Now", + id: "familytreenow", name: "FamilyTree Now", domain: "familytreenow.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.EMAIL, removalUrl: undefined, requiresAccount: false, @@ -150,7 +150,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "accuratebackground", name: "Accurate Background", domain: "accuratebackground.com", - category: "background_check", + category: BrokerCategory.BACKGROUND_CHECK, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://www.accuratebackground.com/optout", requiresAccount: true, @@ -162,7 +162,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "instantcheckmate", name: "Instant Checkmate", domain: "instantcheckmate.com", - category: "background_check", + category: BrokerCategory.BACKGROUND_CHECK, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://www.instantcheckmate.com/opt-out", requiresAccount: true, @@ -174,7 +174,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "pthree", name: "P3 (People Finders)", domain: "pthree.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://www.pthree.com/opt-out", requiresAccount: false, @@ -186,7 +186,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "sortedbee", name: "Sorted Bee", domain: "sortedbee.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://www.sortedbee.com/opt-out", requiresAccount: false, @@ -198,7 +198,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "ussearch", name: "US Search", domain: "ussearch.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.AUTOMATED, removalUrl: "https://www.ussearch.com/opt-out", requiresAccount: false, @@ -210,7 +210,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "tellme", name: "Tell me Online Info", domain: "tellmeonlineinfo.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.MANUAL_FORM, removalUrl: "https://tellmeonlineinfo.com/opt-out", requiresAccount: false, @@ -222,7 +222,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "synpeople", name: "Synpeople", domain: "synpeople.com", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.AUTOMATED, removalUrl: "https://www.synpeople.com/opt-out", requiresAccount: false, @@ -234,7 +234,7 @@ export const BROKER_REGISTRY: BrokerEntry[] = [ id: "atomdata", name: "Atom Data", domain: "atomdata.xyz", - category: "people_search", + category: BrokerCategory.PEOPLE_SEARCH, removalMethod: RemovalMethod.EMAIL, removalUrl: undefined, requiresAccount: false,