@botwall/sdk
Version:
BotWall SDK for site protection and bot crawling
122 lines • 4.35 kB
JavaScript
"use strict";
// BotWall SDK Middleware for Express.js
// Protects routes by verifying bot credentials and deducting credits
Object.defineProperty(exports, "__esModule", { value: true });
exports.requireBotWallMiddleware = void 0;
exports.createBotWallMiddleware = createBotWallMiddleware;
exports.payPerCrawlMiddleware = payPerCrawlMiddleware;
exports.botWall = botWall;
const client_1 = require("./client");
const errors_1 = require("./errors");
function createBotWallMiddleware(options) {
const client = new client_1.BotWallClient(options.apiUrl);
return async (req, res, next) => {
try {
// Check if route should be protected
const path = req.path;
const isProtected = shouldProtectRoute(path, options);
if (!isProtected) {
return next();
}
// Extract bot credentials from headers
const botId = req.headers['x-bot-id'];
const botApiKey = req.headers['x-bot-api-key'];
if (!botId || !botApiKey) {
const error = new errors_1.InvalidCredentialsError('Missing bot credentials in headers');
handleError(error, res, options);
return;
}
// Verify the request
const verifyResult = await client.verify({ botId, apiKey: botApiKey }, { siteId: options.siteId, siteSecret: options.siteSecret }, { path, userAgent: req.get('User-Agent') });
if (!verifyResult.success) {
const error = new errors_1.InvalidCredentialsError(verifyResult.message || 'Verification failed');
handleError(error, res, options);
return;
}
// Log successful crawl
if (options.onSuccess && verifyResult.crawlData) {
options.onSuccess(verifyResult.crawlData);
}
// Continue to the next middleware/route handler
next();
}
catch (error) {
handleError(error, res, options);
}
};
}
function payPerCrawlMiddleware(options) {
return createBotWallMiddleware(options);
}
exports.requireBotWallMiddleware = createBotWallMiddleware;
function shouldProtectRoute(path, options) {
// Check excluded routes first
if (options.excludedRoutes) {
for (const excludedRoute of options.excludedRoutes) {
if (path.startsWith(excludedRoute)) {
return false;
}
}
}
// Check protected routes
if (options.protectedRoutes) {
for (const protectedRoute of options.protectedRoutes) {
if (path.startsWith(protectedRoute)) {
return true;
}
}
return false; // If protected routes are specified, only protect those routes
}
// Default: protect all routes
return true;
}
function handleError(error, res, options) {
// Call custom error handler if provided
if (options.onError) {
options.onError(error);
}
// Send appropriate HTTP response
switch (error.code) {
case 'INVALID_CREDENTIALS':
res.status(401).json({
error: 'Unauthorized',
message: error.message,
code: error.code
});
break;
case 'INSUFFICIENT_CREDITS':
res.status(402).json({
error: 'Payment Required',
message: error.message,
code: error.code
});
break;
case 'VALIDATION_ERROR':
res.status(400).json({
error: 'Bad Request',
message: error.message,
code: error.code
});
break;
default:
res.status(500).json({
error: 'Internal Server Error',
message: error.message,
code: error.code
});
}
}
// Helper function to create middleware with default options
function botWall(options = {}) {
const defaultOptions = {
siteId: '',
siteSecret: '',
protectedRoutes: undefined,
excludedRoutes: undefined,
onError: undefined,
onSuccess: undefined,
...options
};
return createBotWallMiddleware(defaultOptions);
}
//# sourceMappingURL=middleware.js.map