mirror of
https://github.com/skidoodle/erettsegi-browser.git
synced 2026-04-28 05:27:35 +02:00
feat: Add proxy and validation API routes with undici and an insecure HTTP agent.
This commit is contained in:
@@ -5,25 +5,26 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "erettsegi-browser",
|
"name": "erettsegi-browser",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroui/react": "latest",
|
"@heroui/react": "^2.8.7",
|
||||||
"framer-motion": "latest",
|
"framer-motion": "^12.23.26",
|
||||||
"next": "latest",
|
"next": "16.1.0",
|
||||||
"next-themes": "latest",
|
"next-themes": "^0.4.6",
|
||||||
"react": "latest",
|
"react": "19.2.3",
|
||||||
"react-dom": "latest",
|
"react-dom": "19.2.3",
|
||||||
"react-icons": "latest",
|
"react-icons": "^5.5.0",
|
||||||
|
"undici": "^7.16.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "latest",
|
"@biomejs/biome": "2.3.10",
|
||||||
"@tailwindcss/postcss": "latest",
|
"@tailwindcss/postcss": "^4.1.18",
|
||||||
"@types/node": "latest",
|
"@types/node": "25.0.3",
|
||||||
"@types/react": "latest",
|
"@types/react": "19.2.7",
|
||||||
"@types/react-dom": "latest",
|
"@types/react-dom": "19.2.3",
|
||||||
"postcss": "latest",
|
"postcss": "8.5.6",
|
||||||
"prettier": "latest",
|
"prettier": "^3.7.4",
|
||||||
"prettier-plugin-tailwindcss": "latest",
|
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||||
"tailwindcss": "latest",
|
"tailwindcss": "^4.1.18",
|
||||||
"typescript": "latest",
|
"typescript": "5.9.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -636,6 +637,8 @@
|
|||||||
|
|
||||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||||
|
|
||||||
|
"undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],
|
||||||
|
|
||||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||||
|
|
||||||
"use-composed-ref": ["use-composed-ref@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w=="],
|
"use-composed-ref": ["use-composed-ref@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w=="],
|
||||||
|
|||||||
+2
-1
@@ -18,7 +18,8 @@
|
|||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3",
|
"react-dom": "19.2.3",
|
||||||
"react-icons": "^5.5.0"
|
"react-icons": "^5.5.0",
|
||||||
|
"undici": "^7.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "2.3.10",
|
"@biomejs/biome": "2.3.10",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { type NextRequest, NextResponse } from "next/server";
|
import { type NextRequest, NextResponse } from "next/server";
|
||||||
import { parseSegments, getExternalUrl, type ResourceSlug } from "@/utils/edu";
|
import { parseSegments, getExternalUrl, type ResourceSlug } from "@/utils/edu";
|
||||||
|
import { insecureAgent } from "@/utils/http-agent";
|
||||||
|
|
||||||
export async function GET(
|
export async function GET(
|
||||||
_req: NextRequest,
|
_req: NextRequest,
|
||||||
@@ -32,7 +33,10 @@ export async function GET(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const externalResponse = await fetch(targetUrl, { method: "GET" });
|
const externalResponse = await fetch(targetUrl, {
|
||||||
|
method: "GET",
|
||||||
|
dispatcher: insecureAgent,
|
||||||
|
} as RequestInit);
|
||||||
|
|
||||||
if (!externalResponse.ok) {
|
if (!externalResponse.ok) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { type NextRequest, NextResponse } from "next/server";
|
import { type NextRequest, NextResponse } from "next/server";
|
||||||
import { parseSegments, getExternalUrl, type ResourceSlug } from "@/utils/edu";
|
import { parseSegments, getExternalUrl, type ResourceSlug } from "@/utils/edu";
|
||||||
|
import { insecureAgent } from "@/utils/http-agent";
|
||||||
|
|
||||||
export async function GET(
|
export async function GET(
|
||||||
_req: NextRequest,
|
_req: NextRequest,
|
||||||
@@ -10,7 +11,7 @@ export async function GET(
|
|||||||
const { subject, year, period, level, resourceType } = parseSegments(slug);
|
const { subject, year, period, level, resourceType } = parseSegments(slug);
|
||||||
|
|
||||||
if (!subject || !year || !period || !level || !resourceType) {
|
if (!subject || !year || !period || !level || !resourceType) {
|
||||||
return NextResponse.json({ status: 400 });
|
return NextResponse.json({ status: 400 }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetUrl = getExternalUrl(
|
const targetUrl = getExternalUrl(
|
||||||
@@ -20,11 +21,14 @@ export async function GET(
|
|||||||
level,
|
level,
|
||||||
resourceType as ResourceSlug,
|
resourceType as ResourceSlug,
|
||||||
);
|
);
|
||||||
if (!targetUrl) return NextResponse.json({ status: 404 });
|
if (!targetUrl) return NextResponse.json({ status: 404 }, { status: 404 });
|
||||||
|
|
||||||
const res = await fetch(targetUrl, { method: "HEAD" });
|
const res = await fetch(targetUrl, {
|
||||||
return NextResponse.json({ status: res.status });
|
method: "HEAD",
|
||||||
|
dispatcher: insecureAgent,
|
||||||
|
} as RequestInit);
|
||||||
|
return NextResponse.json({ status: res.status }, { status: res.status });
|
||||||
} catch {
|
} catch {
|
||||||
return NextResponse.json({ status: 500 });
|
return NextResponse.json({ status: 500 }, { status: 500 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { Agent } from "undici";
|
||||||
|
|
||||||
|
export const insecureAgent = new Agent({
|
||||||
|
connect: {
|
||||||
|
rejectUnauthorized: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user