From 06d356df5ae164767c0481a77f0de40d114b3648 Mon Sep 17 00:00:00 2001 From: Nayam Amarshe <25067102+NayamAmarshe@users.noreply.github.com> Date: Thu, 8 Feb 2024 01:22:14 +0530 Subject: [PATCH] Add google API check --- .env.local.example | 3 ++- pages/api/create.js | 50 ++++++++++++++++++++++++++++++++++++++++++++- pages/index.jsx | 17 +++++++-------- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/.env.local.example b/.env.local.example index 4e14d5f..aa6b33f 100644 --- a/.env.local.example +++ b/.env.local.example @@ -13,6 +13,7 @@ API_KEY="" # CAN BE ANYTHING, THIS IS FOR BLOCKING API SECRET_KEY="" +SAFE_BROWSING_API_KEY="" # ENTER YOUR WEBSITE DOMAIN NAME HERE @@ -20,4 +21,4 @@ NEXT_PUBLIC_BASE_URL="https://website.com/" # DEFAULT CONFIG -RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED=false +RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED=false \ No newline at end of file diff --git a/pages/api/create.js b/pages/api/create.js index 633a164..568fe87 100644 --- a/pages/api/create.js +++ b/pages/api/create.js @@ -4,11 +4,19 @@ import CryptoJS from "crypto-js"; import { StatusCodes } from "http-status-codes"; const regex = - /(magnet:\?xt=urn:btih:[a-zA-Z0-9]*)|(^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,8}(:[0-9]{1,5})?(\/.*)?$)/; + /^(\S+:\/\/)[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,16}(:[0-9]{1,5})?(\/.*)?$/; + const slugRegex = /^[a-z0-9](-?[a-z0-9])*$/; export default async function handler(req, res) { const { slug, link, password } = req.body; + const apiKey = process.env.SAFE_BROWSING_API_KEY; + + if (!apiKey) { + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .json({ message: "API not available" }); + } const collectionName = process.env.NODE_ENV === "production" ? "links" : "testLinks"; @@ -42,6 +50,45 @@ export default async function handler(req, res) { }); } + try { + const url = new URL(link).hostname; + const response = await fetch( + "https://safebrowsing.googleapis.com/v4/threatMatches:find?key=" + apiKey, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + client: { + clientId: "maglit-website", + clientVersion: "1.0.0", + }, + threatInfo: { + threatTypes: [ + "MALWARE", + "SOCIAL_ENGINEERING", + "UNWANTED_SOFTWARE", + "POTENTIALLY_HARMFUL_APPLICATION", + ], + platformTypes: ["ANY_PLATFORM"], + threatEntryTypes: ["URL"], + threatEntries: [{ url: `${url}` }], + }, + }), + } + ); + + const data = await response.json(); + + if (data && data?.matches?.length > 0) { + // Handle error cases where the URL might not be checked by Safe Browsing + res.status(200).json({ message: "Malicious link entered!" }); + } + } catch (error) { + res.status(500).json({ error: "Failed to check the URL." }); + } + try { // check firebase if slug exists const documentRef = doc(db, collectionName, slug); @@ -65,6 +112,7 @@ export default async function handler(req, res) { const docRef = setDoc(doc(collection(db, collectionName), slug), { link: encryptedLink, slug: slug, + created: new Date(), protected: !(password === ""), }); diff --git a/pages/index.jsx b/pages/index.jsx index ddff44d..3c1b604 100644 --- a/pages/index.jsx +++ b/pages/index.jsx @@ -3,10 +3,8 @@ import LinkOptionsModal from "../components/home/LinkOptionsModal"; import TopRightButtons from "../components/home/TopRightButtons"; import { cardsOpenState } from "../atoms/cardsOpenState"; import LinkClipboard from "../components/home/LinkClipboard"; -import { AnimatePresence, motion } from "framer-motion"; +import { AnimatePresence } from "framer-motion"; import { toast, ToastContainer } from "react-toastify"; -import { AiFillCloseCircle } from "react-icons/ai"; -import { Backdrop } from "../components/Backdrop"; import { navbarState } from "../atoms/navbarAtom"; import { linksState } from "../atoms/linksState"; import { RiArrowUpSLine } from "react-icons/ri"; @@ -15,9 +13,7 @@ import { BsArchiveFill } from "react-icons/bs"; import MainLogo from "../components/home/MainLogo"; import * as Monkey from "monkey-typewriter"; import { BASE_URL } from "../utils/config"; -import { FiCopy } from "react-icons/fi"; import { useRecoilState } from "recoil"; -import { useTheme } from "next-themes"; import Form from "../components/home/Form"; import { useEffect } from "react"; import { useState } from "react"; @@ -40,8 +36,9 @@ export default function Home() { const [locked, setLocked] = useState(false); const [customSlug, setCustomSlug] = useState(""); const slugRegex = /^[a-z0-9](-?[a-z0-9])*$/; + const linkRegex = - /(magnet:\?xt=urn:btih:[a-zA-Z0-9]*)|(^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,8}(:[0-9]{1,5})?(\/.*)?$)/; + /^(\S+:\/\/)[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,16}(:[0-9]{1,5})?(\/.*)?$/; useEffect(() => { const linksInStorage = JSON.parse(localStorage.getItem("links")) || []; @@ -120,10 +117,6 @@ export default function Home() { setPassword(""); } - const slug = await generateSlug(); - - const customOrDefaultSlug = customSlug.length == 0 ? slug : customSlug; - if (magnetLink.length < 1) { toast.error("You entered an invalid link"); return; @@ -136,6 +129,10 @@ export default function Home() { return; } + const slug = await generateSlug(); + + const customOrDefaultSlug = customSlug.length == 0 ? slug : customSlug; + if (slug.length < 1) { toast.error("Invalid Slug!"); return;