Files
url_tracker_tool/apps/api/dist/routes/tracking.routes.js
Andrei f797f9b07c feat: Simplify home page and remove tracking form
- Remove complex tracking form from home page
- Replace with clean 'Analyze URL Redirects' call-to-action button
- Remove announcement badge '🚀 URL Tracker Tool V2 - Now Available'
- Clean up unused imports and form-related code
- Direct users to dedicated /track page for full functionality
- Improve user experience with cleaner, more focused home page

Changes:
- Simplified HomePage component with single CTA button
- Removed form validation, mutation handling, and result display
- Maintained all tracking functionality on /track page
- Professional appearance without promotional clutter
2025-08-23 19:07:02 +00:00

317 lines
11 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const zod_1 = require("zod");
const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
const redirect_tracker_service_1 = require("../services/redirect-tracker.service");
const prisma_1 = require("../lib/prisma");
const auth_middleware_1 = require("../middleware/auth.middleware");
const logger_1 = require("../lib/logger");
const router = express_1.default.Router();
const redirectTracker = new redirect_tracker_service_1.RedirectTrackerService();
router.get('/health', (req, res) => {
res.json({
success: true,
status: 200,
data: {
version: 'v2',
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV || 'development'
}
});
});
const trackingLimiter = (0, express_rate_limit_1.default)({
windowMs: 60 * 60 * 1000,
max: 200,
message: {
success: false,
error: 'Rate limit exceeded',
message: 'Too many tracking requests. Please try again later.'
},
standardHeaders: true,
legacyHeaders: false,
keyGenerator: (req) => {
return req.user ? `user:${req.user.id}` : `ip:${req.ip}`;
},
});
const anonymousTrackingLimiter = (0, express_rate_limit_1.default)({
windowMs: 60 * 60 * 1000,
max: 50,
message: {
success: false,
error: 'Rate limit exceeded',
message: 'Anonymous users are limited to 50 requests per hour. Please register for higher limits.'
},
standardHeaders: true,
legacyHeaders: false,
skip: (req) => !!req.user,
});
const trackUrlSchema = zod_1.z.object({
url: zod_1.z.string().min(1, 'URL is required'),
method: zod_1.z.enum(['GET', 'POST', 'HEAD']).default('GET'),
userAgent: zod_1.z.string().optional(),
headers: zod_1.z.record(zod_1.z.string()).optional(),
projectId: zod_1.z.string().optional(),
followJS: zod_1.z.boolean().default(false),
maxHops: zod_1.z.number().min(1).max(20).default(10),
timeout: zod_1.z.number().min(1000).max(30000).default(15000),
});
const listChecksSchema = zod_1.z.object({
projectId: zod_1.z.string(),
limit: zod_1.z.number().min(1).max(100).default(50),
offset: zod_1.z.number().min(0).default(0),
});
router.post('/test', async (req, res) => {
res.json({ success: true, message: 'Test endpoint working' });
});
router.post('/track', auth_middleware_1.optionalAuth, async (req, res) => {
try {
const validatedData = trackUrlSchema.parse(req.body);
let { url } = validatedData;
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = 'http://' + url;
}
if (!validatedData.projectId) {
if (req.user) {
const userMembership = req.user.memberships[0];
if (userMembership) {
const defaultProject = await prisma_1.prisma.project.findFirst({
where: {
orgId: userMembership.orgId
}
});
if (defaultProject) {
validatedData.projectId = defaultProject.id;
}
else {
const newProject = await prisma_1.prisma.project.create({
data: {
name: 'Default Project',
orgId: userMembership.orgId,
settingsJson: {}
}
});
validatedData.projectId = newProject.id;
}
}
}
else {
let anonymousProject = await prisma_1.prisma.project.findFirst({
where: {
name: 'Anonymous Tracking'
}
});
if (!anonymousProject) {
let anonymousOrg = await prisma_1.prisma.organization.findFirst({
where: {
name: 'Anonymous Users'
}
});
if (!anonymousOrg) {
anonymousOrg = await prisma_1.prisma.organization.create({
data: {
name: 'Anonymous Users',
plan: 'free'
}
});
}
anonymousProject = await prisma_1.prisma.project.create({
data: {
name: 'Anonymous Tracking',
orgId: anonymousOrg.id,
settingsJson: {}
}
});
}
validatedData.projectId = anonymousProject.id;
}
}
const userId = req.user?.id || 'anonymous-user';
const result = await redirectTracker.trackUrl({ ...validatedData, url }, userId);
logger_1.logger.info(`Enhanced tracking completed: ${url}`, {
userId: userId,
isAnonymous: !req.user,
projectId: validatedData.projectId,
checkId: result.id,
status: result.status,
redirectCount: result.redirectCount
});
res.json({
success: true,
status: 200,
data: {
check: result,
url,
method: result.method,
redirectCount: result.redirectCount,
finalUrl: result.finalUrl,
finalStatusCode: result.hops[result.hops.length - 1]?.statusCode,
},
meta: {
version: 'v2',
enhanced: true,
persisted: true,
checkId: result.id,
}
});
}
catch (error) {
logger_1.logger.error('Enhanced tracking failed:', error);
if (error instanceof zod_1.z.ZodError) {
return res.status(400).json({
success: false,
error: 'Validation error',
message: error.errors[0]?.message || 'Invalid input',
details: error.errors
});
}
res.status(500).json({
success: false,
error: 'Tracking failed',
message: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
});
router.get('/track/:checkId', auth_middleware_1.optionalAuth, async (req, res) => {
try {
const { checkId } = req.params;
if (!checkId) {
return res.status(400).json({
success: false,
error: 'Check ID required'
});
}
const check = await redirectTracker.getCheck(checkId, req.user?.id);
if (!check) {
return res.status(404).json({
success: false,
error: 'Check not found',
message: 'The requested check does not exist or you do not have access to it'
});
}
res.json({
success: true,
status: 200,
data: { check },
meta: {
version: 'v2',
checkId: check.id,
}
});
}
catch (error) {
logger_1.logger.error('Failed to retrieve check:', error);
res.status(500).json({
success: false,
error: 'Failed to retrieve check',
message: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
});
router.get('/projects/:projectId/checks', auth_middleware_1.requireAuth, async (req, res) => {
try {
const { projectId } = req.params;
const { limit = 50, offset = 0 } = req.query;
const validatedData = listChecksSchema.parse({
projectId,
limit: Number(limit),
offset: Number(offset),
});
if (!projectId) {
return res.status(400).json({
success: false,
error: 'Project ID required'
});
}
const checks = await redirectTracker.listChecks(validatedData.projectId, validatedData.limit, validatedData.offset);
res.json({
success: true,
status: 200,
data: {
checks,
pagination: {
limit: validatedData.limit,
offset: validatedData.offset,
total: checks.length,
}
},
meta: {
version: 'v2',
projectId: validatedData.projectId,
}
});
}
catch (error) {
logger_1.logger.error('Failed to list checks:', error);
if (error instanceof zod_1.z.ZodError) {
return res.status(400).json({
success: false,
error: 'Validation error',
message: error.errors[0]?.message || 'Invalid input',
details: error.errors
});
}
res.status(500).json({
success: false,
error: 'Failed to list checks',
message: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
});
router.get('/checks/recent', auth_middleware_1.requireAuth, async (req, res) => {
try {
const { limit = 20 } = req.query;
const checks = await redirectTracker.listChecks('anonymous-project', Number(limit), 0);
res.json({
success: true,
status: 200,
data: {
checks,
message: 'Cross-project recent checks will be implemented in a future phase'
},
meta: {
version: 'v2',
userId: req.user.id,
}
});
}
catch (error) {
logger_1.logger.error('Failed to get recent checks:', error);
res.status(500).json({
success: false,
error: 'Failed to get recent checks',
message: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
});
router.post('/track/bulk', auth_middleware_1.requireAuth, async (req, res) => {
try {
logger_1.logger.info(`Bulk tracking request from user: ${req.user.email}`);
res.json({
success: true,
status: 200,
data: {
message: 'Bulk tracking will be implemented in Phase 6',
bulkJobId: null,
},
meta: {
version: 'v2',
feature: 'bulk-tracking',
phase: '6 (future)',
}
});
}
catch (error) {
logger_1.logger.error('Bulk tracking placeholder error:', error);
res.status(500).json({
success: false,
error: 'Bulk tracking not yet available',
message: 'This feature will be implemented in Phase 6'
});
}
});
exports.default = router;
//# sourceMappingURL=tracking.routes.js.map