59 lines
1.4 KiB
TypeScript
59 lines
1.4 KiB
TypeScript
import { Router, Request, Response } from "express";
|
||
import { extractNavLinks } from "../services/scraper";
|
||
import { checkApiKey } from "../middlewares/auth";
|
||
import { isSafeUrl } from "../utils/ssrf";
|
||
|
||
export const scrapeRoute = Router();
|
||
|
||
/**
|
||
* POST /scrape
|
||
* Body: { "url": "https://firma.com" }
|
||
* Headers: x-api-key: <API_KEY> (or Authorization: Bearer <API_KEY>)
|
||
*
|
||
* Response:
|
||
* {
|
||
* "source": "https://firma.com",
|
||
* "count": 6,
|
||
* "links": [
|
||
* { "label": "Hakkımızda", "url": "https://firma.com/hakkimizda" },
|
||
* ...
|
||
* ]
|
||
* }
|
||
*/
|
||
scrapeRoute.post("/", checkApiKey, async (req: Request, res: Response) => {
|
||
const { url } = req.body as { url?: string };
|
||
|
||
if (!url) {
|
||
return res.status(400).json({ error: "'url' alanı zorunlu" });
|
||
}
|
||
|
||
// Basit URL validasyonu
|
||
try {
|
||
new URL(url);
|
||
} catch {
|
||
return res.status(400).json({ error: "Geçersiz URL formatı" });
|
||
}
|
||
|
||
// SSRF Koruması & Yerel Ağ Engellemesi
|
||
const safe = await isSafeUrl(url);
|
||
if (!safe) {
|
||
return res.status(400).json({ error: "Güvensiz veya geçersiz hedef URL." });
|
||
}
|
||
|
||
try {
|
||
const links = await extractNavLinks(url);
|
||
|
||
return res.json({
|
||
source: url,
|
||
count: links.length,
|
||
links,
|
||
});
|
||
} catch (err) {
|
||
return res.status(500).json({
|
||
error: "Link çekme başarısız",
|
||
detail: err instanceof Error ? err.message : String(err),
|
||
});
|
||
}
|
||
});
|
||
|