diff --git a/.npmrc b/.npmrc
deleted file mode 100644
index cb15887..0000000
--- a/.npmrc
+++ /dev/null
@@ -1 +0,0 @@
-public-hoist-pattern[]=*@nextui-org/*
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
deleted file mode 100644
index a3c4bea..0000000
--- a/.prettierrc
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "trailingComma": "es5",
- "tabWidth": 2,
- "semi": false,
- "singleQuote": true,
- "jsxSingleQuote": true
-}
diff --git a/biome.json b/biome.json
index c054f53..1e3c390 100644
--- a/biome.json
+++ b/biome.json
@@ -1,16 +1,17 @@
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"vcs": {
- "enabled": false,
+ "enabled": true,
"clientKind": "git",
- "useIgnoreFile": false
+ "useIgnoreFile": true
},
"files": {
"ignoreUnknown": false
},
"formatter": {
"enabled": true,
- "indentStyle": "tab"
+ "indentStyle": "tab",
+ "lineWidth": 80
},
"linter": {
"enabled": true,
diff --git a/postcss.config.js b/postcss.config.mjs
similarity index 72%
rename from postcss.config.js
rename to postcss.config.mjs
index c148a5e..c42f31c 100644
--- a/postcss.config.js
+++ b/postcss.config.mjs
@@ -4,4 +4,4 @@ const config = {
},
};
-module.exports = config;
+export default config;
diff --git a/src/app/api/erettsegi/route.ts b/src/app/api/erettsegi/route.ts
new file mode 100644
index 0000000..629da99
--- /dev/null
+++ b/src/app/api/erettsegi/route.ts
@@ -0,0 +1,120 @@
+import { type NextRequest, NextResponse } from "next/server";
+import { subjects } from "@/utils/subjects";
+
+export async function GET(req: NextRequest) {
+ try {
+ const { searchParams } = req.nextUrl;
+ const vizsgatargy = searchParams.get("vizsgatargy");
+ const ev = searchParams.get("ev");
+ const idoszak = searchParams.get("idoszak");
+ const szint = searchParams.get("szint");
+
+ if (!vizsgatargy || !ev || !idoszak || !szint) {
+ const missingParams = [];
+ if (!vizsgatargy) missingParams.push("vizsgatargy");
+ if (!ev) missingParams.push("ev");
+ if (!idoszak) missingParams.push("idoszak");
+ if (!szint) missingParams.push("szint");
+
+ return NextResponse.json(
+ { error: `Hiányzó paraméterek: ${missingParams.join(", ")}` },
+ { status: 400 },
+ );
+ }
+
+ if (parseInt(ev, 10) <= 2012) {
+ return NextResponse.json({ error: "Érvénytelen év" }, { status: 400 });
+ }
+
+ const validSubjects = subjects.map((subject) => subject.value);
+ if (!validSubjects.includes(vizsgatargy)) {
+ return NextResponse.json(
+ { error: "Érvénytelen vizsgatárgy" },
+ { status: 400 },
+ );
+ }
+
+ let honap: string;
+ switch (idoszak) {
+ case "osz":
+ honap = "okt";
+ break;
+ case "tavasz":
+ honap = "maj";
+ break;
+ default:
+ return NextResponse.json(
+ { error: "Érvénytelen időszak" },
+ { status: 400 },
+ );
+ }
+
+ let prefix: string;
+ switch (szint) {
+ case "emelt":
+ prefix = `e_${vizsgatargy}`;
+ break;
+ case "kozep":
+ prefix = `k_${vizsgatargy}`;
+ break;
+ default:
+ return NextResponse.json(
+ { error: "Érvénytelen szint" },
+ { status: 400 },
+ );
+ }
+
+ const protocol =
+ req.headers.get("x-forwarded-proto") === "https" ? "https" : "http";
+ const host = req.headers.get("host");
+ const baseUrl = `https://dload-oktatas.educatio.hu/erettsegi/feladatok_${ev}${idoszak}_${szint}/`;
+ const proxiedUrl = `${protocol}://${host}/api/proxy?link=${encodeURI(baseUrl)}`;
+
+ const shortev = ev.slice(-2);
+ const feladat = "fl";
+ const utmutato = "ut";
+ const forras = "for";
+ const megoldas = "meg";
+
+ let flPdfUrl: string | undefined,
+ utPdfUrl: string | undefined,
+ flZipUrl: string | undefined,
+ utZipUrl: string | undefined,
+ flMp3Url: string | undefined;
+
+ switch (vizsgatargy) {
+ case "inf":
+ case "infoism":
+ case "digkult":
+ flZipUrl = `${baseUrl}${prefix}${forras}_${shortev}${honap}_${feladat}.zip`;
+ flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`;
+ utZipUrl = `${baseUrl}${prefix}${megoldas}_${shortev}${honap}_${utmutato}.zip`;
+ utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`;
+ break;
+ case "angol":
+ case "nemet":
+ flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`;
+ utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`;
+ flMp3Url = `${baseUrl}${prefix}_${shortev}${honap}_${feladat}.mp3`;
+ break;
+ default:
+ flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`;
+ utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`;
+ break;
+ }
+
+ return NextResponse.json(
+ { flPdfUrl, utPdfUrl, flZipUrl, utZipUrl, flMp3Url },
+ {
+ status: 200,
+ headers: { "Cache-Control": "s-maxage=31536000" },
+ },
+ );
+ } catch (e: unknown) {
+ console.error("An unexpected error occurred in the API route:", e);
+ return NextResponse.json(
+ { error: "Internal Server Error" },
+ { status: 500 },
+ );
+ }
+}
diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts
new file mode 100644
index 0000000..e73df09
--- /dev/null
+++ b/src/app/api/proxy/route.ts
@@ -0,0 +1,79 @@
+import { type NextRequest, NextResponse } from "next/server";
+import { Agent, fetch } from "undici";
+
+const insecureAgent = new Agent({
+ connect: {
+ rejectUnauthorized: false,
+ },
+});
+
+export async function GET(req: NextRequest) {
+ try {
+ const { searchParams } = req.nextUrl;
+ const link = searchParams.get("link");
+
+ if (!link) {
+ return NextResponse.json(
+ { error: "Hiányzó paraméter: link" },
+ { status: 400 },
+ );
+ }
+
+ let url: URL;
+ try {
+ url = new URL(link);
+ } catch (_error) {
+ return NextResponse.json(
+ { error: "Érvénytelen link formátum" },
+ { status: 400 },
+ );
+ }
+
+ if (url.hostname !== "dload-oktatas.educatio.hu") {
+ return NextResponse.json({ error: "Érvénytelen link" }, { status: 400 });
+ }
+
+ const externalResponse = await fetch(link, {
+ method: "GET",
+ dispatcher: insecureAgent,
+ });
+
+ if (!externalResponse.ok) {
+ return NextResponse.json(
+ { error: "Hiba történt a külső forrás lekérése során." },
+ { status: externalResponse.status },
+ );
+ }
+
+ const body = await externalResponse.arrayBuffer();
+
+ const contentType = externalResponse.headers.get("content-type");
+ const headers = new Headers();
+ headers.set("Cache-Control", "s-maxage=31536000, stale-while-revalidate");
+
+ if (contentType) {
+ headers.set("Content-Type", contentType);
+ if (contentType === "application/pdf") {
+ const filename = url.pathname.split("/").pop() ?? "document.pdf";
+ headers.set("Content-Disposition", `inline; filename="${filename}"`);
+ }
+ }
+
+ return new Response(body, {
+ status: 200,
+ headers: headers,
+ });
+ } catch (e: unknown) {
+ console.error("Proxy Error:", e);
+ if (e instanceof Error) {
+ return NextResponse.json(
+ { error: "Internal Server Error", message: e.message },
+ { status: 500 },
+ );
+ }
+ return NextResponse.json(
+ { error: "An unexpected internal error occurred" },
+ { status: 500 },
+ );
+ }
+}
diff --git a/src/app/api/validate/route.ts b/src/app/api/validate/route.ts
new file mode 100644
index 0000000..6dd450c
--- /dev/null
+++ b/src/app/api/validate/route.ts
@@ -0,0 +1,73 @@
+import { type NextRequest, NextResponse } from "next/server";
+import { Agent, fetch } from "undici";
+
+const insecureAgent = new Agent({
+ connect: {
+ rejectUnauthorized: false,
+ },
+});
+
+const ALLOWED_HOSTS = [
+ "localhost:3000",
+ "erettsegi.albert.lol",
+ "dload-oktatas.educatio.hu",
+];
+
+export async function GET(req: NextRequest) {
+ try {
+ const { searchParams } = req.nextUrl;
+ const link = searchParams.get("link");
+
+ if (!link) {
+ return NextResponse.json(
+ { error: "Hiányzó paraméter: link" },
+ { status: 400 },
+ );
+ }
+
+ let url: URL;
+ try {
+ url = new URL(link);
+ } catch (_error) {
+ return NextResponse.json(
+ { error: "Érvénytelen link formátum" },
+ { status: 400 },
+ );
+ }
+
+ if (!ALLOWED_HOSTS.includes(url.host)) {
+ return NextResponse.json({ error: "Érvénytelen link" }, { status: 400 });
+ }
+
+ const response = await fetch(link, {
+ method: "HEAD",
+ dispatcher: insecureAgent,
+ });
+
+ return NextResponse.json({ status: response.status }, { status: 200 });
+ } catch (e: unknown) {
+ console.error("Validation Error:", e);
+
+ if (e instanceof Error) {
+ const cause = e.cause as { code?: unknown } | undefined;
+ return NextResponse.json(
+ {
+ error: "Internal Server Error",
+ message: e.message,
+ cause: cause?.code ? String(cause.code) : undefined,
+ stack: process.env.NODE_ENV === "development" ? e.stack : undefined,
+ },
+ { status: 500 },
+ );
+ }
+
+ return NextResponse.json(
+ {
+ error: "Internal Server Error",
+ message: "An unexpected error occurred",
+ details: String(e),
+ },
+ { status: 500 },
+ );
+ }
+}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
new file mode 100644
index 0000000..658f29e
--- /dev/null
+++ b/src/app/layout.tsx
@@ -0,0 +1,52 @@
+import type { Metadata, Viewport } from "next";
+import Script from "next/script";
+import { Providers } from "@/app/providers";
+import { Inter } from "next/font/google";
+import "@/styles/globals.css";
+
+const inter = Inter({
+ subsets: ["latin"],
+ variable: "--font-inter",
+});
+
+export const metadata: Metadata = {
+ metadataBase: new URL("https://erettsegi.albert.lol"),
+ title: "Érettségi kereső",
+ description: "Egyszerű keresés és letöltés az érettségi feladatsorokhoz. 🏫",
+ icons: {
+ icon: "/favicon.ico",
+ },
+ openGraph: {
+ title: "Érettségi kereső",
+ description:
+ "Egyszerű keresés és letöltés az érettségi feladatsorokhoz. 🏫",
+ url: "https://erettsegi.albert.lol",
+ images: "/logo.png",
+ },
+};
+
+export const viewport: Viewport = {
+ themeColor: "#121212",
+ width: "device-width",
+ initialScale: 1,
+ maximumScale: 1,
+};
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ return (
+
+
+
+ {children}
+
+
+ );
+}
diff --git a/src/pages/404.tsx b/src/app/not-found.tsx
similarity index 75%
rename from src/pages/404.tsx
rename to src/app/not-found.tsx
index 6736ed5..e58e4fa 100644
--- a/src/pages/404.tsx
+++ b/src/app/not-found.tsx
@@ -1,14 +1,10 @@
+"use client";
+
import { Button } from "@heroui/button";
-import { useRouter } from "next/router";
import { Footer } from "@/components/Footer";
+import Link from "next/link";
-export default function ErrorPage() {
- const router = useRouter();
-
- const handleBack = () => {
- router.push("/");
- };
-
+export default function NotFound() {
return (
<>
@@ -22,9 +18,9 @@ export default function ErrorPage() {
Az keresett oldal nem található.
-
+
+
+
diff --git a/src/pages/index.tsx b/src/app/page.tsx
similarity index 99%
rename from src/pages/index.tsx
rename to src/app/page.tsx
index f80b27d..a5bf412 100644
--- a/src/pages/index.tsx
+++ b/src/app/page.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { ButtonGroup, Divider } from "@heroui/react";
import { useEffect } from "react";
import { Mp3Button, PdfButton, ZipButton } from "@/components/Buttons";
diff --git a/src/app/providers.tsx b/src/app/providers.tsx
new file mode 100644
index 0000000..0df5afd
--- /dev/null
+++ b/src/app/providers.tsx
@@ -0,0 +1,14 @@
+"use client";
+
+import { HeroUIProvider } from "@heroui/react";
+import { ThemeProvider } from "next-themes";
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/src/components/Buttons.tsx b/src/components/Buttons.tsx
index 8390db7..79d1154 100644
--- a/src/components/Buttons.tsx
+++ b/src/components/Buttons.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { Button } from "@heroui/react";
import React, { useCallback, useEffect, useState } from "react";
import type { ButtonProps } from "@/utils/props";
diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx
index d94bdab..c931017 100644
--- a/src/components/Footer.tsx
+++ b/src/components/Footer.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { Source } from "@/components/Source";
import { ThemeSwitcher } from "@/components/ThemeSwitcher";
diff --git a/src/components/Selectors.tsx b/src/components/Selectors.tsx
index be9fed9..b1a2f77 100644
--- a/src/components/Selectors.tsx
+++ b/src/components/Selectors.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { Select, SelectItem } from "@heroui/react";
import type { SelectorProps } from "@/utils/props";
import type { ChangeEvent } from "react";
diff --git a/src/components/Source.tsx b/src/components/Source.tsx
index 11fbe82..2e219a2 100644
--- a/src/components/Source.tsx
+++ b/src/components/Source.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { Button } from "@heroui/button";
import { VscGithubInverted } from "react-icons/vsc";
diff --git a/src/components/ThemeSwitcher.tsx b/src/components/ThemeSwitcher.tsx
index 9939646..6e25394 100644
--- a/src/components/ThemeSwitcher.tsx
+++ b/src/components/ThemeSwitcher.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { Button } from "@heroui/button";
import { useTheme } from "next-themes";
import { VscColorMode } from "react-icons/vsc";
diff --git a/src/hooks/useState.ts b/src/hooks/useState.ts
index fcd417f..aacaff9 100644
--- a/src/hooks/useState.ts
+++ b/src/hooks/useState.ts
@@ -1,3 +1,5 @@
+"use client";
+
import { useState } from "react";
import useYears from "@/hooks/useYears";
diff --git a/src/hooks/useYears.tsx b/src/hooks/useYears.tsx
index ab3442f..5161ab7 100644
--- a/src/hooks/useYears.tsx
+++ b/src/hooks/useYears.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { useEffect } from "react";
export default function useYears(
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
deleted file mode 100644
index a5bffda..0000000
--- a/src/pages/_app.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { HeroUIProvider } from "@heroui/react";
-import type { AppProps } from "next/app";
-import { Inter } from "next/font/google";
-import Head from "next/head";
-import { ThemeProvider as NextThemesProvider } from "next-themes";
-import "@/styles/globals.css";
-
-const inter = Inter({
- subsets: ["latin"],
- variable: "--font-inter",
-});
-
-export default function App({ Component, pageProps }: AppProps) {
- return (
- <>
-
- Érettségi kereső
-
-
-
-
-
-
- >
- );
-}
diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx
deleted file mode 100644
index 99a6a23..0000000
--- a/src/pages/_document.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Head, Html, Main, NextScript } from "next/document";
-
-export default function Document() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/src/pages/api/erettsegi.ts b/src/pages/api/erettsegi.ts
deleted file mode 100644
index 7dd35d8..0000000
--- a/src/pages/api/erettsegi.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import type { NextApiRequest, NextApiResponse } from "next";
-import { subjects } from "@/utils/subjects";
-
-export default function handler(req: NextApiRequest, res: NextApiResponse) {
- try {
- const { vizsgatargy, ev, idoszak, szint } = req.query as {
- vizsgatargy: string;
- ev: string;
- idoszak: string;
- szint: string;
- };
-
- const secure = req.headers["x-forwarded-proto"] === "https";
- const protocol = secure ? "https" : "http";
- const address = req.headers.host;
-
- const baseUrl = `https://dload-oktatas.educatio.hu/erettsegi/feladatok_${ev}${idoszak}_${szint}/`;
- const proxiedUrl = `${protocol}://${address}/api/proxy?link=${encodeURI(
- baseUrl,
- )}`;
-
- const missingParams = [];
- if (!ev) missingParams.push("ev");
- if (!szint) missingParams.push("szint");
- if (!idoszak) missingParams.push("idoszak");
- if (!vizsgatargy) missingParams.push("vizsgatargy");
-
- if (missingParams.length > 0) {
- return res
- .status(400)
- .json({ error: `Hiányzó paraméterek: ${missingParams.join(", ")}` });
- }
-
- if (ev <= "2012") {
- return res.status(400).json({ error: "Érvénytelen év" });
- }
-
- const validSubjects = subjects.map((subject) => subject.value);
- if (!vizsgatargy || !validSubjects.includes(vizsgatargy)) {
- return res.status(400).json({ error: "Érvénytelen vizsgatárgy" });
- }
-
- let honap: string;
- switch (idoszak) {
- case "osz":
- honap = "okt";
- break;
- case "tavasz":
- honap = "maj";
- break;
- default:
- return res.status(400).json({ error: "Érvénytelen időszak" });
- }
-
- let prefix: string;
- switch (szint) {
- case "emelt":
- prefix = `e_${vizsgatargy}`;
- break;
- case "kozep":
- prefix = `k_${vizsgatargy}`;
- break;
- default:
- return res.status(400).json({ error: "Érvénytelen szint" });
- }
-
- const feladat = "fl";
- const utmutato = "ut";
- const forras = "for";
- const megoldas = "meg";
- const shortev = ev.slice(-2);
-
- let flPdfUrl: string | undefined,
- utPdfUrl: string | undefined,
- flZipUrl: string | undefined,
- utZipUrl: string | undefined,
- flMp3Url: string | undefined;
- switch (vizsgatargy) {
- case "inf":
- case "infoism":
- case "digkult":
- flZipUrl = `${baseUrl}${prefix}${forras}_${shortev}${honap}_${feladat}.zip`;
- flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`;
- utZipUrl = `${baseUrl}${prefix}${megoldas}_${shortev}${honap}_${utmutato}.zip`;
- utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`;
- break;
- case "angol":
- case "nemet":
- flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`;
- utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`;
- flMp3Url = `${baseUrl}${prefix}_${shortev}${honap}_${feladat}.mp3`;
- break;
- default:
- flPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${feladat}.pdf`;
- utPdfUrl = `${proxiedUrl}${prefix}_${shortev}${honap}_${utmutato}.pdf`;
- break;
- }
-
- res.setHeader("Cache-Control", "s-maxage=31536000");
- res.status(200).json({ flPdfUrl, utPdfUrl, flZipUrl, utZipUrl, flMp3Url });
- } catch (e: unknown) {
- if (e instanceof Error) {
- let causeCode: string | undefined;
- if (e.cause && typeof e.cause === "object" && "code" in e.cause) {
- causeCode = String((e.cause as { code: unknown }).code);
- }
-
- res.status(500).json({
- error: "Internal Server Error",
- message: e.message,
- cause: causeCode,
- stack: process.env.NODE_ENV === "development" ? e.stack : undefined,
- });
- } else {
- res.status(500).json({
- error: "Internal Server Error",
- message: "An unexpected error occurred",
- details: String(e),
- });
- }
- }
-}
diff --git a/src/pages/api/proxy.ts b/src/pages/api/proxy.ts
deleted file mode 100644
index f7c5bfe..0000000
--- a/src/pages/api/proxy.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import type { NextApiRequest, NextApiResponse } from "next";
-import { Agent, fetch } from "undici";
-
-const insecureAgent = new Agent({
- connect: {
- rejectUnauthorized: false,
- },
-});
-
-export default async function handler(
- req: NextApiRequest,
- res: NextApiResponse,
-) {
- const { link } = req.query as { link: string };
- let missingParam: string | null = null;
- if (!link) {
- missingParam = "link";
- }
-
- if (missingParam) {
- return res
- .status(400)
- .json({ error: `Hiányzó paraméter: ${missingParam}` });
- }
-
- const domain = link.split("/")[2];
- if (domain !== "dload-oktatas.educatio.hu") {
- return res.status(400).json({ error: "Érvénytelen link" });
- }
-
- try {
- res.setHeader("Cache-Control", "s-maxage=31536000");
-
- const response = await fetch(link, {
- method: "GET",
- dispatcher: insecureAgent,
- });
-
- const contentType = response.headers.get("content-type");
-
- if (contentType === "application/pdf") {
- const filename = link.split("/").pop() ?? "document.pdf";
- res.setHeader("Content-Type", contentType);
- res.setHeader("Content-Disposition", `inline; filename="${filename}"`);
- }
-
- if (response.ok) {
- const arrayBuffer: ArrayBuffer = await response.arrayBuffer();
- const buffer: Buffer = Buffer.from(arrayBuffer);
- res.send(buffer);
- } else {
- res
- .status(response.status)
- .json({ error: "Hiba történt a lekérés során." });
- }
- } catch (e: unknown) {
- if (e instanceof Error) {
- let causeCode: string | undefined;
- if (e.cause && typeof e.cause === "object" && "code" in e.cause) {
- causeCode = String((e.cause as { code: unknown }).code);
- }
-
- res.status(500).json({
- error: "Internal Server Error",
- message: e.message,
- cause: causeCode,
- stack: process.env.NODE_ENV === "development" ? e.stack : undefined,
- });
- } else {
- res.status(500).json({
- error: "Internal Server Error",
- message: "An unexpected error occurred",
- details: String(e),
- });
- }
- }
-}
diff --git a/src/pages/api/validate.ts b/src/pages/api/validate.ts
deleted file mode 100644
index 41b98bf..0000000
--- a/src/pages/api/validate.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import type { NextApiRequest, NextApiResponse } from "next";
-import { Agent, fetch } from "undici";
-
-const insecureAgent = new Agent({
- connect: {
- rejectUnauthorized: false,
- },
-});
-
-export default async function handler(
- req: NextApiRequest,
- res: NextApiResponse,
-) {
- const { link } = req.query as { link: string };
- let missingParam: string | null = null;
-
- if (!link) {
- missingParam = "link";
- }
-
- if (missingParam) {
- return res
- .status(400)
- .json({ error: `Hiányzó paraméter: ${missingParam}` });
- }
-
- const domain = link.split("/")[2];
- if (
- domain !== "localhost:3000" &&
- domain !== "erettsegi.albert.lol" &&
- domain !== "dload-oktatas.educatio.hu"
- ) {
- return res.status(400).json({ error: "Érvénytelen link" });
- }
-
- try {
- const { protocol, host } = new URL(link);
- if (!protocol || !host) {
- return res.status(400).json({ error: "Érvénytelen link" });
- }
-
- const response = await fetch(link, {
- method: "HEAD",
- dispatcher: insecureAgent,
- });
-
- const status = response.status;
- res.status(200).json({ status });
- } catch (e: unknown) {
- if (e instanceof Error) {
- let causeCode: string | undefined;
- if (e.cause && typeof e.cause === "object" && "code" in e.cause) {
- causeCode = String((e.cause as { code: unknown }).code);
- }
-
- res.status(500).json({
- error: "Internal Server Error",
- message: e.message,
- cause: causeCode,
- stack: process.env.NODE_ENV === "development" ? e.stack : undefined,
- });
- } else {
- res.status(500).json({
- error: "Internal Server Error",
- message: "An unexpected error occurred",
- details: String(e),
- });
- }
- }
-}
diff --git a/tsconfig.json b/tsconfig.json
index 4c01a40..c284e92 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,27 +1,36 @@
{
"compilerOptions": {
- /* Base Options: */
- "esModuleInterop": true,
- "skipLibCheck": true,
- "target": "es2022",
+ /* Basic Options */
+ "target": "esnext",
+ "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
- "resolveJsonModule": true,
- "moduleDetection": "force",
- "isolatedModules": true,
+ "skipLibCheck": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
/* Strictness */
"strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
- "checkJs": true,
- /* Bundled projects */
- "lib": ["dom", "dom.iterable", "ES2022"],
+ /* Module Resolution */
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "verbatimModuleSyntax": true,
+
+ /* Code Style */
+ "forceConsistentCasingInFileNames": true,
"noEmit": true,
- "module": "ESNext",
- "moduleResolution": "Bundler",
- "jsx": "preserve",
- "plugins": [{ "name": "next" }],
- "incremental": true,
+ "esModuleInterop": true,
/* Path Aliases */
"baseUrl": ".",
@@ -29,16 +38,6 @@
"@/*": ["./src/*"]
}
},
- "include": [
- ".eslintrc.cjs",
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx",
- "**/*.cjs",
- "**/*.js",
- ".next/types/**/*.ts",
- "next.config.mjs",
- "postcss.config.mjs"
- ],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}