-
-
- Password Guard
- One password for protect all others.
-
-
- {user ? (
-
- Entrer
-
- ) : (
-
- )}
-
- {!user && (
-
-
- Sandbox
-
-
- )}
-
-
+
+
+
)
}
diff --git a/src/app/sandbox/page.tsx b/src/app/sandbox/page.tsx
index a70af5f..cfb74cc 100644
--- a/src/app/sandbox/page.tsx
+++ b/src/app/sandbox/page.tsx
@@ -1,22 +1,22 @@
import { AddPasswordCard } from "@/components/add-password-card"
import { PasswordCard } from "@/components/password_card"
import { PasswordsHealthCard } from "@/components/passwords-health"
-import { PassBdd, encryptData } from "@/components/types/types"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card"
-import { guardedPasswordService } from "@/services/GuardedPassword.service"
-import { decryptPassword, privateKeyDecrypt } from "@/services/security.service"
-import { userAppService } from "@/services/userApp.service"
-import { currentUser } from "@clerk/nextjs"
+import { currentUser } from "@/lib/hooks/auth"
+import { guardedPasswordService } from "@/lib/services/GuardedPassword.service"
+import { decryptPassword, privateKeyDecrypt } from "@/lib/services/security.service"
+import { userAppService } from "@/lib/services/userApp.service"
+import { PassBdd, encryptData } from "@/lib/types/types"
import Image from "next/image"
import Link from "next/link"
import { Home } from "../../../node_modules/lucide-react"
export default async function SandBoxPage() {
const sandBoxUser = await userAppService.getByEmail("noemail@sandbox.com")
- const user = await currentUser()
+ const { email } = currentUser()
- if (user) {
+ if (email) {
throw new Error("Déconnectez-vous pour utiliser la sandbox.")
}
@@ -85,7 +85,7 @@ export default async function SandBoxPage() {
.map((password) => {
return (
)
})}
diff --git a/src/app/view-passwords/page.tsx b/src/app/view-passwords/page.tsx
index 0da9f3d..74da895 100644
--- a/src/app/view-passwords/page.tsx
+++ b/src/app/view-passwords/page.tsx
@@ -1,87 +1,59 @@
-"use client"
-
-import { AddPasswordForm } from "@/components/forms/add-password-form"
+import { AddPasswordCard } from "@/components/add-password-card"
import { PasswordCard } from "@/components/password_card"
import { PasswordsHealthCard } from "@/components/passwords-health"
-import { PlusPasswordCard } from "@/components/plus-password-card"
import AccessDenied from "@/components/shared/access-denied"
-import { Loader } from "@/components/shared/loader"
-import { PassBdd, encryptData } from "@/components/types/types"
-import { decryptPassword, privateKeyDecrypt } from "@/services/security.service"
-import { useUser } from "@clerk/nextjs"
-import { useEffect, useState } from "react"
-
-export default function ViewPasswordsPage() {
- const { isLoaded, isSignedIn, user } = useUser()
- const [isLoading, setIsLoading] = useState(true)
- const [isAcces, setIsAcces] = useState(false)
- const [isShow, setIsShow] = useState(false)
- const [passwords, setPasswords] = useState
([])
-
- async function checkIsUserLogged() {
- const response = await fetch("api/user")
- if (response.ok) {
- setIsAcces(true)
- recupPasswords()
- }
- setIsLoading(false)
- }
+import { currentUser } from "@/lib/hooks/auth"
+import { guardedPasswordService } from "@/lib/services/GuardedPassword.service"
+import { decryptPassword, privateKeyDecrypt } from "@/lib/services/security.service"
+import { userAppService } from "@/lib/services/userApp.service"
+import { PassBdd, encryptData } from "@/lib/types/types"
- async function recupPasswords() {
- const privateKey = localStorage.getItem("privateKey")
- if (!privateKey) return
- const response = await fetch("api/passwords")
- if (!response.ok) return
+export default async function ViewPasswordsPage() {
+ const { email, privateKey } = currentUser()
- const data = await response.json()
+ if (!email) return
+ if (!privateKey) throw new Error("Pas de clé privée")
- const privateKeyBuffer = Buffer.from(privateKey, "utf-8")
+ const privateKeyBuffer = Buffer.from(privateKey, "utf-8")
- const passBdds: PassBdd[] = []
+ const cUser = await userAppService.getByEmail(email)
+ if (!cUser) {
+ throw new Error("Impossible de trouver l'utilisateur.")
+ }
- for (const password of data.passwords) {
- const encryptedData: encryptData = {
- iv: password.iv,
- encryptedPassword: Buffer.from(password.password, "hex").toString("hex"),
- }
+ const passwords = await guardedPasswordService.getAllGuardedPasswordByUserID(cUser.id)
+ if (!passwords) {
+ throw new Error("Echec dans la récupération des mots de passe.")
+ }
- const decryptedAESKey = privateKeyDecrypt(Buffer.from(password.encryptedAESKey, "base64"), privateKeyBuffer)
- const decryptedPassword = decryptPassword(encryptedData, decryptedAESKey)
+ const passBdds: PassBdd[] = []
- passBdds.push({ id: password.id, title: password.title, login: password.login, password: decryptedPassword })
+ for (const password of passwords) {
+ const encryptedData: encryptData = {
+ iv: password.iv,
+ encryptedPassword: password.password.toString("hex"),
}
- setPasswords(passBdds)
- }
-
- useEffect(() => {
- checkIsUserLogged()
- }, [isShow])
-
- if (isLoading) {
- return
- }
+ const decryptedAESKey = privateKeyDecrypt(password.encryptedAESKey, privateKeyBuffer)
+ const decryptedPassword = decryptPassword(encryptedData, decryptedAESKey)
- if (!user || !isAcces) {
- return
+ passBdds.push({ id: password.id, title: password.title, login: password.login, password: decryptedPassword })
}
return (
-
+
- {isAcces && passwords.length > 0 && (
- <>
- {passwords.map((password) => {
- return (
-
- )
- })}
- >
- )}
- {isShow ?
:
}
+ {passBdds
+ .sort((a, b) => a.id - b.id)
+ .map((password) => {
+ return (
+
+ )
+ })}
+
)
diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx
index dae27ab..c387a7f 100644
--- a/src/components/NavBar.tsx
+++ b/src/components/NavBar.tsx
@@ -1,8 +1,6 @@
-import { SignedIn, SignedOut, SignInButton, UserButton } from "@clerk/nextjs"
import Image from "next/image"
import Link from "next/link"
import { SwitchToggle } from "./switch-theme"
-import { Button } from "./ui/Button"
export function NavBar() {
return (
@@ -13,14 +11,6 @@ export function NavBar() {
-
-
-
-
-
- Sign in
-
-
diff --git a/src/components/btn-acces-if-logged.tsx b/src/components/btn-acces-if-logged.tsx
deleted file mode 100644
index 541e2db..0000000
--- a/src/components/btn-acces-if-logged.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { currentUser } from "@clerk/nextjs"
-import Link from "next/link"
-import { Description } from "./description"
-import { Button } from "./ui/Button"
-
-export const BtnAccesIfLogged = async () => {
- const user = await currentUser()
-
- if (!user) {
- return
+
+
+
+ setIsSignIn(false)} className="cursor-pointer">
+ Pas encore de coffre ? Clique ici.
+
+
+
)
}
diff --git a/src/components/forms/edit-password-form.tsx b/src/components/forms/edit-password-form.tsx
index 20ba1b6..1e568e6 100644
--- a/src/components/forms/edit-password-form.tsx
+++ b/src/components/forms/edit-password-form.tsx
@@ -1,11 +1,12 @@
"use client"
-import { PassBdd } from "@/components/types/types"
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { toast } from "@/components/ui/use-toast"
-import { encryptPassword, generateAESKey, publicKeyEncrypt } from "@/services/security.service"
+import { generatePassword } from "@/lib/password"
+import { encryptPassword, generateAESKey, publicKeyEncrypt } from "@/lib/services/security.service"
+import { PassBdd } from "@/lib/types/types"
import { addPasswordSchema } from "@/zod/schema.example"
import { zodResolver } from "@hookform/resolvers/zod"
import { useRouter } from "next/navigation"
@@ -13,17 +14,8 @@ import { Dispatch, SetStateAction } from "react"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { ArrowLeft, RefreshCw, Send } from "../../../node_modules/lucide-react"
-import { generatePassword } from "../functions/password"
-export function EditPassword({
- setIsEditing,
- password,
- recupPasswords = undefined,
-}: {
- setIsEditing: Dispatch
>
- password: PassBdd
- recupPasswords: undefined | (() => void)
-}) {
+export function EditPassword({ setIsEditing, password }: { setIsEditing: Dispatch>; password: PassBdd }) {
const router = useRouter()
const form = useForm>({
resolver: zodResolver(addPasswordSchema),
@@ -68,11 +60,7 @@ export function EditPassword({
})
if (response2.ok) {
- if (recupPasswords != undefined) {
- recupPasswords()
- } else {
- router.refresh()
- }
+ router.refresh()
setIsEditing(false)
toast({
description: "Mot de passe modifié avec succes.",
@@ -86,7 +74,7 @@ export function EditPassword({
}
return (
-
+
diff --git a/src/components/forms/master-form-create.tsx b/src/components/forms/master-form-create.tsx
index ddc6d12..0c7c2ba 100644
--- a/src/components/forms/master-form-create.tsx
+++ b/src/components/forms/master-form-create.tsx
@@ -1,119 +1,111 @@
"use client"
-import { robustTest } from "@/components/functions/validators"
-import { PasswordInput } from "@/components/shared/password-input"
+import { InputEye } from "@/components/shared/input-password-eye"
import { Button } from "@/components/ui/Button"
+import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
+import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form"
+import { Input } from "@/components/ui/input"
import { toast } from "@/components/ui/use-toast"
-import { useUser } from "@clerk/nextjs"
+import { newMasterPasswordSchema } from "@/zod/schema.example"
+import { zodResolver } from "@hookform/resolvers/zod"
import CryptoJS from "crypto-js"
-import { useRouter } from "next/navigation"
-import { useRef, useState } from "react"
-import { Lock } from "../../../node_modules/lucide-react"
+import { useForm } from "react-hook-form"
+import { z } from "zod"
-export function MasterFormCreate() {
- const { isLoaded, isSignedIn, user } = useUser()
- const formRef = useRef(null)
- const router = useRouter()
- const [isValidForm, setIsValidForm] = useState(false)
- const [isPaste, setIsPaste] = useState(false)
- const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{15,}$/
+export function MasterFormCreate({ setIsSignIn }: { setIsSignIn: (value: boolean) => void }) {
+ const form = useForm>({
+ resolver: zodResolver(newMasterPasswordSchema),
+ defaultValues: {
+ email: "",
+ master: "",
+ confirm: "",
+ },
+ })
- async function handleSubmit(e: React.FormEvent) {
- e.preventDefault()
+ async function handleSubmit(values: z.infer) {
toast({
description: "Création du mot de passe master en cours ...",
})
- if (formRef.current) {
- const formData = new FormData(formRef.current)
- const master = formData.get("master")
- const confirm = formData.get("confirm")
- if (master && confirm) {
- const isMasterSecure = regex.test(String(formData.get("master")))
- const isConfirmEqualMaster = String(formData.get("master")) === String(formData.get("confirm"))
+ const envSalt = process.env.NEXT_PUBLIC_SUPERMASTERSALT
+ if (!envSalt) return console.error("Probleme d'env")
- if (isMasterSecure && isConfirmEqualMaster) {
- if (user?.primaryEmailAddress) {
- const envSalt = process.env.NEXT_PUBLIC_SUPERMASTERSALT
- if (!envSalt) return console.error("Probleme d&aposenv")
- const supersalt = envSalt + user.primaryEmailAddress.toString()
- const response = await fetch("api/user", {
- method: "POST",
- body: JSON.stringify({
- hashMaster: CryptoJS.SHA256(supersalt + String(formData.get("master"))).toString(CryptoJS.enc.Hex),
- }),
- })
-
- if (response.ok) {
- toast({
- description: "Réussite !",
- })
- router.push("/check")
- } else {
- const error: { error: string } = await response.json()
- toast({
- variant: "destructive",
- description: `Erreur : ${error.error}`,
- })
- }
- }
- }
- }
- }
- }
-
- function validationFormTest() {
- if (formRef.current) {
- const formData = new FormData(formRef.current)
- const master = formData.get("master")
- const confirm = formData.get("confirm")
-
- if (master && confirm) {
- const isMasterSecure = regex.test(String(formData.get("master")))
- const isConfirmEqualMaster = String(formData.get("master")) === String(formData.get("confirm"))
- setIsValidForm(isMasterSecure && isConfirmEqualMaster)
- }
- }
- }
+ const supersalt = envSalt + values.email
+ const response = await fetch("api/user", {
+ method: "POST",
+ body: JSON.stringify({
+ hashMaster: CryptoJS.SHA256(supersalt + values.master).toString(CryptoJS.enc.Hex),
+ email: values.email,
+ }),
+ })
- function samePasswordTest(password: string) {
- if (!formRef.current) {
- return true
+ if (response.ok) {
+ toast({
+ description: "Réussite !",
+ })
+ setIsSignIn(true)
+ } else {
+ toast({
+ variant: "destructive",
+ description: "Echec !",
+ })
}
-
- const formData = new FormData(formRef.current)
- const master = String(formData.get("master"))
-
- return password === master
}
return (
-
-
- setIsPaste(true)}
- />
-
-
- {isValidForm ? "Commencer" : }
-
- <>
- {isValidForm && (
-
- Attention, si vous perdez ce mot de passe. Vous ne pourrez pas le modifier, ni le recuperer, ni acceder à vos eventuels futurs mots de
- passe enregistrés sur Password Guard.
-
- )}
- {isPaste && (
-
- DANGER : Vous avez copié votre mot de passe, soyez certain d&aposêtre capable de le réecrire avant de valider.
-
- )}
- >
-
+
+
+ Création de ton coffre.
+ Créer un compte pour protéger tes mots de passe.
+
+
+
+
+ (
+
+
+
+
+
+
+ )}
+ />
+ (
+
+
+
+
+
+
+ )}
+ />
+ (
+
+
+
+
+
+
+ )}
+ />
+ Créer ton coffre.
+
+
+
+
+ setIsSignIn(true)} className="cursor-pointer">
+ Déjà un coffre ? Clique ici.
+
+
+
)
}
diff --git a/src/components/generate-password-card.tsx b/src/components/generate-password-card.tsx
new file mode 100644
index 0000000..ad1b7d4
--- /dev/null
+++ b/src/components/generate-password-card.tsx
@@ -0,0 +1,33 @@
+"use client"
+import { generatePassword } from "@/lib/password"
+import { useEffect, useState } from "react"
+import { Button } from "./ui/Button"
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./ui/card"
+
+export function GeneratePasswordCard() {
+ const [password, setPassword] = useState("")
+
+ const handleClick = () => {
+ const newPassword = generatePassword()
+ setPassword(newPassword)
+ }
+
+ useEffect(() => {
+ handleClick()
+ }, [])
+
+ return (
+
+
+ Générateur de mot de passe fort.
+
+ Génére automatiquement un mot de passe avec 15 caractères aléatoires dont 1 majuscule, 1 minuscule, 1 chiffre et 1 caractère spécial.
+
+
+ {password}
+ Générer
+
+
+
+ )
+}
diff --git a/src/components/password-details.tsx b/src/components/password-details.tsx
index 47c0bd7..1d934e2 100644
--- a/src/components/password-details.tsx
+++ b/src/components/password-details.tsx
@@ -1,15 +1,15 @@
-import { PassBdd } from "@/components/types/types"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
+import { splitPassword } from "@/lib/password"
+import { PassBdd } from "@/lib/types/types"
import { Dispatch, SetStateAction } from "react"
import { ArrowLeft } from "../../node_modules/lucide-react"
-import { splitPassword } from "./functions/password"
export function PasswordDetail({ password, setIsShowDetail }: { password: PassBdd; setIsShowDetail: Dispatch
> }) {
const splitedPassword = splitPassword(password.password)
const splitedLogin = splitPassword(password.login)
return (
-
+
{password.title}
diff --git a/src/components/password_card.tsx b/src/components/password_card.tsx
index 82cf30c..c9845b6 100644
--- a/src/components/password_card.tsx
+++ b/src/components/password_card.tsx
@@ -1,8 +1,8 @@
"use client"
import CopyToClipboardButton from "@/components/clipBoardButton"
-import { PassBdd } from "@/components/types/types"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { useToast } from "@/components/ui/use-toast"
+import { PassBdd } from "@/lib/types/types"
import { useRouter } from "next/navigation"
import { useState } from "react"
import { Eye, PenBox, Trash2 } from "../../node_modules/lucide-react"
@@ -11,7 +11,7 @@ import { PasswordDetail } from "./password-details"
import { Button } from "./ui/Button"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "./ui/dialog"
-export function PasswordCard({ password, recupPasswords = undefined }: { password: PassBdd; recupPasswords: undefined | (() => void) }) {
+export function PasswordCard({ password }: { password: PassBdd }) {
const [isDeleting, setIsDeleting] = useState(false)
const [isEditing, setIsEditing] = useState(false)
const [isShowDetail, setIsShowDetail] = useState(false)
@@ -34,11 +34,7 @@ export function PasswordCard({ password, recupPasswords = undefined }: { passwor
toast({
description: "Suppression effectuée avec succès.",
})
- if (recupPasswords != undefined) {
- recupPasswords()
- } else {
- router.refresh()
- }
+ router.refresh()
} else {
toast({
variant: "destructive",
@@ -49,7 +45,7 @@ export function PasswordCard({ password, recupPasswords = undefined }: { passwor
}
if (isEditing) {
- return
+ return
}
if (isShowDetail) {
@@ -58,7 +54,7 @@ export function PasswordCard({ password, recupPasswords = undefined }: { passwor
return (
-
+
{password.title}
diff --git a/src/components/passwords-health.tsx b/src/components/passwords-health.tsx
index faada70..c753187 100644
--- a/src/components/passwords-health.tsx
+++ b/src/components/passwords-health.tsx
@@ -1,9 +1,9 @@
"use client"
import { useState } from "react"
import { Radar } from "../../node_modules/lucide-react"
-import { pluralize } from "./functions/format"
-import { isCompomisedPassword } from "./functions/password"
-import { PassBdd } from "./types/types"
+import { pluralize } from "../lib/format"
+import { isCompomisedPassword } from "../lib/password"
+import { PassBdd } from "../lib/types/types"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./ui/card"
import { useToast } from "./ui/use-toast"
diff --git a/src/components/plus-password-card.tsx b/src/components/plus-password-card.tsx
index 8782047..d7ff67f 100644
--- a/src/components/plus-password-card.tsx
+++ b/src/components/plus-password-card.tsx
@@ -5,7 +5,7 @@ import { HoverCard, HoverCardContent, HoverCardTrigger } from "./ui/hover-card"
export function PlusPasswordCard({ setIsShow }: { setIsShow: Dispatch> }) {
return (
-
+
setIsShow(true)} className="cursor-pointer" />
diff --git a/src/components/pwned-password.tsx b/src/components/pwned-password.tsx
index 8359a4e..f0fd696 100644
--- a/src/components/pwned-password.tsx
+++ b/src/components/pwned-password.tsx
@@ -3,8 +3,8 @@ import { simplePasswordSchema } from "@/zod/schema.example"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
-import { isCompomisedPassword } from "./functions/password"
-import { useTimedMessage } from "./hooks/timed-message"
+import { useTimedMessage } from "../lib/hooks/timed-message"
+import { isCompomisedPassword } from "../lib/password"
import { InputEye } from "./shared/input-password-eye"
import { Button } from "./ui/Button"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./ui/card"
@@ -53,7 +53,7 @@ export function PwnedPassword() {
Mot de passe à vérifier
-
+
)}
diff --git a/src/components/shared/input-password-eye.tsx b/src/components/shared/input-password-eye.tsx
index 11250d8..6abcc38 100644
--- a/src/components/shared/input-password-eye.tsx
+++ b/src/components/shared/input-password-eye.tsx
@@ -1,26 +1,18 @@
-import { useState } from "react"
-import { ControllerRenderProps } from "react-hook-form"
+"use client"
+
+import React, { useState } from "react"
import { Eye, EyeOff } from "../../../node_modules/lucide-react"
-import { Input } from "../ui/input"
+import { Input, InputProps } from "../ui/input"
-export function InputEye({
- field,
-}: {
- field: ControllerRenderProps<
- {
- password: string
- },
- "password"
- >
-}) {
+export const InputEye = React.forwardRef(({ className, type, ...props }, ref) => {
const [isShowPassword, setIsShowPassword] = useState(false)
return (
-
- setIsShowPassword(!isShowPassword)}>
+
+ setIsShowPassword(!isShowPassword)}>
{isShowPassword ? : }
)
-}
+})
diff --git a/src/components/shared/input.tsx b/src/components/shared/input.tsx
index f18f5e8..e8a61bd 100644
--- a/src/components/shared/input.tsx
+++ b/src/components/shared/input.tsx
@@ -1,4 +1,4 @@
-import { InputProps } from "@/components/types/types"
+import { InputProps } from "@/lib/types/types"
export function Input({ label, ...props }: InputProps) {
return (
diff --git a/src/components/shared/loader.tsx b/src/components/shared/loader.tsx
index f148858..399cf49 100644
--- a/src/components/shared/loader.tsx
+++ b/src/components/shared/loader.tsx
@@ -1,4 +1,4 @@
-import styles from "@/components/styles/loader.module.css"
+import styles from "@/lib/styles/loader.module.css"
export function Loader() {
return (
diff --git a/src/components/shared/password-input.tsx b/src/components/shared/password-input.tsx
index e06e9ea..b3975b9 100644
--- a/src/components/shared/password-input.tsx
+++ b/src/components/shared/password-input.tsx
@@ -1,8 +1,8 @@
-import styles from "@/components/styles/password-input.module.css"
import { Input } from "@/components/ui/input"
+import styles from "@/styles/password-input.module.css"
+import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/ui/hover-card"
import { ComponentPropsWithoutRef, useState } from "react"
import { Eye, EyeOff } from "../../../node_modules/lucide-react"
-import { HoverCard, HoverCardContent, HoverCardTrigger } from "../ui/hover-card"
type InputProps = ComponentPropsWithoutRef<"input"> & {
label: string
diff --git a/src/components/signin_signup.tsx b/src/components/signin_signup.tsx
new file mode 100644
index 0000000..736e480
--- /dev/null
+++ b/src/components/signin_signup.tsx
@@ -0,0 +1,11 @@
+"use client"
+
+import { useState } from "react"
+import { CheckPasswordForm } from "./forms/check-password-form"
+import { MasterFormCreate } from "./forms/master-form-create"
+
+export function SignInUp() {
+ const [isSignIn, setIsSignIn] = useState(true)
+
+ return <>{isSignIn ? : }>
+}
diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx
index dff04b6..87253bc 100644
--- a/src/components/ui/card.tsx
+++ b/src/components/ui/card.tsx
@@ -2,78 +2,34 @@ import * as React from "react"
import { cn } from "@/lib/utils"
-const Card = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
+const Card = React.forwardRef>(({ className, ...props }, ref) => (
+
))
Card.displayName = "Card"
-const CardHeader = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
+const CardHeader = React.forwardRef>(({ className, ...props }, ref) => (
+
))
CardHeader.displayName = "CardHeader"
-const CardTitle = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
+const CardTitle = React.forwardRef>(({ className, ...props }, ref) => (
+
))
CardTitle.displayName = "CardTitle"
-const CardDescription = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
+const CardDescription = React.forwardRef>(({ className, ...props }, ref) => (
+
))
CardDescription.displayName = "CardDescription"
-const CardContent = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
+const CardContent = React.forwardRef>(({ className, ...props }, ref) => (
))
CardContent.displayName = "CardContent"
-const CardFooter = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
+const CardFooter = React.forwardRef>(({ className, ...props }, ref) => (
+
))
CardFooter.displayName = "CardFooter"
-export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
+export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }
diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx
index 6e4a231..fcec56a 100644
--- a/src/components/ui/input.tsx
+++ b/src/components/ui/input.tsx
@@ -9,7 +9,7 @@ const Input = React.forwardRef(({ className, type,
{ email: string | null; privateKey?: string | null } = () => {
+ const cookieStore = cookies()
+ const accessToken = cookieStore.get("accessToken")
+
+ let email = null
+ let privateKey = null
+
+ if (!accessToken) {
+ return { email, privateKey }
+ }
+
+ const payload = verifyAccessToken(accessToken.value)
+ if (!payload) {
+ return { email, privateKey }
+ }
+
+ const { sub, private_key } = payload
+ email = sub
+ privateKey = private_key
+
+ return { email, privateKey }
+}
diff --git a/src/components/hooks/timed-message.ts b/src/lib/hooks/timed-message.ts
similarity index 100%
rename from src/components/hooks/timed-message.ts
rename to src/lib/hooks/timed-message.ts
diff --git a/src/components/functions/password.ts b/src/lib/password.ts
similarity index 100%
rename from src/components/functions/password.ts
rename to src/lib/password.ts
diff --git a/src/services/GuardedPassword.service.ts b/src/lib/services/GuardedPassword.service.ts
similarity index 100%
rename from src/services/GuardedPassword.service.ts
rename to src/lib/services/GuardedPassword.service.ts
diff --git a/src/lib/services/auth.service.ts b/src/lib/services/auth.service.ts
new file mode 100644
index 0000000..b5d6b1f
--- /dev/null
+++ b/src/lib/services/auth.service.ts
@@ -0,0 +1,56 @@
+import jwt, { JwtPayload } from "jsonwebtoken"
+
+const JWT_SECRET = process.env.JWT_SECRET
+const JWT_REFRESH_SECRET = process.env.JWT_REFRESH_SECRET
+
+if (!JWT_SECRET) {
+ throw new Error("JWT_SECRET is not defined in the envronement.")
+}
+
+if (!JWT_REFRESH_SECRET) {
+ throw new Error("JWT_REFRESH_SECRET is not defined in the envronement.")
+}
+
+interface AccessTokenPayload extends JwtPayload {
+ sub: string
+ type: "access" | "refresh"
+ private_key: string
+}
+
+export const generateAccessToken = (userEmail: string, privateKey: string) => {
+ const payload: AccessTokenPayload = {
+ sub: userEmail,
+ type: "access",
+ private_key: privateKey,
+ }
+
+ return jwt.sign(payload, JWT_SECRET, { expiresIn: "1h" })
+}
+
+export const generateRefreshToken = (userEmail: string, privateKey: string): string => {
+ const payload: AccessTokenPayload = {
+ sub: userEmail,
+ type: "refresh",
+ private_key: privateKey,
+ }
+
+ return jwt.sign(payload, JWT_REFRESH_SECRET, { expiresIn: "1h" })
+}
+
+export const verifyAccessToken = (token: string): AccessTokenPayload | null => {
+ try {
+ const payload = jwt.verify(token, JWT_SECRET) as AccessTokenPayload
+ return payload
+ } catch (err) {
+ return null
+ }
+}
+
+export const verifyRefreshToken = (token: string): AccessTokenPayload | null => {
+ try {
+ const payload = jwt.verify(token, JWT_REFRESH_SECRET) as AccessTokenPayload
+ return payload
+ } catch (err) {
+ return null
+ }
+}
diff --git a/src/services/security.service.ts b/src/lib/services/security.service.ts
similarity index 97%
rename from src/services/security.service.ts
rename to src/lib/services/security.service.ts
index e1d0596..55a27f4 100644
--- a/src/services/security.service.ts
+++ b/src/lib/services/security.service.ts
@@ -1,4 +1,4 @@
-import { encryptData } from "@/components/types/types"
+import { encryptData } from "@/lib/types/types"
import crypto from "crypto"
// Générer une paire de clés RSA (privée et publique)
diff --git a/src/services/userApp.service.ts b/src/lib/services/userApp.service.ts
similarity index 100%
rename from src/services/userApp.service.ts
rename to src/lib/services/userApp.service.ts
diff --git a/src/components/styles/loader.module.css b/src/lib/styles/loader.module.css
similarity index 100%
rename from src/components/styles/loader.module.css
rename to src/lib/styles/loader.module.css
diff --git a/src/components/styles/password-input.module.css b/src/lib/styles/password-input.module.css
similarity index 100%
rename from src/components/styles/password-input.module.css
rename to src/lib/styles/password-input.module.css
diff --git a/src/components/types/types.ts b/src/lib/types/types.ts
similarity index 100%
rename from src/components/types/types.ts
rename to src/lib/types/types.ts
diff --git a/src/components/functions/validators.ts b/src/lib/validators.ts
similarity index 100%
rename from src/components/functions/validators.ts
rename to src/lib/validators.ts
diff --git a/src/middleware.ts b/src/middleware.ts
deleted file mode 100644
index 62e74ba..0000000
--- a/src/middleware.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { authMiddleware } from "@clerk/nextjs"
-
-export default authMiddleware({
- publicRoutes: ["/", "/sandbox", "/api/get-public-key", "/api/passwords", "/api/passwords/:id*"],
-})
-
-export const config = {
- matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
-}
diff --git a/src/services/auth.service.ts b/src/services/auth.service.ts
deleted file mode 100644
index dd7c694..0000000
--- a/src/services/auth.service.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import jwt from 'jsonwebtoken'
-
-if (!process.env.JWT_SECRET) {
- throw new Error('JWT_SECRET is not defined in the envronement.')
-}
-
-if (!process.env.JWT_REFRESH_SECRET) {
- throw new Error('JWT_REFRESH_SECRET is not defined in the envronement.')
-}
-
-const JWT_SECRET = process.env.JWT_SECRET
-const JWT_REFRESH_SECRET = process.env.JWT_REFRESH_SECRET
-
-export const generateAccessToken = (userEmail: string) => {
- const payload = {
- sub: userEmail,
- type: 'access',
- }
-
- return jwt.sign(payload, JWT_SECRET, { expiresIn: '1h' })
-}
-
-export const generateRefreshToken = (userEmail: string) => {
- const payload = {
- sub: userEmail,
- type: 'refresh',
- }
-
- return jwt.sign(payload, JWT_REFRESH_SECRET, { expiresIn: '1h' })
-}
-
-export const verifyAccessToken = (token: string) => {
- return jwt.verify(token, JWT_SECRET)
-}
-
-export const verifyRefreshToken = (token: string) => {
- return jwt.verify(token, JWT_REFRESH_SECRET)
-}
diff --git a/src/zod/schema.example.ts b/src/zod/schema.example.ts
index 7061daf..1b51a70 100644
--- a/src/zod/schema.example.ts
+++ b/src/zod/schema.example.ts
@@ -18,3 +18,23 @@ export const addPasswordSchema = z.object({
export const simplePasswordSchema = z.object({
password: z.string(),
})
+
+export const newMasterPasswordSchema = z
+ .object({
+ email: z.string().email({ message: "L'email n'est pas valide" }),
+ master: z.string().regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{15,}$/, {
+ message: "Le mot de passe doit contenir au moins 15 caractères, une majuscule, une minuscule, un chiffre et un caractère spécial",
+ }),
+ confirm: z.string(),
+ })
+ .refine((data) => data.master === data.confirm, {
+ message: "Les mots de passe ne correspondent pas",
+ path: ["confirm"],
+ })
+
+export const checkMasterPasswordSchema = z.object({
+ email: z.string().email({ message: "L'email n'est pas valide" }),
+ master: z.string().regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{15,}$/, {
+ message: "Le mot de passe doit contenir au moins 15 caractères, une majuscule, une minuscule, un chiffre et un caractère spécial",
+ }),
+})