From a72b33597d8f5c22b80756bc20b36ea6d8adc859 Mon Sep 17 00:00:00 2001 From: Pablo Lara Date: Wed, 2 Oct 2024 16:09:26 +0200 Subject: [PATCH] WIP --- actions/auth.ts | 55 ---------- actions/auth/auth.ts | 102 ++++++++++++++++++ actions/auth/index.ts | 1 + actions/{ => providers}/index.ts | 1 - actions/{ => providers}/providers.ts | 7 -- app/(prowler)/providers/page.tsx | 2 +- auth.config.ts | 40 ++----- components/auth/AuthForm.tsx | 4 +- .../providers/CheckConnectionProvider.tsx | 2 +- components/providers/forms/add-form.tsx | 2 +- components/providers/forms/delete-form.tsx | 2 +- components/providers/forms/edit-form.tsx | 2 +- components/ui/sidebar/SidebarWrap.tsx | 2 +- lib/index.ts | 1 - lib/seed.ts | 25 ----- package-lock.json | 18 +++- package.json | 2 + 17 files changed, 133 insertions(+), 135 deletions(-) delete mode 100644 actions/auth.ts create mode 100644 actions/auth/auth.ts create mode 100644 actions/auth/index.ts rename actions/{ => providers}/index.ts (54%) rename actions/{ => providers}/providers.ts (96%) delete mode 100644 lib/seed.ts diff --git a/actions/auth.ts b/actions/auth.ts deleted file mode 100644 index 2cdf70bfd2..0000000000 --- a/actions/auth.ts +++ /dev/null @@ -1,55 +0,0 @@ -"use server"; - -import { AuthError } from "next-auth"; -import { z } from "zod"; - -import { signIn, signOut } from "@/auth.config"; -import { authFormSchema } from "@/types"; - -const formSchemaSignIn = authFormSchema("sign-in"); - -const defaultValues: z.infer = { - email: "", - password: "", -}; - -export async function authenticate( - prevState: unknown, - formData: z.infer, -) { - try { - await new Promise((resolve) => setTimeout(resolve, 2000)); - await signIn("credentials", { - ...formData, - redirect: false, - }); - return { - message: "Success", - }; - } catch (error) { - if (error instanceof AuthError) { - switch (error.type) { - case "CredentialsSignin": - return { - message: "Credentials error", - errors: { - ...defaultValues, - credentials: "Incorrect email or password", - }, - }; - default: - return { - message: "Unknown error", - errors: { - ...defaultValues, - unknown: "Unknown error", - }, - }; - } - } - } -} - -export async function logOut() { - await signOut(); -} diff --git a/actions/auth/auth.ts b/actions/auth/auth.ts new file mode 100644 index 0000000000..2bd7f6e4c1 --- /dev/null +++ b/actions/auth/auth.ts @@ -0,0 +1,102 @@ +"use server"; + +import { AuthError } from "next-auth"; +import { z } from "zod"; + +import { signIn, signOut } from "@/auth.config"; +import { authFormSchema } from "@/types"; + +const formSchemaSignIn = authFormSchema("sign-in"); +// const formSchemaSignUp = authFormSchema("sign-up"); + +const defaultValues: z.infer = { + email: "", + password: "", +}; + +export async function authenticate( + prevState: unknown, + formData: z.infer, +) { + try { + await signIn("credentials", { + ...formData, + redirect: false, + }); + return { + message: "Success", + }; + } catch (error) { + if (error instanceof AuthError) { + switch (error.type) { + case "CredentialsSignin": + return { + message: "Credentials error", + errors: { + ...defaultValues, + credentials: "Incorrect email or password", + }, + }; + default: + return { + message: "Unknown error", + errors: { + ...defaultValues, + unknown: "Unknown error", + }, + }; + } + } + } +} + +export const getToken = async (formData: z.infer) => { + const keyServer = process.env.API_BASE_URL; + const url = new URL(`${keyServer}/tokens`); + + const bodyData = { + data: { + type: "Token", + attributes: { + email: formData.email, + password: formData.password, + }, + }, + }; + + try { + const response = await fetch(url.toString(), { + method: "POST", + headers: { + "Content-Type": "application/vnd.api+json", + Accept: "application/vnd.api+json", + }, + body: JSON.stringify(bodyData), + }); + + if (!response.ok) { + return null; + } + const data = await response.json(); + + // Verify if the response contains the expected data + if (data && data.data && data.data.attributes) { + // const token = data.data.attributes.access; + // const decodedToken = jwtDecode(token); + return { + // userId: decodedToken.user_id, + email: formData.email, + // token: token, + // Add here other user fields we need in the session + }; + } + } catch (error) { + // eslint-disable-next-line no-console + console.error("Error en getToken:", error); + return null; + } +}; + +export async function logOut() { + await signOut(); +} diff --git a/actions/auth/index.ts b/actions/auth/index.ts new file mode 100644 index 0000000000..97ccf76494 --- /dev/null +++ b/actions/auth/index.ts @@ -0,0 +1 @@ +export * from "./auth"; diff --git a/actions/index.ts b/actions/providers/index.ts similarity index 54% rename from actions/index.ts rename to actions/providers/index.ts index 0085735bb3..5532383f5f 100644 --- a/actions/index.ts +++ b/actions/providers/index.ts @@ -1,2 +1 @@ -export * from "./auth"; export * from "./providers"; diff --git a/actions/providers.ts b/actions/providers/providers.ts similarity index 96% rename from actions/providers.ts rename to actions/providers/providers.ts index 8b06cb9b5c..ea37ca8986 100644 --- a/actions/providers.ts +++ b/actions/providers/providers.ts @@ -11,8 +11,6 @@ export const getProviders = async ({ sort = "", filters = {}, }) => { - // const session = await auth(); - if (isNaN(Number(page)) || page < 1) redirect("/providers"); const keyServer = process.env.API_BASE_URL; @@ -46,7 +44,6 @@ export const getProviders = async ({ }; export const getProvider = async (formData: FormData) => { - // const session = await auth(); const providerId = formData.get("id"); const keyServer = process.env.API_BASE_URL; @@ -69,7 +66,6 @@ export const getProvider = async (formData: FormData) => { }; export const updateProvider = async (formData: FormData) => { - // const session = await auth(); const keyServer = process.env.API_BASE_URL; const providerId = formData.get("providerId"); @@ -106,7 +102,6 @@ export const updateProvider = async (formData: FormData) => { }; export const addProvider = async (formData: FormData) => { - // const session = await auth(); const keyServer = process.env.API_BASE_URL; const providerType = formData.get("providerType"); @@ -145,7 +140,6 @@ export const addProvider = async (formData: FormData) => { }; export const checkConnectionProvider = async (formData: FormData) => { - // const session = await auth(); const keyServer = process.env.API_BASE_URL; const providerId = formData.get("id"); @@ -170,7 +164,6 @@ export const checkConnectionProvider = async (formData: FormData) => { }; export const deleteProvider = async (formData: FormData) => { - // const session = await auth(); const keyServer = process.env.API_BASE_URL; const providerId = formData.get("id"); diff --git a/app/(prowler)/providers/page.tsx b/app/(prowler)/providers/page.tsx index a10cd9a618..34b347d8e0 100644 --- a/app/(prowler)/providers/page.tsx +++ b/app/(prowler)/providers/page.tsx @@ -1,7 +1,7 @@ import { Spacer } from "@nextui-org/react"; import { Suspense } from "react"; -import { getProviders } from "@/actions"; +import { getProviders } from "@/actions/providers"; import { FilterControls, filtersProviders } from "@/components/filters"; import { AddProvider } from "@/components/providers"; import { diff --git a/auth.config.ts b/auth.config.ts index 2756263fd1..c744a258aa 100644 --- a/auth.config.ts +++ b/auth.config.ts @@ -1,34 +1,8 @@ -import bcryptjs from "bcryptjs"; import NextAuth, { type NextAuthConfig } from "next-auth"; import Credentials from "next-auth/providers/credentials"; import { z } from "zod"; -import { userMockData } from "./lib"; - -// const key = new TextEncoder().encode(process.env.AUTH_SECRET); -// const SALT_ROUNDS = 10; - -// export async function hashPassword(password: string) { -// return hash(password, SALT_ROUNDS); -// } - -async function getUser(email: string, password: string): Promise { - // Check if the user exists in the userMockData array. - const user = userMockData.find((user) => user.email === email); - if (!user) return null; - - if (!bcryptjs.compareSync(password, user.password)) return null; - - return { - id: user.id, - tenantId: user.tenantId, - name: user.name, - companyName: user.companyName, - email: user.email, - role: user.role, - image: user.image, - }; -} +import { getToken } from "./actions/auth"; export const authConfig = { session: { @@ -65,6 +39,7 @@ export const authConfig = { session({ session, token }) { session.user = token.data as any; + console.log("session", session); return session; }, }, @@ -83,15 +58,12 @@ export const authConfig = { }) .safeParse(credentials); - if (!parsedCredentials.success) { - return null; - } - const { email, password } = parsedCredentials.data; - console.log("email", email); - console.log("password", password); + if (!parsedCredentials.success) return null; + + const user = await getToken(parsedCredentials.data); - const user = await getUser(email, password); if (!user) return null; + return user; }, }), diff --git a/components/auth/AuthForm.tsx b/components/auth/AuthForm.tsx index 2d01e39320..e14ca3ec0e 100644 --- a/components/auth/AuthForm.tsx +++ b/components/auth/AuthForm.tsx @@ -9,7 +9,7 @@ import { useFormState } from "react-dom"; import { useForm } from "react-hook-form"; import { z } from "zod"; -import { authenticate } from "@/actions"; +import { authenticate } from "@/actions/auth"; import { Form, FormControl, @@ -53,14 +53,12 @@ export const AuthForm = ({ type }: { type: string }) => { try { // Sign-up logic will be here. if (type === "sign-in") { - console.log(data); dispatch({ email: data.email.toLowerCase(), password: data.password, }); } if (type === "sign-up") { - console.log(data); // const newUser = await signUp(data); } } catch (error) { diff --git a/components/providers/CheckConnectionProvider.tsx b/components/providers/CheckConnectionProvider.tsx index 2fadafad04..d5bc9e727d 100644 --- a/components/providers/CheckConnectionProvider.tsx +++ b/components/providers/CheckConnectionProvider.tsx @@ -2,7 +2,7 @@ import { useRef } from "react"; -import { checkConnectionProvider } from "@/actions"; +import { checkConnectionProvider } from "@/actions/providers"; import { CustomButtonClientAction } from "../ui/custom"; import { useToast } from "../ui/toast"; diff --git a/components/providers/forms/add-form.tsx b/components/providers/forms/add-form.tsx index f30855d2d0..4c063c7aef 100644 --- a/components/providers/forms/add-form.tsx +++ b/components/providers/forms/add-form.tsx @@ -5,7 +5,7 @@ import { Dispatch, SetStateAction } from "react"; import { useForm } from "react-hook-form"; import * as z from "zod"; -import { addProvider } from "@/actions"; +import { addProvider } from "@/actions/providers"; import { SaveIcon } from "@/components/icons"; import { useToast } from "@/components/ui"; import { CustomButton, CustomInput } from "@/components/ui/custom"; diff --git a/components/providers/forms/delete-form.tsx b/components/providers/forms/delete-form.tsx index 434f453279..e08ac4ada5 100644 --- a/components/providers/forms/delete-form.tsx +++ b/components/providers/forms/delete-form.tsx @@ -5,7 +5,7 @@ import React, { Dispatch, SetStateAction } from "react"; import { useForm } from "react-hook-form"; import * as z from "zod"; -import { deleteProvider } from "@/actions"; +import { deleteProvider } from "@/actions/providers"; import { DeleteIcon } from "@/components/icons"; import { useToast } from "@/components/ui"; import { CustomButton } from "@/components/ui/custom"; diff --git a/components/providers/forms/edit-form.tsx b/components/providers/forms/edit-form.tsx index 669e4a9184..bae117b7da 100644 --- a/components/providers/forms/edit-form.tsx +++ b/components/providers/forms/edit-form.tsx @@ -5,7 +5,7 @@ import { Dispatch, SetStateAction } from "react"; import { useForm } from "react-hook-form"; import * as z from "zod"; -import { updateProvider } from "@/actions"; +import { updateProvider } from "@/actions/providers"; import { SaveIcon } from "@/components/icons"; import { useToast } from "@/components/ui"; import { CustomButton, CustomInput } from "@/components/ui/custom"; diff --git a/components/ui/sidebar/SidebarWrap.tsx b/components/ui/sidebar/SidebarWrap.tsx index 949cd59da0..59b29bb458 100644 --- a/components/ui/sidebar/SidebarWrap.tsx +++ b/components/ui/sidebar/SidebarWrap.tsx @@ -9,7 +9,7 @@ import { useSession } from "next-auth/react"; import React, { useCallback } from "react"; import { useMediaQuery } from "usehooks-ts"; -import { logOut } from "@/actions"; +import { logOut } from "@/actions/auth"; import { useUIStore } from "@/store"; import { diff --git a/lib/index.ts b/lib/index.ts index 8edc14574b..38d384fb6e 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,3 +1,2 @@ export * from "./custom"; -export * from "./seed"; export * from "./utils"; diff --git a/lib/seed.ts b/lib/seed.ts deleted file mode 100644 index 1ff00ee60b..0000000000 --- a/lib/seed.ts +++ /dev/null @@ -1,25 +0,0 @@ -import bcryptjs from "bcryptjs"; -import { v4 as uuidv4 } from "uuid"; - -export const userMockData = [ - { - id: uuidv4(), // Generate a unique UUID. - tenantId: "12646005-9067-4d2a-a098-8bb378604362", - email: "admin@prowler.com", - name: "Admin Prowler", - companyName: "Prowler", - password: bcryptjs.hashSync("123123", 10), - role: "admin", - image: null, - }, - { - id: uuidv4(), // Generate a unique UUID. - tenantId: "12646005-9067-4d2a-a098-8bb378604362", - email: "user@prowler.com", - name: "User Prowler", - companyName: "Prowler", - password: bcryptjs.hashSync("123123", 10), - role: "user", - image: null, - }, -]; diff --git a/package-lock.json b/package-lock.json index 9d3fc5073c..1f8510886b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,8 @@ "date-fns": "^3.6.0", "framer-motion": "~11.1.1", "intl-messageformat": "^10.5.0", + "jose": "^5.9.3", + "jwt-decode": "^4.0.0", "lucide-react": "^0.417.0", "next": "^14.2.12", "next-auth": "^5.0.0-beta.20", @@ -9423,9 +9425,10 @@ } }, "node_modules/jose": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/jose/-/jose-5.7.0.tgz", - "integrity": "sha512-3P9qfTYDVnNn642LCAqIKbTGb9a1TBxZ9ti5zEVEr48aDdflgRjhspWFb6WM4PzAfFbGMJYC4+803v8riCRAKw==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.9.3.tgz", + "integrity": "sha512-egLIoYSpcd+QUF+UHgobt5YzI2Pkw/H39ou9suW687MY6PmCwPmkNV/4TNjn1p2tX5xO3j0d0sq5hiYE24bSlg==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -9507,6 +9510,15 @@ "node": ">=4.0" } }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", diff --git a/package.json b/package.json index 468ce86d58..67ac210f66 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,8 @@ "date-fns": "^3.6.0", "framer-motion": "~11.1.1", "intl-messageformat": "^10.5.0", + "jose": "^5.9.3", + "jwt-decode": "^4.0.0", "lucide-react": "^0.417.0", "next": "^14.2.12", "next-auth": "^5.0.0-beta.20",