ChandimaPrabath commited on
Commit
2ea6bf5
·
1 Parent(s): 92f01f5

username validation

Browse files
frontend/app/layout.js CHANGED
@@ -6,7 +6,7 @@ import { ToastContainer, Flip } from 'react-toastify';
6
  import { CheckCircleIcon, InformationCircleIcon, ExclamationCircleIcon } from '@heroicons/react/20/solid';
7
  import Sidebar from "@components/Sidebar";
8
 
9
- import { ToastProvider } from "@/lib/ToastContext"; // Update with your file path
10
 
11
  export default function RootLayout({ children }) {
12
  const contentStyle = {
 
6
  import { CheckCircleIcon, InformationCircleIcon, ExclamationCircleIcon } from '@heroicons/react/20/solid';
7
  import Sidebar from "@components/Sidebar";
8
 
9
+ import { ToastProvider } from "@lib/ToastContext";
10
 
11
  export default function RootLayout({ children }) {
12
  const contentStyle = {
frontend/app/page.js CHANGED
@@ -1,6 +1,7 @@
1
  'use client';
2
 
3
  import { useState, useEffect } from "react";
 
4
  import NexusAuthApi from "@lib/Nexus_Auth_API";
5
 
6
  export default function Home() {
@@ -8,6 +9,7 @@ export default function Home() {
8
  const [userID, setUserID] = useState(null);
9
  const [token, setToken] = useState(null);
10
  const [accessLevel, setAccessLevel] = useState(null);
 
11
 
12
  useEffect(() => {
13
  setUsername(localStorage.getItem('me'));
@@ -28,6 +30,7 @@ export default function Home() {
28
  NexusAuthApi.logout(userID, token)
29
  .then(() => {
30
  clearLocalStorage();
 
31
  window.location.reload();
32
  })
33
  .catch((error) => {
 
1
  'use client';
2
 
3
  import { useState, useEffect } from "react";
4
+ import { useRouter } from "next/router";
5
  import NexusAuthApi from "@lib/Nexus_Auth_API";
6
 
7
  export default function Home() {
 
9
  const [userID, setUserID] = useState(null);
10
  const [token, setToken] = useState(null);
11
  const [accessLevel, setAccessLevel] = useState(null);
12
+ const router = useRouter();
13
 
14
  useEffect(() => {
15
  setUsername(localStorage.getItem('me'));
 
30
  NexusAuthApi.logout(userID, token)
31
  .then(() => {
32
  clearLocalStorage();
33
+ router.push('/');
34
  window.location.reload();
35
  })
36
  .catch((error) => {
frontend/components/NexusAuth.js CHANGED
@@ -12,10 +12,14 @@ const SignupForm = ({ onSignup }) => {
12
  const [confirmPassword, setConfirmPassword] = useState('');
13
  const [email, setEmail] = useState('');
14
  const [usernameAvailable, setUsernameAvailable] = useState(null); // null for initial state
 
 
15
  const [passwordValid, setPasswordValid] = useState(false); // Initially invalid
16
  const [formValid, setFormValid] = useState(false);
17
  const [debounceTimeout, setDebounceTimeout] = useState(null); // Store timeout ID
18
 
 
 
19
  const validatePassword = (password) => {
20
  return password.length >= 8;
21
  };
@@ -32,11 +36,29 @@ const SignupForm = ({ onSignup }) => {
32
  clearTimeout(debounceTimeout);
33
  }
34
 
35
- if (newUsername.trim().length > 0) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  // Set a new timeout to check availability
37
  const newTimeout = setTimeout(async () => {
38
  try {
39
- const response = await NexusAuthApi.isUsernameAvailable(newUsername);
40
  setUsernameAvailable(response?.is_available === true);
41
  } catch (error) {
42
  console.error('Error checking username availability:', error);
@@ -48,6 +70,9 @@ const SignupForm = ({ onSignup }) => {
48
  } else {
49
  setUsernameAvailable(null); // Reset availability check when input is empty
50
  }
 
 
 
51
  };
52
 
53
  const handlePasswordChange = (e) => {
@@ -76,7 +101,8 @@ const SignupForm = ({ onSignup }) => {
76
  usernameAvailable === true &&
77
  password === confirmPassword &&
78
  passwordValid &&
79
- username.length > 0
 
80
  );
81
  }, [username, password, confirmPassword, usernameAvailable, passwordValid]);
82
 
@@ -94,6 +120,12 @@ const SignupForm = ({ onSignup }) => {
94
  {usernameAvailable === true && username.length > 0 && (
95
  <CheckCircleIcon className="h-5 w-5 text-green-500" />
96
  )}
 
 
 
 
 
 
97
  {usernameAvailable === false && (
98
  <p className="error-message text-red-500">Username is already taken</p>
99
  )}
 
12
  const [confirmPassword, setConfirmPassword] = useState('');
13
  const [email, setEmail] = useState('');
14
  const [usernameAvailable, setUsernameAvailable] = useState(null); // null for initial state
15
+ const [doesUsernameContainInvalidChars, setDoesUsernameContainInvalidChars] = useState(false);
16
+ const [doesUsernameExceedMinLength, setDoesUsernameExceedMinLength] = useState(false);
17
  const [passwordValid, setPasswordValid] = useState(false); // Initially invalid
18
  const [formValid, setFormValid] = useState(false);
19
  const [debounceTimeout, setDebounceTimeout] = useState(null); // Store timeout ID
20
 
21
+ const minUsernameLength = 3;
22
+
23
  const validatePassword = (password) => {
24
  return password.length >= 8;
25
  };
 
36
  clearTimeout(debounceTimeout);
37
  }
38
 
39
+ // Check for invalid characters
40
+ const invalidChars = /[^a-zA-Z0-9_]/g;
41
+ if (invalidChars.test(newUsername)) {
42
+ setDoesUsernameContainInvalidChars(true);
43
+ setTimeout(() => {
44
+ setDoesUsernameContainInvalidChars(false);
45
+ }, 2000); // Show error for 2 seconds
46
+ }
47
+
48
+ // Basic sanitization to prevent SQL injection
49
+ const sanitizedUsername = newUsername.replace(invalidChars, '');
50
+
51
+ if (sanitizedUsername.length < minUsernameLength) {
52
+ setDoesUsernameExceedMinLength(false);
53
+ return;
54
+ } else {
55
+ setDoesUsernameExceedMinLength(true);}
56
+
57
+ if (sanitizedUsername.trim().length > 0) {
58
  // Set a new timeout to check availability
59
  const newTimeout = setTimeout(async () => {
60
  try {
61
+ const response = await NexusAuthApi.isUsernameAvailable(sanitizedUsername);
62
  setUsernameAvailable(response?.is_available === true);
63
  } catch (error) {
64
  console.error('Error checking username availability:', error);
 
70
  } else {
71
  setUsernameAvailable(null); // Reset availability check when input is empty
72
  }
73
+
74
+ // Set sanitized username
75
+ setUsername(sanitizedUsername);
76
  };
77
 
78
  const handlePasswordChange = (e) => {
 
101
  usernameAvailable === true &&
102
  password === confirmPassword &&
103
  passwordValid &&
104
+ username.length >= minUsernameLength &&
105
+ !doesUsernameContainInvalidChars
106
  );
107
  }, [username, password, confirmPassword, usernameAvailable, passwordValid]);
108
 
 
120
  {usernameAvailable === true && username.length > 0 && (
121
  <CheckCircleIcon className="h-5 w-5 text-green-500" />
122
  )}
123
+ {doesUsernameExceedMinLength === false && (
124
+ <p className="error-message text-red-500">Username must have more than {minUsernameLength} characters.</p>
125
+ )}
126
+ {doesUsernameContainInvalidChars === true && (
127
+ <p className="error-message text-red-500">Username cannot contain invalid characters.</p>
128
+ )}
129
  {usernameAvailable === false && (
130
  <p className="error-message text-red-500">Username is already taken</p>
131
  )}