diff --git a/chatto/pom.xml b/chatto/pom.xml index 13ba685..ec9dfd3 100644 --- a/chatto/pom.xml +++ b/chatto/pom.xml @@ -51,10 +51,7 @@ spring-boot-starter-test test - - org.springframework.boot - spring-boot-starter-freemarker - + org.springframework.boot spring-boot-starter-thymeleaf @@ -74,12 +71,19 @@ 2.1.2 - + org.projectlombok lombok + + + org.modelmapper + modelmapper + 2.3.5 + + diff --git a/chatto/src/main/java/org/ros/chatto/BeanConfigurations.java b/chatto/src/main/java/org/ros/chatto/BeanConfigurations.java index d457bce..eb1da74 100644 --- a/chatto/src/main/java/org/ros/chatto/BeanConfigurations.java +++ b/chatto/src/main/java/org/ros/chatto/BeanConfigurations.java @@ -1,5 +1,6 @@ -package org.ros.chatto.controller; +package org.ros.chatto; +import org.modelmapper.ModelMapper; import org.ros.chatto.security.AuthenticationSuccessHandlerImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -7,9 +8,16 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand @Configuration public class BeanConfigurations { - - @Bean - public AuthenticationSuccessHandler authenticationSuccessHandler() { - return new AuthenticationSuccessHandlerImpl(); - } + + @Bean + public AuthenticationSuccessHandler authenticationSuccessHandler() { + return new AuthenticationSuccessHandlerImpl(); + } + + @Bean + public ModelMapper modelMapper() { + ModelMapper modelMapper = new ModelMapper(); + return modelMapper; + } + } diff --git a/chatto/src/main/java/org/ros/chatto/ChattoApplication.java b/chatto/src/main/java/org/ros/chatto/ChattoApplication.java index 8fa00f5..66d5461 100644 --- a/chatto/src/main/java/org/ros/chatto/ChattoApplication.java +++ b/chatto/src/main/java/org/ros/chatto/ChattoApplication.java @@ -12,6 +12,7 @@ public class ChattoApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(ChattoApplication.class, args); + } @Override diff --git a/chatto/src/main/java/org/ros/chatto/RestAuthenticationEntryPoint.java b/chatto/src/main/java/org/ros/chatto/RestAuthenticationEntryPoint.java new file mode 100644 index 0000000..83550e9 --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/RestAuthenticationEntryPoint.java @@ -0,0 +1,42 @@ +package org.ros.chatto; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component +public final class RestAuthenticationEntryPoint + extends BasicAuthenticationEntryPoint { + +// @Override +// public void commence( +// HttpServletRequest request, +// HttpServletResponse response, +// AuthenticationException authException) throws IOException { +// +// response.sendError(HttpServletResponse.SC_UNAUTHORIZED, +// "Unauthorized"); +// } + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx) + throws IOException, ServletException { + response.addHeader("WWW-Authenticate", "Basic realm=" +getRealmName()); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + PrintWriter writer = response.getWriter(); + writer.println("HTTP Status 401 - " + authEx.getMessage()); + } + + @Override + public void afterPropertiesSet() throws Exception { + setRealmName("Chatto"); + super.afterPropertiesSet(); + } +} diff --git a/chatto/src/main/java/org/ros/chatto/WebConfig.java b/chatto/src/main/java/org/ros/chatto/WebConfig.java new file mode 100644 index 0000000..f2c7136 --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/WebConfig.java @@ -0,0 +1,20 @@ +package org.ros.chatto; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +//@EnableWebMvc +public class WebConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/api/**") + .allowedOrigins("*") + .allowedMethods("POST","GET","OPTIONS") + .allowedHeaders("*") + .allowCredentials(false).maxAge(3600); + + } +} \ No newline at end of file diff --git a/chatto/src/main/java/org/ros/chatto/WebSecurityConfiguration.java b/chatto/src/main/java/org/ros/chatto/WebSecurityConfiguration.java index 631f068..e5a1437 100644 --- a/chatto/src/main/java/org/ros/chatto/WebSecurityConfiguration.java +++ b/chatto/src/main/java/org/ros/chatto/WebSecurityConfiguration.java @@ -4,7 +4,7 @@ import org.ros.chatto.security.MyUserDetailsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; +import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -18,69 +18,119 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration @EnableWebSecurity public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { - - @Autowired - private AuthenticationSuccessHandler authenticationSuccessHandler; - @Autowired - private MyUserDetailsService myUserDetailsService; - @Autowired - private PasswordEncoder passwordEncoder; + + @Autowired + private AuthenticationSuccessHandler authenticationSuccessHandler; + @Autowired + private MyUserDetailsService myUserDetailsService; + @Autowired + private PasswordEncoder passwordEncoder; + + // @SuppressWarnings("deprecation") @Bean - public AuthenticationProvider authenticationProvider() - { + public AuthenticationProvider authenticationProvider() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(myUserDetailsService); provider.setPasswordEncoder(passwordEncoder); return provider; } + @Bean public static PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); + return new BCryptPasswordEncoder(); + } + + + + @Configuration + @Order(1) + public static class ApiWebSecurity extends WebSecurityConfigurerAdapter { + @Autowired + private RestAuthenticationEntryPoint restAuthenticationEntryPoint; + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .csrf().disable() + .exceptionHandling() + + .and() +// .cors().and() + .antMatcher("/api/**") + .authorizeRequests() +// .antMatchers("/perform-login").permitAll() + .anyRequest() +// .hasAnyRole("USER", "ADMIN", "SUPER_USER") + .authenticated() + .and().httpBasic() + .authenticationEntryPoint(restAuthenticationEntryPoint) +// .and() +// .logout().invalidateHttpSession(true).clearAuthentication(true) +// .logoutRequestMatcher(new AntPathRequestMatcher("/api/perform_logout")) +// .logoutSuccessUrl("/").permitAll() +// .and() +// .formLogin() +// .loginProcessingUrl("/api/perform_login").permitAll() +// .and() +// .formLogin() +// .and() +// .logout(); + ; + + } + + } + + @Configuration + @Order(2) + public static class FormWebSecurity extends WebSecurityConfigurerAdapter { + @Override + + protected void configure(HttpSecurity httpSecurity) throws Exception { + httpSecurity.authorizeRequests() +// .antMatchers(HttpMethod.POST, "/api/**").permitAll() + .antMatchers("/", "perform_login","/login*", "/registration", "/perform_registration", "/css/**", "/js/**", + "/images/**") + .permitAll() +// .antMatchers("/","/api**","/api/**","/login*","/registration","/perform_registration","/css/**", "/js/**", "/images/**").permitAll() + .antMatchers("/user/**").hasAnyRole("USER", "ADMIN", "SUPER_USER") + .antMatchers("/admin/**").hasAnyRole("ADMIN", "SUPER_USER") +// .and() +// .antMatcher("/api/**") +// .authorizeRequests() + .anyRequest().authenticated() + + .and() + + .formLogin() + .loginPage("/login").permitAll() + .loginProcessingUrl("/login") +// .successHandler(authenticationSuccessHandler) +// .failureUrl("/?login_error") + .and() + .logout().invalidateHttpSession(true).clearAuthentication(true) + .logoutRequestMatcher(new AntPathRequestMatcher("/perform_logout")) +// .logoutSuccessUrl("/").permitAll() +// .and().httpBasic(); +// .and().cors() +// .and().csrf().disable(); + ; +// httpSecurity +// .csrf().disable() +// .authorizeRequests().antMatchers("login").permitAll() +// .anyRequest().authenticated() +// .and() +// .formLogin() +// .loginPage("/login").permitAll() +// .and() +// .logout().invalidateHttpSession(true) +// .clearAuthentication(true) +// .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) +// .logoutSuccessUrl("/").permitAll(); + + } } - @Override - protected void configure(HttpSecurity httpSecurity) throws Exception { - httpSecurity.authorizeRequests() - .antMatchers(HttpMethod.POST, "/api/**").permitAll() - .antMatchers("/","/login*","/registration","/perform_registration","/css/**", "/js/**", "/images/**").permitAll() -// .antMatchers("/","/api**","/api/**","/login*","/registration","/perform_registration","/css/**", "/js/**", "/images/**").permitAll() - .antMatchers("/user/**").hasAnyRole("USER", "ADMIN","SUPER_USER") - .antMatchers("/admin/**").hasAnyRole("ADMIN","SUPER_USER") - .anyRequest() - .authenticated() - - .and() - - .formLogin() -// .loginPage("/login").permitAll() - .loginProcessingUrl("/perform_login") -// .successHandler(authenticationSuccessHandler) - .failureUrl("/?login_error") - .and() - .logout().invalidateHttpSession(true) - .clearAuthentication(true) - .logoutRequestMatcher(new AntPathRequestMatcher("/perform_logout")) - .logoutSuccessUrl("/").permitAll() - .and().cors().and().csrf().disable(); - - - -// httpSecurity -// .csrf().disable() -// .authorizeRequests().antMatchers("login").permitAll() -// .anyRequest().authenticated() -// .and() -// .formLogin() -// .loginPage("/login").permitAll() -// .and() -// .logout().invalidateHttpSession(true) -// .clearAuthentication(true) -// .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) -// .logoutSuccessUrl("/").permitAll(); - - } - // @Override // protected void configure(AuthenticationManagerBuilder auth) throws Exception { // auth.inMemoryAuthentication() @@ -113,6 +163,6 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { // auth.userDetailsService(myUserDetailsService); // } // auth.userDetailsService(myUserDetailsService); - + // } } diff --git a/chatto/src/main/java/org/ros/chatto/controller/ChatMessageController.java b/chatto/src/main/java/org/ros/chatto/controller/ChatMessageController.java new file mode 100644 index 0000000..11e8aa8 --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/controller/ChatMessageController.java @@ -0,0 +1,76 @@ +package org.ros.chatto.controller; + +import java.security.Principal; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.util.Date; +import java.util.List; + +import org.ros.chatto.dto.ChatMessageDTO; +import org.ros.chatto.model.MessageCipher; +import org.ros.chatto.service.ChatService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/chat") +public class ChatMessageController { + @Autowired + private ChatService chatService; + + @PostMapping(value = "/post/message", consumes = { "application/json" }) + @ResponseBody + public ResponseEntity newMessage(@RequestBody ChatMessageDTO chatMessageDTO, Principal principal) { + MessageCipher messageCipher = chatMessageDTO.getMessageCipher(); + String fromUser = principal.getName(); + String toUser = chatMessageDTO.getToUser(); + System.out.println("Message cipher = " + messageCipher); + chatService.saveNewMessage(fromUser, toUser, messageCipher); + return new ResponseEntity(HttpStatus.OK); + } + + @GetMapping(value = "/get/messages/{userName}") + @ResponseBody + public List sendAllMessages(@PathVariable String userName, Principal principal) { + List chatMessageDTOs = chatService.getAllMessages(principal.getName(), userName); + return chatMessageDTOs; + } + @GetMapping(value = "/get/messages/{userName}/{lastMessageTime}") + @ResponseBody + public List sendNewMessages(@PathVariable String userName, @PathVariable String lastMessageTime, Principal principal) { + System.out.println("Last message time = " + lastMessageTime ); + DateTimeFormatter formatter = new DateTimeFormatterBuilder() + // date/time + .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + // offset (hh:mm - "+00:00" when it's zero) + .optionalStart().appendOffset("+HH:MM", "+00:00").optionalEnd() + // offset (hhmm - "+0000" when it's zero) + .optionalStart().appendOffset("+HHMM", "+0000").optionalEnd() + // offset (hh - "Z" when it's zero) + .optionalStart().appendOffset("+HH", "Z").optionalEnd() + // create formatter + .toFormatter(); + Date date = Date.from(OffsetDateTime.parse(lastMessageTime, formatter).toInstant()); + + List chatMessageDTOs = chatService.getNewMessages(principal.getName(), userName, date); + return chatMessageDTOs; + } +} + +//public ResponseEntity> getMessages(@PathVariable String userName, Principal principal) { +////List chatMessages = chatMessageRepository.getAllMessages(principal.getName(), userName); +// +//// return posts.stream() +//// .map(post -> convertToDto(post)) +//// .collect(Collectors.toList()); +//return new ResponseEntity>(chatMessages, HttpStatus.OK); +//} diff --git a/chatto/src/main/java/org/ros/chatto/controller/DemoRestController.java b/chatto/src/main/java/org/ros/chatto/controller/DemoRestController.java index 76b315f..4b7f7a1 100644 --- a/chatto/src/main/java/org/ros/chatto/controller/DemoRestController.java +++ b/chatto/src/main/java/org/ros/chatto/controller/DemoRestController.java @@ -1,27 +1,38 @@ package org.ros.chatto.controller; -import org.ros.chatto.repository.UserRepositoryCustom; -import org.ros.chatto.repository.UserRoleRepository; +import java.security.Principal; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.ros.chatto.model.ChatMessage; +import org.ros.chatto.model.ChatUser; +import org.ros.chatto.model.MessageCipher; +import org.ros.chatto.model.UserRole; +import org.ros.chatto.repository.ChatMessageRepository; import org.ros.chatto.repository.MessageCipherRepository; import org.ros.chatto.repository.RoleRepository; import org.ros.chatto.repository.UserRepository; +import org.ros.chatto.repository.UserRepositoryCustom; +import org.ros.chatto.repository.UserRoleRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -import org.ros.chatto.model.ChatUser; -import org.ros.chatto.model.MessageCipher; -import org.ros.chatto.model.UserRole; +import org.springframework.web.servlet.ModelAndView; @RestController @RequestMapping("/api") +//@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*") public class DemoRestController { @Autowired @@ -34,6 +45,8 @@ public class DemoRestController { UserRoleRepository userRoleRepository; @Autowired MessageCipherRepository messageCipherRepository; + @Autowired + ChatMessageRepository chatMessageRepository; @GetMapping("/users") public List getAllUsers() { @@ -45,23 +58,35 @@ public class DemoRestController { return userRepositoryCustom.getAllUserNames("hmm"); } - @GetMapping("/user") + @GetMapping("/user_old") public ChatUser getUser() { return userRepository.findByUserName("hmm"); } + @GetMapping("/user") + public ChatUser currentUserName(Principal principal) { + ChatUser user = userRepository.findByUserName(principal.getName()); + return user; + } + @GetMapping("/roles") public List getAllRoles() { return userRoleRepository.findAll(); } - @GetMapping("/messages") + @GetMapping("/ciphers") public List getAllCiphers() { return messageCipherRepository.findAll(); } + @GetMapping("/messages") + public List getAllMessages() + { + return chatMessageRepository.findAll(); + } + // @RequestMapping(value = "/", method = RequestMethod.POST) // public ResponseEntity update(@RequestBody Car car) { // @@ -80,5 +105,20 @@ public class DemoRestController { messageCipherRepository.save(messageCipher); return new ResponseEntity(HttpStatus.OK); } + + @GetMapping("/logout") + public ModelAndView logoutPage() + { + ModelAndView modelAndView = new ModelAndView("restLogout"); + return modelAndView; + } + @RequestMapping(value="perform_logout", method = RequestMethod.POST) + public String performLogout (HttpServletRequest request, HttpServletResponse response) { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null){ + new SecurityContextLogoutHandler().logout(request, response, auth); + } + return "redirect:/users"; + } } diff --git a/chatto/src/main/java/org/ros/chatto/controller/Home.java b/chatto/src/main/java/org/ros/chatto/controller/Home.java index 20b3d32..e68572c 100644 --- a/chatto/src/main/java/org/ros/chatto/controller/Home.java +++ b/chatto/src/main/java/org/ros/chatto/controller/Home.java @@ -1,7 +1,14 @@ package org.ros.chatto.controller; -import org.ros.chatto.repository.UserRepositoryCustom; + +import java.security.Principal; + +import org.ros.chatto.dto.ChatMessageDTO; +import org.ros.chatto.service.UserService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @@ -23,15 +30,46 @@ public class TestController { @Controller public class Home { + @Autowired - UserRepositoryCustom userRepositoryCustom; + UserService userService; + @RequestMapping("/") - public ModelAndView showPage() { + public ModelAndView showPage(Principal principal) { ModelAndView mv = new ModelAndView("home"); mv.addObject("message", "Welcome!"); - mv.addObject("userNames", userRepositoryCustom.getAllUserNames("hmm")); +// mv.addObject("userNames", userService.findAllOtherUsers(principal.getName())); return mv; } + + @GetMapping("/crypt") + public String showCrypt() { + return "crypto"; + } + + @GetMapping("/chat") + public ModelAndView showChat(Principal principal) { + ModelAndView modelAndView = new ModelAndView("chat"); + modelAndView.addObject(new ChatMessageDTO()); +// modelAndView.addObject("userNames", userRepositoryCustom.getAllUserNames("hmm")); + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + +// Set roles = authentication.getAuthorities().stream().map(r -> r.getAuthority()) +// .collect(Collectors.toSet()); +// for (String r : roles) { +// System.out.println(r); +// } + +// boolean hasUserRole = authentication.getAuthorities().stream() +// .anyMatch(r -> r.getAuthority().equals("ROLE_USER")); + + boolean isAdmin = authentication.getAuthorities().stream() + .anyMatch(r -> r.getAuthority().equals("ROLE_ADMIN") || r.getAuthority().equals("ROLE_SUPER_USER")); + System.out.println("Is admin? " + isAdmin); + modelAndView.addObject("userNames", userService.findAllOtherUsers(principal.getName())); + return modelAndView; + } // public String showHome(Model model) // { // model.addAttribute("message", "Welcome"); diff --git a/chatto/src/main/java/org/ros/chatto/controller/RegisterController.java b/chatto/src/main/java/org/ros/chatto/controller/RegisterController.java index a13e786..23767aa 100644 --- a/chatto/src/main/java/org/ros/chatto/controller/RegisterController.java +++ b/chatto/src/main/java/org/ros/chatto/controller/RegisterController.java @@ -3,7 +3,7 @@ package org.ros.chatto.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.ros.chatto.model.UserDTO; +import org.ros.chatto.dto.UserRegistrationDTO; import org.ros.chatto.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -21,14 +21,14 @@ public class RegisterController { public ModelAndView registrationForm() { ModelAndView modelAndView = new ModelAndView("registration"); - modelAndView.addObject("userDTO",new UserDTO()); + modelAndView.addObject("userDTO",new UserRegistrationDTO()); return modelAndView; } @PostMapping("/perform_registration") - public ModelAndView performRegistration(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, @ModelAttribute("userDTO") UserDTO userDTO) + public ModelAndView performRegistration(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, @ModelAttribute("userDTO") UserRegistrationDTO userRegistrationDTO) { ModelAndView modelAndView = new ModelAndView("user/home"); - userService.registerUser(userDTO); + userService.registerUser(userRegistrationDTO); return modelAndView; } } diff --git a/chatto/src/main/java/org/ros/chatto/datae.sql b/chatto/src/main/java/org/ros/chatto/datae.sql new file mode 100644 index 0000000..c014ab3 --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/datae.sql @@ -0,0 +1,39 @@ +--INSERT INTO `admins` (`admin_id`, `user_id`) VALUES +--(1, 3); +--INSERT INTO `chat_messages` (`m_id`, `from_user`, `to_user`, `message`, `message_time`) VALUES +--(5, 3, 6, 3, '2019-09-28 15:42:15'), +--(6, 8, 3, 9, '2019-09-30 10:38:18'), +--(7, 8, 6, 10, '2019-09-30 10:40:31'), +--(8, 8, 3, 11, '2019-09-30 10:42:54'), +--(9, 3, 8, 4, '2019-09-30 12:40:16'), +--(10, 8, 3, 12, '2019-09-30 13:47:41'), +--(11, 8, 13, 13, '2019-09-30 13:47:48'), +--(12, 8, 6, 14, '2019-09-30 13:48:00'), +--(13, 8, 3, 15, '2019-10-01 06:34:10'), +--(14, 8, 3, 16, '2019-10-01 06:37:19'), +--(15, 8, 13, 17, '2019-10-01 06:56:07'), +--(16, 8, 13, 18, '2019-10-01 20:42:32'), +--(17, 3, 6, 19, '2019-10-01 20:44:59'), +--(18, 3, 13, 20, '2019-10-02 04:47:23'), +--(19, 3, 8, 21, '2019-10-02 04:56:07'), +--(20, 3, 8, 22, '2019-10-02 04:56:19'), +--(21, 3, 3, 23, '2019-10-02 06:42:21'), +--(22, 8, 3, 24, '2019-10-02 07:14:02'), +--(23, 3, 8, 25, '2019-10-02 09:07:13'), +--(24, 8, 13, 26, '2019-10-02 09:17:28'), +--(25, 8, 3, 27, '2019-10-02 09:18:54'), +--(26, 8, 3, 28, '2019-10-02 09:20:49'), +--(27, 3, 8, 29, '2019-10-02 09:47:29'), +--(28, 3, 8, 30, '2019-10-02 09:47:58'), +--(29, 3, 8, 31, '2019-10-02 10:14:32'); +-- +--INSERT INTO `chatmessage` (`Id`, `Message`, `userName`, `MsgTime`, `colorSelected`) VALUES +--(400, '', 'dae', '2019/08/19 12:58:52', '333'), +--(401, 'aegqe\n', 'dae', '2019/08/19 12:58:52', '333'); +-- +-- +--INSERT INTO `users` (`user_id`, `name`, `password`, `join_date`) VALUES +--(3, 'user2', '$2a$10$nLhkNrGu0/2ahSlULoQ0ROvUK2sRTEZBV014BLB/W9nBSMxy0rTGy', '2019-09-23 07:44:59'), +--(6, 'novo', '$2a$10$nLhkNrGu0/2ahSlULoQ0ROvUK2sRTEZBV014BLB/W9nBSMxy0rTGy', '2019-09-23 07:45:06'), +--(8, 'hmm', '$2a$10$k4tASmvqJ1mPA7avuzAnSO1KmWOmNhp7K8Y5Yg.dV/VXMX2L73/Ma', '2019-09-23 07:40:56'), +--(13, 'hmm2', '$2a$10$F.lMGPDXOguXWehMf1fvq.7XqzbFZWweLv3DYwB.1zpDEuPDcKBv6', '2019-09-23 13:46:33'); \ No newline at end of file diff --git a/chatto/src/main/java/org/ros/chatto/dto/ChatMessageDTO.java b/chatto/src/main/java/org/ros/chatto/dto/ChatMessageDTO.java new file mode 100644 index 0000000..2515e7b --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/dto/ChatMessageDTO.java @@ -0,0 +1,14 @@ +package org.ros.chatto.dto; + +import java.util.Date; + +import org.ros.chatto.model.MessageCipher; + +import lombok.Data; + +@Data +public class ChatMessageDTO { + private String toUser, fromUser; + private MessageCipher messageCipher; + private Date messageTime; +} diff --git a/chatto/src/main/java/org/ros/chatto/dto/UserPublicDTO.java b/chatto/src/main/java/org/ros/chatto/dto/UserPublicDTO.java new file mode 100644 index 0000000..781b6e8 --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/dto/UserPublicDTO.java @@ -0,0 +1,14 @@ +package org.ros.chatto.dto; + +import java.sql.Date; + +import org.ros.chatto.model.MessageCipher; + +import lombok.Data; + +@Data +public class UserPublicDTO { + String fromUser, toUser; + MessageCipher messageCipher; + Date messageTime; +} diff --git a/chatto/src/main/java/org/ros/chatto/dto/UserRegistrationDTO.java b/chatto/src/main/java/org/ros/chatto/dto/UserRegistrationDTO.java index fd3b718..7b780f1 100644 --- a/chatto/src/main/java/org/ros/chatto/dto/UserRegistrationDTO.java +++ b/chatto/src/main/java/org/ros/chatto/dto/UserRegistrationDTO.java @@ -1,8 +1,8 @@ -package org.ros.chatto.model; +package org.ros.chatto.dto; import javax.persistence.Transient; -public class UserDTO { +public class UserRegistrationDTO { private String userName; @Transient private String password; diff --git a/chatto/src/main/java/org/ros/chatto/model/ChatMessage.java b/chatto/src/main/java/org/ros/chatto/model/ChatMessage.java index 82ac76c..ed0c883 100644 --- a/chatto/src/main/java/org/ros/chatto/model/ChatMessage.java +++ b/chatto/src/main/java/org/ros/chatto/model/ChatMessage.java @@ -29,7 +29,9 @@ public class ChatMessage { @OneToOne @JoinColumn(name = "to_user") private ChatUser toUser; - private String message; + @OneToOne + @JoinColumn(name = "message") + private MessageCipher messageCipher; @Temporal(TemporalType.TIMESTAMP) private Date messageTime; } diff --git a/chatto/src/main/java/org/ros/chatto/model/Role.java b/chatto/src/main/java/org/ros/chatto/model/Role.java index a782ff5..ce2d831 100644 --- a/chatto/src/main/java/org/ros/chatto/model/Role.java +++ b/chatto/src/main/java/org/ros/chatto/model/Role.java @@ -3,6 +3,7 @@ package org.ros.chatto.model; import java.util.HashSet; import java.util.Set; +import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @@ -21,7 +22,7 @@ public class Role { @Column(name = "role_name") private String name; private String description; - @OneToMany(mappedBy = "role") + @OneToMany(mappedBy = "role", cascade = CascadeType.ALL) @JsonBackReference private Set userRoles = new HashSet<>(); public int getRoleId() { diff --git a/chatto/src/main/java/org/ros/chatto/repository/ChatMessageRepository.java b/chatto/src/main/java/org/ros/chatto/repository/ChatMessageRepository.java index eea47c5..e26e060 100644 --- a/chatto/src/main/java/org/ros/chatto/repository/ChatMessageRepository.java +++ b/chatto/src/main/java/org/ros/chatto/repository/ChatMessageRepository.java @@ -1,8 +1,25 @@ package org.ros.chatto.repository; +import java.util.Date; +import java.util.List; + import org.ros.chatto.model.ChatMessage; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; +@Repository public interface ChatMessageRepository extends JpaRepository { - +// @Query("select r from RoleRepository where name = ?1") +// @Query("select ur from UserRole ur where ur.user.userID = ?1") +// @Query("select m from ChatMessage m where m.toUser.userID = ?1 or m.toUser.userID = ?2 and " +// + "m.fromUser.userID = ?1 or m.fromUser.userID = ?2 order by m.messageTime asc") + @Query("select m from ChatMessage m where (m.toUser.userName = ?1 or m.toUser.userName = ?2) and " + + "(m.fromUser.userName = ?1 or m.fromUser.userName = ?2) order by m.messageTime asc") + public List getAllMessages(String fromUser, String toUser); + + @Query("select m from ChatMessage m where (m.toUser.userName = ?1 or m.toUser.userName = ?2) and " + + "(m.fromUser.userName = ?1 or m.fromUser.userName = ?2) and" + + "(m.messageTime >= ?3) order by m.messageTime asc") + public List getNewMessages(String fromUser, String toUser, Date lastMessageTime); } diff --git a/chatto/src/main/java/org/ros/chatto/repository/UserRepositoryCustomImpl.java b/chatto/src/main/java/org/ros/chatto/repository/UserRepositoryCustomImpl.java index 339d9ed..73fffdf 100644 --- a/chatto/src/main/java/org/ros/chatto/repository/UserRepositoryCustomImpl.java +++ b/chatto/src/main/java/org/ros/chatto/repository/UserRepositoryCustomImpl.java @@ -30,10 +30,10 @@ class UserRepositoryCustomImpl implements UserRepositoryCustom{ criteriaQuery.where(criteriaBuilder.notEqual(root.get("userName"), userName)); userNamesList = entityManager.createQuery(criteriaQuery).getResultList(); - for(String un: userNamesList) - { - System.out.println(un); - } +// for(String un: userNamesList) +// { +// System.out.println(un); +// } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); diff --git a/chatto/src/main/java/org/ros/chatto/scheme.sql b/chatto/src/main/java/org/ros/chatto/scheme.sql new file mode 100644 index 0000000..9001901 --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/scheme.sql @@ -0,0 +1,187 @@ +-- Database: `chatto_db` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `admins` +-- + +CREATE TABLE `admins` ( + `admin_id` int(11) NOT NULL, + `user_id` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Dumping data for table `admins` +-- + + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `chatmessage` +-- + +CREATE TABLE `chatmessage` ( + `Id` int(10) UNSIGNED NOT NULL, + `Message` varchar(4000) NOT NULL, + `userName` varchar(100) NOT NULL, + `MsgTime` varchar(45) NOT NULL, + `colorSelected` varchar(45) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `chatmessage` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `chat_messages` +-- + +CREATE TABLE `chat_messages` ( + `m_id` bigint(20) NOT NULL, + `from_user` int(11) NOT NULL, + `to_user` int(11) NOT NULL, + `message` int(10) NOT NULL, + `message_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Dumping data for table `chat_messages` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `total_messages` +-- + +CREATE TABLE `total_messages` ( + `t_id` int(101) NOT NULL, + `from_user` int(11) NOT NULL, + `to_user` int(11) NOT NULL, + `total_messages` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `users` +-- + +CREATE TABLE `users` ( + `user_id` int(11) NOT NULL, + `name` varchar(10) NOT NULL, + `password` varchar(80) NOT NULL, + `join_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Dumping data for table `users` +-- + + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `admins` +-- +ALTER TABLE `admins` + ADD PRIMARY KEY (`admin_id`), + ADD UNIQUE KEY `user_id_2` (`user_id`), + ADD KEY `admin_id` (`admin_id`), + ADD KEY `user_id` (`user_id`); + +-- +-- Indexes for table `chatmessage` +-- +ALTER TABLE `chatmessage` + ADD PRIMARY KEY (`Id`); + +-- +-- Indexes for table `chat_messages` +-- +ALTER TABLE `chat_messages` + ADD PRIMARY KEY (`m_id`), + ADD UNIQUE KEY `identifier_message_number` (`m_id`), + ADD KEY `identifier_message_number_2` (`m_id`), + ADD KEY `from_user` (`from_user`,`to_user`), + ADD KEY `message` (`message`), + ADD KEY `FOREIGN KEY TO USER IN MESSAGES TABLE` (`to_user`); + +-- +-- Indexes for table `total_messages` +-- +ALTER TABLE `total_messages` + ADD PRIMARY KEY (`t_id`), + ADD UNIQUE KEY `identifier` (`t_id`); + +-- +-- Indexes for table `users` +-- +ALTER TABLE `users` + ADD PRIMARY KEY (`user_id`), + ADD UNIQUE KEY `name` (`name`), + ADD KEY `user_id` (`user_id`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `admins` +-- +ALTER TABLE `admins` + MODIFY `admin_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2; +-- +-- AUTO_INCREMENT for table `chatmessage` +-- +ALTER TABLE `chatmessage` + MODIFY `Id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=402; +-- +-- AUTO_INCREMENT for table `chat_messages` +-- +ALTER TABLE `chat_messages` + MODIFY `m_id` bigint(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=30; +-- +-- AUTO_INCREMENT for table `total_messages` +-- +ALTER TABLE `total_messages` + MODIFY `t_id` int(101) NOT NULL AUTO_INCREMENT; +-- +-- AUTO_INCREMENT for table `users` +-- +ALTER TABLE `users` + MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=14; +-- +-- Constraints for dumped tables +-- + +-- +-- Constraints for table `admins` +-- +ALTER TABLE `admins` + ADD CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE; + +-- +-- Constraints for table `chat_messages` +-- +ALTER TABLE `chat_messages` + ADD CONSTRAINT `FOREIGN KEY ENC MESSAGE TABLE` FOREIGN KEY (`message`) REFERENCES `message_ciphers` (`id`) ON UPDATE CASCADE, + ADD CONSTRAINT `FOREIGN KEY FROM USER IN MESSAGES TABLE` FOREIGN KEY (`from_user`) REFERENCES `users` (`user_id`) ON UPDATE CASCADE, + ADD CONSTRAINT `FOREIGN KEY TO USER IN MESSAGES TABLE` FOREIGN KEY (`to_user`) REFERENCES `users` (`user_id`) ON UPDATE CASCADE; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; + + + diff --git a/chatto/src/main/java/org/ros/chatto/service/ChatService.java b/chatto/src/main/java/org/ros/chatto/service/ChatService.java new file mode 100644 index 0000000..c837ce7 --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/service/ChatService.java @@ -0,0 +1,17 @@ +package org.ros.chatto.service; + +import java.util.Date; +import java.util.List; + +import org.ros.chatto.dto.ChatMessageDTO; +import org.ros.chatto.model.MessageCipher; + +public interface ChatService { + void saveNewMessage(String fromUser, String toUser , MessageCipher messageCipher); + + List getAllMessages(String fromUser, String toUser); + + List getMessagePage(int page, int size); + + List getNewMessages(String fromUser, String toUser, Date lastMessageTime); +} diff --git a/chatto/src/main/java/org/ros/chatto/service/ChatServiceImpl.java b/chatto/src/main/java/org/ros/chatto/service/ChatServiceImpl.java new file mode 100644 index 0000000..5c37aea --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/service/ChatServiceImpl.java @@ -0,0 +1,68 @@ +package org.ros.chatto.service; + +import java.util.Date; +import java.util.List; + +import org.ros.chatto.dto.ChatMessageDTO; +import org.ros.chatto.model.ChatMessage; +import org.ros.chatto.model.ChatUser; +import org.ros.chatto.model.MessageCipher; +import org.ros.chatto.repository.ChatMessageRepository; +import org.ros.chatto.repository.MessageCipherRepository; +import org.ros.chatto.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +@Service +public class ChatServiceImpl implements ChatService { + +// @Autowired +// UserService userService; + @Autowired + UserRepository userRepository; + @Autowired + MessageCipherRepository messageCipherRepository; + @Autowired + ChatMessageRepository chatMessageRepository; + @Autowired + MyConversionService myConversionService; + + public void saveNewMessage(String fromUserName, String toUserName, MessageCipher messageCipher) { + + ChatUser fromUser = userRepository.findByUserName(fromUserName); + ChatUser toUser = userRepository.findByUserName(toUserName); + ChatMessage chatMessage = new ChatMessage(); + messageCipher = messageCipherRepository.save(messageCipher); + chatMessage.setMessageCipher(messageCipher); + chatMessage.setFromUser(fromUser); + chatMessage.setToUser(toUser); + + chatMessageRepository.save(chatMessage); + + } + + @Override + public List getAllMessages(String fromUser, String toUser) { + List chatMessages = chatMessageRepository.getAllMessages(fromUser, toUser); + List chatMessageDTOs = myConversionService.convertToChatMessageDTOs(chatMessages); + return chatMessageDTOs; + } + + @Override + public List getMessagePage(int page, int size) { +// Sort sort = Sort + Page chatMessages = chatMessageRepository.findAll(PageRequest.of(page, size)); + List chatMessageDTOs = myConversionService.convertToChatMessageDTOs(chatMessages); + return chatMessageDTOs; + } + + @Override + public List getNewMessages(String fromUser, String toUser, Date lastMessageTime) { + // TODO Auto-generated method stub + List chatMessages = chatMessageRepository.getNewMessages(fromUser, toUser, lastMessageTime); +// List chatMessageDTOs + return myConversionService.convertToChatMessageDTOs(chatMessages); + } +} diff --git a/chatto/src/main/java/org/ros/chatto/service/MyConversionService.java b/chatto/src/main/java/org/ros/chatto/service/MyConversionService.java new file mode 100644 index 0000000..bfc024c --- /dev/null +++ b/chatto/src/main/java/org/ros/chatto/service/MyConversionService.java @@ -0,0 +1,58 @@ +package org.ros.chatto.service; + +import java.util.List; +import java.util.stream.Collectors; + +import org.modelmapper.ModelMapper; +import org.ros.chatto.dto.ChatMessageDTO; +import org.ros.chatto.model.ChatMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + + +//private PostDto convertToDto(Post post) { +// PostDto postDto = modelMapper.map(post, PostDto.class); +// postDto.setSubmissionDate(post.getSubmissionDate(), +// userService.getCurrentUser().getPreference().getTimezone()); +// return postDto; +//} +// +// +//private Post convertToEntity(PostDto postDto) throws ParseException { +// Post post = modelMapper.map(postDto, Post.class); +// post.setSubmissionDate(postDto.getSubmissionDateConverted( +// userService.getCurrentUser().getPreference().getTimezone())); +// +// if (postDto.getId() != null) { +// Post oldPost = postService.getPostById(postDto.getId()); +// post.setRedditID(oldPost.getRedditID()); +// post.setSent(oldPost.isSent()); +// } +// return post; +//} +@Service +public class MyConversionService { + @Autowired + ModelMapper modelMapper; + + public ChatMessageDTO convertToChatMessageDTO(ChatMessage chatMessage) + { + ChatMessageDTO chatMessageDTO = modelMapper.map(chatMessage, ChatMessageDTO.class); + return chatMessageDTO; + } + + public List convertToChatMessageDTOs(List chatMessages) + { + return chatMessages.stream() + .map(chatMessage -> convertToChatMessageDTO(chatMessage)) + .collect(Collectors.toList()); + } + + public List convertToChatMessageDTOs(Page chatMessages) + { + return chatMessages.stream() + .map(chatMessage -> convertToChatMessageDTO(chatMessage)) + .collect(Collectors.toList()); + } +} diff --git a/chatto/src/main/java/org/ros/chatto/service/UserService.java b/chatto/src/main/java/org/ros/chatto/service/UserService.java index 1941e60..c5f9154 100644 --- a/chatto/src/main/java/org/ros/chatto/service/UserService.java +++ b/chatto/src/main/java/org/ros/chatto/service/UserService.java @@ -1,11 +1,14 @@ package org.ros.chatto.service; +import java.util.List; + +import org.ros.chatto.dto.UserRegistrationDTO; import org.ros.chatto.model.ChatUser; -import org.ros.chatto.model.UserDTO; +import org.springframework.stereotype.Service; -//@Service +@Service public interface UserService { public void saveChatUser(ChatUser user); - - public void registerUser(UserDTO userDTO); + public List findAllOtherUsers(String userName); + public void registerUser(UserRegistrationDTO userRegistrationDTO); } diff --git a/chatto/src/main/java/org/ros/chatto/service/UserServiceImpl.java b/chatto/src/main/java/org/ros/chatto/service/UserServiceImpl.java index 7148f1b..eaf6c00 100644 --- a/chatto/src/main/java/org/ros/chatto/service/UserServiceImpl.java +++ b/chatto/src/main/java/org/ros/chatto/service/UserServiceImpl.java @@ -1,10 +1,13 @@ package org.ros.chatto.service; +import java.util.List; + +import org.ros.chatto.dto.UserRegistrationDTO; import org.ros.chatto.model.ChatUser; import org.ros.chatto.model.Role; -import org.ros.chatto.model.UserDTO; import org.ros.chatto.model.UserRole; import org.ros.chatto.repository.UserRepository; +import org.ros.chatto.repository.UserRepositoryCustom; import org.ros.chatto.repository.UserRoleRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; @@ -23,6 +26,9 @@ public class UserServiceImpl implements UserService{ @Autowired RoleService roleService; + + @Autowired + UserRepositoryCustom userRepositoryCustom; @Override public void saveChatUser(ChatUser user) { @@ -35,11 +41,11 @@ public class UserServiceImpl implements UserService{ } @Override - public void registerUser(UserDTO userDTO) { + public void registerUser(UserRegistrationDTO userRegistrationDTO) { // TODO Auto-generated method stub ChatUser user = new ChatUser(); - user.setUserName(userDTO.getUserName()); - user.setPassword(passwordEncoder.encode(userDTO.getPassword())); + user.setUserName(userRegistrationDTO.getUserName()); + user.setPassword(passwordEncoder.encode(userRegistrationDTO.getPassword())); ChatUser changedUser = userRepository.save(user); UserRole userRole = new UserRole(); Role role = roleService.getRole("USER"); @@ -50,4 +56,10 @@ public class UserServiceImpl implements UserService{ userRoleRepository.save(userRole); } + @Override + public List findAllOtherUsers(String userName) { + // TODO Auto-generated method stub + return userRepositoryCustom.getAllUserNames(userName); + } + } diff --git a/chatto/src/main/resources/application.properties b/chatto/src/main/resources/application.properties index c19e2be..a64c327 100644 --- a/chatto/src/main/resources/application.properties +++ b/chatto/src/main/resources/application.properties @@ -17,4 +17,7 @@ logging.level.org.springframework.web=DEBUG logging.level.web=DEBUG logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE -spring.http.log-request-details=true \ No newline at end of file +spring.http.log-request-details=true +#spring.jackson.date-format=yyyy-MM-d +spring.jackson.serialization.write-dates-as-timestamps=false +#spring.mvc.static-path-pattern=/static/** \ No newline at end of file diff --git a/chatto/src/main/resources/static/css/master.css b/chatto/src/main/resources/static/css/master.css new file mode 100644 index 0000000..0895505 --- /dev/null +++ b/chatto/src/main/resources/static/css/master.css @@ -0,0 +1,24 @@ +.myClass { + color: red; +} +#body-container { + margin: 0 auto 0 auto; + max-width: 80%; + /* vertical-align: auto; */ +} +.shadow-sm { + width: 50%; +} +input[type="radio"]{ + /*position:fixed;*/ + opacity:0; +} +input[type=radio]+label { + font-weight: normal; +} +input[type=radio]:checked+label { + font-weight: bold; +} +input[type=radio]:focus+label { + border: 1px dotted #000; +} \ No newline at end of file diff --git a/chatto/src/main/resources/static/js/chat.js b/chatto/src/main/resources/static/js/chat.js new file mode 100644 index 0000000..7dcb6a0 --- /dev/null +++ b/chatto/src/main/resources/static/js/chat.js @@ -0,0 +1,267 @@ +// import { sprintf } from 'sprintf-js'; +// import { vsprintf } from 'sprintf-js'; +/*var off_payment_method = document.getElementsByName('offline_payment_method'); +var ischecked_method = false; +for ( var i = 0; i < off_payment_method.length; i++) { + if(off_payment_method[i].checked) { + ischecked_method = true; + break; + } +} +if(!ischecked_method) { //payment method button is not checked + alert("Please choose Offline Payment Method"); +}*/ +var toUserRadios = document.getElementsByName('toUser'); +var isCheckedUser = false; +var chatTextArea = document.getElementById('chatTextArea'); +var passphraseInput = document.getElementById('passphrase'); +var postNewMessageUrl = "http://192.168.1.8:8080/api/chat/post/message"; +var getAllMessagesUrl = "http://192.168.1.8:8080/api/chat/get/messages/"; +var getNewMessagesUrl = "http://192.168.1.8:8080/api/chat/get/messages/"; +// var messageLog = []; +var username = sessionStorage.getItem('username'); +var password = sessionStorage.getItem('password'); +var authToken = 'Basic ' + btoa(username + ":" + password); +// var lastMessageTimeStamp; + +// console.log(authToken); +// 'Basic ' + btoa("hmm" + ":" + "hmm") + + + + +// var user; +function getSelectedUser() { + for (var i = 0; i < toUserRadios.length; i++) { + if (toUserRadios[i].checked) { + let user = toUserRadios[i].value; + console.log('sending to user = ' + user); + isCheckedUser = true; + return user; + } + } + +} + +// console.log('Credentials = ' + JSON.parse(sessionStorage.getItem('credentials'))); + +function handleChatForm() { + let chatInput = document.getElementById('chatInput'); + let myForm = document.getElementById('chatMessageForm').addEventListener( + 'submit', function (e) { + e.preventDefault(); + let user = getSelectedUser(); + if (!isCheckedUser) { + window.alert('please select a user'); + return; + } + // console.log('second user = ' + user); + let messageContent = chatInput.value; + let localDate = new Date(); + let messageLine = sprintf('%s %s %s: %s', localDate.toLocaleDateString(), localDate.toLocaleTimeString() ,username, messageContent); + chatTextArea.append(messageLine + "\n"); + // let messageCipher = sjcl.encrypt("password", messageContent); + let messageCipher = sjcl.encrypt(passphraseInput.value, messageContent); + let messageCipherJson = JSON.parse(messageCipher); + // let messageCipherSpring = JSON.stringify(messageCipherJson); + // console.log('message cipher json ' + messageCipherJson); + // console.log('message cipher string ' + messageCipherSpring); + let chatMessageDTO = { + "toUser": user, + "messageCipher": messageCipherJson + } + // console.log(chatMessageDTO); + // console.log(JSON.stringify(chatMessageDTO)); + messageSend(JSON.stringify(chatMessageDTO)); + // sessionStorage.setItem('passphrase', passphraseInput.value); + // console.log(sessionStorage.getItem('passphrase')); + + }) +} + +function messageSend(chatMessageDTO) { + let headers = new Headers(); + // console.log("Token = " + btoa("hmm" + ":" + "hmm")) + + // headers.append('Accept','application/json') + headers.append('Content-Type', 'application/json'); + headers.append('Authorization', authToken); + fetch(postNewMessageUrl, { + method: 'POST', + headers: headers, + body: chatMessageDTO + }) + .then(response => console.log(response)); +} + +// function getMessages(toUser) { +// let headers = new Headers(); +// let messageLog = []; +// // console.log("Token = " + btoa("hmm" + ":" + "hmm")) + +// // headers.append('Accept','application/json') +// // headers.append('Content-Type', 'application/json'); +// headers.append('Authorization', 'Basic ' + btoa("hmm" + ":" + "hmm")); +// let myPromise = fetch(getUrl + toUser, { +// method: 'GET', +// headers: headers +// }) +// .then(response => { +// console.log(response); +// return response.json(); +// }) +// .then(json => { + +// console.log(json); +// let i = 0; +// json.forEach(function (obj) { +// // console.log(obj.toUser); +// messageCipher = JSON.stringify(obj.messageCipher); +// console.log(messageCipher); +// // let message = sjcl.decrypt("password", messageCipher); +// let message = sjcl.decrypt(passphraseInput.value, messageCipher); +// let messageLine = sprintf('%s %s: %s \n', obj.messageTime, obj.fromUser, message); +// console.log(messageLine); +// // chatTextArea.append(obj.fromUser + ": " + message + "\n"); +// chatTextArea.append(messageLine); +// messageLog[i++] = messageLine; +// }); +// console.log(messageLog); +// // return messageLog; + +// }); +// return messageLog; +// } + +// async function getUserAsync(name) +// { +// let response = await fetch(`https://api.github.com/users/${name}`); +// let data = await response.json() +// return data; +// } + +// getUserAsync('yourUsernameHere') +// .then(data => console.log(data)); + +async function getAllMessages(toUser) { + let headers = new Headers(); + // headers.append('Accept','application/json') + // headers.append('Content-Type', 'application/json'); + headers.append('Authorization', authToken); + let response = await fetch(getAllMessagesUrl + toUser, { + method: 'GET', + headers: headers + }); + let data = await response.json(); + return data; +} + +async function getNewMessages(toUser, lastMessageTimeStamp) { + let headers = new Headers(); + headers.append('Authorization', authToken); + let response = await fetch(`${getNewMessagesUrl}${toUser}/${lastMessageTimeStamp}`, { + method: 'GET', + headers: headers + }); + let data = await response.json(); + return data; +} + +// getMessages('user2'); +window.EventTarget.prototype.addDelegatedListener = function (type, delegateSelector, listener) { + this.addEventListener(type, function (event) { + if (event.target && event.target.matches(delegateSelector)) { + listener.call(event.target, event) + } + }); +} +let parent = document.getElementById('chatMessageForm') +parent.addDelegatedListener("click", "input[type='radio']", function (event) { + // if (sessionStorage.getItem('status') != null) { + if (passphraseInput.value == '') { + alert('Please input passphrase') + return; + } + console.log(this.value); + if (sessionStorage.getItem(this.value) == null) { + chatTextArea.textContent = ''; + getAllMessages(this.value) + .then(json => { + console.log(json); + let i = 0; + let messageLog = []; + let lastMessageTimeStamp; + json.forEach(function (obj) { + // console.log(obj.toUser); + messageCipher = JSON.stringify(obj.messageCipher); + console.log(messageCipher); + // let message = sjcl.decrypt("password", messageCipher); + let message = sjcl.decrypt(passphraseInput.value, messageCipher); + let utcDate = obj.messageTime; + lastMessageTimeStamp = utcDate; + let localDate = new Date(utcDate); + let messageLine = sprintf('%s %s: %s ', localDate, obj.fromUser, message); + + // localDate.`` + // console.log('localDate = ' + localDate); + console.log(messageLine); + // chatTextArea.append(obj.fromUser + ": " + message + "\n"); + chatTextArea.append(messageLine + '\n'); + messageLog[i++] = messageLine; + + }); + // console.log('Message log = ' + messageLog); + sessionStorage.setItem(this.value, JSON.stringify(messageLog)); + // sessionStorage.clear(); + console.log('Last message time = ' + lastMessageTimeStamp); + sessionStorage.setItem(this.value + '-time', lastMessageTimeStamp); + }); + } + else { + + + console.log("Stored messages = " + sessionStorage.getItem(this.value)); + let storedMessages = JSON.parse(sessionStorage.getItem(this.value)); + getNewMessages(this.value, sessionStorage.getItem(this.value + '-time')) + .then(json => { + console.log(json) + json.forEach(function (obj) + { + let messageCipher = JSON.stringify(obj.messageCipher); + let message = sjcl.decrypt(passphraseInput.value, messageCipher); + // console.log(message); + // chatTextArea.append(message + "\n"); + let utcDate = obj.messageTime; + lastMessageTimeStamp = utcDate; + let localDate = new Date(utcDate); + let messageLine = sprintf('%s %s: %s', localDate, obj.fromUser, message); + + // localDate.`` + // console.log('localDate = ' + localDate); + console.log(messageLine); + // chatTextArea.append(obj.fromUser + ": " + message + "\n"); + chatTextArea.append(messageLine + '\n'); + storedMessages.push(messageLine); + }) + }); + // sessionStorage.clear(); + // chatTextArea.append(JSON.stringify(storedMessages)); + chatTextArea.textContent = ''; + console.log("Stored messages 2 = " + storedMessages); + storedMessages.forEach(function (messageLine) { + chatTextArea.append(messageLine + '\n'); + }) + } + // sessionStorage.setItem('status', 'ready'); + // sessionStorage.setItem('this.value', messageLog); + // console.log('Message log = ' + messageLog); + // } + + // let passphraseKey = this.value + '-passphrase'; + // sessionStorage.setItem(passphraseKey, passphraseInput.value); + // console.log(sessionStorage.getItem(passphraseKey)); +}); + + +handleChatForm(); + diff --git a/chatto/src/main/resources/static/js/loginPage.js b/chatto/src/main/resources/static/js/loginPage.js new file mode 100644 index 0000000..3abf6e1 --- /dev/null +++ b/chatto/src/main/resources/static/js/loginPage.js @@ -0,0 +1,19 @@ + +function storeCredentials() { + let usernameInput = document.getElementById('username'); + let passwordInput = document.getElementById('password'); + let credentials = { + username: usernameInput.value, + password: passwordInput.value + } + // sessionStorage.setItem('credentials', JSON.stringify(credentials)); + sessionStorage.setItem('username',usernameInput.value); + sessionStorage.setItem('password',passwordInput.value); +} + +let loginForm = document.getElementById('loginForm'); +loginForm.addEventListener('submit', function (e) { + storeCredentials(); +}) + +// storeCredentials(); diff --git a/chatto/src/main/resources/static/js/my_Crypto.js b/chatto/src/main/resources/static/js/my_Crypto.js new file mode 100644 index 0000000..9ef7b37 --- /dev/null +++ b/chatto/src/main/resources/static/js/my_Crypto.js @@ -0,0 +1,57 @@ +var cipherText = sjcl.encrypt("password", "data"); +console.log(cipherText); +var plainText = sjcl.decrypt("password", cipherText); +console.log(plainText); + +var field = document.getElementById('crypt'); +// field.innerText = plainText; + +var jsonString = "{\"iv\":\"2rtnuXaJXFuQGO9ncaVkmA==\",\"v\":1,\"iter\":10000,\"ks\":128,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"H1z7o3f6qlQ=\",\"ct\":\"lF9Uno7ihjVv01M8\"}"; + +var myJSON = JSON.parse(jsonString); +console.log(myJSON); + +// let base64 = require('base-64'); + +let headers = new Headers(); +console.log("Token = " + btoa("hmm" + ":" + "hmm")) + +// headers.append('Accept','application/json') +// headers.append('Content-Type', 'application/json'); +headers.append('Authorization', 'Basic ' + btoa("hmm" + ":" + "hmm")); +// headers.append('Authorization', 'Basic aG1tOmhtbQ=='); + + +// aG1tOmhtbQ== +var messageCipher; +fetch('http://localhost:8080/api/messages', { + method: 'GET', + headers: headers + // credentials: 'include' +}).then(response => response.json()) + .then(json => { + // console.log('parsed json', JSON.stringify(json)) // access json.body here + // console.log('parsed json', json[0].messageCipher); + messageCipher = JSON.stringify(json[0].messageCipher); + console.log(messageCipher); + console.log(sjcl.decrypt("password", messageCipher)); + + }); + // console.log("New message = " + messageCipher); + + // [{"messageID":5,"fromUser":{"userID":3,"userName":"user2","joinDate":1569224699000},"toUser":{"userID":6,"userName":"novo","joinDate":1569224706000},"messageCipher":{"iv":"2rtnuXaJXFuQGO9ncaVkmA==","v":1,"mode":"ccm","adata":"","cipher":"aes","salt":"H1z7o3f6qlQ=","iter":10000,"ks":128,"ts":64,"ct":"lF9Uno7ihjVv01M8"},"messageTime":1569685335000}] + +var url = 'http://localhost:8080/api/users' +xml = new XMLHttpRequest(); +xml.onreadystatechange = function () { + if (xml.readyState == XMLHttpRequest.DONE) { + // alert(xhr.responseText); + console.log(xml.responseText); + // console.log(xml.getResponseHeader('X-CSRF-TOKEN')); + } +} +xml.open('GET', url) +xml.setRequestHeader('Authorization', 'Basic aG1tOmhtbQ=='); +xml.setRequestHeader("X-CSRF-TOKEN", "fetch"); +xml.send(null); + diff --git a/chatto/src/main/resources/static/js/scljs.js b/chatto/src/main/resources/static/js/scljs.js new file mode 100644 index 0000000..c3c3ea9 --- /dev/null +++ b/chatto/src/main/resources/static/js/scljs.js @@ -0,0 +1,60 @@ +"use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}}; +sjcl.cipher.aes=function(a){this.s[0][0][0]||this.O();var b,c,d,e,f=this.s[0][4],g=this.s[1];b=a.length;var h=1;if(4!==b&&6!==b&&8!==b)throw new sjcl.exception.invalid("invalid aes key size");this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^g[3][f[c& +255]]}; +sjcl.cipher.aes.prototype={encrypt:function(a){return t(this,a,0)},decrypt:function(a){return t(this,a,1)},s:[[[],[],[],[],[]],[[],[],[],[],[]]],O:function(){var a=this.s[0],b=this.s[1],c=a[4],d=b[4],e,f,g,h=[],k=[],l,n,m,p;for(e=0;0x100>e;e++)k[(h[e]=e<<1^283*(e>>7))^e]=e;for(f=g=0;!c[f];f^=l||1,g=k[g]||1)for(m=g^g<<1^g<<2^g<<3^g<<4,m=m>>8^m&255^99,c[f]=m,d[m]=f,n=h[e=h[l=h[f]]],p=0x1010101*n^0x10001*e^0x101*l^0x1010100*f,n=0x101*h[m]^0x1010100*m,e=0;4>e;e++)a[e][f]=n=n<<24^n>>>8,b[e][m]=p=p<<24^p>>>8;for(e= +0;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}}; +function t(a,b,c){if(4!==b.length)throw new sjcl.exception.invalid("invalid aes block size");var d=a.b[c],e=b[0]^d[0],f=b[c?3:1]^d[1],g=b[2]^d[2];b=b[c?1:3]^d[3];var h,k,l,n=d.length/4-2,m,p=4,r=[0,0,0,0];h=a.s[c];a=h[0];var q=h[1],v=h[2],w=h[3],x=h[4];for(m=0;m>>24]^q[f>>16&255]^v[g>>8&255]^w[b&255]^d[p],k=a[f>>>24]^q[g>>16&255]^v[b>>8&255]^w[e&255]^d[p+1],l=a[g>>>24]^q[b>>16&255]^v[e>>8&255]^w[f&255]^d[p+2],b=a[b>>>24]^q[e>>16&255]^v[f>>8&255]^w[g&255]^d[p+3],p+=4,e=h,f=k,g=l;for(m= +0;4>m;m++)r[c?3&-m:m]=x[e>>>24]<<24^x[f>>16&255]<<16^x[g>>8&255]<<8^x[b&255]^d[p++],h=e,e=f,f=g,g=b,b=h;return r} +sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.$(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+0x10000000000*a},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return!1;var c=0,d;for(d=0;d>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,32>>24|c>>>8&0xff00|(c&0xff00)<<8|c<<24;return a}}; +sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d>>8>>>8>>>8),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c>>g)>>>e),gn){if(!b)try{return sjcl.codec.base32hex.toBits(a)}catch(p){}throw new sjcl.exception.invalid("this isn't "+m+"!");}h>e?(h-=e,f.push(l^n>>>h),l=n<>>e)>>>26),6>e?(g=a[c]<<6-e,e+=26,c++):(g<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,f=sjcl.codec.base64.B,g=0,h;b&&(f=f.substr(0,62)+"-_");for(d=0;dh)throw new sjcl.exception.invalid("this isn't base64!");26>>e),g=h<<32-e):(e+=6,g^=h<<32-e)}e&56&&c.push(sjcl.bitArray.partial(e&56,g,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.b[0]||this.O();a?(this.F=a.F.slice(0),this.A=a.A.slice(0),this.l=a.l):this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()}; +sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.F=this.Y.slice(0);this.A=[];this.l=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.A=sjcl.bitArray.concat(this.A,a);b=this.l;a=this.l=b+sjcl.bitArray.bitLength(a);if(0x1fffffffffffffb;c++){e=!0;for(d=2;d*d<=c;d++)if(0===c%d){e= +!1;break}e&&(8>b&&(this.Y[b]=a(Math.pow(c,.5))),this.b[b]=a(Math.pow(c,1/3)),b++)}}}; +function u(a,b){var c,d,e,f=a.F,g=a.b,h=f[0],k=f[1],l=f[2],n=f[3],m=f[4],p=f[5],r=f[6],q=f[7];for(c=0;64>c;c++)16>c?d=b[c]:(d=b[c+1&15],e=b[c+14&15],d=b[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+b[c&15]+b[c+9&15]|0),d=d+q+(m>>>6^m>>>11^m>>>25^m<<26^m<<21^m<<7)+(r^m&(p^r))+g[c],q=r,r=p,p=m,m=n+d|0,n=l,l=k,k=h,h=d+(k&l^n&(k^l))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+h|0;f[1]=f[1]+k|0;f[2]=f[2]+l|0;f[3]=f[3]+n|0;f[4]=f[4]+m|0;f[5]=f[5]+p|0;f[6]=f[6]+r|0;f[7]= +f[7]+q|0} +sjcl.mode.ccm={name:"ccm",G:[],listenProgress:function(a){sjcl.mode.ccm.G.push(a)},unListenProgress:function(a){a=sjcl.mode.ccm.G.indexOf(a);-1k)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;4>f&&l>>>8*f;f++);f<15-k&&(f=15-k);c=h.clamp(c, +8*(15-f));b=sjcl.mode.ccm.V(a,b,c,d,e,f);g=sjcl.mode.ccm.C(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),k=f.clamp(b,h-e),l=f.bitSlice(b,h-e),h=(h-e)/8;if(7>g)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;4>b&&h>>>8*b;b++);b<15-g&&(b=15-g);c=f.clamp(c,8*(15-b));k=sjcl.mode.ccm.C(a,k,c,l,e,b);a=sjcl.mode.ccm.V(a,k.data,c,d,e,b);if(!f.equal(k.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match"); +return k.data},na:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,k=h.i;d=[h.partial(8,(b.length?64:0)|d-2<<2|f-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length)for(c=h.bitLength(b)/8,65279>=c?g=[h.partial(16,c)]:0xffffffff>=c&&(g=h.concat([h.partial(16,65534)],[c])),g=h.concat(g,b),b=0;be||16n&&(sjcl.mode.ccm.fa(g/ +k),n+=m),c[3]++,e=a.encrypt(c),b[g]^=e[0],b[g+1]^=e[1],b[g+2]^=e[2],b[g+3]^=e[3];return{tag:d,data:h.clamp(b,l)}}}; +sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(128!==sjcl.bitArray.bitLength(c))throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.S,k=sjcl.bitArray,l=k.i,n=[0,0,0,0];c=h(a.encrypt(c));var m,p=[];d=d||[];e=e||64;for(g=0;g+4e.bitLength(c)&&(h=f(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));g=f(g,c); +return a.encrypt(f(d(f(h,d(h))),g))},S:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}}; +sjcl.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var f=b.slice(0);b=sjcl.bitArray;d=d||[];a=sjcl.mode.gcm.C(!0,a,f,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var f=b.slice(0),g=sjcl.bitArray,h=g.bitLength(f);e=e||128;d=d||[];e<=h?(b=g.bitSlice(f,h-e),f=g.bitSlice(f,0,h-e)):(b=f,f=[]);a=sjcl.mode.gcm.C(!1,a,f,d,c,e);if(!g.equal(a.tag,b))throw new sjcl.exception.corrupt("gcm: tag doesn't match");return a.data},ka:function(a,b){var c,d,e,f,g,h=sjcl.bitArray.i;e=[0,0, +0,0];f=b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,f));g=0!==(f[3]&1);for(d=3;0>>1|(f[d-1]&1)<<31;f[0]>>>=1;g&&(f[0]^=-0x1f000000)}return e},j:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;de&&(a=b.hash(a));for(d=0;dd||0>c)throw new sjcl.exception.invalid("invalid params to pbkdf2");"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,k,l=[],n=sjcl.bitArray;for(k=1;32*l.length<(d||1);k++){e=f=a.encrypt(n.concat(b,[k]));for(g=1;gg;g++)e.push(0x100000000*Math.random()|0);for(g=0;g=1<this.o&&(this.o= +f);this.P++;this.b=sjcl.hash.sha256.hash(this.b.concat(e));this.L=new sjcl.cipher.aes(this.b);for(d=0;4>d&&(this.h[d]=this.h[d]+1|0,!this.h[d]);d++);}for(d=0;d>>1;this.c[g].update([d,this.N++,2,b,f,a.length].concat(a))}break;case "string":void 0===b&&(b=a.length);this.c[g].update([d,this.N++,3,b,f,a.length]);this.c[g].update(a);break;default:k=1}if(k)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");this.m[g]+=b;this.f+=b;h===this.u&&(this.isReady()!==this.u&&A("seeded",Math.max(this.o,this.f)),A("progress",this.getProgress()))}, +isReady:function(a){a=this.T[void 0!==a?a:this.M];return this.o&&this.o>=a?this.m[0]>this.ba&&(new Date).valueOf()>this.Z?this.J|this.I:this.I:this.f>=a?this.J|this.u:this.u},getProgress:function(a){a=this.T[a?a:this.M];return this.o>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.D){this.a={loadTimeCollector:B(this,this.ma),mouseCollector:B(this,this.oa),keyboardCollector:B(this,this.la),accelerometerCollector:B(this,this.ea),touchCollector:B(this,this.qa)};if(window.addEventListener)window.addEventListener("load", +this.a.loadTimeCollector,!1),window.addEventListener("mousemove",this.a.mouseCollector,!1),window.addEventListener("keypress",this.a.keyboardCollector,!1),window.addEventListener("devicemotion",this.a.accelerometerCollector,!1),window.addEventListener("touchmove",this.a.touchCollector,!1);else if(document.attachEvent)document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector);else throw new sjcl.exception.bug("can't attach event"); +this.D=!0}},stopCollectors:function(){this.D&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,!1),window.removeEventListener("mousemove",this.a.mouseCollector,!1),window.removeEventListener("keypress",this.a.keyboardCollector,!1),window.removeEventListener("devicemotion",this.a.accelerometerCollector,!1),window.removeEventListener("touchmove",this.a.touchCollector,!1)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove", +this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.D=!1)},addEventListener:function(a,b){this.K[a][this.ga++]=b},removeEventListener:function(a,b){var c,d,e=this.K[a],f=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&f.push(d);for(c=0;cb&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a.L.encrypt(a.h)} +function B(a,b){return function(){b.apply(a,arguments)}}sjcl.random=new sjcl.prng(6); +a:try{var D,E,F,G;if(G="undefined"!==typeof module&&module.exports){var H;try{H=require("crypto")}catch(a){H=null}G=E=H}if(G&&E.randomBytes)D=E.randomBytes(128),D=new Uint32Array((new Uint8Array(D)).buffer),sjcl.random.addEntropy(D,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){F=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(F);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(F); +else break a;sjcl.random.addEntropy(F,1024,"crypto['getRandomValues']")}}catch(a){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(a))} +sjcl.json={defaults:{v:1,iter:1E4,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},ja:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.g({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.g(f,c);c=f.adata;"string"===typeof f.salt&&(f.salt=sjcl.codec.base64.toBits(f.salt));"string"===typeof f.iv&&(f.iv=sjcl.codec.base64.toBits(f.iv));if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||"string"===typeof a&&100>=f.iter||64!==f.ts&&96!==f.ts&&128!==f.ts||128!==f.ks&&192!==f.ks&&0x100!==f.ks||2>f.iv.length|| +4=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&0x100!==b.ks||!b.iv||2>b.iv.length||4 + + + +
+ + Chat +
+ + + + + + + + + + + +
+ + + + +
+ +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/chatto/src/main/resources/templates/crypto.html b/chatto/src/main/resources/templates/crypto.html new file mode 100644 index 0000000..026bc1b --- /dev/null +++ b/chatto/src/main/resources/templates/crypto.html @@ -0,0 +1,18 @@ + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/chatto/src/main/resources/templates/fragments/head.html b/chatto/src/main/resources/templates/fragments/head.html new file mode 100644 index 0000000..37a6d90 --- /dev/null +++ b/chatto/src/main/resources/templates/fragments/head.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + + Layout Generic Title + + + + + + + + + \ No newline at end of file diff --git a/chatto/src/main/resources/templates/login.html b/chatto/src/main/resources/templates/login.html index c0a2fc6..ccc2936 100644 --- a/chatto/src/main/resources/templates/login.html +++ b/chatto/src/main/resources/templates/login.html @@ -1,17 +1,24 @@ + -Title +
+ Login +
+ - -
Login Page
- +
+
+ - - - - -

-

- - + Please Login +
+ Invalid username or password. +
+
+ You have been logged out. +
+ + + +

+ + +

+ + +
+ + + + \ No newline at end of file diff --git a/chatto/src/main/resources/templates/registration.html b/chatto/src/main/resources/templates/registration.html index 4f328fc..4f6eb61 100644 --- a/chatto/src/main/resources/templates/registration.html +++ b/chatto/src/main/resources/templates/registration.html @@ -11,6 +11,7 @@ type="text" name="username" id="username">



+ diff --git a/chatto/src/main/resources/templates/restLogout.html b/chatto/src/main/resources/templates/restLogout.html new file mode 100644 index 0000000..3624be9 --- /dev/null +++ b/chatto/src/main/resources/templates/restLogout.html @@ -0,0 +1,12 @@ + + + + +Insert title here + + +
+ +
+ + \ No newline at end of file diff --git a/chatto/src/test/java/org/ros/chatto/ChattoApplicationTests.java b/chatto/src/test/java/org/ros/chatto/ChattoApplicationTests.java index cf039ee..b8dfbfb 100644 --- a/chatto/src/test/java/org/ros/chatto/ChattoApplicationTests.java +++ b/chatto/src/test/java/org/ros/chatto/ChattoApplicationTests.java @@ -52,19 +52,16 @@ public class ChattoApplicationTests { // chatMessageRepository.save(chatMessage); // } - @Test - public void testSave() { - ChatUser fromUser = new ChatUser(); - fromUser = userRepository.findByUserName("hmm"); - ChatUser toUser = new ChatUser(); - toUser = userRepository.findByUserName("user2"); - ChatMessage chatMessage = new ChatMessage(); - chatMessage.setMessage("Hello!"); - chatMessage.setFromUser(fromUser); - chatMessage.setToUser(toUser); - -// chatMessageRepository.save(chatMessage); - when(mockChatMessageRepository.save(any(ChatMessage.class))).thenReturn(chatMessage); - verify(mockChatMessageRepository, times(1)).save(Mockito.any(ChatMessage.class)); - } + /* + * @Test public void testSave() { ChatUser fromUser = new ChatUser(); fromUser = + * userRepository.findByUserName("hmm"); ChatUser toUser = new ChatUser(); + * toUser = userRepository.findByUserName("user2"); ChatMessage chatMessage = + * new ChatMessage(); chatMessage.setMessage("Hello!"); + * chatMessage.setFromUser(fromUser); chatMessage.setToUser(toUser); + * + * // chatMessageRepository.save(chatMessage); + * when(mockChatMessageRepository.save(any(ChatMessage.class))).thenReturn( + * chatMessage); verify(mockChatMessageRepository, + * times(1)).save(Mockito.any(ChatMessage.class)); } + */ }