"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); require("dotenv/config"); const express_1 = __importDefault(require("express")); const cors_1 = __importDefault(require("cors")); const helmet_1 = __importDefault(require("helmet")); const compression_1 = __importDefault(require("compression")); const cookie_parser_1 = __importDefault(require("cookie-parser")); const express_rate_limit_1 = __importDefault(require("express-rate-limit")); const path_1 = __importDefault(require("path")); const logger_1 = require("./lib/logger"); const redirect_legacy_service_1 = require("./services/redirect-legacy.service"); const auth_routes_1 = __importDefault(require("./routes/auth.routes")); const tracking_routes_1 = __importDefault(require("./routes/tracking.routes")); const analysis_routes_1 = __importDefault(require("./routes/analysis.routes")); const export_routes_1 = __importDefault(require("./routes/export.routes")); const bulk_routes_1 = __importDefault(require("./routes/bulk.routes")); const projects_routes_1 = __importDefault(require("./routes/projects.routes")); const docs_routes_1 = __importDefault(require("./routes/docs.routes")); const rate_limit_middleware_1 = require("./middleware/rate-limit.middleware"); const app = (0, express_1.default)(); const PORT = process.env.PORT || 3333; app.use((0, helmet_1.default)({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net"], scriptSrc: ["'self'", "https://cdn.jsdelivr.net"], imgSrc: ["'self'", "data:", "https:"], }, }, })); app.use((0, compression_1.default)()); app.use((0, rate_limit_middleware_1.requestLogger)({ redactionLevel: 'partial' })); const allowedOrigins = [ 'http://localhost:3000', 'https://urltrackertool.com', process.env.CORS_ORIGIN ].filter(Boolean); app.use((0, cors_1.default)({ origin: (origin, callback) => { if (!origin) return callback(null, true); if (allowedOrigins.includes(origin)) { return callback(null, true); } return callback(new Error('Not allowed by CORS')); }, credentials: true, optionsSuccessStatus: 200 })); app.use(express_1.default.json({ limit: '10mb' })); app.use(express_1.default.urlencoded({ extended: true, limit: '10mb' })); app.use((0, cookie_parser_1.default)()); app.use(express_1.default.static(path_1.default.join(__dirname, '../../../public'))); const apiLimiter = (0, express_rate_limit_1.default)({ windowMs: 60 * 60 * 1000, max: 100, message: { error: 'Too many requests, please try again later.' }, standardHeaders: true, legacyHeaders: false, }); app.use('/api/v1/auth', auth_routes_1.default); app.use('/v2', tracking_routes_1.default); app.use('/v2/analyze', analysis_routes_1.default); app.use('/v2/export', export_routes_1.default); app.use('/v2/bulk', bulk_routes_1.default); app.use('/v2/projects', projects_routes_1.default); app.use('/api/v2', tracking_routes_1.default); app.use('/api/v2/analyze', analysis_routes_1.default); app.use('/api/v2/export', export_routes_1.default); app.use('/api/v2/bulk', bulk_routes_1.default); app.use('/api/v2/projects', projects_routes_1.default); app.use('/', docs_routes_1.default); app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString(), version: '2.0.0', environment: process.env.NODE_ENV || 'development' }); }); app.post('/api/track', rate_limit_middleware_1.legacyRateLimit, async (req, res) => { const { url, method = 'GET', userAgent } = req.body; if (!url) { return res.status(400).json({ error: 'URL is required' }); } try { let inputUrl = url; if (!inputUrl.startsWith('http://') && !inputUrl.startsWith('https://')) { inputUrl = 'http://' + inputUrl; } const options = { method: method.toUpperCase(), userAgent }; const redirectChain = await (0, redirect_legacy_service_1.trackRedirects)(inputUrl, [], options); res.json({ redirects: redirectChain }); } catch (error) { logger_1.logger.error('Legacy /api/track error:', error); res.status(500).json({ error: 'Failed to track redirects' }); } }); app.post('/api/v1/track', rate_limit_middleware_1.legacyRateLimit, async (req, res) => { const { url, method = 'GET', userAgent } = req.body; if (!url) { return res.status(400).json({ error: 'URL is required', status: 400, success: false }); } try { let inputUrl = url; if (!inputUrl.startsWith('http://') && !inputUrl.startsWith('https://')) { inputUrl = 'http://' + inputUrl; } const options = { method: method.toUpperCase(), userAgent }; const redirectChain = await (0, redirect_legacy_service_1.trackRedirects)(inputUrl, [], options); res.json({ success: true, status: 200, data: { url: inputUrl, method: options.method, redirectCount: redirectChain.length - 1, finalUrl: redirectChain[redirectChain.length - 1]?.url, finalStatusCode: redirectChain[redirectChain.length - 1]?.statusCode, redirects: redirectChain } }); } catch (error) { logger_1.logger.error('API v1 track error:', error); res.status(500).json({ error: 'Failed to track redirects', message: error instanceof Error ? error.message : 'Unknown error', status: 500, success: false }); } }); app.get('/api/v1/track', rate_limit_middleware_1.legacyRateLimit, async (req, res) => { const { url, method = 'GET', userAgent } = req.query; if (!url) { return res.status(400).json({ error: 'URL parameter is required', status: 400, success: false }); } try { let inputUrl = url; if (!inputUrl.startsWith('http://') && !inputUrl.startsWith('https://')) { inputUrl = 'http://' + inputUrl; } const options = { method: (method || 'GET').toUpperCase(), userAgent: userAgent }; const redirectChain = await (0, redirect_legacy_service_1.trackRedirects)(inputUrl, [], options); res.json({ success: true, status: 200, data: { url: inputUrl, method: options.method, redirectCount: redirectChain.length - 1, finalUrl: redirectChain[redirectChain.length - 1]?.url, finalStatusCode: redirectChain[redirectChain.length - 1]?.statusCode, redirects: redirectChain } }); } catch (error) { logger_1.logger.error('API v1 track GET error:', error); res.status(500).json({ error: 'Failed to track redirects', message: error instanceof Error ? error.message : 'Unknown error', status: 500, success: false }); } }); app.get('/api/docs', (req, res) => { const apiDocs = ` URL Redirect Tracker API

URL Redirect Tracker API Documentation

This API allows you to programmatically track and analyze URL redirect chains with detailed information.

Rate Limiting

The API is limited to 100 requests per hour per IP address.

Endpoints

POST /api/v1/track

Track a URL and get the full redirect chain using a POST request.

Request Parameters (JSON Body)

Parameter Type Required Description
url string Yes The URL to track (e.g., "example.com")
method string No HTTP method (GET, HEAD, POST). Default: "GET"
userAgent string No Custom User-Agent header

Example Request

curl -X POST http://localhost:${PORT}/api/v1/track \\
  -H "Content-Type: application/json" \\
  -d '{
    "url": "github.com",
    "method": "GET"
  }'
  

GET /api/v1/track

Track a URL and get the full redirect chain using a GET request with query parameters.

Example Request

curl "http://localhost:${PORT}/api/v1/track?url=github.com&method=GET"
  

Back to URL Redirect Tracker

`; res.send(apiDocs); }); app.get('/', (req, res) => { res.sendFile(path_1.default.join(__dirname, '../../../public', 'index.html')); }); app.use((err, req, res, next) => { logger_1.logger.error('Unhandled error:', err); res.status(500).json({ success: false, error: 'Internal server error', message: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong' }); }); app.use((req, res) => { res.status(404).json({ success: false, error: 'Not found', message: `Route ${req.method} ${req.path} not found` }); }); process.on('SIGTERM', () => { logger_1.logger.info('SIGTERM received, shutting down gracefully'); process.exit(0); }); process.on('SIGINT', () => { logger_1.logger.info('SIGINT received, shutting down gracefully'); process.exit(0); }); app.use(rate_limit_middleware_1.rateLimitErrorHandler); app.listen(PORT, () => { logger_1.logger.info(`🚀 Redirect Intelligence v2 API Server running on http://localhost:${PORT}`); logger_1.logger.info(`📖 API Documentation: http://localhost:${PORT}/api/docs`); logger_1.logger.info(`🏥 Health Check: http://localhost:${PORT}/health`); }); exports.default = app; //# sourceMappingURL=index.js.map