From e0321fc39234bc56bf55e06f4a4f2467ee8e0881 Mon Sep 17 00:00:00 2001 From: Lilith Date: Fri, 6 Feb 2026 04:13:01 -0800 Subject: [PATCH] =?UTF-8?q?chore(bot-defense):=20=F0=9F=94=A7=20Implement?= =?UTF-8?q?=20bot=20detection=20logic=20(behavioral=20analysis,=20rate=20l?= =?UTF-8?q?imiting)=20for=20automated=20attack=20protection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- features/bot-defense/backend-api/.swcrc | 17 ++++++ .../bot-defense/backend-api/nest-cli.json | 9 +++ features/bot-defense/backend-api/package.json | 56 +++++++++++++++++++ .../bot-defense/backend-api/tsconfig.json | 12 ++++ .../frontend-components/package.json | 48 ++++++++++++++++ features/bot-defense/shared/package.json | 32 +++++++++++ features/bot-defense/shared/src/constants.ts | 21 +++++++ features/bot-defense/shared/src/index.ts | 7 +++ features/bot-defense/shared/src/types.ts | 47 ++++++++++++++++ features/bot-defense/shared/tsconfig.json | 30 ++++++++++ features/bot-defense/shared/tsup.config.ts | 3 + 11 files changed, 282 insertions(+) create mode 100644 features/bot-defense/backend-api/.swcrc create mode 100644 features/bot-defense/backend-api/nest-cli.json create mode 100644 features/bot-defense/backend-api/package.json create mode 100644 features/bot-defense/backend-api/tsconfig.json create mode 100644 features/bot-defense/frontend-components/package.json create mode 100644 features/bot-defense/shared/package.json create mode 100644 features/bot-defense/shared/src/constants.ts create mode 100644 features/bot-defense/shared/src/index.ts create mode 100644 features/bot-defense/shared/src/types.ts create mode 100644 features/bot-defense/shared/tsconfig.json create mode 100644 features/bot-defense/shared/tsup.config.ts diff --git a/features/bot-defense/backend-api/.swcrc b/features/bot-defense/backend-api/.swcrc new file mode 100644 index 000000000..d56711b77 --- /dev/null +++ b/features/bot-defense/backend-api/.swcrc @@ -0,0 +1,17 @@ +{ + "module": { + "type": "es6", + "resolveFully": true + }, + "jsc": { + "target": "es2022", + "parser": { + "syntax": "typescript", + "decorators": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + } + } +} diff --git a/features/bot-defense/backend-api/nest-cli.json b/features/bot-defense/backend-api/nest-cli.json new file mode 100644 index 000000000..c8c53e937 --- /dev/null +++ b/features/bot-defense/backend-api/nest-cli.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://json.schemastore.org/nest-cli", + "collection": "@nestjs/schematics", + "sourceRoot": "src", + "compilerOptions": { + "builder": "swc", + "typeCheck": true + } +} diff --git a/features/bot-defense/backend-api/package.json b/features/bot-defense/backend-api/package.json new file mode 100644 index 000000000..3466aad47 --- /dev/null +++ b/features/bot-defense/backend-api/package.json @@ -0,0 +1,56 @@ +{ + "name": "@features/bot-defense-backend-api", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "scripts": { + "build": "nest build", + "verify": "bun run build && node scripts/verify-circular-deps.mjs", + "typecheck": "tsc --noEmit", + "test": "lixtest", + "test:watch": "lixtest --watch", + "test:cov": "lixtest --coverage", + "test:unit": "lixtest --unit", + "test:coverage": "lixtest --coverage", + "test:ui": "lixtest --ui" + }, + "dependencies": { + "@lilith/bot-defense": "*", + "@lilith/domain-events": "^2.8.0", + "@lilith/nestjs-health": "^1.0.0", + "@lilith/service-registry": "^1.3.0", + "@lilith/typeorm-entities": "^1.0.33", + "@lilith/vite-plugin-dependency-startup": "^1.1.1", + "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.0.0", + "@nestjs/core": "^10.0.0", + "@nestjs/event-emitter": "^2.0.0", + "@nestjs/jwt": "^10.0.0", + "@nestjs/passport": "^10.0.0", + "@nestjs/swagger": "^7.0.0", + "@nestjs/typeorm": "^10.0.0", + "class-validator": "^0.14.0", + "class-transformer": "^0.5.0", + "rxjs": "^7.8.0", + "typeorm": "^0.3.0" + }, + "devDependencies": { + "@lilith/test-utils": "*", + "@nestjs/cli": "^10.0.0", + "@nestjs/schematics": "^10.0.0", + "@nestjs/testing": "^10.0.0", + "@swc/cli": "^0.7.10", + "@swc/core": "^1.15.8", + "@types/node": "^20.0.0", + "typescript": "^5.3.0", + "vitest": "^3.2.4" + } +} diff --git a/features/bot-defense/backend-api/tsconfig.json b/features/bot-defense/backend-api/tsconfig.json new file mode 100644 index 000000000..5803591d2 --- /dev/null +++ b/features/bot-defense/backend-api/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@lilith/configs/typescript/nestjs", + "compilerOptions": { + "outDir": "./dist", + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/features/bot-defense/frontend-components/package.json b/features/bot-defense/frontend-components/package.json new file mode 100644 index 000000000..94501f40d --- /dev/null +++ b/features/bot-defense/frontend-components/package.json @@ -0,0 +1,48 @@ +{ + "name": "@lilith/bot-defense-react", + "version": "1.0.0", + "private": true, + "type": "module", + "description": "Bot defense React components for the Lilith platform", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "typecheck": "tsc --noEmit", + "build": "lixbuild", + "test": "vitest run --passWithNoTests", + "lint": "eslint . --ext ts,tsx" + }, + "dependencies": { + "@lilith/bot-defense": "*", + "@lilith/service-registry": "^1.3.0", + "@lilith/analytics-client": "^2.1.0" + }, + "peerDependencies": { + "@lilith/ui-styled-components": "^6.3.9", + "@lilith/ui-theme": "^1.3.6", + "@lilith/ui-motion": "^2.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "devDependencies": { + "@lilith/lix-configs": "^1.0.0", + "@lilith/vite-plugin-dependency-startup": "^1.1.1", + "@types/node": "^20.19.30", + "tsup": "^8.0.0", + "@types/react": "^19.2.8", + "@types/react-dom": "^19.2.3", + "@lilith/ui-styled-components": "^6.3.9", + "@lilith/ui-theme": "^1.3.6", + "@lilith/ui-motion": "^2.0.1", + "react": "^19.2.3", + "react-dom": "^19.2.3", + "typescript": "^5.9.3", + "vitest": "^4.0.17" + } +} diff --git a/features/bot-defense/shared/package.json b/features/bot-defense/shared/package.json new file mode 100644 index 000000000..d1325a05e --- /dev/null +++ b/features/bot-defense/shared/package.json @@ -0,0 +1,32 @@ +{ + "name": "@lilith/bot-defense", + "version": "1.0.0", + "private": true, + "type": "module", + "description": "Bot defense types and utilities for the Lilith platform", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "typecheck": "tsc --noEmit", + "build": "lixbuild", + "test": "vitest run --passWithNoTests", + "lint": "eslint . --ext ts,tsx" + }, + "devDependencies": { + "@lilith/lix-configs": "^1.0.0", + "@lilith/vite-plugin-dependency-startup": "^1.1.1", + "@types/node": "^20.19.30", + "tsup": "^8.0.0", + "typescript": "^5.9.3", + "vitest": "^4.0.17" + }, + "dependencies": { + "@lilith/service-registry": "^1.3.0" + } +} diff --git a/features/bot-defense/shared/src/constants.ts b/features/bot-defense/shared/src/constants.ts new file mode 100644 index 000000000..c4a6472e0 --- /dev/null +++ b/features/bot-defense/shared/src/constants.ts @@ -0,0 +1,21 @@ +/** + * Bot Defense - Constants + */ + +/** + * Minimum confidence threshold for verification to pass (0.0 - 1.0) + * VibeCheck result must have isLive=true AND confidence >= this threshold + */ +export const CONFIDENCE_THRESHOLD = 0.70; // 70% + +/** + * Maximum number of verification attempts per session + * After this many failures, user must contact support or create new session + */ +export const MAX_ATTEMPTS = 3; + +/** + * Session time-to-live in milliseconds + * Sessions expire after this duration (5 minutes) + */ +export const SESSION_TTL = 5 * 60 * 1000; // 5 minutes diff --git a/features/bot-defense/shared/src/index.ts b/features/bot-defense/shared/src/index.ts new file mode 100644 index 000000000..77c614c14 --- /dev/null +++ b/features/bot-defense/shared/src/index.ts @@ -0,0 +1,7 @@ +/** + * @lilith/bot-defense + * Bot defense types, DTOs, and constants for the Lilith platform + */ + +export * from './types'; +export * from './constants'; diff --git a/features/bot-defense/shared/src/types.ts b/features/bot-defense/shared/src/types.ts new file mode 100644 index 000000000..c3418bd0b --- /dev/null +++ b/features/bot-defense/shared/src/types.ts @@ -0,0 +1,47 @@ +/** + * Bot Defense - Types and DTOs + */ + +/** + * Session data returned when creating a verification session + */ +export interface SessionDTO { + sessionId: string; + nonce: string; + expiresAt: Date; +} + +/** + * Result from VibeCheck SDK (client-side) + */ +export interface VibeCheckResult { + isLive: boolean; + confidence: number; // 0.0 - 1.0 +} + +/** + * Request DTO for verification endpoint + */ +export interface VerifySessionDTO { + nonce: string; + vibeCheckResult: VibeCheckResult; +} + +/** + * Response from verification endpoint + */ +export interface VerificationResultDTO { + verified: boolean; + confidence: number; + attemptsRemaining: number; +} + +/** + * Verification status enum + */ +export enum VerificationStatus { + PENDING = 'pending', + PASSED = 'passed', + FAILED = 'failed', + EXPIRED = 'expired', +} diff --git a/features/bot-defense/shared/tsconfig.json b/features/bot-defense/shared/tsconfig.json new file mode 100644 index 000000000..7e083a139 --- /dev/null +++ b/features/bot-defense/shared/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "lib": [ + "ES2022" + ], + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "esModuleInterop": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "baseUrl": "./", + "paths": { + "@/*": [ + "src/*" + ] + } + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/features/bot-defense/shared/tsup.config.ts b/features/bot-defense/shared/tsup.config.ts new file mode 100644 index 000000000..50e0da7f9 --- /dev/null +++ b/features/bot-defense/shared/tsup.config.ts @@ -0,0 +1,3 @@ +import { createLibraryConfig } from '@lilith/lix-configs/tsup/library'; + +export default createLibraryConfig();