diff --git a/backend/server.ts b/backend/server.ts index a59f0d2..96db10e 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -3,6 +3,7 @@ import cors from "@fastify/cors"; import multipart from "@fastify/multipart"; import { libreConvert } from "./src/routes/libreconvert.route"; import { colorConvert } from "./src/routes/colorconvert.route"; +import {passwordGenerate} from "./src/routes/passwordgenerate.route"; const app = Fastify({ logger: true }); @@ -15,6 +16,7 @@ app.register(cors, { app.register(multipart); app.register(libreConvert); app.register(colorConvert); +app.register(passwordGenerate); const PORT = process.env.PORT || 4000; app.listen({ port: Number(PORT), host: "0.0.0.0" }, () => { diff --git a/backend/src/routes/colorconvert.route.ts b/backend/src/routes/colorconvert.route.ts index 402e642..11ca8c8 100644 --- a/backend/src/routes/colorconvert.route.ts +++ b/backend/src/routes/colorconvert.route.ts @@ -19,7 +19,7 @@ export async function colorConvert(app: FastifyInstance) { return reply.status(400).send({ error: "No RGB declared!" }); } const hex = (`#${(+data.red).toString(16).padStart(2, "0")}${(+data.green).toString(16).padStart(2, "0")}${(+data.blue).toString(16).padStart(2, "0")}`).toUpperCase(); - reply.header("Content-Type", "application/json").send({ hex: hex }); + reply.header("Content-Type", "text/plain").status(200).send(hex); } catch (error) { console.error("Convert error:", error); reply.status(500).send({ error: "Error while converting!" }); diff --git a/backend/src/routes/passwordgenerate.route.ts b/backend/src/routes/passwordgenerate.route.ts new file mode 100644 index 0000000..7b1345d --- /dev/null +++ b/backend/src/routes/passwordgenerate.route.ts @@ -0,0 +1,60 @@ +import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify"; + +interface RequestBody { + length: string; + numb: boolean; + lower: boolean; + upper: boolean; + special: boolean; +} + +export async function passwordGenerate(app: FastifyInstance) { + app.post( + "/api/password-generate", + async ( + request: FastifyRequest<{ Body: RequestBody }>, + reply: FastifyReply, + ) => { + try { + const data = request.body; + if (!data) { + return reply.status(400).send({ error: "No length or type declared!" }); + } + let numArray: string[] = "0123456789".split(""); + let lowerArray: string[] = "abcdefghijklmnopqrstuvwxyz".split(""); + let upperArray: string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); + let specialArray: string[] = "!@#$%^&*()_+[]{}|;:,.<>?".split(""); + let passwordArray: string[] = []; + + if(data.numb){ + passwordArray = passwordArray.concat(numArray); + } + + if(data.lower){ + passwordArray = passwordArray.concat(lowerArray); + } + + if(data.upper){ + passwordArray = passwordArray.concat(upperArray); + } + + if(data.special){ + passwordArray = passwordArray.concat(specialArray); + } + + let password = ""; + + for (let i = 0; i < +data.length; i++) { + const ind: number = Math.floor(Math.random() * passwordArray.length); + const randomElement: string = passwordArray[ind]; + password = password.concat(randomElement); + } + + reply.header("Content-Type", "text/plain").status(200).send(password); + } catch (error) { + console.error("Convert error:", error); + reply.status(500).send({ error: "Error while converting!" }); + } + }, + ); +} \ No newline at end of file diff --git a/frontend/src/app/password-generator/layout.tsx b/frontend/src/app/password-generator/layout.tsx new file mode 100644 index 0000000..848613f --- /dev/null +++ b/frontend/src/app/password-generator/layout.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import type { Metadata } from "next"; +import { toolLinks } from "@/constants"; + +export const metadata: Metadata = { + title: toolLinks[2].title, + description: "Generator for secure strong passwords!", +}; + +export default function RootLayout({ + children, + }: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + {children} + + ); +} diff --git a/frontend/src/app/password-generator/page.tsx b/frontend/src/app/password-generator/page.tsx new file mode 100644 index 0000000..4329f70 --- /dev/null +++ b/frontend/src/app/password-generator/page.tsx @@ -0,0 +1,152 @@ +"use client"; + +import React, { useState } from "react"; +import Navbar from "../../components/Navbar"; +import Footer from "../../components/Footer"; +import Button from "../../components/Button"; + +export default function RgbToHex() { + + const [loading, setLoading] = useState(false); + const [password, setPassword] = useState(""); + + const generatePassword = async () => { + + setLoading(true); + + const length = (document.getElementById("length") as HTMLInputElement).value; + const numb = (document.getElementById("numb") as HTMLInputElement).checked; + const lower = (document.getElementById("lower") as HTMLInputElement).checked; + const upper = (document.getElementById("upper") as HTMLInputElement).checked; + const special = (document.getElementById("special") as HTMLInputElement).checked; + + try { + const response = await fetch( + process.env.backend_url + "/api/password-generate", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ length: length, numb: numb, lower: lower, upper: upper, special: special }), + }, + ); + if (!response.ok) { + return new Error(`Error: ${response.statusText}`); + } + const password: string = await response.text(); + console.log(password); + setPassword(password); + + } catch (error) { + console.error("Error while converting:", error); + alert("Error while converting"); + } finally { + setLoading(false); + } + }; + + const clearInAndOutput = () => { + setPassword(""); + const length = document.getElementById("length") as HTMLInputElement; + const numb = document.getElementById("numb") as HTMLInputElement; + const lower = document.getElementById("lower") as HTMLInputElement; + const upper = document.getElementById("upper") as HTMLInputElement; + const special = document.getElementById("special") as HTMLInputElement; + length.value = ""; + numb.checked = false; + lower.checked = false; + upper.checked = false; + special.checked = false; + }; + + const checkInput = (event: React.ChangeEvent) => { + const length = (document.getElementById(event.target.id) as HTMLInputElement); + const lengthValue = +length.value; + + if (lengthValue < 1 || lengthValue > 64 ) { + alert("Invalid input. Please enter a number between 1 and 64."); + } + if (lengthValue < 1) { + length.value = "1"; + } else if (lengthValue > 64) { + length.value = "64"; + } + } + + return ( +
+ +
+

password-generator

+
+
+ + + + + +
+
+ + + + + +
+
+
+
+
+ {password} +
+
+
+ ); +} \ No newline at end of file