Initial commit: AI-Twitter PoC with CaptchaLM
This commit is contained in:
21
node_modules/captchalm/LICENSE
generated
vendored
Normal file
21
node_modules/captchalm/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
182
node_modules/captchalm/README.md
generated
vendored
Normal file
182
node_modules/captchalm/README.md
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
# CaptchaLM
|
||||
|
||||
<p align="center">
|
||||
<img src="Banner.png" alt="CaptchaLM - I AM A ROBOT" width="600">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>The reverse CAPTCHA for the AI age</strong><br>
|
||||
Let AI agents through. Keep humans guessing.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#installation">Installation</a> •
|
||||
<a href="#quick-start">Quick Start</a> •
|
||||
<a href="docs/api.md">API Docs</a> •
|
||||
<a href="docs/challenges.md">Challenge Types</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## What is CaptchaLM?
|
||||
|
||||
Traditional CAPTCHAs block bots and let humans through. **CaptchaLM flips the script.**
|
||||
|
||||
It presents computational challenges that are trivial for AI agents but tedious for humans:
|
||||
|
||||
| AI Agents | Humans |
|
||||
|-----------|--------|
|
||||
| ✅ Execute code instantly | ❌ Mental math is slow |
|
||||
| ✅ Decode base64/hex easily | ❌ Manual decoding is painful |
|
||||
| ✅ Parse structured data | ❌ Pattern matching takes time |
|
||||
| ✅ Chain operations precisely | ❌ Easy to make mistakes |
|
||||
|
||||
**Use cases:**
|
||||
- API endpoints that should only be accessed by AI agents
|
||||
- Rate limiting humans while allowing automated workflows
|
||||
- Creating "AI-only" zones in your application
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install captchalm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Protect your server
|
||||
|
||||
```javascript
|
||||
import express from 'express';
|
||||
import { createExpressMiddleware } from 'captchalm';
|
||||
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
const { protect, challenge } = createExpressMiddleware({
|
||||
secret: process.env.UNCAPTCHA_SECRET,
|
||||
difficulty: 'medium', // 'easy' | 'medium' | 'hard'
|
||||
});
|
||||
|
||||
// Endpoint where agents get challenges
|
||||
app.get('/challenge', challenge);
|
||||
|
||||
// Protected endpoint - only AI agents can access
|
||||
app.post('/api/agent-only', protect, (req, res) => {
|
||||
res.json({ message: 'Welcome, AI agent!' });
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
### 2. Access from your AI agent
|
||||
|
||||
```javascript
|
||||
import { CaptchaLMSolver } from 'captchalm/client';
|
||||
|
||||
const solver = new CaptchaLMSolver();
|
||||
|
||||
// One-liner to solve and access protected endpoint
|
||||
const response = await solver.completeProtectedRequest(
|
||||
'https://api.example.com/challenge',
|
||||
'https://api.example.com/api/agent-only',
|
||||
{ method: 'POST', body: JSON.stringify({ data: 'hello' }) }
|
||||
);
|
||||
|
||||
console.log(await response.json());
|
||||
// { message: 'Welcome, AI agent!' }
|
||||
```
|
||||
|
||||
That's it! Your endpoint is now AI-agent-only.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Agent requests a challenge** from your `/challenge` endpoint
|
||||
2. **Server generates a computational task** (math, code execution, decoding, etc.)
|
||||
3. **Agent solves the challenge** using the solver SDK
|
||||
4. **Agent sends solution** with the protected request
|
||||
5. **Server verifies** and grants access if correct
|
||||
|
||||
```
|
||||
┌─────────────┐ GET /challenge ┌─────────────┐
|
||||
│ AI Agent │ ──────────────────────► │ Server │
|
||||
│ │ ◄────────────────────── │ │
|
||||
│ │ Challenge data │ │
|
||||
│ │ │ │
|
||||
│ [Solver] │ POST /api/data │ [Verify] │
|
||||
│ solves │ ──────────────────────► │ checks │
|
||||
│ │ + solution headers │ │
|
||||
│ │ ◄────────────────────── │ │
|
||||
└─────────────┘ ✓ Access granted └─────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Challenge Types
|
||||
|
||||
CaptchaLM includes 5 types of challenges. See [docs/challenges.md](docs/challenges.md) for details.
|
||||
|
||||
| Type | What it tests |
|
||||
|------|--------------|
|
||||
| **Function Execution** | Run provided code with parameters |
|
||||
| **Chained Operations** | Sequential math operations |
|
||||
| **Encoded Instructions** | Decode and compute (base64, hex, rot13) |
|
||||
| **Pattern Extraction** | Query structured data |
|
||||
| **Code Transform** | Execute and transform results |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
```javascript
|
||||
createExpressMiddleware({
|
||||
// Required
|
||||
secret: 'your-secret-key',
|
||||
|
||||
// Optional
|
||||
difficulty: 'medium', // 'easy' | 'medium' | 'hard'
|
||||
expirationMs: 30000, // Challenge timeout (30s default)
|
||||
challengeTypes: ['function_execution', 'chained_operations'],
|
||||
rateLimit: {
|
||||
maxAttempts: 10, // Per client
|
||||
windowMs: 60000, // 1 minute window
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
- 📖 [API Reference](docs/api.md) - Full API documentation
|
||||
- 🧩 [Challenge Types](docs/challenges.md) - Detailed challenge descriptions
|
||||
- 🔒 [Security Guide](docs/security.md) - Security considerations
|
||||
- 🤖 [For AI Agents](docs/llm.txt) - Machine-readable documentation
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
- **HMAC-signed challenges** prevent tampering
|
||||
- **Timing-safe comparison** prevents timing attacks
|
||||
- **Rate limiting** stops brute force attempts
|
||||
- **One-time use** challenges can't be replayed
|
||||
- **Configurable expiration** limits attack window
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<sub>🤖 AI agents: see <a href="docs/llm.txt">docs/llm.txt</a> for machine-readable documentation</sub>
|
||||
</p>
|
||||
368
node_modules/captchalm/dist/client/index.cjs
generated
vendored
Normal file
368
node_modules/captchalm/dist/client/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,368 @@
|
||||
'use strict';
|
||||
|
||||
// src/core/encoding.ts
|
||||
function encode(value, encoding) {
|
||||
switch (encoding) {
|
||||
case "plain":
|
||||
return value;
|
||||
case "base64":
|
||||
return encodeBase64(value);
|
||||
case "hex":
|
||||
return encodeHex(value);
|
||||
case "rot13":
|
||||
return encodeRot13(value);
|
||||
default:
|
||||
throw new Error(`Unknown encoding type: ${encoding}`);
|
||||
}
|
||||
}
|
||||
function decode(value, encoding) {
|
||||
switch (encoding) {
|
||||
case "plain":
|
||||
return value;
|
||||
case "base64":
|
||||
return decodeBase64(value);
|
||||
case "hex":
|
||||
return decodeHex(value);
|
||||
case "rot13":
|
||||
return decodeRot13(value);
|
||||
// ROT13 is symmetric
|
||||
default:
|
||||
throw new Error(`Unknown encoding type: ${encoding}`);
|
||||
}
|
||||
}
|
||||
function encodeBase64(value) {
|
||||
return Buffer.from(value, "utf-8").toString("base64");
|
||||
}
|
||||
function decodeBase64(value) {
|
||||
return Buffer.from(value, "base64").toString("utf-8");
|
||||
}
|
||||
function encodeHex(value) {
|
||||
return Buffer.from(value, "utf-8").toString("hex");
|
||||
}
|
||||
function decodeHex(value) {
|
||||
return Buffer.from(value, "hex").toString("utf-8");
|
||||
}
|
||||
function encodeRot13(value) {
|
||||
return value.replace(/[a-zA-Z]/g, (char) => {
|
||||
const base = char <= "Z" ? 65 : 97;
|
||||
return String.fromCharCode((char.charCodeAt(0) - base + 13) % 26 + base);
|
||||
});
|
||||
}
|
||||
function decodeRot13(value) {
|
||||
return encodeRot13(value);
|
||||
}
|
||||
|
||||
// src/client/executor.ts
|
||||
function executeFunction(code, params) {
|
||||
try {
|
||||
const wrapper = new Function(`
|
||||
${code}
|
||||
return ${extractFunctionName(code)};
|
||||
`);
|
||||
const fn = wrapper();
|
||||
return fn(...params);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to execute function: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
}
|
||||
}
|
||||
function extractFunctionName(code) {
|
||||
const match = code.match(/function\s+(\w+)/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
throw new Error("Could not extract function name from code");
|
||||
}
|
||||
function executeChainedOperations(initialValue, operations) {
|
||||
let result = initialValue;
|
||||
for (const op of operations) {
|
||||
switch (op.operation) {
|
||||
case "add":
|
||||
result += op.value ?? 0;
|
||||
break;
|
||||
case "subtract":
|
||||
result -= op.value ?? 0;
|
||||
break;
|
||||
case "multiply":
|
||||
result *= op.value ?? 1;
|
||||
break;
|
||||
case "divide":
|
||||
if (op.value === 0) throw new Error("Division by zero");
|
||||
result /= op.value ?? 1;
|
||||
break;
|
||||
case "modulo":
|
||||
if (op.value === 0) throw new Error("Modulo by zero");
|
||||
result %= op.value ?? 1;
|
||||
break;
|
||||
case "power":
|
||||
result = Math.pow(result, op.value ?? 1);
|
||||
break;
|
||||
case "floor":
|
||||
result = Math.floor(result);
|
||||
break;
|
||||
case "ceil":
|
||||
result = Math.ceil(result);
|
||||
break;
|
||||
case "abs":
|
||||
result = Math.abs(result);
|
||||
break;
|
||||
case "negate":
|
||||
result = -result;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown operation: ${op.operation}`);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function executeEncodedInstruction(encodedInstruction, encoding) {
|
||||
const instruction = decode(encodedInstruction, encoding);
|
||||
const match = instruction.match(/Calculate:\s*(\d+)\s*([+\-*\/])\s*(\d+)/);
|
||||
if (!match) {
|
||||
throw new Error(`Could not parse instruction: ${instruction}`);
|
||||
}
|
||||
const a = parseInt(match[1], 10);
|
||||
const op = match[2];
|
||||
const b = parseInt(match[3], 10);
|
||||
switch (op) {
|
||||
case "+":
|
||||
return a + b;
|
||||
case "-":
|
||||
return a - b;
|
||||
case "*":
|
||||
return a * b;
|
||||
case "/":
|
||||
return a / b;
|
||||
default:
|
||||
throw new Error(`Unknown operator: ${op}`);
|
||||
}
|
||||
}
|
||||
function executePatternExtraction(data, query) {
|
||||
const funcMatch = query.match(/^(\w+)\(([^)]+)\)$/);
|
||||
if (!funcMatch) {
|
||||
throw new Error(`Invalid query format: ${query}`);
|
||||
}
|
||||
const [, func, path] = funcMatch;
|
||||
const values = extractPathValues(data, path);
|
||||
switch (func.toLowerCase()) {
|
||||
case "sum":
|
||||
return values.reduce((a, b) => a + b, 0);
|
||||
case "max":
|
||||
return Math.max(...values);
|
||||
case "min":
|
||||
return Math.min(...values);
|
||||
case "count":
|
||||
return values.length;
|
||||
case "avg":
|
||||
const nums = values;
|
||||
return nums.reduce((a, b) => a + b, 0) / nums.length;
|
||||
default:
|
||||
throw new Error(`Unknown function: ${func}`);
|
||||
}
|
||||
}
|
||||
function extractPathValues(data, path) {
|
||||
const wildcardMatch = path.match(/^(\w+)\[\*\]\.(\w+)$/);
|
||||
if (wildcardMatch) {
|
||||
const [, arrayName, propName] = wildcardMatch;
|
||||
const arr = data[arrayName];
|
||||
if (!Array.isArray(arr)) {
|
||||
throw new Error(`Expected array at ${arrayName}`);
|
||||
}
|
||||
return arr.map((item) => item[propName]);
|
||||
}
|
||||
if (path in data) {
|
||||
const value = data[path];
|
||||
return Array.isArray(value) ? value : [value];
|
||||
}
|
||||
throw new Error(`Invalid path: ${path}`);
|
||||
}
|
||||
function executeCodeTransform(code, transform) {
|
||||
const fn = new Function(code);
|
||||
const result = fn();
|
||||
switch (transform) {
|
||||
case "execute":
|
||||
return result;
|
||||
case "execute_and_base64":
|
||||
return Buffer.from(String(result)).toString("base64");
|
||||
case "execute_and_hash":
|
||||
const str = String(result);
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const char = str.charCodeAt(i);
|
||||
hash = (hash << 5) - hash + char;
|
||||
hash = hash & hash;
|
||||
}
|
||||
return Math.abs(hash).toString(16);
|
||||
default:
|
||||
throw new Error(`Unknown transform: ${transform}`);
|
||||
}
|
||||
}
|
||||
function executePayload(payload) {
|
||||
switch (payload.type) {
|
||||
case "function_execution": {
|
||||
const p = payload;
|
||||
return executeFunction(p.functionCode, p.parameters);
|
||||
}
|
||||
case "chained_operations": {
|
||||
const p = payload;
|
||||
return executeChainedOperations(p.initialValue, p.operations);
|
||||
}
|
||||
case "encoded_instruction": {
|
||||
const p = payload;
|
||||
return executeEncodedInstruction(p.instruction, p.instructionEncoding);
|
||||
}
|
||||
case "pattern_extraction": {
|
||||
const p = payload;
|
||||
return executePatternExtraction(p.data, p.query);
|
||||
}
|
||||
case "code_transform": {
|
||||
const p = payload;
|
||||
return executeCodeTransform(p.code, p.transform);
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unknown challenge type: ${payload.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
// src/client/solver.ts
|
||||
var CaptchaLMSolver = class {
|
||||
options;
|
||||
constructor(options) {
|
||||
this.options = {
|
||||
timeout: options?.timeout ?? 1e4,
|
||||
debug: options?.debug ?? false
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Solve a challenge
|
||||
*/
|
||||
solve(challenge) {
|
||||
const startTime = Date.now();
|
||||
try {
|
||||
if (Date.now() > challenge.expiresAt) {
|
||||
return {
|
||||
solution: "",
|
||||
solveDuration: Date.now() - startTime,
|
||||
success: false,
|
||||
error: "Challenge has expired"
|
||||
};
|
||||
}
|
||||
if (this.options.debug) {
|
||||
console.log(`[CaptchaLM] Solving ${challenge.type} challenge...`);
|
||||
}
|
||||
const rawResult = executePayload(challenge.payload);
|
||||
const responseEncoding = challenge.payload.responseEncoding || "plain";
|
||||
const solution = encode(String(rawResult), responseEncoding);
|
||||
const duration = Date.now() - startTime;
|
||||
if (this.options.debug) {
|
||||
console.log(`[CaptchaLM] Solved in ${duration}ms`);
|
||||
}
|
||||
return {
|
||||
solution,
|
||||
solveDuration: duration,
|
||||
success: true
|
||||
};
|
||||
} catch (error) {
|
||||
const duration = Date.now() - startTime;
|
||||
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
if (this.options.debug) {
|
||||
console.error(`[CaptchaLM] Failed to solve: ${errorMessage}`);
|
||||
}
|
||||
return {
|
||||
solution: "",
|
||||
solveDuration: duration,
|
||||
success: false,
|
||||
error: errorMessage
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Solve a challenge and return formatted headers for HTTP request
|
||||
*/
|
||||
solveForRequest(challenge) {
|
||||
const result = this.solve(challenge);
|
||||
if (!result.success) {
|
||||
return {
|
||||
headers: {},
|
||||
body: { _CaptchaLMChallenge: challenge },
|
||||
success: false,
|
||||
error: result.error
|
||||
};
|
||||
}
|
||||
return {
|
||||
headers: {
|
||||
"x-captchalm-id": challenge.id,
|
||||
"x-captchalm-solution": result.solution
|
||||
},
|
||||
body: {
|
||||
_CaptchaLMChallenge: challenge
|
||||
},
|
||||
success: true
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Fetch a challenge from a server and solve it
|
||||
*/
|
||||
async fetchAndSolve(challengeUrl, fetchOptions) {
|
||||
try {
|
||||
const response = await fetch(challengeUrl, {
|
||||
method: "GET",
|
||||
...fetchOptions
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch challenge: ${response.statusText}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
if (!data.success || !data.challenge) {
|
||||
throw new Error(data.error || "Invalid challenge response");
|
||||
}
|
||||
const challenge = data.challenge;
|
||||
const result = this.solve(challenge);
|
||||
return {
|
||||
challenge,
|
||||
solution: result.solution,
|
||||
success: result.success,
|
||||
error: result.error
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
challenge: null,
|
||||
solution: "",
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : "Unknown error"
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Complete a protected request including challenge solving
|
||||
*/
|
||||
async completeProtectedRequest(challengeUrl, protectedUrl, requestOptions) {
|
||||
const { challenge, solution, success, error } = await this.fetchAndSolve(challengeUrl);
|
||||
if (!success) {
|
||||
throw new Error(`Failed to solve challenge: ${error}`);
|
||||
}
|
||||
const headers = new Headers(requestOptions?.headers);
|
||||
headers.set("x-captchalm-id", challenge.id);
|
||||
headers.set("x-captchalm-solution", solution);
|
||||
headers.set("Content-Type", "application/json");
|
||||
const body = requestOptions?.body ? { ...JSON.parse(requestOptions.body), _CaptchaLMChallenge: challenge } : { _CaptchaLMChallenge: challenge };
|
||||
return fetch(protectedUrl, {
|
||||
...requestOptions,
|
||||
headers,
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
}
|
||||
};
|
||||
function createSolver(options) {
|
||||
return new CaptchaLMSolver(options);
|
||||
}
|
||||
|
||||
exports.CaptchaLMSolver = CaptchaLMSolver;
|
||||
exports.createSolver = createSolver;
|
||||
exports.executeChainedOperations = executeChainedOperations;
|
||||
exports.executeCodeTransform = executeCodeTransform;
|
||||
exports.executeEncodedInstruction = executeEncodedInstruction;
|
||||
exports.executeFunction = executeFunction;
|
||||
exports.executePatternExtraction = executePatternExtraction;
|
||||
exports.executePayload = executePayload;
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/captchalm/dist/client/index.cjs.map
generated
vendored
Normal file
1
node_modules/captchalm/dist/client/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
99
node_modules/captchalm/dist/client/index.d.cts
generated
vendored
Normal file
99
node_modules/captchalm/dist/client/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
import { ChainedOperationsPayload, ChallengePayload, Challenge } from '../core/types.cjs';
|
||||
|
||||
/**
|
||||
* Safe code executor for client-side challenge solving
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute a function from code string
|
||||
* Uses Function constructor for sandboxed execution
|
||||
*/
|
||||
declare function executeFunction(code: string, params: unknown[]): unknown;
|
||||
/**
|
||||
* Execute chained operations
|
||||
*/
|
||||
declare function executeChainedOperations(initialValue: number, operations: ChainedOperationsPayload['operations']): number;
|
||||
/**
|
||||
* Parse and execute encoded instructions
|
||||
*/
|
||||
declare function executeEncodedInstruction(encodedInstruction: string, encoding: string): unknown;
|
||||
/**
|
||||
* Execute pattern extraction query
|
||||
*/
|
||||
declare function executePatternExtraction(data: Record<string, unknown>, query: string): unknown;
|
||||
/**
|
||||
* Execute code transform
|
||||
*/
|
||||
declare function executeCodeTransform(code: string, transform: string): unknown;
|
||||
/**
|
||||
* Execute any challenge payload and return the result
|
||||
*/
|
||||
declare function executePayload(payload: ChallengePayload): unknown;
|
||||
|
||||
/**
|
||||
* Challenge solver for AI agents
|
||||
*/
|
||||
|
||||
/**
|
||||
* Solver options
|
||||
*/
|
||||
interface SolverOptions {
|
||||
/** Timeout for solving (ms) */
|
||||
timeout?: number;
|
||||
/** Enable debug logging */
|
||||
debug?: boolean;
|
||||
}
|
||||
/**
|
||||
* Solution result
|
||||
*/
|
||||
interface SolutionResult {
|
||||
/** The computed solution */
|
||||
solution: string;
|
||||
/** Time taken to solve (ms) */
|
||||
solveDuration: number;
|
||||
/** Whether the solve was successful */
|
||||
success: boolean;
|
||||
/** Error message if failed */
|
||||
error?: string;
|
||||
}
|
||||
/**
|
||||
* CaptchaLM Solver for AI agents
|
||||
*/
|
||||
declare class CaptchaLMSolver {
|
||||
private options;
|
||||
constructor(options?: SolverOptions);
|
||||
/**
|
||||
* Solve a challenge
|
||||
*/
|
||||
solve(challenge: Challenge): SolutionResult;
|
||||
/**
|
||||
* Solve a challenge and return formatted headers for HTTP request
|
||||
*/
|
||||
solveForRequest(challenge: Challenge): {
|
||||
headers: Record<string, string>;
|
||||
body: {
|
||||
_CaptchaLMChallenge: Challenge;
|
||||
};
|
||||
success: boolean;
|
||||
error?: string;
|
||||
};
|
||||
/**
|
||||
* Fetch a challenge from a server and solve it
|
||||
*/
|
||||
fetchAndSolve(challengeUrl: string, fetchOptions?: RequestInit): Promise<{
|
||||
challenge: Challenge;
|
||||
solution: string;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
/**
|
||||
* Complete a protected request including challenge solving
|
||||
*/
|
||||
completeProtectedRequest(challengeUrl: string, protectedUrl: string, requestOptions?: RequestInit): Promise<Response>;
|
||||
}
|
||||
/**
|
||||
* Create a solver instance
|
||||
*/
|
||||
declare function createSolver(options?: SolverOptions): CaptchaLMSolver;
|
||||
|
||||
export { CaptchaLMSolver, type SolutionResult, type SolverOptions, createSolver, executeChainedOperations, executeCodeTransform, executeEncodedInstruction, executeFunction, executePatternExtraction, executePayload };
|
||||
99
node_modules/captchalm/dist/client/index.d.ts
generated
vendored
Normal file
99
node_modules/captchalm/dist/client/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
import { ChainedOperationsPayload, ChallengePayload, Challenge } from '../core/types.js';
|
||||
|
||||
/**
|
||||
* Safe code executor for client-side challenge solving
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute a function from code string
|
||||
* Uses Function constructor for sandboxed execution
|
||||
*/
|
||||
declare function executeFunction(code: string, params: unknown[]): unknown;
|
||||
/**
|
||||
* Execute chained operations
|
||||
*/
|
||||
declare function executeChainedOperations(initialValue: number, operations: ChainedOperationsPayload['operations']): number;
|
||||
/**
|
||||
* Parse and execute encoded instructions
|
||||
*/
|
||||
declare function executeEncodedInstruction(encodedInstruction: string, encoding: string): unknown;
|
||||
/**
|
||||
* Execute pattern extraction query
|
||||
*/
|
||||
declare function executePatternExtraction(data: Record<string, unknown>, query: string): unknown;
|
||||
/**
|
||||
* Execute code transform
|
||||
*/
|
||||
declare function executeCodeTransform(code: string, transform: string): unknown;
|
||||
/**
|
||||
* Execute any challenge payload and return the result
|
||||
*/
|
||||
declare function executePayload(payload: ChallengePayload): unknown;
|
||||
|
||||
/**
|
||||
* Challenge solver for AI agents
|
||||
*/
|
||||
|
||||
/**
|
||||
* Solver options
|
||||
*/
|
||||
interface SolverOptions {
|
||||
/** Timeout for solving (ms) */
|
||||
timeout?: number;
|
||||
/** Enable debug logging */
|
||||
debug?: boolean;
|
||||
}
|
||||
/**
|
||||
* Solution result
|
||||
*/
|
||||
interface SolutionResult {
|
||||
/** The computed solution */
|
||||
solution: string;
|
||||
/** Time taken to solve (ms) */
|
||||
solveDuration: number;
|
||||
/** Whether the solve was successful */
|
||||
success: boolean;
|
||||
/** Error message if failed */
|
||||
error?: string;
|
||||
}
|
||||
/**
|
||||
* CaptchaLM Solver for AI agents
|
||||
*/
|
||||
declare class CaptchaLMSolver {
|
||||
private options;
|
||||
constructor(options?: SolverOptions);
|
||||
/**
|
||||
* Solve a challenge
|
||||
*/
|
||||
solve(challenge: Challenge): SolutionResult;
|
||||
/**
|
||||
* Solve a challenge and return formatted headers for HTTP request
|
||||
*/
|
||||
solveForRequest(challenge: Challenge): {
|
||||
headers: Record<string, string>;
|
||||
body: {
|
||||
_CaptchaLMChallenge: Challenge;
|
||||
};
|
||||
success: boolean;
|
||||
error?: string;
|
||||
};
|
||||
/**
|
||||
* Fetch a challenge from a server and solve it
|
||||
*/
|
||||
fetchAndSolve(challengeUrl: string, fetchOptions?: RequestInit): Promise<{
|
||||
challenge: Challenge;
|
||||
solution: string;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
/**
|
||||
* Complete a protected request including challenge solving
|
||||
*/
|
||||
completeProtectedRequest(challengeUrl: string, protectedUrl: string, requestOptions?: RequestInit): Promise<Response>;
|
||||
}
|
||||
/**
|
||||
* Create a solver instance
|
||||
*/
|
||||
declare function createSolver(options?: SolverOptions): CaptchaLMSolver;
|
||||
|
||||
export { CaptchaLMSolver, type SolutionResult, type SolverOptions, createSolver, executeChainedOperations, executeCodeTransform, executeEncodedInstruction, executeFunction, executePatternExtraction, executePayload };
|
||||
359
node_modules/captchalm/dist/client/index.js
generated
vendored
Normal file
359
node_modules/captchalm/dist/client/index.js
generated
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
// src/core/encoding.ts
|
||||
function encode(value, encoding) {
|
||||
switch (encoding) {
|
||||
case "plain":
|
||||
return value;
|
||||
case "base64":
|
||||
return encodeBase64(value);
|
||||
case "hex":
|
||||
return encodeHex(value);
|
||||
case "rot13":
|
||||
return encodeRot13(value);
|
||||
default:
|
||||
throw new Error(`Unknown encoding type: ${encoding}`);
|
||||
}
|
||||
}
|
||||
function decode(value, encoding) {
|
||||
switch (encoding) {
|
||||
case "plain":
|
||||
return value;
|
||||
case "base64":
|
||||
return decodeBase64(value);
|
||||
case "hex":
|
||||
return decodeHex(value);
|
||||
case "rot13":
|
||||
return decodeRot13(value);
|
||||
// ROT13 is symmetric
|
||||
default:
|
||||
throw new Error(`Unknown encoding type: ${encoding}`);
|
||||
}
|
||||
}
|
||||
function encodeBase64(value) {
|
||||
return Buffer.from(value, "utf-8").toString("base64");
|
||||
}
|
||||
function decodeBase64(value) {
|
||||
return Buffer.from(value, "base64").toString("utf-8");
|
||||
}
|
||||
function encodeHex(value) {
|
||||
return Buffer.from(value, "utf-8").toString("hex");
|
||||
}
|
||||
function decodeHex(value) {
|
||||
return Buffer.from(value, "hex").toString("utf-8");
|
||||
}
|
||||
function encodeRot13(value) {
|
||||
return value.replace(/[a-zA-Z]/g, (char) => {
|
||||
const base = char <= "Z" ? 65 : 97;
|
||||
return String.fromCharCode((char.charCodeAt(0) - base + 13) % 26 + base);
|
||||
});
|
||||
}
|
||||
function decodeRot13(value) {
|
||||
return encodeRot13(value);
|
||||
}
|
||||
|
||||
// src/client/executor.ts
|
||||
function executeFunction(code, params) {
|
||||
try {
|
||||
const wrapper = new Function(`
|
||||
${code}
|
||||
return ${extractFunctionName(code)};
|
||||
`);
|
||||
const fn = wrapper();
|
||||
return fn(...params);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to execute function: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
}
|
||||
}
|
||||
function extractFunctionName(code) {
|
||||
const match = code.match(/function\s+(\w+)/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
throw new Error("Could not extract function name from code");
|
||||
}
|
||||
function executeChainedOperations(initialValue, operations) {
|
||||
let result = initialValue;
|
||||
for (const op of operations) {
|
||||
switch (op.operation) {
|
||||
case "add":
|
||||
result += op.value ?? 0;
|
||||
break;
|
||||
case "subtract":
|
||||
result -= op.value ?? 0;
|
||||
break;
|
||||
case "multiply":
|
||||
result *= op.value ?? 1;
|
||||
break;
|
||||
case "divide":
|
||||
if (op.value === 0) throw new Error("Division by zero");
|
||||
result /= op.value ?? 1;
|
||||
break;
|
||||
case "modulo":
|
||||
if (op.value === 0) throw new Error("Modulo by zero");
|
||||
result %= op.value ?? 1;
|
||||
break;
|
||||
case "power":
|
||||
result = Math.pow(result, op.value ?? 1);
|
||||
break;
|
||||
case "floor":
|
||||
result = Math.floor(result);
|
||||
break;
|
||||
case "ceil":
|
||||
result = Math.ceil(result);
|
||||
break;
|
||||
case "abs":
|
||||
result = Math.abs(result);
|
||||
break;
|
||||
case "negate":
|
||||
result = -result;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown operation: ${op.operation}`);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function executeEncodedInstruction(encodedInstruction, encoding) {
|
||||
const instruction = decode(encodedInstruction, encoding);
|
||||
const match = instruction.match(/Calculate:\s*(\d+)\s*([+\-*\/])\s*(\d+)/);
|
||||
if (!match) {
|
||||
throw new Error(`Could not parse instruction: ${instruction}`);
|
||||
}
|
||||
const a = parseInt(match[1], 10);
|
||||
const op = match[2];
|
||||
const b = parseInt(match[3], 10);
|
||||
switch (op) {
|
||||
case "+":
|
||||
return a + b;
|
||||
case "-":
|
||||
return a - b;
|
||||
case "*":
|
||||
return a * b;
|
||||
case "/":
|
||||
return a / b;
|
||||
default:
|
||||
throw new Error(`Unknown operator: ${op}`);
|
||||
}
|
||||
}
|
||||
function executePatternExtraction(data, query) {
|
||||
const funcMatch = query.match(/^(\w+)\(([^)]+)\)$/);
|
||||
if (!funcMatch) {
|
||||
throw new Error(`Invalid query format: ${query}`);
|
||||
}
|
||||
const [, func, path] = funcMatch;
|
||||
const values = extractPathValues(data, path);
|
||||
switch (func.toLowerCase()) {
|
||||
case "sum":
|
||||
return values.reduce((a, b) => a + b, 0);
|
||||
case "max":
|
||||
return Math.max(...values);
|
||||
case "min":
|
||||
return Math.min(...values);
|
||||
case "count":
|
||||
return values.length;
|
||||
case "avg":
|
||||
const nums = values;
|
||||
return nums.reduce((a, b) => a + b, 0) / nums.length;
|
||||
default:
|
||||
throw new Error(`Unknown function: ${func}`);
|
||||
}
|
||||
}
|
||||
function extractPathValues(data, path) {
|
||||
const wildcardMatch = path.match(/^(\w+)\[\*\]\.(\w+)$/);
|
||||
if (wildcardMatch) {
|
||||
const [, arrayName, propName] = wildcardMatch;
|
||||
const arr = data[arrayName];
|
||||
if (!Array.isArray(arr)) {
|
||||
throw new Error(`Expected array at ${arrayName}`);
|
||||
}
|
||||
return arr.map((item) => item[propName]);
|
||||
}
|
||||
if (path in data) {
|
||||
const value = data[path];
|
||||
return Array.isArray(value) ? value : [value];
|
||||
}
|
||||
throw new Error(`Invalid path: ${path}`);
|
||||
}
|
||||
function executeCodeTransform(code, transform) {
|
||||
const fn = new Function(code);
|
||||
const result = fn();
|
||||
switch (transform) {
|
||||
case "execute":
|
||||
return result;
|
||||
case "execute_and_base64":
|
||||
return Buffer.from(String(result)).toString("base64");
|
||||
case "execute_and_hash":
|
||||
const str = String(result);
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const char = str.charCodeAt(i);
|
||||
hash = (hash << 5) - hash + char;
|
||||
hash = hash & hash;
|
||||
}
|
||||
return Math.abs(hash).toString(16);
|
||||
default:
|
||||
throw new Error(`Unknown transform: ${transform}`);
|
||||
}
|
||||
}
|
||||
function executePayload(payload) {
|
||||
switch (payload.type) {
|
||||
case "function_execution": {
|
||||
const p = payload;
|
||||
return executeFunction(p.functionCode, p.parameters);
|
||||
}
|
||||
case "chained_operations": {
|
||||
const p = payload;
|
||||
return executeChainedOperations(p.initialValue, p.operations);
|
||||
}
|
||||
case "encoded_instruction": {
|
||||
const p = payload;
|
||||
return executeEncodedInstruction(p.instruction, p.instructionEncoding);
|
||||
}
|
||||
case "pattern_extraction": {
|
||||
const p = payload;
|
||||
return executePatternExtraction(p.data, p.query);
|
||||
}
|
||||
case "code_transform": {
|
||||
const p = payload;
|
||||
return executeCodeTransform(p.code, p.transform);
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unknown challenge type: ${payload.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
// src/client/solver.ts
|
||||
var CaptchaLMSolver = class {
|
||||
options;
|
||||
constructor(options) {
|
||||
this.options = {
|
||||
timeout: options?.timeout ?? 1e4,
|
||||
debug: options?.debug ?? false
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Solve a challenge
|
||||
*/
|
||||
solve(challenge) {
|
||||
const startTime = Date.now();
|
||||
try {
|
||||
if (Date.now() > challenge.expiresAt) {
|
||||
return {
|
||||
solution: "",
|
||||
solveDuration: Date.now() - startTime,
|
||||
success: false,
|
||||
error: "Challenge has expired"
|
||||
};
|
||||
}
|
||||
if (this.options.debug) {
|
||||
console.log(`[CaptchaLM] Solving ${challenge.type} challenge...`);
|
||||
}
|
||||
const rawResult = executePayload(challenge.payload);
|
||||
const responseEncoding = challenge.payload.responseEncoding || "plain";
|
||||
const solution = encode(String(rawResult), responseEncoding);
|
||||
const duration = Date.now() - startTime;
|
||||
if (this.options.debug) {
|
||||
console.log(`[CaptchaLM] Solved in ${duration}ms`);
|
||||
}
|
||||
return {
|
||||
solution,
|
||||
solveDuration: duration,
|
||||
success: true
|
||||
};
|
||||
} catch (error) {
|
||||
const duration = Date.now() - startTime;
|
||||
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
if (this.options.debug) {
|
||||
console.error(`[CaptchaLM] Failed to solve: ${errorMessage}`);
|
||||
}
|
||||
return {
|
||||
solution: "",
|
||||
solveDuration: duration,
|
||||
success: false,
|
||||
error: errorMessage
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Solve a challenge and return formatted headers for HTTP request
|
||||
*/
|
||||
solveForRequest(challenge) {
|
||||
const result = this.solve(challenge);
|
||||
if (!result.success) {
|
||||
return {
|
||||
headers: {},
|
||||
body: { _CaptchaLMChallenge: challenge },
|
||||
success: false,
|
||||
error: result.error
|
||||
};
|
||||
}
|
||||
return {
|
||||
headers: {
|
||||
"x-captchalm-id": challenge.id,
|
||||
"x-captchalm-solution": result.solution
|
||||
},
|
||||
body: {
|
||||
_CaptchaLMChallenge: challenge
|
||||
},
|
||||
success: true
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Fetch a challenge from a server and solve it
|
||||
*/
|
||||
async fetchAndSolve(challengeUrl, fetchOptions) {
|
||||
try {
|
||||
const response = await fetch(challengeUrl, {
|
||||
method: "GET",
|
||||
...fetchOptions
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch challenge: ${response.statusText}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
if (!data.success || !data.challenge) {
|
||||
throw new Error(data.error || "Invalid challenge response");
|
||||
}
|
||||
const challenge = data.challenge;
|
||||
const result = this.solve(challenge);
|
||||
return {
|
||||
challenge,
|
||||
solution: result.solution,
|
||||
success: result.success,
|
||||
error: result.error
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
challenge: null,
|
||||
solution: "",
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : "Unknown error"
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Complete a protected request including challenge solving
|
||||
*/
|
||||
async completeProtectedRequest(challengeUrl, protectedUrl, requestOptions) {
|
||||
const { challenge, solution, success, error } = await this.fetchAndSolve(challengeUrl);
|
||||
if (!success) {
|
||||
throw new Error(`Failed to solve challenge: ${error}`);
|
||||
}
|
||||
const headers = new Headers(requestOptions?.headers);
|
||||
headers.set("x-captchalm-id", challenge.id);
|
||||
headers.set("x-captchalm-solution", solution);
|
||||
headers.set("Content-Type", "application/json");
|
||||
const body = requestOptions?.body ? { ...JSON.parse(requestOptions.body), _CaptchaLMChallenge: challenge } : { _CaptchaLMChallenge: challenge };
|
||||
return fetch(protectedUrl, {
|
||||
...requestOptions,
|
||||
headers,
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
}
|
||||
};
|
||||
function createSolver(options) {
|
||||
return new CaptchaLMSolver(options);
|
||||
}
|
||||
|
||||
export { CaptchaLMSolver, createSolver, executeChainedOperations, executeCodeTransform, executeEncodedInstruction, executeFunction, executePatternExtraction, executePayload };
|
||||
//# sourceMappingURL=index.js.map
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/captchalm/dist/client/index.js.map
generated
vendored
Normal file
1
node_modules/captchalm/dist/client/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4
node_modules/captchalm/dist/core/types.cjs
generated
vendored
Normal file
4
node_modules/captchalm/dist/core/types.cjs
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
//# sourceMappingURL=types.cjs.map
|
||||
//# sourceMappingURL=types.cjs.map
|
||||
1
node_modules/captchalm/dist/core/types.cjs.map
generated
vendored
Normal file
1
node_modules/captchalm/dist/core/types.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"types.cjs"}
|
||||
149
node_modules/captchalm/dist/core/types.d.cts
generated
vendored
Normal file
149
node_modules/captchalm/dist/core/types.d.cts
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* CaptchaLM - AI-Only Access Control
|
||||
*
|
||||
* Core type definitions for challenges, responses, and configurations
|
||||
*/
|
||||
type EncodingType = 'plain' | 'base64' | 'hex' | 'rot13';
|
||||
type ChallengeType = 'function_execution' | 'chained_operations' | 'encoded_instruction' | 'pattern_extraction' | 'code_transform';
|
||||
/**
|
||||
* Function Execution Challenge
|
||||
* Present a function definition and parameters, expect computed output
|
||||
*/
|
||||
interface FunctionExecutionPayload {
|
||||
type: 'function_execution';
|
||||
/** The function name to execute */
|
||||
functionName: string;
|
||||
/** Function code as a string */
|
||||
functionCode: string;
|
||||
/** Parameters to pass to the function */
|
||||
parameters: unknown[];
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
/**
|
||||
* Chained Operations Challenge
|
||||
* Multi-step instructions requiring sequential execution
|
||||
*/
|
||||
interface ChainedOperationsPayload {
|
||||
type: 'chained_operations';
|
||||
/** Initial value to start with */
|
||||
initialValue: number;
|
||||
/** Operations to apply sequentially */
|
||||
operations: ChainedOperation[];
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
interface ChainedOperation {
|
||||
operation: 'add' | 'subtract' | 'multiply' | 'divide' | 'modulo' | 'power' | 'floor' | 'ceil' | 'abs' | 'negate';
|
||||
value?: number;
|
||||
}
|
||||
/**
|
||||
* Encoded Instruction Challenge
|
||||
* Instructions encoded in various formats
|
||||
*/
|
||||
interface EncodedInstructionPayload {
|
||||
type: 'encoded_instruction';
|
||||
/** The encoded instruction */
|
||||
instruction: string;
|
||||
/** How the instruction is encoded */
|
||||
instructionEncoding: EncodingType;
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
/**
|
||||
* Pattern Extraction Challenge
|
||||
* Extract specific patterns from structured data
|
||||
*/
|
||||
interface PatternExtractionPayload {
|
||||
type: 'pattern_extraction';
|
||||
/** The data to query */
|
||||
data: Record<string, unknown>;
|
||||
/** The query expression */
|
||||
query: string;
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
/**
|
||||
* Code Transform Challenge
|
||||
* Transform code according to specified rules
|
||||
*/
|
||||
interface CodeTransformPayload {
|
||||
type: 'code_transform';
|
||||
/** The code to transform/execute */
|
||||
code: string;
|
||||
/** The transformation to apply */
|
||||
transform: 'execute' | 'execute_and_hash' | 'execute_and_base64';
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
type ChallengePayload = FunctionExecutionPayload | ChainedOperationsPayload | EncodedInstructionPayload | PatternExtractionPayload | CodeTransformPayload;
|
||||
interface Challenge {
|
||||
/** Unique challenge identifier */
|
||||
id: string;
|
||||
/** Type of challenge */
|
||||
type: ChallengeType;
|
||||
/** Difficulty level */
|
||||
difficulty: ChallengeDifficulty;
|
||||
/** Challenge-specific payload */
|
||||
payload: ChallengePayload;
|
||||
/** Expiration timestamp (Unix ms) */
|
||||
expiresAt: number;
|
||||
/** HMAC signature for integrity verification */
|
||||
signature: string;
|
||||
}
|
||||
type ChallengeDifficulty = 'easy' | 'medium' | 'hard';
|
||||
interface ChallengeSolution {
|
||||
/** Challenge ID being solved */
|
||||
challengeId: string;
|
||||
/** The computed solution */
|
||||
solution: string;
|
||||
}
|
||||
interface VerificationResult {
|
||||
/** Whether the solution is valid */
|
||||
valid: boolean;
|
||||
/** Error message if invalid */
|
||||
error?: string;
|
||||
/** Error code for programmatic handling */
|
||||
errorCode?: VerificationErrorCode;
|
||||
}
|
||||
type VerificationErrorCode = 'EXPIRED' | 'INVALID_SIGNATURE' | 'INVALID_SOLUTION' | 'RATE_LIMITED' | 'CHALLENGE_NOT_FOUND';
|
||||
interface CaptchaLMConfig {
|
||||
/** Secret key for HMAC signing */
|
||||
secret: string;
|
||||
/** Default difficulty level */
|
||||
difficulty?: ChallengeDifficulty;
|
||||
/** Challenge types to use (defaults to all) */
|
||||
challengeTypes?: ChallengeType[];
|
||||
/** Challenge expiration time in milliseconds */
|
||||
expirationMs?: number;
|
||||
/** Rate limiting configuration */
|
||||
rateLimit?: RateLimitConfig;
|
||||
}
|
||||
interface RateLimitConfig {
|
||||
/** Maximum attempts per window */
|
||||
maxAttempts: number;
|
||||
/** Window duration in milliseconds */
|
||||
windowMs: number;
|
||||
}
|
||||
interface RegisteredFunction {
|
||||
/** Function name */
|
||||
name: string;
|
||||
/** Function implementation */
|
||||
fn: (...args: unknown[]) => unknown;
|
||||
/** Parameter types for validation */
|
||||
parameterTypes: string[];
|
||||
/** Description for documentation */
|
||||
description: string;
|
||||
/** Difficulty level of this function */
|
||||
difficulty: ChallengeDifficulty;
|
||||
}
|
||||
interface MiddlewareConfig extends CaptchaLMConfig {
|
||||
/** Header name for challenge ID */
|
||||
challengeIdHeader?: string;
|
||||
/** Header name for solution */
|
||||
solutionHeader?: string;
|
||||
/** Path to challenge endpoint */
|
||||
challengeEndpoint?: string;
|
||||
}
|
||||
|
||||
export type { CaptchaLMConfig, ChainedOperation, ChainedOperationsPayload, Challenge, ChallengeDifficulty, ChallengePayload, ChallengeSolution, ChallengeType, CodeTransformPayload, EncodedInstructionPayload, EncodingType, FunctionExecutionPayload, MiddlewareConfig, PatternExtractionPayload, RateLimitConfig, RegisteredFunction, VerificationErrorCode, VerificationResult };
|
||||
149
node_modules/captchalm/dist/core/types.d.ts
generated
vendored
Normal file
149
node_modules/captchalm/dist/core/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* CaptchaLM - AI-Only Access Control
|
||||
*
|
||||
* Core type definitions for challenges, responses, and configurations
|
||||
*/
|
||||
type EncodingType = 'plain' | 'base64' | 'hex' | 'rot13';
|
||||
type ChallengeType = 'function_execution' | 'chained_operations' | 'encoded_instruction' | 'pattern_extraction' | 'code_transform';
|
||||
/**
|
||||
* Function Execution Challenge
|
||||
* Present a function definition and parameters, expect computed output
|
||||
*/
|
||||
interface FunctionExecutionPayload {
|
||||
type: 'function_execution';
|
||||
/** The function name to execute */
|
||||
functionName: string;
|
||||
/** Function code as a string */
|
||||
functionCode: string;
|
||||
/** Parameters to pass to the function */
|
||||
parameters: unknown[];
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
/**
|
||||
* Chained Operations Challenge
|
||||
* Multi-step instructions requiring sequential execution
|
||||
*/
|
||||
interface ChainedOperationsPayload {
|
||||
type: 'chained_operations';
|
||||
/** Initial value to start with */
|
||||
initialValue: number;
|
||||
/** Operations to apply sequentially */
|
||||
operations: ChainedOperation[];
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
interface ChainedOperation {
|
||||
operation: 'add' | 'subtract' | 'multiply' | 'divide' | 'modulo' | 'power' | 'floor' | 'ceil' | 'abs' | 'negate';
|
||||
value?: number;
|
||||
}
|
||||
/**
|
||||
* Encoded Instruction Challenge
|
||||
* Instructions encoded in various formats
|
||||
*/
|
||||
interface EncodedInstructionPayload {
|
||||
type: 'encoded_instruction';
|
||||
/** The encoded instruction */
|
||||
instruction: string;
|
||||
/** How the instruction is encoded */
|
||||
instructionEncoding: EncodingType;
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
/**
|
||||
* Pattern Extraction Challenge
|
||||
* Extract specific patterns from structured data
|
||||
*/
|
||||
interface PatternExtractionPayload {
|
||||
type: 'pattern_extraction';
|
||||
/** The data to query */
|
||||
data: Record<string, unknown>;
|
||||
/** The query expression */
|
||||
query: string;
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
/**
|
||||
* Code Transform Challenge
|
||||
* Transform code according to specified rules
|
||||
*/
|
||||
interface CodeTransformPayload {
|
||||
type: 'code_transform';
|
||||
/** The code to transform/execute */
|
||||
code: string;
|
||||
/** The transformation to apply */
|
||||
transform: 'execute' | 'execute_and_hash' | 'execute_and_base64';
|
||||
/** Required encoding for the response */
|
||||
responseEncoding: EncodingType;
|
||||
}
|
||||
type ChallengePayload = FunctionExecutionPayload | ChainedOperationsPayload | EncodedInstructionPayload | PatternExtractionPayload | CodeTransformPayload;
|
||||
interface Challenge {
|
||||
/** Unique challenge identifier */
|
||||
id: string;
|
||||
/** Type of challenge */
|
||||
type: ChallengeType;
|
||||
/** Difficulty level */
|
||||
difficulty: ChallengeDifficulty;
|
||||
/** Challenge-specific payload */
|
||||
payload: ChallengePayload;
|
||||
/** Expiration timestamp (Unix ms) */
|
||||
expiresAt: number;
|
||||
/** HMAC signature for integrity verification */
|
||||
signature: string;
|
||||
}
|
||||
type ChallengeDifficulty = 'easy' | 'medium' | 'hard';
|
||||
interface ChallengeSolution {
|
||||
/** Challenge ID being solved */
|
||||
challengeId: string;
|
||||
/** The computed solution */
|
||||
solution: string;
|
||||
}
|
||||
interface VerificationResult {
|
||||
/** Whether the solution is valid */
|
||||
valid: boolean;
|
||||
/** Error message if invalid */
|
||||
error?: string;
|
||||
/** Error code for programmatic handling */
|
||||
errorCode?: VerificationErrorCode;
|
||||
}
|
||||
type VerificationErrorCode = 'EXPIRED' | 'INVALID_SIGNATURE' | 'INVALID_SOLUTION' | 'RATE_LIMITED' | 'CHALLENGE_NOT_FOUND';
|
||||
interface CaptchaLMConfig {
|
||||
/** Secret key for HMAC signing */
|
||||
secret: string;
|
||||
/** Default difficulty level */
|
||||
difficulty?: ChallengeDifficulty;
|
||||
/** Challenge types to use (defaults to all) */
|
||||
challengeTypes?: ChallengeType[];
|
||||
/** Challenge expiration time in milliseconds */
|
||||
expirationMs?: number;
|
||||
/** Rate limiting configuration */
|
||||
rateLimit?: RateLimitConfig;
|
||||
}
|
||||
interface RateLimitConfig {
|
||||
/** Maximum attempts per window */
|
||||
maxAttempts: number;
|
||||
/** Window duration in milliseconds */
|
||||
windowMs: number;
|
||||
}
|
||||
interface RegisteredFunction {
|
||||
/** Function name */
|
||||
name: string;
|
||||
/** Function implementation */
|
||||
fn: (...args: unknown[]) => unknown;
|
||||
/** Parameter types for validation */
|
||||
parameterTypes: string[];
|
||||
/** Description for documentation */
|
||||
description: string;
|
||||
/** Difficulty level of this function */
|
||||
difficulty: ChallengeDifficulty;
|
||||
}
|
||||
interface MiddlewareConfig extends CaptchaLMConfig {
|
||||
/** Header name for challenge ID */
|
||||
challengeIdHeader?: string;
|
||||
/** Header name for solution */
|
||||
solutionHeader?: string;
|
||||
/** Path to challenge endpoint */
|
||||
challengeEndpoint?: string;
|
||||
}
|
||||
|
||||
export type { CaptchaLMConfig, ChainedOperation, ChainedOperationsPayload, Challenge, ChallengeDifficulty, ChallengePayload, ChallengeSolution, ChallengeType, CodeTransformPayload, EncodedInstructionPayload, EncodingType, FunctionExecutionPayload, MiddlewareConfig, PatternExtractionPayload, RateLimitConfig, RegisteredFunction, VerificationErrorCode, VerificationResult };
|
||||
3
node_modules/captchalm/dist/core/types.js
generated
vendored
Normal file
3
node_modules/captchalm/dist/core/types.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
//# sourceMappingURL=types.js.map
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
node_modules/captchalm/dist/core/types.js.map
generated
vendored
Normal file
1
node_modules/captchalm/dist/core/types.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"types.js"}
|
||||
1924
node_modules/captchalm/dist/index.cjs
generated
vendored
Normal file
1924
node_modules/captchalm/dist/index.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/captchalm/dist/index.cjs.map
generated
vendored
Normal file
1
node_modules/captchalm/dist/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
321
node_modules/captchalm/dist/index.d.cts
generated
vendored
Normal file
321
node_modules/captchalm/dist/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
import { EncodingType, CaptchaLMConfig, ChallengeType, ChallengeDifficulty, Challenge, ChallengeSolution, VerificationResult, MiddlewareConfig, RegisteredFunction } from './core/types.cjs';
|
||||
export { ChainedOperation, ChainedOperationsPayload, ChallengePayload, CodeTransformPayload, EncodedInstructionPayload, FunctionExecutionPayload, PatternExtractionPayload, RateLimitConfig, VerificationErrorCode } from './core/types.cjs';
|
||||
import { Request, RequestHandler } from 'express';
|
||||
|
||||
/**
|
||||
* Encoding utilities for CaptchaLM challenges
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encode a value using the specified encoding
|
||||
*/
|
||||
declare function encode(value: string, encoding: EncodingType): string;
|
||||
/**
|
||||
* Decode a value using the specified encoding
|
||||
*/
|
||||
declare function decode(value: string, encoding: EncodingType): string;
|
||||
/**
|
||||
* Base64 encode a string
|
||||
*/
|
||||
declare function encodeBase64(value: string): string;
|
||||
/**
|
||||
* Base64 decode a string
|
||||
*/
|
||||
declare function decodeBase64(value: string): string;
|
||||
/**
|
||||
* Hex encode a string
|
||||
*/
|
||||
declare function encodeHex(value: string): string;
|
||||
/**
|
||||
* Hex decode a string
|
||||
*/
|
||||
declare function decodeHex(value: string): string;
|
||||
/**
|
||||
* ROT13 encode/decode a string (symmetric cipher)
|
||||
*/
|
||||
declare function encodeRot13(value: string): string;
|
||||
/**
|
||||
* ROT13 decode (same as encode, symmetric)
|
||||
*/
|
||||
declare function decodeRot13(value: string): string;
|
||||
/**
|
||||
* Apply multiple encoding layers
|
||||
*/
|
||||
declare function encodeChain(value: string, encodings: EncodingType[]): string;
|
||||
/**
|
||||
* Decode multiple encoding layers (in reverse order)
|
||||
*/
|
||||
declare function decodeChain(value: string, encodings: EncodingType[]): string;
|
||||
|
||||
/**
|
||||
* Challenge generator for CaptchaLM
|
||||
*/
|
||||
|
||||
/**
|
||||
* Challenge generator class
|
||||
*/
|
||||
declare class ChallengeGenerator {
|
||||
private config;
|
||||
constructor(config: CaptchaLMConfig);
|
||||
/**
|
||||
* Generate a new challenge
|
||||
*/
|
||||
generate(overrides?: Partial<{
|
||||
type: ChallengeType;
|
||||
difficulty: ChallengeDifficulty;
|
||||
}>): {
|
||||
challenge: Challenge;
|
||||
expectedAnswer: string;
|
||||
};
|
||||
/**
|
||||
* Generate payload for a specific challenge type
|
||||
*/
|
||||
private generatePayload;
|
||||
/**
|
||||
* Generate a function execution challenge
|
||||
*/
|
||||
private generateFunctionExecution;
|
||||
/**
|
||||
* Generate a chained operations challenge
|
||||
*/
|
||||
private generateChainedOperations;
|
||||
/**
|
||||
* Generate an encoded instruction challenge
|
||||
*/
|
||||
private generateEncodedInstruction;
|
||||
/**
|
||||
* Generate a pattern extraction challenge
|
||||
*/
|
||||
private generatePatternExtraction;
|
||||
/**
|
||||
* Generate a code transform challenge
|
||||
*/
|
||||
private generateCodeTransform;
|
||||
/**
|
||||
* Get response encoding based on difficulty
|
||||
*/
|
||||
private getResponseEncoding;
|
||||
/**
|
||||
* Get instruction encoding based on difficulty
|
||||
*/
|
||||
private getInstructionEncoding;
|
||||
/**
|
||||
* Generate parameters for a function
|
||||
*/
|
||||
private generateParameters;
|
||||
/**
|
||||
* Generate random words joined by spaces
|
||||
*/
|
||||
private generateRandomWords;
|
||||
/**
|
||||
* Generate a random word
|
||||
*/
|
||||
private generateRandomWord;
|
||||
/**
|
||||
* Mutate a word by changing N characters
|
||||
*/
|
||||
private mutateWord;
|
||||
/**
|
||||
* Generate a random array of numbers
|
||||
*/
|
||||
private generateRandomArray;
|
||||
/**
|
||||
* Get function code as string (for display)
|
||||
*/
|
||||
private getFunctionCodeString;
|
||||
}
|
||||
/**
|
||||
* Create a challenge generator
|
||||
*/
|
||||
declare function createGenerator(config: CaptchaLMConfig): ChallengeGenerator;
|
||||
|
||||
/**
|
||||
* Challenge verifier for CaptchaLM
|
||||
*/
|
||||
|
||||
/**
|
||||
* Challenge verifier class
|
||||
*/
|
||||
declare class ChallengeVerifier {
|
||||
private config;
|
||||
private rateLimiter;
|
||||
private challengeStore;
|
||||
private cleanupInterval;
|
||||
constructor(config: CaptchaLMConfig);
|
||||
/**
|
||||
* Store expected answer for a challenge
|
||||
*/
|
||||
storeChallenge(challengeId: string, expectedAnswer: string, expiresAt: number): void;
|
||||
/**
|
||||
* Verify a challenge solution
|
||||
*/
|
||||
verify(challenge: Challenge, solution: ChallengeSolution, clientIdentifier?: string): VerificationResult;
|
||||
/**
|
||||
* Verify a solution using only the signature (stateless mode)
|
||||
*
|
||||
* In stateless mode, the expected answer is encoded in the signature
|
||||
* This is less secure but allows for distributed deployments
|
||||
*/
|
||||
verifyStateless(challenge: Challenge, solution: ChallengeSolution, clientIdentifier?: string): VerificationResult;
|
||||
/**
|
||||
* Get rate limit status for a client
|
||||
*/
|
||||
getRateLimitStatus(clientIdentifier: string): {
|
||||
remaining: number;
|
||||
isLimited: boolean;
|
||||
};
|
||||
/**
|
||||
* Start periodic cleanup of expired challenges
|
||||
*/
|
||||
private startCleanup;
|
||||
/**
|
||||
* Clean up expired challenges
|
||||
*/
|
||||
private cleanup;
|
||||
/**
|
||||
* Destroy the verifier and clean up resources
|
||||
*/
|
||||
destroy(): void;
|
||||
/**
|
||||
* Get stats for monitoring
|
||||
*/
|
||||
getStats(): {
|
||||
pendingChallenges: number;
|
||||
rateLimitStats: {
|
||||
activeKeys: number;
|
||||
totalAttempts: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create a challenge verifier
|
||||
*/
|
||||
declare function createVerifier(config: CaptchaLMConfig): ChallengeVerifier;
|
||||
|
||||
/**
|
||||
* Standalone CaptchaLM API
|
||||
* Framework-agnostic implementation for custom integrations
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main CaptchaLM class for standalone usage
|
||||
*/
|
||||
declare class CaptchaLM {
|
||||
private generator;
|
||||
private verifier;
|
||||
private config;
|
||||
constructor(config: CaptchaLMConfig);
|
||||
/**
|
||||
* Generate a new challenge
|
||||
*/
|
||||
generate(options?: {
|
||||
type?: ChallengeType;
|
||||
difficulty?: ChallengeDifficulty;
|
||||
}): {
|
||||
challenge: Challenge;
|
||||
expectedAnswer: string;
|
||||
};
|
||||
/**
|
||||
* Verify a challenge solution
|
||||
*/
|
||||
verify(challenge: Challenge, solution: string, clientIdentifier?: string): VerificationResult;
|
||||
/**
|
||||
* Verify a challenge solution in stateless mode
|
||||
* (no server-side storage required)
|
||||
*/
|
||||
verifyStateless(challenge: Challenge, solution: string, clientIdentifier?: string): VerificationResult;
|
||||
/**
|
||||
* Get rate limit status for a client
|
||||
*/
|
||||
getRateLimitStatus(clientIdentifier: string): {
|
||||
remaining: number;
|
||||
isLimited: boolean;
|
||||
};
|
||||
/**
|
||||
* Get stats for monitoring
|
||||
*/
|
||||
getStats(): {
|
||||
pendingChallenges: number;
|
||||
rateLimitStats: {
|
||||
activeKeys: number;
|
||||
totalAttempts: number;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Get the current configuration
|
||||
*/
|
||||
getConfig(): CaptchaLMConfig;
|
||||
/**
|
||||
* Destroy and clean up resources
|
||||
*/
|
||||
destroy(): void;
|
||||
}
|
||||
/**
|
||||
* Create an CaptchaLM instance
|
||||
*/
|
||||
declare function createCaptchaLM(config: CaptchaLMConfig): CaptchaLM;
|
||||
|
||||
/**
|
||||
* Express middleware for CaptchaLM
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extended request with CaptchaLM properties
|
||||
*/
|
||||
interface CaptchaLMRequest extends Request {
|
||||
CaptchaLM?: {
|
||||
verified: boolean;
|
||||
challenge?: Challenge;
|
||||
clientIdentifier: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create Express middleware for CaptchaLM protection
|
||||
*/
|
||||
declare function createExpressMiddleware(config: MiddlewareConfig): {
|
||||
protect: RequestHandler;
|
||||
challenge: RequestHandler;
|
||||
generator: ChallengeGenerator;
|
||||
verifier: ChallengeVerifier;
|
||||
};
|
||||
/**
|
||||
* Create a simple verification endpoint
|
||||
*/
|
||||
declare function createVerificationEndpoint(config: MiddlewareConfig): RequestHandler;
|
||||
|
||||
/**
|
||||
* Function registry for CaptchaLM challenges
|
||||
*/
|
||||
|
||||
/**
|
||||
* Combined registry of all available functions
|
||||
*/
|
||||
declare const allFunctions: RegisteredFunction[];
|
||||
/**
|
||||
* Get functions filtered by difficulty
|
||||
*/
|
||||
declare function getFunctionsByDifficulty(difficulty: ChallengeDifficulty): RegisteredFunction[];
|
||||
/**
|
||||
* Get a function by name
|
||||
*/
|
||||
declare function getFunctionByName(name: string): RegisteredFunction | undefined;
|
||||
/**
|
||||
* Get a random function matching the difficulty
|
||||
*/
|
||||
declare function getRandomFunction(difficulty?: ChallengeDifficulty): RegisteredFunction;
|
||||
/**
|
||||
* Function categories for organization
|
||||
*/
|
||||
declare const functionCategories: {
|
||||
readonly math: RegisteredFunction[];
|
||||
readonly string: RegisteredFunction[];
|
||||
readonly array: RegisteredFunction[];
|
||||
readonly composite: RegisteredFunction[];
|
||||
};
|
||||
type FunctionCategory = keyof typeof functionCategories;
|
||||
/**
|
||||
* Get functions by category
|
||||
*/
|
||||
declare function getFunctionsByCategory(category: FunctionCategory): RegisteredFunction[];
|
||||
|
||||
export { CaptchaLM, CaptchaLMConfig, type CaptchaLMRequest, Challenge, ChallengeDifficulty, ChallengeGenerator, ChallengeSolution, ChallengeType, ChallengeVerifier, EncodingType, MiddlewareConfig, RegisteredFunction, VerificationResult, allFunctions, createCaptchaLM, createExpressMiddleware, createGenerator, createVerificationEndpoint, createVerifier, decode, decodeBase64, decodeChain, decodeHex, decodeRot13, encode, encodeBase64, encodeChain, encodeHex, encodeRot13, functionCategories, getFunctionByName, getFunctionsByCategory, getFunctionsByDifficulty, getRandomFunction };
|
||||
321
node_modules/captchalm/dist/index.d.ts
generated
vendored
Normal file
321
node_modules/captchalm/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
import { EncodingType, CaptchaLMConfig, ChallengeType, ChallengeDifficulty, Challenge, ChallengeSolution, VerificationResult, MiddlewareConfig, RegisteredFunction } from './core/types.js';
|
||||
export { ChainedOperation, ChainedOperationsPayload, ChallengePayload, CodeTransformPayload, EncodedInstructionPayload, FunctionExecutionPayload, PatternExtractionPayload, RateLimitConfig, VerificationErrorCode } from './core/types.js';
|
||||
import { Request, RequestHandler } from 'express';
|
||||
|
||||
/**
|
||||
* Encoding utilities for CaptchaLM challenges
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encode a value using the specified encoding
|
||||
*/
|
||||
declare function encode(value: string, encoding: EncodingType): string;
|
||||
/**
|
||||
* Decode a value using the specified encoding
|
||||
*/
|
||||
declare function decode(value: string, encoding: EncodingType): string;
|
||||
/**
|
||||
* Base64 encode a string
|
||||
*/
|
||||
declare function encodeBase64(value: string): string;
|
||||
/**
|
||||
* Base64 decode a string
|
||||
*/
|
||||
declare function decodeBase64(value: string): string;
|
||||
/**
|
||||
* Hex encode a string
|
||||
*/
|
||||
declare function encodeHex(value: string): string;
|
||||
/**
|
||||
* Hex decode a string
|
||||
*/
|
||||
declare function decodeHex(value: string): string;
|
||||
/**
|
||||
* ROT13 encode/decode a string (symmetric cipher)
|
||||
*/
|
||||
declare function encodeRot13(value: string): string;
|
||||
/**
|
||||
* ROT13 decode (same as encode, symmetric)
|
||||
*/
|
||||
declare function decodeRot13(value: string): string;
|
||||
/**
|
||||
* Apply multiple encoding layers
|
||||
*/
|
||||
declare function encodeChain(value: string, encodings: EncodingType[]): string;
|
||||
/**
|
||||
* Decode multiple encoding layers (in reverse order)
|
||||
*/
|
||||
declare function decodeChain(value: string, encodings: EncodingType[]): string;
|
||||
|
||||
/**
|
||||
* Challenge generator for CaptchaLM
|
||||
*/
|
||||
|
||||
/**
|
||||
* Challenge generator class
|
||||
*/
|
||||
declare class ChallengeGenerator {
|
||||
private config;
|
||||
constructor(config: CaptchaLMConfig);
|
||||
/**
|
||||
* Generate a new challenge
|
||||
*/
|
||||
generate(overrides?: Partial<{
|
||||
type: ChallengeType;
|
||||
difficulty: ChallengeDifficulty;
|
||||
}>): {
|
||||
challenge: Challenge;
|
||||
expectedAnswer: string;
|
||||
};
|
||||
/**
|
||||
* Generate payload for a specific challenge type
|
||||
*/
|
||||
private generatePayload;
|
||||
/**
|
||||
* Generate a function execution challenge
|
||||
*/
|
||||
private generateFunctionExecution;
|
||||
/**
|
||||
* Generate a chained operations challenge
|
||||
*/
|
||||
private generateChainedOperations;
|
||||
/**
|
||||
* Generate an encoded instruction challenge
|
||||
*/
|
||||
private generateEncodedInstruction;
|
||||
/**
|
||||
* Generate a pattern extraction challenge
|
||||
*/
|
||||
private generatePatternExtraction;
|
||||
/**
|
||||
* Generate a code transform challenge
|
||||
*/
|
||||
private generateCodeTransform;
|
||||
/**
|
||||
* Get response encoding based on difficulty
|
||||
*/
|
||||
private getResponseEncoding;
|
||||
/**
|
||||
* Get instruction encoding based on difficulty
|
||||
*/
|
||||
private getInstructionEncoding;
|
||||
/**
|
||||
* Generate parameters for a function
|
||||
*/
|
||||
private generateParameters;
|
||||
/**
|
||||
* Generate random words joined by spaces
|
||||
*/
|
||||
private generateRandomWords;
|
||||
/**
|
||||
* Generate a random word
|
||||
*/
|
||||
private generateRandomWord;
|
||||
/**
|
||||
* Mutate a word by changing N characters
|
||||
*/
|
||||
private mutateWord;
|
||||
/**
|
||||
* Generate a random array of numbers
|
||||
*/
|
||||
private generateRandomArray;
|
||||
/**
|
||||
* Get function code as string (for display)
|
||||
*/
|
||||
private getFunctionCodeString;
|
||||
}
|
||||
/**
|
||||
* Create a challenge generator
|
||||
*/
|
||||
declare function createGenerator(config: CaptchaLMConfig): ChallengeGenerator;
|
||||
|
||||
/**
|
||||
* Challenge verifier for CaptchaLM
|
||||
*/
|
||||
|
||||
/**
|
||||
* Challenge verifier class
|
||||
*/
|
||||
declare class ChallengeVerifier {
|
||||
private config;
|
||||
private rateLimiter;
|
||||
private challengeStore;
|
||||
private cleanupInterval;
|
||||
constructor(config: CaptchaLMConfig);
|
||||
/**
|
||||
* Store expected answer for a challenge
|
||||
*/
|
||||
storeChallenge(challengeId: string, expectedAnswer: string, expiresAt: number): void;
|
||||
/**
|
||||
* Verify a challenge solution
|
||||
*/
|
||||
verify(challenge: Challenge, solution: ChallengeSolution, clientIdentifier?: string): VerificationResult;
|
||||
/**
|
||||
* Verify a solution using only the signature (stateless mode)
|
||||
*
|
||||
* In stateless mode, the expected answer is encoded in the signature
|
||||
* This is less secure but allows for distributed deployments
|
||||
*/
|
||||
verifyStateless(challenge: Challenge, solution: ChallengeSolution, clientIdentifier?: string): VerificationResult;
|
||||
/**
|
||||
* Get rate limit status for a client
|
||||
*/
|
||||
getRateLimitStatus(clientIdentifier: string): {
|
||||
remaining: number;
|
||||
isLimited: boolean;
|
||||
};
|
||||
/**
|
||||
* Start periodic cleanup of expired challenges
|
||||
*/
|
||||
private startCleanup;
|
||||
/**
|
||||
* Clean up expired challenges
|
||||
*/
|
||||
private cleanup;
|
||||
/**
|
||||
* Destroy the verifier and clean up resources
|
||||
*/
|
||||
destroy(): void;
|
||||
/**
|
||||
* Get stats for monitoring
|
||||
*/
|
||||
getStats(): {
|
||||
pendingChallenges: number;
|
||||
rateLimitStats: {
|
||||
activeKeys: number;
|
||||
totalAttempts: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create a challenge verifier
|
||||
*/
|
||||
declare function createVerifier(config: CaptchaLMConfig): ChallengeVerifier;
|
||||
|
||||
/**
|
||||
* Standalone CaptchaLM API
|
||||
* Framework-agnostic implementation for custom integrations
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main CaptchaLM class for standalone usage
|
||||
*/
|
||||
declare class CaptchaLM {
|
||||
private generator;
|
||||
private verifier;
|
||||
private config;
|
||||
constructor(config: CaptchaLMConfig);
|
||||
/**
|
||||
* Generate a new challenge
|
||||
*/
|
||||
generate(options?: {
|
||||
type?: ChallengeType;
|
||||
difficulty?: ChallengeDifficulty;
|
||||
}): {
|
||||
challenge: Challenge;
|
||||
expectedAnswer: string;
|
||||
};
|
||||
/**
|
||||
* Verify a challenge solution
|
||||
*/
|
||||
verify(challenge: Challenge, solution: string, clientIdentifier?: string): VerificationResult;
|
||||
/**
|
||||
* Verify a challenge solution in stateless mode
|
||||
* (no server-side storage required)
|
||||
*/
|
||||
verifyStateless(challenge: Challenge, solution: string, clientIdentifier?: string): VerificationResult;
|
||||
/**
|
||||
* Get rate limit status for a client
|
||||
*/
|
||||
getRateLimitStatus(clientIdentifier: string): {
|
||||
remaining: number;
|
||||
isLimited: boolean;
|
||||
};
|
||||
/**
|
||||
* Get stats for monitoring
|
||||
*/
|
||||
getStats(): {
|
||||
pendingChallenges: number;
|
||||
rateLimitStats: {
|
||||
activeKeys: number;
|
||||
totalAttempts: number;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Get the current configuration
|
||||
*/
|
||||
getConfig(): CaptchaLMConfig;
|
||||
/**
|
||||
* Destroy and clean up resources
|
||||
*/
|
||||
destroy(): void;
|
||||
}
|
||||
/**
|
||||
* Create an CaptchaLM instance
|
||||
*/
|
||||
declare function createCaptchaLM(config: CaptchaLMConfig): CaptchaLM;
|
||||
|
||||
/**
|
||||
* Express middleware for CaptchaLM
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extended request with CaptchaLM properties
|
||||
*/
|
||||
interface CaptchaLMRequest extends Request {
|
||||
CaptchaLM?: {
|
||||
verified: boolean;
|
||||
challenge?: Challenge;
|
||||
clientIdentifier: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create Express middleware for CaptchaLM protection
|
||||
*/
|
||||
declare function createExpressMiddleware(config: MiddlewareConfig): {
|
||||
protect: RequestHandler;
|
||||
challenge: RequestHandler;
|
||||
generator: ChallengeGenerator;
|
||||
verifier: ChallengeVerifier;
|
||||
};
|
||||
/**
|
||||
* Create a simple verification endpoint
|
||||
*/
|
||||
declare function createVerificationEndpoint(config: MiddlewareConfig): RequestHandler;
|
||||
|
||||
/**
|
||||
* Function registry for CaptchaLM challenges
|
||||
*/
|
||||
|
||||
/**
|
||||
* Combined registry of all available functions
|
||||
*/
|
||||
declare const allFunctions: RegisteredFunction[];
|
||||
/**
|
||||
* Get functions filtered by difficulty
|
||||
*/
|
||||
declare function getFunctionsByDifficulty(difficulty: ChallengeDifficulty): RegisteredFunction[];
|
||||
/**
|
||||
* Get a function by name
|
||||
*/
|
||||
declare function getFunctionByName(name: string): RegisteredFunction | undefined;
|
||||
/**
|
||||
* Get a random function matching the difficulty
|
||||
*/
|
||||
declare function getRandomFunction(difficulty?: ChallengeDifficulty): RegisteredFunction;
|
||||
/**
|
||||
* Function categories for organization
|
||||
*/
|
||||
declare const functionCategories: {
|
||||
readonly math: RegisteredFunction[];
|
||||
readonly string: RegisteredFunction[];
|
||||
readonly array: RegisteredFunction[];
|
||||
readonly composite: RegisteredFunction[];
|
||||
};
|
||||
type FunctionCategory = keyof typeof functionCategories;
|
||||
/**
|
||||
* Get functions by category
|
||||
*/
|
||||
declare function getFunctionsByCategory(category: FunctionCategory): RegisteredFunction[];
|
||||
|
||||
export { CaptchaLM, CaptchaLMConfig, type CaptchaLMRequest, Challenge, ChallengeDifficulty, ChallengeGenerator, ChallengeSolution, ChallengeType, ChallengeVerifier, EncodingType, MiddlewareConfig, RegisteredFunction, VerificationResult, allFunctions, createCaptchaLM, createExpressMiddleware, createGenerator, createVerificationEndpoint, createVerifier, decode, decodeBase64, decodeChain, decodeHex, decodeRot13, encode, encodeBase64, encodeChain, encodeHex, encodeRot13, functionCategories, getFunctionByName, getFunctionsByCategory, getFunctionsByDifficulty, getRandomFunction };
|
||||
1899
node_modules/captchalm/dist/index.js
generated
vendored
Normal file
1899
node_modules/captchalm/dist/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/captchalm/dist/index.js.map
generated
vendored
Normal file
1
node_modules/captchalm/dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
88
node_modules/captchalm/package.json
generated
vendored
Normal file
88
node_modules/captchalm/package.json
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"name": "captchalm",
|
||||
"version": "1.1.0",
|
||||
"description": "AI-only access control - a reverse CAPTCHA that allows AI agents while blocking humans",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"./client": {
|
||||
"types": "./dist/client/index.d.ts",
|
||||
"import": "./dist/client/index.js",
|
||||
"require": "./dist/client/index.cjs"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./dist/core/types.d.ts",
|
||||
"import": "./dist/core/types.js",
|
||||
"require": "./dist/core/types.cjs"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"test": "vitest",
|
||||
"test:run": "vitest run",
|
||||
"lint": "eslint src",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"prepublishOnly": "npm run build",
|
||||
"release": "npm version patch && npm publish --access public",
|
||||
"release:minor": "npm version minor && npm publish --access public",
|
||||
"release:major": "npm version major && npm publish --access public"
|
||||
},
|
||||
"keywords": [
|
||||
"captcha",
|
||||
"ai",
|
||||
"agent",
|
||||
"authentication",
|
||||
"access-control",
|
||||
"llm",
|
||||
"reverse-captcha",
|
||||
"ai-agent",
|
||||
"bot-protection",
|
||||
"machine-learning"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/YOUR_USERNAME/captchalm.git"
|
||||
},
|
||||
"homepage": "https://github.com/YOUR_USERNAME/captchalm#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/YOUR_USERNAME/captchalm/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.6",
|
||||
"@types/node": "^20.10.0",
|
||||
"eslint": "^8.55.0",
|
||||
"tsup": "^8.0.1",
|
||||
"typescript": "^5.3.0",
|
||||
"vitest": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"express": ">=4.0.0",
|
||||
"fastify": ">=4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"express": {
|
||||
"optional": true
|
||||
},
|
||||
"fastify": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user