diff --git a/app/accountSetting.tsx b/app/accountSetting.tsx index e5af9a4..dc29b8f 100644 --- a/app/accountSetting.tsx +++ b/app/accountSetting.tsx @@ -1,9 +1,10 @@ -import React, { useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet } from 'react-native'; -// import { cLog } from './log'; -import { IPAddr } from './constants'; -import axios from 'axios'; +// import { IPAddr } from './constants'; +// import axios from 'axios'; import { cLog } from './log'; +import { useFocusEffect } from '@react-navigation/native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; // import { useFocusEffect } from '@react-navigation/native'; // import GenericViewPageForm from './viewEventPage'; @@ -14,18 +15,13 @@ export default function AccountSetting () { const handleSave = async () => { try { - // Add current date to formData - const currentDate = new Date().toISOString().split('T')[0]; // Get current date in ISO format (e.g., 2024-06-14T10:00:00.000Z) - const currentTime = new Date().toTimeString().split(' ')[0]; - const updatedFormData = { - ...formData, - event_date: currentDate, // Add date field - event_time: currentTime, // Add time field - }; - const hit = IPAddr + '/add_note'; // Backend endpoint - const response = await axios.put(hit, updatedFormData); // Send request with updated data - - cLog('Note saved successfully: ' + response.data); + cLog(formData); + await AsyncStorage.setItem('name', formData.name); + await AsyncStorage.setItem('userName', formData.userName); + await AsyncStorage.setItem('email', formData.email); + // const hit = IPAddr + '/modify_user'; // Backend endpoint + // const response = await axios.put(hit, formData); // Send request with updated data + // cLog('Note saved successfully: ' + response.data); } catch (error) { console.error('Error saving note:', error); } @@ -35,13 +31,40 @@ export default function AccountSetting () { setFormData({ ...formData, [name]: value }); }; + // Fetch local data from AsyncStorage + const getLocalValues = async () => { + try { + const userId = await AsyncStorage.getItem('userId'); + const name = await AsyncStorage.getItem('name'); + const userName = await AsyncStorage.getItem('userName'); + const email = await AsyncStorage.getItem('email'); + + // Update state with retrieved values + setFormData({ + userId: userId ? parseInt(userId, 10) : 1, // Default to 1 if not found + name: name || '', + userName: userName || '', + email: email || '', + }); + } catch (error) { + console.error("Error fetching local values from AsyncStorage:", error); + } + }; + + + useFocusEffect( + useCallback(() => { + getLocalValues(); + }, []) + ); + return ( Name handleChange("text", text)} // Handle text changes + onChangeText={(text) => handleChange("name", text)} // Handle text changes style={styles.textInput} placeholder="name" multiline={true} @@ -49,7 +72,7 @@ export default function AccountSetting () { Username handleChange("text", text)} // Handle text changes + onChangeText={(text) => handleChange("userName", text)} // Handle text changes style={styles.textInput} placeholder="username" multiline={true} @@ -57,7 +80,7 @@ export default function AccountSetting () { Email handleChange("text", text)} // Handle text changes + onChangeText={(text) => handleChange("email", text)} // Handle text changes style={styles.textInput} placeholder="email" multiline={true} diff --git a/app/home.tsx b/app/home.tsx index 1f61d83..3e5e7b3 100644 --- a/app/home.tsx +++ b/app/home.tsx @@ -59,7 +59,7 @@ export default function TaskScreen() { return ( { @Query("SELECT u FROM User u WHERE u.userName = :userName") List findByUserName(String userName); + + User save(User user); } diff --git a/backend/omniplanner/src/main/java/com/main/omniplanner/user/UserService.java b/backend/omniplanner/src/main/java/com/main/omniplanner/user/UserService.java index 43afb59..1008d1b 100644 --- a/backend/omniplanner/src/main/java/com/main/omniplanner/user/UserService.java +++ b/backend/omniplanner/src/main/java/com/main/omniplanner/user/UserService.java @@ -12,9 +12,13 @@ public class UserService { @Autowired private UserRepository userRepository; + @Autowired + private PasswordService passwordService; + // Constructor injection - public UserService(UserRepository userRepository) { + public UserService(UserRepository userRepository, PasswordService passwordService){ this.userRepository = userRepository; + this.passwordService = passwordService; } public List getAllUsers() { @@ -23,13 +27,16 @@ public List getAllUsers() { public String login(String username, String password) { List users = userRepository.findByUserName(username); + if (users.isEmpty()) { System.out.println("No users found with username: " + username); - return null; + User newUser = new User(); + newUser.setUserName(username); + return registerUser(newUser, password)+"," + username + "," + null + "," + null; } for (User user : users) { - if (user.getPassword().equals(password)) { + if (passwordService.verifyPassword(password, user.getSalt(), user.getPasswordHash())) { return user.getId() + "," + user.getUserName() + "," + user.getEmail() + "," + user.getName(); } } @@ -37,5 +44,14 @@ public String login(String username, String password) { System.out.println("No matching password for username: " + username); return null; } + + public Integer registerUser(User user, String password) { + String salt = passwordService.generateSalt(); + String hashedPassword = passwordService.hashPassword(password, salt); + user.setSalt(salt); + user.setPasswordHash(hashedPassword);// Ensure the ID is null for new users + userRepository.save(user); + return user.getId(); + } } diff --git a/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/PasswordServiceTest.java b/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/PasswordServiceTest.java new file mode 100644 index 0000000..b260119 --- /dev/null +++ b/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/PasswordServiceTest.java @@ -0,0 +1,72 @@ +package com.main.omniplanner.UserTests; + +import com.main.omniplanner.user.PasswordService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +public class PasswordServiceTest { + + @Mock + private BCryptPasswordEncoder passwordEncoder; + + private PasswordService passwordService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + passwordService = new PasswordService(passwordEncoder); + } + + @Test + public void testGenerateSaltLength() { + String salt = passwordService.generateSalt(); + assertEquals(24, salt.length()); + } + + @Test + public void testGenerateSaltUnique() { + String salt1 = passwordService.generateSalt(); + String salt2 = passwordService.generateSalt(); + assertNotEquals(salt1, salt2); + } + + @Test + public void hashPasswordLength() { + String password = "mySecurePassword"; + String salt = "randomSalt"; + + String hashedPassword = "hashedPasswordExample"; + when(passwordEncoder.encode(password + salt)).thenReturn(hashedPassword); + + assertEquals(hashedPassword, passwordService.hashPassword(password, salt)); + } + + @Test + public void hashPasswordNotSame() { + String password = "mySecurePassword"; + String salt = "randomSalt"; + + when(passwordEncoder.encode(password + salt)).thenReturn("hashedPassword1", "hashedPassword2"); + + assertNotEquals(passwordService.hashPassword(password, salt), passwordService.hashPassword(password, salt)); + } + + @Test + public void verifyPassword() { + String password = "mySecurePassword"; + String salt = "randomSalt"; + String hashedPassword = "hashedPassword"; + + when(passwordEncoder.matches(password + salt, hashedPassword)).thenReturn(true); + + assertTrue(passwordService.verifyPassword(password, salt, hashedPassword)); + + verify(passwordEncoder).matches(password + salt, hashedPassword); + } +} diff --git a/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/UserServiceTest.java b/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/UserServiceTest.java index ea21007..5372951 100644 --- a/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/UserServiceTest.java +++ b/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/UserServiceTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; +import com.main.omniplanner.user.PasswordService; import com.main.omniplanner.user.User; import com.main.omniplanner.user.UserRepository; import com.main.omniplanner.user.UserService; @@ -22,19 +23,23 @@ public class UserServiceTest { @Mock private UserRepository userRepository; + @Mock + private PasswordService passwordService; + private User user; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); - userService = new UserService(userRepository); + userService = new UserService(userRepository, passwordService); user = new User(); user.setId(0); user.setName("John Doe"); user.setEmail("johndoe@example.com"); user.setGoogle_calendar_linked(true); user.setGoogle_calendar_access_token("access_token_123"); - user.setPassword("password123"); + user.setPasswordHash("passwordhash123"); + user.setSalt("salt123"); } @Test @@ -55,7 +60,7 @@ public void testGetSaveEvent() { @Test public void testLoginSuccess() { when(userRepository.findByUserName("johndoe")).thenReturn(Arrays.asList(user)); - + when(passwordService.verifyPassword("password123", user.getSalt(), user.getPasswordHash())).thenReturn(true); String result = userService.login("johndoe", "password123"); assertNotNull(result); @@ -65,6 +70,7 @@ public void testLoginSuccess() { @Test public void testLoginFailure() { when(userRepository.findByUserName("johndoe")).thenReturn(Arrays.asList(user)); + when(passwordService.verifyPassword("wrongpassword", user.getSalt(), user.getPasswordHash())).thenReturn(false); String result = userService.login("johndoe", "wrongpassword"); @@ -77,6 +83,6 @@ public void testUserNotFound() { String result = userService.login("nonexistent", "password123"); - assertNull(result); + assertEquals(result, "0,nonexistent,null,null"); } } diff --git a/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/UserTest.java b/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/UserTest.java index f615885..8758ae4 100644 --- a/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/UserTest.java +++ b/backend/omniplanner/src/test/java/com/main/omniplanner/UserTests/UserTest.java @@ -54,8 +54,8 @@ public void testGetSetUserName() { user.setUserName("johndoe"); assertEquals("johndoe", user.getUserName()); } - @Test public void testGetSetPassword() { - user.setPassword("password123"); - assertEquals("password123", user.getPassword()); + @Test public void testGetSetPasswordHash() { + user.setPasswordHash("password123"); + assertEquals("password123", user.getPasswordHash()); } }