Skip to content
Snippets Groups Projects
Commit 2b22a8dc authored by abdu's avatar abdu
Browse files

add comments, minor adjustments

parent d6647ce1
No related branches found
No related tags found
No related merge requests found
Showing
with 49 additions and 2 deletions
...@@ -29,7 +29,7 @@ export default { ...@@ -29,7 +29,7 @@ export default {
<!-- Bottom-left description --> <!-- Bottom-left description -->
<div class="list-item-description mb-0"> <div class="list-item-description mb-0">
{{ description.length > 50 ? description.slice(0, 30) + '...' : description }} {{ description.length > 50 ? description.slice(0, 50) + '...' : description }}
</div> </div>
</div> </div>
</template> </template>
......
...@@ -17,12 +17,15 @@ export default { ...@@ -17,12 +17,15 @@ export default {
} }
}, },
computed: { computed: {
// checks if sign up input fields are empty
checkEmptyFieldsSignup(){ checkEmptyFieldsSignup(){
return this.user.userName === '' || this.user.password === '' || this.repeatedPassword === '' || this.user.password !== this.repeatedPassword; return this.user.userName === '' || this.user.password === '' || this.repeatedPassword === '' || this.user.password !== this.repeatedPassword;
}, },
// checks if login input fields are empty
checkEmptyFieldsSignin(){ checkEmptyFieldsSignin(){
return this.user.userName === '' || this.user.password === '' return this.user.userName === '' || this.user.password === ''
}, },
// checks if passwords have the same length at sign up
checkPasswordSame(){ checkPasswordSame(){
let pw = this.user.password let pw = this.user.password
let pw_repeated = this.repeatedPassword let pw_repeated = this.repeatedPassword
...@@ -51,6 +54,7 @@ export default { ...@@ -51,6 +54,7 @@ export default {
}) })
}); });
// showing a toast message depending on the response code
if(response.status === 201){ if(response.status === 201){
this.$bvToast.show('account-created-toast') this.$bvToast.show('account-created-toast')
} else if(response.status === 409){ } else if(response.status === 409){
...@@ -74,11 +78,12 @@ export default { ...@@ -74,11 +78,12 @@ export default {
let responseData = '' let responseData = ''
//muss hier rein, bei status 401 wird nämlich kein json zurückgesendet und response.json() ist sonst nicht möglich // muss hier rein, bei status 401 wird nämlich kein json zurückgesendet und response.json() ist sonst nicht möglich
if(response.status === 200) { if(response.status === 200) {
responseData = await response.json(); responseData = await response.json();
} }
// if login was successful, neccessary attributes are set in frontends/browsers webstorage and toast is displayed
if(response.status === 200){ if(response.status === 200){
localStorage.setItem('userId', responseData.userId) localStorage.setItem('userId', responseData.userId)
localStorage.setItem('isLoggedIn', 'true') localStorage.setItem('isLoggedIn', 'true')
...@@ -139,6 +144,9 @@ export default { ...@@ -139,6 +144,9 @@ export default {
<b-toast invalid-user-password auto-hide-delay="10000" variant="danger" id="invalid-user-password" title="error"> <b-toast invalid-user-password auto-hide-delay="10000" variant="danger" id="invalid-user-password" title="error">
username or password invalid username or password invalid
</b-toast> </b-toast>
<b-toast auto-hide-delay="2000" variant="success" id="todo-set-complete" title="todo completed">
</b-toast>
</b-container> </b-container>
</template> </template>
......
...@@ -4,16 +4,22 @@ import CustomListElement from "@/components/CustomListElement.vue"; ...@@ -4,16 +4,22 @@ import CustomListElement from "@/components/CustomListElement.vue";
export default { export default {
name: "MainPage", name: "MainPage",
components: {CustomListElement}, components: {CustomListElement},
// this method will be called once the dom has been rendered
// we use this to check for login status when the mainpage is opened
created(){ created(){
// redirect user to login page when hes not logged in
if(localStorage.getItem('isLoggedIn') === false || localStorage.getItem('userId') === null){ if(localStorage.getItem('isLoggedIn') === false || localStorage.getItem('userId') === null){
this.$router.push({ name: 'login' }) this.$router.push({ name: 'login' })
} }
// setting userId for further use and fetching all todos
this.userId = localStorage.getItem('userId') this.userId = localStorage.getItem('userId')
this.getAllTodos() this.getAllTodos()
// validating session every 60 seconds
setInterval(this.validateSession, 60000) setInterval(this.validateSession, 60000)
}, },
// all the variables we will be using in our view
data() { data() {
return { return {
items: [], items: [],
...@@ -37,10 +43,13 @@ export default { ...@@ -37,10 +43,13 @@ export default {
todoIdForDeleteModal: '' todoIdForDeleteModal: ''
} }
}, },
// our methods (obviously)
methods: { methods: {
// sets the id of the todoObject to be displayed in the delete modal
setToDoIdForDeleteModal(todoId){ setToDoIdForDeleteModal(todoId){
this.todoIdForDeleteModal = todoId this.todoIdForDeleteModal = todoId
}, },
// sends fetch-request to check for session validity
async validateSession(){ async validateSession(){
if(this.$route.name === 'main') { if(this.$route.name === 'main') {
let url = "http://localhost:9876/user/validateSession" let url = "http://localhost:9876/user/validateSession"
...@@ -50,6 +59,7 @@ export default { ...@@ -50,6 +59,7 @@ export default {
credentials: 'include' credentials: 'include'
}) })
// if session is invalid, user will be logged out
if (response.status === 401) { if (response.status === 401) {
localStorage.removeItem("userId") localStorage.removeItem("userId")
localStorage.removeItem("isLoggedIn") localStorage.removeItem("isLoggedIn")
...@@ -57,10 +67,12 @@ export default { ...@@ -57,10 +67,12 @@ export default {
} }
} }
}, },
// shows dtails of the given item
showDetails(item) { showDetails(item) {
this.selectedItem = item; this.selectedItem = item;
this.showDetailsModal = true; this.showDetailsModal = true;
}, },
// fetches all todos for the current user
async getAllTodos(){ async getAllTodos(){
let url = `http://localhost:9876/user/getAllTodos?userId=${localStorage.getItem('userId')}` let url = `http://localhost:9876/user/getAllTodos?userId=${localStorage.getItem('userId')}`
...@@ -69,12 +81,14 @@ export default { ...@@ -69,12 +81,14 @@ export default {
credentials: 'include', credentials: 'include',
}) })
// fills list with the todos if request was successful
if(response.status === 200) { if(response.status === 200) {
const items = await response.json() const items = await response.json()
this.items = items.filter(item => item.completed === false) this.items = items.filter(item => item.completed === false)
this.completedItems = items.filter(item => item.completed === true) this.completedItems = items.filter(item => item.completed === true)
} }
}, },
// creates a todoJsonObject and sends it to backend for persistence
async addTodo(){ async addTodo(){
let url = "http://localhost:9876/user/addTodo" let url = "http://localhost:9876/user/addTodo"
...@@ -92,12 +106,14 @@ export default { ...@@ -92,12 +106,14 @@ export default {
}) })
}); });
// iff request was successful backend resends complete list of todos so frontend can refill the list
if(response.status === 201) { if(response.status === 201) {
const items = await response.json() const items = await response.json()
this.items = items.filter(item => item.completed === false) this.items = items.filter(item => item.completed === false)
this.completedItems = items.filter(item => item.completed === true) this.completedItems = items.filter(item => item.completed === true)
} }
}, },
// deletes given todo
async deleteTodo(todoId){ async deleteTodo(todoId){
let url = `http://localhost:9876/user/deleteTodo?userId=${localStorage.getItem('userId')}&todoId=${todoId}` let url = `http://localhost:9876/user/deleteTodo?userId=${localStorage.getItem('userId')}&todoId=${todoId}`
...@@ -109,10 +125,12 @@ export default { ...@@ -109,10 +125,12 @@ export default {
credentials: 'include', credentials: 'include',
}) })
// if deleted successfully, we fetch all todos again
if(response.status === 204) { if(response.status === 204) {
await this.getAllTodos() await this.getAllTodos()
} }
}, },
// sets the given todo as complete
async setTodoComplete(todoId){ async setTodoComplete(todoId){
let url = `http://localhost:9876/user/setTodoComplete?userId=${localStorage.getItem('userId')}&todoId=${todoId}` let url = `http://localhost:9876/user/setTodoComplete?userId=${localStorage.getItem('userId')}&todoId=${todoId}`
...@@ -128,6 +146,7 @@ export default { ...@@ -128,6 +146,7 @@ export default {
await this.getAllTodos() await this.getAllTodos()
} }
}, },
// logs out the current user and resets attributes in storage
async signout(){ async signout(){
let url = "http://localhost:9876/user/signout" let url = "http://localhost:9876/user/signout"
......
...@@ -5,11 +5,13 @@ import MainPage from '../components/MainPage.vue'; ...@@ -5,11 +5,13 @@ import MainPage from '../components/MainPage.vue';
Vue.use(Router); Vue.use(Router);
// the routes we use in our app
const routes = [ const routes = [
{ path: '/', name: 'login', component: LoginPage }, { path: '/', name: 'login', component: LoginPage },
{ path: '/main', name: 'main', component: MainPage }, { path: '/main', name: 'main', component: MainPage },
] ]
// using history mode instead of hash mode (/#/ in url looks ugly af)
const router = new Router({ const router = new Router({
mode: 'history', mode: 'history',
routes, routes,
......
...@@ -5,6 +5,8 @@ import lombok.Setter; ...@@ -5,6 +5,8 @@ import lombok.Setter;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
// todoEntity, used for object relational mapping with spring data
@Getter @Getter
@Setter @Setter
@Document @Document
......
...@@ -5,6 +5,8 @@ import lombok.Setter; ...@@ -5,6 +5,8 @@ import lombok.Setter;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
// user entity, used for object relational mapping with spring data
@Getter @Getter
@Setter @Setter
@Document(collection = "users") @Document(collection = "users")
......
...@@ -7,6 +7,7 @@ import org.springframework.stereotype.Component; ...@@ -7,6 +7,7 @@ import org.springframework.stereotype.Component;
@Component @Component
public class TodoMapper { public class TodoMapper {
// maps entity attributes on dto
public TodoDTO entityToDto(Todo todo) { public TodoDTO entityToDto(Todo todo) {
TodoDTO todoDTO = new TodoDTO(); TodoDTO todoDTO = new TodoDTO();
todoDTO.setTodoId(todo.getTodoId()); todoDTO.setTodoId(todo.getTodoId());
...@@ -18,6 +19,7 @@ public class TodoMapper { ...@@ -18,6 +19,7 @@ public class TodoMapper {
return todoDTO; return todoDTO;
} }
// maps dto attributes on entity
public Todo dtoToEntity(TodoDTO dto){ public Todo dtoToEntity(TodoDTO dto){
Todo todo = new Todo(); Todo todo = new Todo();
todo.setTodoId(dto.getTodoId()); todo.setTodoId(dto.getTodoId());
......
...@@ -8,6 +8,7 @@ import org.springframework.stereotype.Component; ...@@ -8,6 +8,7 @@ import org.springframework.stereotype.Component;
@Component @Component
public class UserMapper { public class UserMapper {
// maps entity attributes to dto
public UserDTO entityToDto(User user) { public UserDTO entityToDto(User user) {
UserDTO userDTO = new UserDTO(); UserDTO userDTO = new UserDTO();
userDTO.setUserId(user.getUserId()); userDTO.setUserId(user.getUserId());
...@@ -16,6 +17,7 @@ public class UserMapper { ...@@ -16,6 +17,7 @@ public class UserMapper {
return userDTO; return userDTO;
} }
// maps dto attributes to entity
public User dtoToEntity(UserDTO userDTO) { public User dtoToEntity(UserDTO userDTO) {
User user = new User(); User user = new User();
user.setUserId(userDTO.getUserId()); user.setUserId(userDTO.getUserId());
...@@ -30,6 +32,7 @@ public class UserMapper { ...@@ -30,6 +32,7 @@ public class UserMapper {
* *
*/ */
//salts and hashes password by byte values
public String saltAndHashPassword(String userName, String pw) { public String saltAndHashPassword(String userName, String pw) {
//turn username into byte-array to use as unique salt //turn username into byte-array to use as unique salt
byte[] salt = userName.getBytes(); byte[] salt = userName.getBytes();
......
...@@ -3,6 +3,7 @@ package com.cloudcomputing.todo.repository; ...@@ -3,6 +3,7 @@ package com.cloudcomputing.todo.repository;
import com.cloudcomputing.todo.entity.User; import com.cloudcomputing.todo.entity.User;
import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.MongoRepository;
// spring data parses the method names and creates the according queries
public interface UserRepository extends MongoRepository<User, String> { public interface UserRepository extends MongoRepository<User, String> {
boolean existsByUserName(String userName); boolean existsByUserName(String userName);
boolean existsByUserId(String userId); boolean existsByUserId(String userId);
......
...@@ -43,6 +43,7 @@ public class UserService { ...@@ -43,6 +43,7 @@ public class UserService {
public UserDTO createUser(UserDTO userDTO) { public UserDTO createUser(UserDTO userDTO) {
User newUser; User newUser;
// creates user from userDTO if user doesnt exist yet (checked by userid + username)
if (!(userRepository.existsByUserId(userDTO.getUserId()) || userRepository.existsByUserName(userDTO.getUserName()))) { if (!(userRepository.existsByUserId(userDTO.getUserId()) || userRepository.existsByUserName(userDTO.getUserName()))) {
newUser = userMapper.dtoToEntity(userDTO); newUser = userMapper.dtoToEntity(userDTO);
return userMapper.entityToDto(userRepository.save(newUser)); return userMapper.entityToDto(userRepository.save(newUser));
...@@ -56,6 +57,7 @@ public class UserService { ...@@ -56,6 +57,7 @@ public class UserService {
* @return the userDTO with the given username * @return the userDTO with the given username
*/ */
public UserDTO getUser(UserDTO userDTO) { public UserDTO getUser(UserDTO userDTO) {
// looks for user entity in db and converts it to dto
return userMapper.entityToDto(userRepository.findByUserName(userDTO.getUserName())); return userMapper.entityToDto(userRepository.findByUserName(userDTO.getUserName()));
} }
...@@ -65,6 +67,7 @@ public class UserService { ...@@ -65,6 +67,7 @@ public class UserService {
* @return boolean value which indicates if the login was successful or not * @return boolean value which indicates if the login was successful or not
*/ */
public boolean login(HttpServletRequest request, UserDTO userDTO) { public boolean login(HttpServletRequest request, UserDTO userDTO) {
// authenticates user (pw-hash-check) and sets the attribute "userId" of the given session
if (customAuthenticator.authenticate(userDTO)) { if (customAuthenticator.authenticate(userDTO)) {
String userId = userRepository.findByUserName(userDTO.getUserName()).getUserId(); String userId = userRepository.findByUserName(userDTO.getUserName()).getUserId();
HttpSession session = request.getSession(); HttpSession session = request.getSession();
...@@ -81,6 +84,7 @@ public class UserService { ...@@ -81,6 +84,7 @@ public class UserService {
* @return true to indicate successful logout * @return true to indicate successful logout
*/ */
public boolean logout(HttpServletRequest request, String userId) { public boolean logout(HttpServletRequest request, String userId) {
// checks if session exists and invalidates it
HttpSession session = request.getSession(); HttpSession session = request.getSession();
if (session != null) { if (session != null) {
...@@ -95,9 +99,12 @@ public class UserService { ...@@ -95,9 +99,12 @@ public class UserService {
* @return list of todoDTOs * @return list of todoDTOs
*/ */
public List<TodoDTO> getAllTodos(String userId) { public List<TodoDTO> getAllTodos(String userId) {
// finds all todos for the given userId in the db
List<Todo> todoList = todoRepository.findAllByUserId(userId); List<Todo> todoList = todoRepository.findAllByUserId(userId);
List<TodoDTO> todoDTOList = new ArrayList<>(); List<TodoDTO> todoDTOList = new ArrayList<>();
// iterates through the list of todos, converts them to dtos
// and adds them to a list of dtos which is returned after
todoList.forEach((todoItem) -> { todoList.forEach((todoItem) -> {
todoDTOList.add(todoMapper.entityToDto(todoItem)); todoDTOList.add(todoMapper.entityToDto(todoItem));
}); });
......
...@@ -17,6 +17,7 @@ public class CustomAuthenticator { ...@@ -17,6 +17,7 @@ public class CustomAuthenticator {
@Autowired @Autowired
private UserMapper userMapper; private UserMapper userMapper;
// checks if the given password of the user dto ( received from frontend ) has same hash as stored password-hash
public boolean authenticate(UserDTO userDTO) { public boolean authenticate(UserDTO userDTO) {
User user = userRepository.findByUserName(userDTO.getUserName()); User user = userRepository.findByUserName(userDTO.getUserName());
String expectedHash = ""; String expectedHash = "";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment