diff --git a/service/migrations/000011_create_users/up.sql b/service/migrations/000011_create_users/up.sql index 6fe1727..4235954 100644 --- a/service/migrations/000011_create_users/up.sql +++ b/service/migrations/000011_create_users/up.sql @@ -3,5 +3,6 @@ CREATE TABLE IF NOT EXISTS users ( hash TEXT NOT NULL, role TEXT NOT NULL, first_name TEXT NOT NULL, - last_name TEXT NOT NULL + last_name TEXT NOT NULL, + verified BOOLEAN NOT NULL DEFAULT FALSE, ); \ No newline at end of file diff --git a/ui/src/components/Topbar/index.tsx b/ui/src/components/Topbar/index.tsx index 9e90bb7..c7f14ab 100644 --- a/ui/src/components/Topbar/index.tsx +++ b/ui/src/components/Topbar/index.tsx @@ -26,6 +26,7 @@ import { useForm } from '@mantine/form'; import { login, register, logout, me, refresh } from '@/api/auth'; import { User } from '@/api/auth.types'; import { useToggle } from '@mantine/hooks'; +import { notifications } from '@mantine/notifications'; interface HeaderItem { name: string; @@ -187,6 +188,41 @@ interface LoginModalProps { } function LoginModal({ type, toggle, setUser }: LoginModalProps) { + function passwordValidator(value: string) { + if (value.trim().length < 10) { + return 'Password must be at least 10 characters'; + } + if (value.trim().length >= 128) { + return 'Password must be at most 128 characters'; + } + if (!/(\d)/.test(value)) { + return 'Password must contain at least one number'; + } + if (!/[a-z]/.test(value)) { + return 'Password must contain at least one lowercase letter'; + } + if (!/[A-Z]/.test(value)) { + return 'Password must contain at least one uppercase letter'; + } + if (!/[!@#$%^&*]/.test(value)) { + return 'Password must contain at least one special character'; + } + if (/(.)\1\1/.test(value)) { + return 'Password must not contain more than 2 repeating characters'; + } + return null; + } + + function emailValidator(value: string) { + if (value.trim().length == 0) { + return 'Email is required'; + } + if (!/^\S+@\S+$/.test(value)) { + return 'Invalid email'; + } + return null; + } + const form = useForm({ initialValues: { firstName: '', @@ -194,6 +230,12 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) { email: '', password: '', remember: false + }, + validate: { + firstName: (value) => (value.trim().length > 0 ? null : 'First name is required'), + lastName: (value) => (value.trim().length > 0 ? null : 'Last name is required'), + email: emailValidator, + password: passwordValidator } }); @@ -210,18 +252,13 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) { Reset password - Enter your email and we will send you a link to reset your password + Enter your email and we will send you a link to reset your password.{' '} + toggle('login')}> + Go Back + -
{ - const response = await login(values.email, values.password); - if (response) { - setUser(response.user); - onClose(); - } - })} - > + console.log(values))}>