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
This commit is contained in:
2
apps/api/dist/index.d.ts.map
vendored
2
apps/api/dist/index.d.ts.map
vendored
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,eAAe,CAAC;AAkBvB,QAAA,MAAM,GAAG,6CAAY,CAAC;AAwVtB,eAAe,GAAG,CAAC"}
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,eAAe,CAAC;AAmBvB,QAAA,MAAM,GAAG,6CAAY,CAAC;AAyWtB,eAAe,GAAG,CAAC"}
|
||||
17
apps/api/dist/index.js
vendored
17
apps/api/dist/index.js
vendored
@@ -18,6 +18,7 @@ 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)();
|
||||
@@ -34,8 +35,20 @@ app.use((0, helmet_1.default)({
|
||||
}));
|
||||
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: process.env.CORS_ORIGIN || 'http://localhost:3000',
|
||||
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
|
||||
}));
|
||||
@@ -55,10 +68,12 @@ 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({
|
||||
|
||||
2
apps/api/dist/index.js.map
vendored
2
apps/api/dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
3
apps/api/dist/routes/projects.routes.d.ts
vendored
Normal file
3
apps/api/dist/routes/projects.routes.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare const router: import("express-serve-static-core").Router;
|
||||
export default router;
|
||||
//# sourceMappingURL=projects.routes.d.ts.map
|
||||
1
apps/api/dist/routes/projects.routes.d.ts.map
vendored
Normal file
1
apps/api/dist/routes/projects.routes.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"projects.routes.d.ts","sourceRoot":"","sources":["../../src/routes/projects.routes.ts"],"names":[],"mappings":"AAYA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AAibhC,eAAe,MAAM,CAAC"}
|
||||
373
apps/api/dist/routes/projects.routes.js
vendored
Normal file
373
apps/api/dist/routes/projects.routes.js
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
"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 auth_middleware_1 = require("../middleware/auth.middleware");
|
||||
const client_1 = require("@prisma/client");
|
||||
const logger_1 = require("../lib/logger");
|
||||
const router = express_1.default.Router();
|
||||
const prisma = new client_1.PrismaClient();
|
||||
const createProjectSchema = zod_1.z.object({
|
||||
name: zod_1.z.string().min(1, 'Project name is required').max(100, 'Project name too long'),
|
||||
description: zod_1.z.string().optional(),
|
||||
settings: zod_1.z.object({
|
||||
defaultMethod: zod_1.z.enum(['GET', 'POST', 'HEAD']).default('GET'),
|
||||
defaultTimeout: zod_1.z.number().min(1000).max(30000).default(15000),
|
||||
defaultMaxHops: zod_1.z.number().min(1).max(20).default(10),
|
||||
enableSSLAnalysis: zod_1.z.boolean().default(true),
|
||||
enableSEOAnalysis: zod_1.z.boolean().default(true),
|
||||
enableSecurityAnalysis: zod_1.z.boolean().default(true),
|
||||
}).optional(),
|
||||
});
|
||||
const updateProjectSchema = zod_1.z.object({
|
||||
name: zod_1.z.string().min(1).max(100).optional(),
|
||||
description: zod_1.z.string().optional(),
|
||||
settings: zod_1.z.object({
|
||||
defaultMethod: zod_1.z.enum(['GET', 'POST', 'HEAD']).optional(),
|
||||
defaultTimeout: zod_1.z.number().min(1000).max(30000).optional(),
|
||||
defaultMaxHops: zod_1.z.number().min(1).max(20).optional(),
|
||||
enableSSLAnalysis: zod_1.z.boolean().optional(),
|
||||
enableSEOAnalysis: zod_1.z.boolean().optional(),
|
||||
enableSecurityAnalysis: zod_1.z.boolean().optional(),
|
||||
}).optional(),
|
||||
});
|
||||
const projectParamsSchema = zod_1.z.object({
|
||||
projectId: zod_1.z.string().min(1),
|
||||
});
|
||||
router.get('/', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
message: 'User must belong to an organization to access projects'
|
||||
});
|
||||
}
|
||||
const projects = await prisma.project.findMany({
|
||||
where: {
|
||||
orgId: orgId,
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
checks: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc',
|
||||
},
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
projects: projects.map(project => ({
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: project.settingsJson?.description || null,
|
||||
settings: project.settingsJson,
|
||||
trackingCount: project._count.checks,
|
||||
createdAt: project.createdAt,
|
||||
})),
|
||||
},
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to get projects:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get projects',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.post('/', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
message: 'User must belong to an organization to create projects'
|
||||
});
|
||||
}
|
||||
const validatedData = createProjectSchema.parse(req.body);
|
||||
const project = await prisma.project.create({
|
||||
data: {
|
||||
name: validatedData.name,
|
||||
orgId: orgId,
|
||||
settingsJson: {
|
||||
description: validatedData.description || '',
|
||||
...validatedData.settings,
|
||||
},
|
||||
},
|
||||
});
|
||||
logger_1.logger.info(`Project created: ${project.id}`, {
|
||||
userId: user.id,
|
||||
orgId,
|
||||
projectName: project.name,
|
||||
});
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: {
|
||||
project: {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: validatedData.description || null,
|
||||
settings: project.settingsJson,
|
||||
trackingCount: 0,
|
||||
createdAt: project.createdAt,
|
||||
},
|
||||
},
|
||||
message: 'Project created successfully',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to create project:', error);
|
||||
if (error instanceof zod_1.z.ZodError) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors,
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to create project',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.get('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const { projectId } = projectParamsSchema.parse(req.params);
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
});
|
||||
}
|
||||
const project = await prisma.project.findFirst({
|
||||
where: {
|
||||
id: projectId,
|
||||
orgId: orgId,
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
checks: true,
|
||||
},
|
||||
},
|
||||
checks: {
|
||||
take: 10,
|
||||
orderBy: {
|
||||
startedAt: 'desc',
|
||||
},
|
||||
include: {
|
||||
hops: {
|
||||
select: {
|
||||
url: true,
|
||||
statusCode: true,
|
||||
redirectType: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!project) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'Project not found',
|
||||
message: 'Project does not exist or you do not have access to it',
|
||||
});
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
project: {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: project.settingsJson?.description || null,
|
||||
settings: project.settingsJson,
|
||||
trackingCount: project._count.checks,
|
||||
recentChecks: project.checks.map(check => ({
|
||||
id: check.id,
|
||||
inputUrl: check.inputUrl,
|
||||
finalUrl: check.finalUrl,
|
||||
status: check.status,
|
||||
startedAt: check.startedAt,
|
||||
hopCount: check.hops.length,
|
||||
})),
|
||||
createdAt: project.createdAt,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to get project:', error);
|
||||
if (error instanceof zod_1.z.ZodError) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid project ID',
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get project',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.put('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const { projectId } = projectParamsSchema.parse(req.params);
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
});
|
||||
}
|
||||
const validatedData = updateProjectSchema.parse(req.body);
|
||||
const existingProject = await prisma.project.findFirst({
|
||||
where: {
|
||||
id: projectId,
|
||||
orgId: orgId,
|
||||
},
|
||||
});
|
||||
if (!existingProject) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'Project not found',
|
||||
message: 'Project does not exist or you do not have access to it',
|
||||
});
|
||||
}
|
||||
const currentSettings = existingProject.settingsJson || {};
|
||||
const project = await prisma.project.update({
|
||||
where: {
|
||||
id: projectId,
|
||||
},
|
||||
data: {
|
||||
...(validatedData.name && { name: validatedData.name }),
|
||||
settingsJson: {
|
||||
...currentSettings,
|
||||
...(validatedData.description !== undefined && { description: validatedData.description }),
|
||||
...validatedData.settings,
|
||||
},
|
||||
},
|
||||
});
|
||||
logger_1.logger.info(`Project updated: ${project.id}`, {
|
||||
userId: user.id,
|
||||
orgId,
|
||||
changes: validatedData,
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
project: {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: project.settingsJson?.description || null,
|
||||
settings: project.settingsJson,
|
||||
createdAt: project.createdAt,
|
||||
},
|
||||
},
|
||||
message: 'Project updated successfully',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to update project:', error);
|
||||
if (error instanceof zod_1.z.ZodError) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors,
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to update project',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.delete('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const { projectId } = projectParamsSchema.parse(req.params);
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
});
|
||||
}
|
||||
const existingProject = await prisma.project.findFirst({
|
||||
where: {
|
||||
id: projectId,
|
||||
orgId: orgId,
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
checks: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!existingProject) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'Project not found',
|
||||
message: 'Project does not exist or you do not have access to it',
|
||||
});
|
||||
}
|
||||
if (existingProject._count.checks > 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Cannot delete project with tracking data',
|
||||
message: `This project has ${existingProject._count.checks} tracking records. Please archive or move the data first.`,
|
||||
});
|
||||
}
|
||||
await prisma.project.delete({
|
||||
where: {
|
||||
id: projectId,
|
||||
},
|
||||
});
|
||||
logger_1.logger.info(`Project deleted: ${projectId}`, {
|
||||
userId: user.id,
|
||||
orgId,
|
||||
projectName: existingProject.name,
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Project deleted successfully',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to delete project:', error);
|
||||
if (error instanceof zod_1.z.ZodError) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid project ID',
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to delete project',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
exports.default = router;
|
||||
//# sourceMappingURL=projects.routes.js.map
|
||||
1
apps/api/dist/routes/projects.routes.js.map
vendored
Normal file
1
apps/api/dist/routes/projects.routes.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"version":3,"file":"tracking.routes.d.ts","sourceRoot":"","sources":["../../src/routes/tracking.routes.ts"],"names":[],"mappings":"AAcA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AAmWhC,eAAe,MAAM,CAAC"}
|
||||
{"version":3,"file":"tracking.routes.d.ts","sourceRoot":"","sources":["../../src/routes/tracking.routes.ts"],"names":[],"mappings":"AAeA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AAsZhC,eAAe,MAAM,CAAC"}
|
||||
49
apps/api/dist/routes/tracking.routes.js
vendored
49
apps/api/dist/routes/tracking.routes.js
vendored
@@ -7,6 +7,7 @@ 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();
|
||||
@@ -77,11 +78,55 @@ router.post('/track', auth_middleware_1.optionalAuth, async (req, res) => {
|
||||
if (req.user) {
|
||||
const userMembership = req.user.memberships[0];
|
||||
if (userMembership) {
|
||||
validatedData.projectId = 'default-project';
|
||||
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 {
|
||||
validatedData.projectId = 'anonymous-project';
|
||||
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';
|
||||
|
||||
2
apps/api/dist/routes/tracking.routes.js.map
vendored
2
apps/api/dist/routes/tracking.routes.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -62,6 +62,11 @@ export interface CheckResult {
|
||||
redirectCount: number;
|
||||
loopDetected?: boolean;
|
||||
error?: string;
|
||||
analysis?: {
|
||||
ssl?: any;
|
||||
seo?: any;
|
||||
security?: any;
|
||||
};
|
||||
}
|
||||
export declare class RedirectTrackerService {
|
||||
private sslAnalyzer;
|
||||
@@ -74,6 +79,7 @@ export declare class RedirectTrackerService {
|
||||
getCheck(checkId: string, userId?: string): Promise<CheckResult | null>;
|
||||
listChecks(projectId: string, limit?: number, offset?: number): Promise<CheckResult[]>;
|
||||
private performEnhancedAnalysis;
|
||||
private getAnalysisResults;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=redirect-tracker.service.d.ts.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"redirect-tracker.service.d.ts","sourceRoot":"","sources":["../../src/services/redirect-tracker.service.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO3D,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAG9D,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;IACjB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,gBAAgB,CAAiC;IAKnD,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;YAuI9D,oBAAoB;YA2JpB,kBAAkB;IAoBhC,OAAO,CAAC,kBAAkB;IAkBpB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAoDvE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;YAyCrF,uBAAuB;CAiHtC"}
|
||||
{"version":3,"file":"redirect-tracker.service.d.ts","sourceRoot":"","sources":["../../src/services/redirect-tracker.service.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO3D,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAG9D,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;IACjB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,GAAG,CAAC,EAAE,GAAG,CAAC;QACV,GAAG,CAAC,EAAE,GAAG,CAAC;QACV,QAAQ,CAAC,EAAE,GAAG,CAAC;KAChB,CAAC;CACH;AAOD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,gBAAgB,CAAiC;IAKnD,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;YA2I9D,oBAAoB;YA2JpB,kBAAkB;IAoBhC,OAAO,CAAC,kBAAkB;IAkBpB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAoDvE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,MAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;YAyCrF,uBAAuB;YAqHvB,kBAAkB;CAkCjC"}
|
||||
@@ -23,9 +23,9 @@ const trackRequestSchema = zod_1.z.object({
|
||||
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),
|
||||
enableSSLAnalysis: zod_1.z.boolean().default(false),
|
||||
enableSEOAnalysis: zod_1.z.boolean().default(false),
|
||||
enableSecurityAnalysis: zod_1.z.boolean().default(false),
|
||||
enableSSLAnalysis: zod_1.z.boolean().default(true),
|
||||
enableSEOAnalysis: zod_1.z.boolean().default(true),
|
||||
enableSecurityAnalysis: zod_1.z.boolean().default(true),
|
||||
});
|
||||
class RedirectTrackerService {
|
||||
sslAnalyzer = new ssl_analyzer_service_1.SSLAnalyzerService();
|
||||
@@ -82,6 +82,7 @@ class RedirectTrackerService {
|
||||
});
|
||||
await this.saveHopsToDatabase(check.id, hops);
|
||||
await this.performEnhancedAnalysis(check.id, finalUrl || inputUrl, hops.map(h => h.url), validatedRequest);
|
||||
const analysisData = await this.getAnalysisResults(check.id);
|
||||
const result = {
|
||||
id: check.id,
|
||||
inputUrl,
|
||||
@@ -104,6 +105,7 @@ class RedirectTrackerService {
|
||||
})),
|
||||
redirectCount,
|
||||
loopDetected,
|
||||
analysis: analysisData,
|
||||
};
|
||||
logger_1.logger.info(`Enhanced redirect tracking completed: ${inputUrl}`, {
|
||||
checkId: check.id,
|
||||
@@ -448,6 +450,36 @@ class RedirectTrackerService {
|
||||
logger_1.logger.error(`Enhanced analysis failed for check ${checkId}:`, error);
|
||||
}
|
||||
}
|
||||
async getAnalysisResults(checkId) {
|
||||
try {
|
||||
const [sslInspections, seoFlags, securityFlags] = await Promise.all([
|
||||
prisma_1.prisma.sslInspection.findMany({
|
||||
where: { checkId }
|
||||
}),
|
||||
prisma_1.prisma.seoFlags.findMany({
|
||||
where: { checkId }
|
||||
}),
|
||||
prisma_1.prisma.securityFlags.findMany({
|
||||
where: { checkId }
|
||||
})
|
||||
]);
|
||||
const analysis = {};
|
||||
if (sslInspections.length > 0) {
|
||||
analysis.ssl = sslInspections[0];
|
||||
}
|
||||
if (seoFlags.length > 0) {
|
||||
analysis.seo = seoFlags[0];
|
||||
}
|
||||
if (securityFlags.length > 0) {
|
||||
analysis.security = securityFlags[0];
|
||||
}
|
||||
return Object.keys(analysis).length > 0 ? analysis : null;
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error(`Failed to fetch analysis results for check ${checkId}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.RedirectTrackerService = RedirectTrackerService;
|
||||
//# sourceMappingURL=redirect-tracker.service.js.map
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user