Architecture improvements and validation
Improved system architecture and added sample regex validation to registration
This commit is contained in:
parent
4607ae5e17
commit
acbacc8fa8
@ -100,18 +100,20 @@
|
||||
<artifactId>cache-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId>
|
||||
<version>2.2.11</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-core</artifactId> <version>2.2.11</version> </dependency> -->
|
||||
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5 -->
|
||||
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>2.2.11</version>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-core</artifactId>
|
||||
<version>2.2.11</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5 -->
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
@ -124,6 +126,7 @@
|
||||
<!-- <dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId>
|
||||
<version>1.1.0</version> </dependency> -->
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -31,7 +31,7 @@ public final class RESTAuthenticationEntryPoint
|
||||
response.addHeader("WWW-Authenticate", "Basic realm=" +getRealmName());
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
PrintWriter writer = response.getWriter();
|
||||
writer.println("HTTP Status 401 - " + authEx.getMessage());
|
||||
writer.println("HTTP ApplicationStatus 401 - " + authEx.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,14 +1,25 @@
|
||||
package org.ros.chatto.controller;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
import org.ros.chatto.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/admin")
|
||||
public class AdminController {
|
||||
|
||||
@RequestMapping
|
||||
public String viewManageUsers() {
|
||||
return "/admin/home";
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@RequestMapping
|
||||
public ModelAndView viewManageUsers(Principal principal) {
|
||||
ModelAndView modelAndView = new ModelAndView("/admin/home");
|
||||
modelAndView.addObject("user", new String());
|
||||
modelAndView.addObject("userNames", userService.getAllRegularUsers());
|
||||
return modelAndView;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
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.dto.ReencryptionDTO;
|
||||
import org.ros.chatto.model.ChatMessage;
|
||||
import org.ros.chatto.service.ChatService;
|
||||
import org.ros.chatto.service.UserService;
|
||||
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/admin")
|
||||
public class AdminRESTController {
|
||||
@Autowired
|
||||
private ChatService chatService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@PostMapping(value = "/post/re-encrypt", consumes = { "application/json" })
|
||||
@ResponseBody
|
||||
public ResponseEntity<ReencryptionDTO> reencryptMessages(@RequestBody List<ReencryptionDTO> reencryptionDTOs,
|
||||
Principal principal) {
|
||||
if (reencryptionDTOs.size() > 0) {
|
||||
chatService.reencryptMessages(reencryptionDTOs);
|
||||
}
|
||||
return new ResponseEntity<ReencryptionDTO>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get/messages/{userName}")
|
||||
@ResponseBody
|
||||
public List<ReencryptionDTO> sendAllMessages(@PathVariable String userName, Principal principal) {
|
||||
List<ReencryptionDTO> reencryptionDTOs = chatService.getAllMessagesForReencryption(principal.getName(), userName);
|
||||
return reencryptionDTOs;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get/messages/{userName}/{lastMessageTime}")
|
||||
@ResponseBody
|
||||
public List<ChatMessageDTO> 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<ChatMessageDTO> chatMessageDTOs = chatService.getNewMessages(principal.getName(), userName, date);
|
||||
return chatMessageDTOs;
|
||||
}
|
||||
|
||||
@GetMapping("/get/users")
|
||||
public List<String> getAllOtherUsers(Principal principal) {
|
||||
return userService.findAllOtherUsers(principal.getName());
|
||||
}
|
||||
}
|
||||
|
||||
//public ResponseEntity<List<ChatMessage>> getMessages(@PathVariable String userName, Principal principal) {
|
||||
////List<ChatMessage> chatMessages = chatMessageRepository.getAllMessages(principal.getName(), userName);
|
||||
//
|
||||
//// return posts.stream()
|
||||
//// .map(post -> convertToDto(post))
|
||||
//// .collect(Collectors.toList());
|
||||
//return new ResponseEntity<List<ChatMessage>>(chatMessages, HttpStatus.OK);
|
||||
//}
|
@ -8,6 +8,8 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.ros.chatto.dto.ChatMessageDTO;
|
||||
import org.ros.chatto.dto.MessageCipherDTO;
|
||||
import org.ros.chatto.dto.ReencryptionDTO;
|
||||
import org.ros.chatto.model.MessageCipher;
|
||||
import org.ros.chatto.service.ChatService;
|
||||
import org.ros.chatto.service.UserService;
|
||||
@ -19,6 +21,7 @@ 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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@ -27,14 +30,14 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class ChatMessageController {
|
||||
@Autowired
|
||||
private ChatService chatService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@PostMapping(value = "/post/message", consumes = { "application/json" })
|
||||
@ResponseBody
|
||||
public ResponseEntity<ChatMessageDTO> newMessage(@RequestBody ChatMessageDTO chatMessageDTO, Principal principal) {
|
||||
MessageCipher messageCipher = chatMessageDTO.getMessageCipher();
|
||||
MessageCipherDTO messageCipher = chatMessageDTO.getMessageCipher();
|
||||
String fromUser = principal.getName();
|
||||
String toUser = chatMessageDTO.getToUser();
|
||||
System.out.println("Message cipher = " + messageCipher);
|
||||
@ -46,31 +49,41 @@ public class ChatMessageController {
|
||||
@ResponseBody
|
||||
public List<ChatMessageDTO> sendAllMessages(@PathVariable String userName, Principal principal) {
|
||||
List<ChatMessageDTO> chatMessageDTOs = chatService.getAllMessages(principal.getName(), userName);
|
||||
return chatMessageDTOs;
|
||||
return chatMessageDTOs;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get/messages/{userName}", params = { "page", "size" })
|
||||
@ResponseBody
|
||||
public List<ChatMessageDTO> findPaginated(@RequestParam("page") int page, @RequestParam("size") int size,
|
||||
@PathVariable String userName, Principal principal) {
|
||||
List<ChatMessageDTO> chatMessageDTOs = chatService.getMessagePage(principal.getName(), userName, page, size);
|
||||
return chatMessageDTOs;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get/messages/{userName}/{lastMessageTime}")
|
||||
@ResponseBody
|
||||
public List<ChatMessageDTO> sendNewMessages(@PathVariable String userName, @PathVariable String lastMessageTime, Principal principal) {
|
||||
System.out.println("Last message time = " + lastMessageTime );
|
||||
public List<ChatMessageDTO> 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/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<ChatMessageDTO> chatMessageDTOs = chatService.getNewMessages(principal.getName(), userName, date);
|
||||
return chatMessageDTOs;
|
||||
return chatMessageDTOs;
|
||||
}
|
||||
|
||||
@GetMapping("/get/users")
|
||||
public List<String> getAllOtherUsers(Principal principal)
|
||||
{
|
||||
public List<String> getAllOtherUsers(Principal principal) {
|
||||
return userService.findAllOtherUsers(principal.getName());
|
||||
}
|
||||
}
|
||||
|
@ -62,31 +62,33 @@ public class DemoRestController {
|
||||
public ChatUser getUser() {
|
||||
return userRepository.findByUserName("hmm");
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/user")
|
||||
public ChatUser currentUserName(Principal principal) {
|
||||
ChatUser user = userRepository.findByUserName(principal.getName());
|
||||
return user;
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@GetMapping("/roles")
|
||||
public List<UserRole> getAllRoles()
|
||||
{
|
||||
public List<UserRole> getAllRoles() {
|
||||
return userRoleRepository.findAll();
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/ciphers")
|
||||
public List<MessageCipher> getAllCiphers()
|
||||
{
|
||||
public List<MessageCipher> getAllCiphers() {
|
||||
return messageCipherRepository.findAll();
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/messages")
|
||||
public List<ChatMessage> getAllMessages()
|
||||
{
|
||||
public List<ChatMessage> getAllMessages() {
|
||||
return chatMessageRepository.findAll();
|
||||
}
|
||||
|
||||
@GetMapping("/regular-users")
|
||||
public List<String> getAllRegularUsers() {
|
||||
return userRoleRepository.getAllRegularUser();
|
||||
}
|
||||
|
||||
// @RequestMapping(value = "/", method = RequestMethod.POST)
|
||||
// public ResponseEntity<Car> update(@RequestBody Car car) {
|
||||
//
|
||||
@ -97,28 +99,27 @@ public class DemoRestController {
|
||||
// // TODO: call persistence layer to update
|
||||
// return new ResponseEntity<Car>(car, HttpStatus.OK);
|
||||
// }
|
||||
|
||||
@PostMapping(value="/post-message", consumes = {"application/json"})
|
||||
public ResponseEntity<MessageCipher> postMessage(@RequestBody MessageCipher messageCipher)
|
||||
{
|
||||
|
||||
@PostMapping(value = "/post-message", consumes = { "application/json" })
|
||||
public ResponseEntity<MessageCipher> postMessage(@RequestBody MessageCipher messageCipher) {
|
||||
System.out.println("Message cipher = " + messageCipher);
|
||||
messageCipherRepository.save(messageCipher);
|
||||
return new ResponseEntity<MessageCipher>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/logout")
|
||||
public ModelAndView logoutPage()
|
||||
{
|
||||
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";
|
||||
|
||||
@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";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,34 +1,37 @@
|
||||
package org.ros.chatto.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.ros.chatto.dto.UserRegistrationDTO;
|
||||
import org.ros.chatto.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@Controller
|
||||
public class RegisterController {
|
||||
|
||||
public class RegistrationController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@GetMapping("/registration")
|
||||
public ModelAndView registrationForm()
|
||||
{
|
||||
ModelAndView modelAndView = new ModelAndView("registration");
|
||||
modelAndView.addObject("userDTO",new UserRegistrationDTO());
|
||||
return modelAndView;
|
||||
public String registrationForm(Model model) {
|
||||
model.addAttribute("userRegistrationDTO", new UserRegistrationDTO());
|
||||
return "registration";
|
||||
}
|
||||
|
||||
@PostMapping("/perform_registration")
|
||||
public ModelAndView performRegistration(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, @ModelAttribute("userDTO") UserRegistrationDTO userRegistrationDTO)
|
||||
{
|
||||
ModelAndView modelAndView = new ModelAndView("user/home");
|
||||
public String performRegistration(Model model,
|
||||
@ModelAttribute("userRegistrationDTO") @Valid UserRegistrationDTO userRegistrationDTO, BindingResult bindingResult) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
System.out.println("Input has errors!");
|
||||
return "registration";
|
||||
}
|
||||
userService.registerUser(userRegistrationDTO);
|
||||
return modelAndView;
|
||||
return "user/home";
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,6 @@ import lombok.Data;
|
||||
@Data
|
||||
public class ChatMessageDTO {
|
||||
private String toUser, fromUser;
|
||||
private MessageCipher messageCipher;
|
||||
private MessageCipherDTO messageCipher;
|
||||
private Date messageTime;
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
package org.ros.chatto.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class MessageCipherDTO {
|
||||
private String iv;
|
||||
private int v;
|
||||
@JsonProperty("iter")
|
||||
private int iterations;
|
||||
@JsonProperty("ks")
|
||||
private int keySize;
|
||||
@JsonProperty("ts")
|
||||
private int tagSize;
|
||||
private String mode;
|
||||
private String adata;
|
||||
private String cipher;
|
||||
private String salt;
|
||||
@JsonProperty("ct")
|
||||
private String cipherText;
|
||||
}
|
14
chatto/src/main/java/org/ros/chatto/dto/ReencryptionDTO.java
Normal file
14
chatto/src/main/java/org/ros/chatto/dto/ReencryptionDTO.java
Normal file
@ -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 ReencryptionDTO {
|
||||
private String toUser, fromUser;
|
||||
private MessageCipher messageCipher;
|
||||
private Date messageTime;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
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;
|
||||
}
|
@ -1,23 +1,35 @@
|
||||
package org.ros.chatto.dto;
|
||||
|
||||
import javax.persistence.Transient;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
public class UserRegistrationDTO {
|
||||
@Size(min = 4, max = 10, message = "Username must be between 4 and 10 characters")
|
||||
@NotBlank(message = " Username should not be blank")
|
||||
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "Username must be alphanumeric")
|
||||
private String userName;
|
||||
@Transient
|
||||
@Size(min = 4, max = 75, message = "Username must be between 4 and 75 characters")
|
||||
@NotBlank(message = " Password should not be blank")
|
||||
@Pattern(regexp = "^.*(?=.{6,})(?=.*d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$", message = "Invalid password format")
|
||||
private String password;
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package org.ros.chatto.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(name="status")
|
||||
public class ApplicationStatus {
|
||||
@Id
|
||||
private int id;
|
||||
private String name;
|
||||
@Column(name="value")
|
||||
private boolean done;
|
||||
}
|
@ -20,7 +20,7 @@ this is what the json will look like*/
|
||||
@Entity
|
||||
@Table(name = "message_ciphers")
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
@JsonIgnoreProperties(value = { "id"}, allowGetters = false)
|
||||
//@JsonIgnoreProperties(value = { "id"}, allowGetters = false)
|
||||
public class MessageCipher {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
@ -1,9 +1,11 @@
|
||||
package org.ros.chatto.repository;
|
||||
|
||||
import java.awt.print.Pageable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.ros.chatto.model.ChatMessage;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@ -22,4 +24,14 @@ public interface ChatMessageRepository extends JpaRepository<ChatMessage, Long>
|
||||
+ "(m.fromUser.userName = ?1 or m.fromUser.userName = ?2) and"
|
||||
+ "(m.messageTime > ?3) order by m.messageTime asc")
|
||||
public List<ChatMessage> getNewMessages(String fromUser, String toUser, Date lastMessageTime);
|
||||
|
||||
@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<ChatMessage> getAllMessages(String fromUser, String toUser, PageRequest pageRequest);
|
||||
|
||||
|
||||
// DELETE FROM Country c WHERE c.population < :p
|
||||
// @Query("delete from ChatMessage m where where (m.toUser.userName = ?1 or m.toUser.userName = ?2) and"
|
||||
// + " (m.fromUser.userName = ?1 or m.fromUser.userName = ?2)")
|
||||
// public void deleteConversation(String fromUser, String toUser);
|
||||
}
|
||||
|
@ -14,4 +14,7 @@ public interface UserRoleRepository extends JpaRepository<UserRole, Long>{
|
||||
|
||||
@Query("select ur from UserRole ur where ur.user.userName = ?1")
|
||||
public List<UserRole> findByUser(String username);
|
||||
|
||||
@Query("select ur.user.userName from UserRole ur where ur.role.roleID = 2")
|
||||
public List<String> getAllRegularUser();
|
||||
}
|
||||
|
@ -4,14 +4,23 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.ros.chatto.dto.ChatMessageDTO;
|
||||
import org.ros.chatto.model.MessageCipher;
|
||||
import org.ros.chatto.dto.MessageCipherDTO;
|
||||
import org.ros.chatto.dto.ReencryptionDTO;
|
||||
import org.ros.chatto.model.ChatMessage;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
public interface ChatService {
|
||||
void saveNewMessage(String fromUser, String toUser , MessageCipher messageCipher);
|
||||
|
||||
List<ChatMessageDTO> getAllMessages(String fromUser, String toUser);
|
||||
|
||||
List<ChatMessageDTO> getMessagePage(int page, int size);
|
||||
|
||||
List<ChatMessageDTO> getNewMessages(String fromUser, String toUser, Date lastMessageTime);
|
||||
public void saveNewMessage(String fromUser, String toUser, MessageCipherDTO messageCipherDTO);
|
||||
|
||||
public List<ChatMessageDTO> getAllMessages(String fromUser, String toUser);
|
||||
|
||||
public List<ChatMessageDTO> getMessagePage(String fromUser, String toUser, int page, int size);
|
||||
|
||||
public List<ChatMessageDTO> getNewMessages(String fromUser, String toUser, Date lastMessageTime);
|
||||
|
||||
public void reencryptMessages(List<ReencryptionDTO> reencryptionDTOs);
|
||||
|
||||
public List<ReencryptionDTO> getAllMessagesForReencryption(String fromUser, String toUser);
|
||||
|
||||
public List<ChatMessageDTO> getAllMessages(String name, String userName, PageRequest pageRequest);
|
||||
}
|
||||
|
@ -2,8 +2,13 @@ package org.ros.chatto.service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import org.ros.chatto.dto.ChatMessageDTO;
|
||||
import org.ros.chatto.dto.MessageCipherDTO;
|
||||
import org.ros.chatto.dto.ReencryptionDTO;
|
||||
import org.ros.chatto.model.ChatMessage;
|
||||
import org.ros.chatto.model.ChatUser;
|
||||
import org.ros.chatto.model.MessageCipher;
|
||||
@ -29,8 +34,9 @@ public class ChatServiceImpl implements ChatService {
|
||||
@Autowired
|
||||
MyConversionService myConversionService;
|
||||
|
||||
public void saveNewMessage(String fromUserName, String toUserName, MessageCipher messageCipher) {
|
||||
public void saveNewMessage(String fromUserName, String toUserName, MessageCipherDTO messageCipherDTO) {
|
||||
|
||||
MessageCipher messageCipher = myConversionService.convertToMessageCipher(messageCipherDTO);
|
||||
ChatUser fromUser = userRepository.findByUserName(fromUserName);
|
||||
ChatUser toUser = userRepository.findByUserName(toUserName);
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
@ -49,13 +55,19 @@ public class ChatServiceImpl implements ChatService {
|
||||
List<ChatMessageDTO> chatMessageDTOs = myConversionService.convertToChatMessageDTOs(chatMessages);
|
||||
return chatMessageDTOs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReencryptionDTO> getAllMessagesForReencryption(String fromUser, String toUser) {
|
||||
return myConversionService.convertToReencryptionDTOs(chatMessageRepository.getAllMessages(fromUser, toUser));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatMessageDTO> getMessagePage(int page, int size) {
|
||||
public List<ChatMessageDTO> getMessagePage(String fromUser, String toUser, int page, int size) {
|
||||
// Sort sort = Sort
|
||||
Page<ChatMessage> chatMessages = chatMessageRepository.findAll(PageRequest.of(page, size));
|
||||
List<ChatMessageDTO> chatMessageDTOs = myConversionService.convertToChatMessageDTOs(chatMessages);
|
||||
return chatMessageDTOs;
|
||||
// Page<ChatMessage> chatMessages = chatMessageRepository.getAllMessages(fromUser, toUser,PageRequest.of(page, size));
|
||||
// List<ChatMessageDTO> chatMessageDTOs = myConversionService.convertToChatMessageDTOs(chatMessages);
|
||||
// return chatMessageDTOs;
|
||||
return myConversionService.convertToChatMessageDTOs(chatMessageRepository.getAllMessages(fromUser, toUser,PageRequest.of(page, size)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -65,4 +77,20 @@ public class ChatServiceImpl implements ChatService {
|
||||
// List<ChatMessageDTO> chatMessageDTOs
|
||||
return myConversionService.convertToChatMessageDTOs(chatMessages);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void reencryptMessages(List<ReencryptionDTO> reencryptionDTOs) {
|
||||
// TODO Auto-generated method stub
|
||||
// chatMessageRepository.saveAll(chatMessages);
|
||||
List<MessageCipher> messageCiphers = reencryptionDTOs.stream().map(reencryptionDTO -> reencryptionDTO.getMessageCipher()).collect(Collectors.toList());
|
||||
messageCipherRepository.saveAll(messageCiphers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatMessageDTO> getAllMessages(String name, String userName, PageRequest pageRequest) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package org.ros.chatto.service;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
@ -10,9 +9,15 @@ import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.ros.chatto.ChattoApplication;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.ros.chatto.model.ApplicationStatus;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
@ -51,6 +56,12 @@ public class DBInitializerService {
|
||||
|
||||
private Connection connection;
|
||||
|
||||
@PersistenceContext
|
||||
EntityManager entityManager;
|
||||
|
||||
private final String tablesCreatedKey = "tables_created";
|
||||
private final String rolesPopulatedKey = "roles_populated";
|
||||
|
||||
// public DBInitializerService(Connection connection) {
|
||||
// this.connection = connection;
|
||||
// // TODO Auto-generated constructor stub
|
||||
@ -125,9 +136,29 @@ public class DBInitializerService {
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void doSomethingAfterStartup() throws SQLException, IOException {
|
||||
// setProperties();
|
||||
|
||||
System.out.println("Hello world, I have just started up");
|
||||
System.out.println("Initializing database");
|
||||
|
||||
List<ApplicationStatus> applicationStatusList = getStatusList();
|
||||
Map<String, Boolean> statusMap = listToMap(applicationStatusList);
|
||||
|
||||
// applicationStatus.
|
||||
connectDB();
|
||||
/*
|
||||
* if (statusMap.get(tablesCreatedKey) == null ||
|
||||
* !statusMap.get(tablesCreatedKey)) {
|
||||
* System.out.println("Initializing database"); if (getNumTables() == 0) {
|
||||
* populateDB(); System.out.println("Tables created"); } ApplicationStatus
|
||||
* status = new ApplicationStatus(); status.setName(tablesCreatedKey);
|
||||
* status.setDone(true);
|
||||
*
|
||||
* }
|
||||
*
|
||||
* if (statusMap.get(rolesPopulatedKey) == null ||
|
||||
* !statusMap.get(rolesPopulatedKey)) { System.out.println("Populating roles");
|
||||
* }
|
||||
*/
|
||||
|
||||
if (getNumTables() == 0)
|
||||
populateDB();
|
||||
closeConnection();
|
||||
@ -163,7 +194,7 @@ public class DBInitializerService {
|
||||
|
||||
public void setProperties() throws IOException {
|
||||
// InputStream input = ChattoApplication.class.getClassLoader().getResourceAsStream("messages.properties");
|
||||
OutputStream outputStream = new FileOutputStream("messages.properties");
|
||||
OutputStream outputStream = new FileOutputStream("messages.properties");
|
||||
// FileInputStream in = new FileInputStream("First.properties");
|
||||
// Properties props = new Properties();
|
||||
// props.load(in);
|
||||
@ -175,14 +206,14 @@ public class DBInitializerService {
|
||||
// out.close();
|
||||
Properties prop = new Properties();
|
||||
System.out.println("Hello from setProperties");
|
||||
|
||||
|
||||
prop.setProperty("test.bindAddress", bindAddress);
|
||||
prop.store(outputStream, null);
|
||||
// if (input == null) {
|
||||
// System.out.println("Sorry, unable to find messages.properties");
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
// load a properties file from class path, inside static method
|
||||
// prop.load(input);
|
||||
// Object object = prop.setProperty("test.bindAddress", bindAddress);
|
||||
@ -191,6 +222,23 @@ public class DBInitializerService {
|
||||
// prop.store(object, comments);
|
||||
}
|
||||
|
||||
List<ApplicationStatus> getStatusList() {
|
||||
// List<Object[]> persons = entityManager.createNativeQuery("SELECT * FROM Person" ).getResultList();
|
||||
List<ApplicationStatus> applicationStatus = entityManager
|
||||
.createQuery("from ApplicationStatus s", ApplicationStatus.class).getResultList();
|
||||
applicationStatus.stream().forEach(status -> status.getName());
|
||||
// System.out.println(applicationStatus.get(0).getName() + applicationStatus.get(0).isDone());
|
||||
return applicationStatus;
|
||||
}
|
||||
|
||||
Map<String, Boolean> listToMap(List<ApplicationStatus> applicationStatusList) {
|
||||
Map<String, Boolean> statusMap = new HashMap<>();
|
||||
for (ApplicationStatus applicationStatus : applicationStatusList) {
|
||||
statusMap.put(applicationStatus.getName(), applicationStatus.isDone());
|
||||
}
|
||||
return statusMap;
|
||||
}
|
||||
|
||||
public void closeConnection() throws SQLException {
|
||||
connection.close();
|
||||
}
|
||||
|
@ -5,7 +5,10 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.ros.chatto.dto.ChatMessageDTO;
|
||||
import org.ros.chatto.dto.MessageCipherDTO;
|
||||
import org.ros.chatto.dto.ReencryptionDTO;
|
||||
import org.ros.chatto.model.ChatMessage;
|
||||
import org.ros.chatto.model.MessageCipher;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -42,6 +45,18 @@ public class MyConversionService {
|
||||
return chatMessageDTO;
|
||||
}
|
||||
|
||||
public ChatMessage convertToChatMessage(ChatMessageDTO chatMessageDTO)
|
||||
{
|
||||
ChatMessage chatMessage = modelMapper.map(chatMessageDTO, ChatMessage.class);
|
||||
return chatMessage;
|
||||
}
|
||||
|
||||
public MessageCipher convertToMessageCipher(MessageCipherDTO messageCipherDTO)
|
||||
{
|
||||
MessageCipher messageCipher = modelMapper.map(messageCipherDTO, MessageCipher.class);
|
||||
return messageCipher;
|
||||
}
|
||||
|
||||
public List<ChatMessageDTO> convertToChatMessageDTOs(List<ChatMessage> chatMessages)
|
||||
{
|
||||
return chatMessages.stream()
|
||||
@ -49,6 +64,33 @@ public class MyConversionService {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public ReencryptionDTO convertToReencryptionDTO(ChatMessage chatMessage)
|
||||
{
|
||||
ReencryptionDTO reencryptionDTO = modelMapper.map(chatMessage, ReencryptionDTO.class);
|
||||
return reencryptionDTO;
|
||||
}
|
||||
|
||||
public ChatMessage convertToChatMessage(ReencryptionDTO reencryptionDTO)
|
||||
{
|
||||
ChatMessage chatMessage = modelMapper.map(reencryptionDTO, ChatMessage.class);
|
||||
return chatMessage;
|
||||
}
|
||||
|
||||
public List<ReencryptionDTO> convertToReencryptionDTOs(List<ChatMessage> chatMessages)
|
||||
{
|
||||
return chatMessages.stream()
|
||||
.map(chatMessage -> convertToReencryptionDTO(chatMessage))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public Iterable<ChatMessage> convertoToChatMessages(List<ChatMessageDTO> chatMessageDTOs)
|
||||
{
|
||||
|
||||
return chatMessageDTOs.stream()
|
||||
.map(chatMessageDTO -> convertToChatMessage(chatMessageDTO)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<ChatMessageDTO> convertToChatMessageDTOs(Page<ChatMessage> chatMessages)
|
||||
{
|
||||
return chatMessages.stream()
|
||||
|
@ -11,4 +11,5 @@ public interface UserService {
|
||||
public void saveChatUser(ChatUser user);
|
||||
public List<String> findAllOtherUsers(String userName);
|
||||
public void registerUser(UserRegistrationDTO userRegistrationDTO);
|
||||
public List<String> getAllRegularUsers();
|
||||
}
|
||||
|
@ -62,4 +62,10 @@ public class UserServiceImpl implements UserService{
|
||||
return userRepositoryCustom.getAllUserNames(userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllRegularUsers() {
|
||||
// TODO Auto-generated method stub
|
||||
return userRoleRepository.getAllRegularUser();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
num-tables = SELECT COUNT(*) as num_tables FROM information_schema.tables WHERE table_schema = ? and TABLE_TYPE='BASE TABLE'
|
||||
num-tables = SELECT COUNT(*) as num_tables FROM information_schema.tables WHERE table_schema = ? and TABLE_TYPE='BASE TABLE'
|
||||
#tables-created =
|
135
chatto/src/main/resources/static/js/admin.js
Normal file
135
chatto/src/main/resources/static/js/admin.js
Normal file
@ -0,0 +1,135 @@
|
||||
console.log('Hello world!');
|
||||
|
||||
var getAllMessagesURL = `http://${hostAddress}/api/admin/get/messages/`; //hostAddress set in thymeleaf backend
|
||||
var reencryptURL = `http://${hostAddress}/api/admin/post/re-encrypt`;
|
||||
var getAllRegularUsersURL = `http://${hostAddress}/api/regular-users`;
|
||||
var username = sessionStorage.getItem('username');
|
||||
var password = sessionStorage.getItem('password');
|
||||
var authToken = 'Basic ' + btoa(username + ":" + password);
|
||||
var iterations = 10000;
|
||||
|
||||
function handleAddToAdminForm() {
|
||||
document.getElementById('addUserToAdminForm').addEventListener(
|
||||
'submit',
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
getAllRegularUsers()
|
||||
// .then(usernamesArray => {
|
||||
// console.lo
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
function handleChangePassphraseForm() {
|
||||
document.getElementById('changePassphraseForm').addEventListener(
|
||||
'submit',
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
let changePassphraseDropDown = document.getElementById('changePassphraseDropDown');
|
||||
let user = changePassphraseDropDown.value;
|
||||
let passphraseOld = document.getElementById('passphraseOld');
|
||||
let passphraseNew = document.getElementById('passphraseNew');
|
||||
// let messageCipherNew = {};
|
||||
console.log(user);
|
||||
getAllMessages(user)
|
||||
.then(json => {
|
||||
console.log(json);
|
||||
|
||||
return json;
|
||||
})
|
||||
.then(json => {
|
||||
let jsonNew = [];
|
||||
let messageCiphers = [];
|
||||
let chatMessageDTOs = [];
|
||||
if (json.length > 0) {
|
||||
json.forEach(function(obj) {
|
||||
let newObj = obj;
|
||||
let messageID = obj.messageCipher.id;
|
||||
let plainText = sjcl.decrypt(passphraseOld.value, JSON.stringify(obj.messageCipher));
|
||||
let messageCipherNew = sjcl.encrypt(passphraseNew.value, plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations });
|
||||
// let plainText = sjcl.decrypt("password", JSON.stringify(obj.messageCipher));
|
||||
// let messageCipherNew = sjcl.encrypt("password2", plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations });
|
||||
// console.log(messageCipherNew)
|
||||
let messageCipherNewObj = JSON.parse(messageCipherNew);
|
||||
// console.log(messageCipherNewObj);
|
||||
messageCipherNewObj.id = messageID;
|
||||
newObj.messageCipher = messageCipherNewObj;
|
||||
// obj.messageCipher = messageCipherNewObj;
|
||||
// console.log(obj.messageCipher);
|
||||
// console.log(plainText);
|
||||
// console.log(messageCipherNewObj);
|
||||
jsonNew.push(newObj);
|
||||
messageCiphers.push(messageCipherNewObj);
|
||||
|
||||
// let messageCipherJson = JSON.stringify(messageCipherNewObj);
|
||||
let fromUser = sessionStorage.getItem('username');
|
||||
let chatMessageDTO = {
|
||||
"toUser": user,
|
||||
"fromUser": username,
|
||||
"messageCipher": messageCipherNewObj
|
||||
}
|
||||
chatMessageDTOs.push(chatMessageDTO);
|
||||
});
|
||||
// console.log(jsonNew);
|
||||
|
||||
}
|
||||
// sendReencryptedMessages(JSON.stringify(jsonNew));
|
||||
console.log
|
||||
sendReencryptedMessages(JSON.stringify(chatMessageDTOs));
|
||||
// sendReencryptedMessages(JSON.stringify(messageCiphers));
|
||||
|
||||
return jsonNew;
|
||||
})
|
||||
.then(json => {
|
||||
json.forEach(function(obj) {
|
||||
let plainText = sjcl.decrypt("password2", JSON.stringify(obj.messageCipher));
|
||||
console.log(plainText);
|
||||
})
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function getAllMessages(user) {
|
||||
let headers = new Headers();
|
||||
// headers.append('Accept','application/json')
|
||||
// headers.append('Content-Type', 'application/json');
|
||||
headers.append('Authorization', authToken);
|
||||
let response = await fetch(`${getAllMessagesURL}${user}`, {
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
});
|
||||
let data = await response.json();
|
||||
return data;
|
||||
}
|
||||
|
||||
async function getAllRegularUsers() {
|
||||
let headers = new Headers();
|
||||
// headers.append('Accept','application/json')
|
||||
// headers.append('Content-Type', 'application/json');
|
||||
headers.append('Authorization', authToken);
|
||||
let response = await fetch(`${getAllRegularUsersURL}`, {
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
});
|
||||
let data = await response.json();
|
||||
return data;
|
||||
}
|
||||
|
||||
function sendReencryptedMessages(chatMessageDTOs) {
|
||||
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(reencryptURL, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: chatMessageDTOs
|
||||
})
|
||||
.then(response => console.log(response));
|
||||
}
|
||||
|
||||
handleAddToAdminForm();
|
||||
handleChangePassphraseForm();
|
@ -37,68 +37,78 @@ var iterations = 100000;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
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");
|
||||
chatTextArea.scrollTop = chatTextArea.scrollHeight;
|
||||
// let messageCipher = sjcl.encrypt("password", messageContent);
|
||||
let messageCipher = sjcl.encrypt(passphraseInput.value, messageContent,{mode: "gcm",ts: 128, adata: "",iter: iterations});
|
||||
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'));
|
||||
|
||||
let chatInput = document.getElementById('chatInput');
|
||||
let myForm = document.getElementById('chatMessageForm');
|
||||
myForm.addEventListener(
|
||||
'submit',
|
||||
function(e) {
|
||||
e.preventDefault();
|
||||
let user = getSelectedUser();
|
||||
|
||||
})
|
||||
if (!myForm.checkValidity()) {
|
||||
console.log("error");
|
||||
myForm.classList.add('was-validated');
|
||||
return;
|
||||
}
|
||||
myForm.classList.add('was-validated');
|
||||
|
||||
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");
|
||||
chatTextArea.scrollTop = chatTextArea.scrollHeight;
|
||||
// let messageCipher = sjcl.encrypt("password", messageContent);
|
||||
let messageCipher = sjcl.encrypt(passphraseInput.value, messageContent, { mode: "gcm", ts: 128, adata: "", iter: iterations });
|
||||
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"))
|
||||
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));
|
||||
// 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) {
|
||||
@ -151,155 +161,153 @@ function messageSend(chatMessageDTO) {
|
||||
// .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;
|
||||
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;
|
||||
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)
|
||||
}
|
||||
});
|
||||
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;
|
||||
// console.log("Json length = " + json.length);
|
||||
//
|
||||
// if(json.length == 0)
|
||||
// {
|
||||
// console.log("JSON LENGTH IS 0")
|
||||
// }
|
||||
if (json.length > 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 utcDate = obj.messageTime;
|
||||
lastMessageTimeStamp = utcDate;
|
||||
let localDate = new Date(utcDate);
|
||||
let messageLine = sprintf('%s %s: %s ', localDate, obj.fromUser, message);
|
||||
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;
|
||||
// console.log("Json length = " + json.length);
|
||||
//
|
||||
// if(json.length == 0)
|
||||
// {
|
||||
// console.log("JSON LENGTH IS 0")
|
||||
// }
|
||||
if (json.length > 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 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;
|
||||
chatTextArea.scrollTop = chatTextArea.scrollHeight;
|
||||
// console.log('Message log = ' + messageLog);
|
||||
// localDate.``
|
||||
// console.log('localDate = ' + localDate);
|
||||
console.log(messageLine);
|
||||
// chatTextArea.append(obj.fromUser + ": " + message + "\n");
|
||||
chatTextArea.append(messageLine + '\n');
|
||||
messageLog[i++] = messageLine;
|
||||
chatTextArea.scrollTop = chatTextArea.scrollHeight;
|
||||
// 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);
|
||||
});
|
||||
sessionStorage.setItem(this.value, JSON.stringify(messageLog));
|
||||
// sessionStorage.clear();
|
||||
console.log('Last message time = ' + lastMessageTimeStamp);
|
||||
sessionStorage.setItem(this.value + '-time', lastMessageTimeStamp);
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
|
||||
console.log("Stored messages = " + sessionStorage.getItem(this.value));
|
||||
let storedMessages = JSON.parse(sessionStorage.getItem(this.value));
|
||||
let lastMessageTime = sessionStorage.getItem(this.value + '-time');
|
||||
console.log("last message time stamp = " + lastMessageTime);
|
||||
if (lastMessageTime != null) {
|
||||
getNewMessages(this.value, lastMessageTime)
|
||||
.then(json => {
|
||||
console.log(json)
|
||||
if (json.length > 0) {
|
||||
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);
|
||||
console.log("Stored messages = " + sessionStorage.getItem(this.value));
|
||||
let storedMessages = JSON.parse(sessionStorage.getItem(this.value));
|
||||
let lastMessageTime = sessionStorage.getItem(this.value + '-time');
|
||||
console.log("last message time stamp = " + lastMessageTime);
|
||||
if (lastMessageTime != null) {
|
||||
getNewMessages(this.value, lastMessageTime)
|
||||
.then(json => {
|
||||
console.log(json)
|
||||
if (json.length > 0) {
|
||||
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');
|
||||
chatTextArea.scrollTop = chatTextArea.scrollHeight;
|
||||
storedMessages.push(messageLine);
|
||||
// localDate.``
|
||||
// console.log('localDate = ' + localDate);
|
||||
console.log(messageLine);
|
||||
// chatTextArea.append(obj.fromUser + ": " + message + "\n");
|
||||
chatTextArea.append(messageLine + '\n');
|
||||
chatTextArea.scrollTop = chatTextArea.scrollHeight;
|
||||
storedMessages.push(messageLine);
|
||||
|
||||
})
|
||||
sessionStorage.setItem(this.value + '-time', lastMessageTimeStamp);
|
||||
sessionStorage.setItem(this.value, JSON.stringify(storedMessages));
|
||||
console.log("this value stored" + sessionStorage.getItem(this.value))
|
||||
console.log("last message time stamp = " + lastMessageTimeStamp);
|
||||
console.log(sessionStorage.getItem(this.value + '-time'));
|
||||
|
||||
}
|
||||
chatTextArea.textContent = '';
|
||||
console.log("Stored messages 2 = " + storedMessages);
|
||||
storedMessages.forEach(function (messageLine) {
|
||||
chatTextArea.append(messageLine + '\n');
|
||||
chatTextArea.scrollTop = chatTextArea.scrollHeight;
|
||||
})
|
||||
})
|
||||
sessionStorage.setItem(this.value + '-time', lastMessageTimeStamp);
|
||||
sessionStorage.setItem(this.value, JSON.stringify(storedMessages));
|
||||
console.log("this value stored" + sessionStorage.getItem(this.value))
|
||||
console.log("last message time stamp = " + lastMessageTimeStamp);
|
||||
console.log(sessionStorage.getItem(this.value + '-time'));
|
||||
|
||||
}
|
||||
chatTextArea.textContent = '';
|
||||
console.log("Stored messages 2 = " + storedMessages);
|
||||
storedMessages.forEach(function(messageLine) {
|
||||
chatTextArea.append(messageLine + '\n');
|
||||
chatTextArea.scrollTop = chatTextArea.scrollHeight;
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
// sessionStorage.clear();
|
||||
// chatTextArea.append(JSON.stringify(storedMessages));
|
||||
}
|
||||
// sessionStorage.clear();
|
||||
// chatTextArea.append(JSON.stringify(storedMessages));
|
||||
|
||||
}
|
||||
// sessionStorage.setItem('status', 'ready');
|
||||
// sessionStorage.setItem('this.value', messageLog);
|
||||
// console.log('Message log = ' + messageLog);
|
||||
// }
|
||||
}
|
||||
// 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));
|
||||
// let passphraseKey = this.value + '-passphrase';
|
||||
// sessionStorage.setItem(passphraseKey, passphraseInput.value);
|
||||
// console.log(sessionStorage.getItem(passphraseKey));
|
||||
});
|
||||
|
||||
|
||||
handleChatForm();
|
||||
|
||||
handleChatForm();
|
@ -1,13 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Insert title here</title>
|
||||
<div th:replace="fragments/head :: headFragment">
|
||||
<title id="pageTitle">Admin Home</title>
|
||||
</div>
|
||||
<script src="https://code.jquery.com/jquery-2.1.4.min.js" th:if="false"></script>
|
||||
<script src="http://blackpeppersoftware.github.io/thymeleaf-fragment.js/thymeleaf-fragment.js" data-template-prefix="../" defer="defer" th:if="false"></script>
|
||||
<script th:src="@{js/admin.js}" src="../../static/js/admin.js" defer="defer"></script>
|
||||
<link th:href="@{/css/master.css}" href="../../static/css/master.css" rel="stylesheet" th:if="false">
|
||||
<link th:href="@{/css/colors.css}" href="../../static/css/colors.css" rel="stylesheet" th:if="false">
|
||||
</head>
|
||||
<!-- TODO
|
||||
Make user admin / remove user from admin
|
||||
Change E2E passphrase
|
||||
Delete Messages
|
||||
-->
|
||||
|
||||
<body>
|
||||
admin page
|
||||
<form action="#" th:action="@{/perform_logout}" method="POST">
|
||||
<input type="submit" value="logout">
|
||||
</form>
|
||||
<div th:include="fragments/navbar :: navbarFragment"></div>
|
||||
|
||||
<header>
|
||||
<div class="container bg-primary">
|
||||
<div class="row">
|
||||
<div class="col-sm py-5">
|
||||
<h1 class="display-4 text-center">Admin Page</h1>
|
||||
<p class="alert-danger px-2">Warning: these settings can be dangerous..</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm col-md-4">
|
||||
<h4>Make User an Admin</h4>
|
||||
<form id="addUserToAdminForm">
|
||||
<div class="form-group">
|
||||
<label for="addUserToDropDown">Select User:</label>
|
||||
<select class="form-control custom-select" size="4" id="addUserToAdminDropDown">
|
||||
|
||||
<option th:each="userName : ${userNames}"
|
||||
th:value="${userName}"
|
||||
th:text="#{${userName}}">
|
||||
Wireframe
|
||||
</option>
|
||||
|
||||
</select>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-danger form-control">Make admin</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-sm col-md-4">
|
||||
<h4>Change passphrases</h4>
|
||||
<form id="changePassphraseForm">
|
||||
<div class="form-group">
|
||||
<label for="changePassphraseDropDown">Select User:</label>
|
||||
<select class="form-control" id="changePassphraseDropDown">
|
||||
|
||||
<option th:each="userName : ${userNames}"
|
||||
th:value="${userName}"
|
||||
th:text="#{${userName}}">
|
||||
Wireframe
|
||||
</option>
|
||||
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="passphraseOld">Passphrase Old</label>
|
||||
<input type="password" id="passphraseOld" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="passphraseNew">Passphrase New</label>
|
||||
<input type="password" id="passphraseNew" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-danger form-control">Change Passphrase</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<!-- <div class="col-sm"></div> -->
|
||||
|
||||
<div class="col-sm d-lg-block">
|
||||
<div class="d-flex justify-content-center">
|
||||
<div class="py-5">
|
||||
<h4 class="p-2 text-center">Logout</h4>
|
||||
<form action="#" th:action="@{/logout}" method="POST">
|
||||
<!-- <input type="submit" value="logout"> -->
|
||||
<!-- <input type="hidden" th:name="${_csrf.parameterName}"
|
||||
th:value="${_csrf.token}" /> -->
|
||||
<div class="form-group">
|
||||
<button class="btn btn-secondary form-control">Logout</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -45,7 +45,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<h4 class="display-4 text-center py-2">Chat</h4>
|
||||
<div class="card text-white bg-primary mb-3 text-center card-form rounded mx-auto">
|
||||
<div class="card text-white bg-primary mb-3 card-form rounded mx-auto">
|
||||
|
||||
<div class="card-body rounded">
|
||||
<!-- <h4 class="card-title">Chat</h4> -->
|
||||
@ -57,7 +57,7 @@
|
||||
<div class="card-text">
|
||||
|
||||
</div>
|
||||
<form action="#" th:object="${chatMessageDTO}" method="post" id="chatMessageForm">
|
||||
<form action="#" th:object="${chatMessageDTO}" method="post" id="chatMessageForm" class="needs-validation" novalidate>
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<div class="form-group">
|
||||
@ -65,8 +65,8 @@
|
||||
<th:block th:each="userName: ${userNames}">
|
||||
<input class="form-control" type="radio" th:field="*{toUser}" th:value="${userName}">
|
||||
<label class="btn btn-secondary" th:for="${#ids.prev('toUser')}" th:text="${userName}">
|
||||
Demo User
|
||||
</label>
|
||||
Demo User
|
||||
</label>
|
||||
</th:block>
|
||||
</div>
|
||||
</div>
|
||||
@ -74,14 +74,18 @@
|
||||
<div class="my-form-inputs container">
|
||||
<div class="form-group">
|
||||
<label for="chatInput">Your message: </label>
|
||||
<textarea class="form-control" type="text" id="chatInput"></textarea>
|
||||
<textarea class="form-control" type="text" id="chatInput" required></textarea>
|
||||
<div class="invalid-feedback">
|
||||
Cannot be empty
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="passphrase">Passphrase: </label>
|
||||
<input class="form-control" type="password" id="passphrase">
|
||||
<input class="form-control" type="password" id="passphrase" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input class="form-control btn btn-secondary" type="submit" value="Send">
|
||||
<button class="btn btn-secondary">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
|
||||
<head>
|
||||
<div th:replace="fragments/head :: headFragment">
|
||||
@ -34,13 +34,16 @@
|
||||
<a href="home.html" th:href="@{/}" class="nav-link">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="user/home.html" th:href="@{/user}" class="nav-link">User Area</a>
|
||||
<a href="user/home.html" sec:authorize="isFullyAuthenticated()" th:href="@{/user}" class="nav-link">User Area</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a th:href="chat" href="chat.html" class="nav-link">Chat</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a th:href="login" href="login.html" class="nav-link">Login</a>
|
||||
<a th:href="login" sec:authorize="!isFullyAuthenticated()" href="login.html" class="nav-link">Login</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a th:href="registration" sec:authorize="!isFullyAuthenticated()" href="registration.html" class="nav-link">Register</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link">About</a>
|
||||
@ -48,7 +51,16 @@
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link">Contact</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a href="#" sec:authorize="isFullyAuthenticated()" th:href="@{/admin}" class="nav-link">
|
||||
Admin Area
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#" sec:authorize="isFullyAuthenticated()" th:text="${#authentication.name}" class="nav-link text-white font-weight-bold">
|
||||
nova
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
|
||||
<head>
|
||||
<div th:replace="fragments/head :: headFragment">
|
||||
@ -35,7 +35,7 @@
|
||||
<th:block th:each="userName: ${userNames}">
|
||||
<div th:text="${userName}"></div>
|
||||
</th:block> -->
|
||||
<span th:if="${message}"> Welcome <span th:text="${message}"></span></span>
|
||||
<span th:if="${message}"> </span> Welcome <span th:text="${#authentication.name}">nova</span>
|
||||
<p>Chatto is a minimal, end to end encrypted chat application.</p>
|
||||
<!-- <button class="btn btn-secondary"> <a href="registration.html" th:href="{@/registration}">Get Started</a></button> -->
|
||||
<a class="btn btn-secondary" href="registration.html" th:href="@{/registration}">Get Started</a>
|
||||
@ -53,12 +53,14 @@
|
||||
<li>
|
||||
<p class="lead">
|
||||
<!-- <i class="fas fa-check"></i> -->
|
||||
Self Hosted</p>
|
||||
Self Hosted
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p class="lead">
|
||||
<!-- <i class="fas fa-check"></i> -->
|
||||
End To End Encrypted Messaging</p>
|
||||
End To End Encrypted Messaging
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p class="lead">
|
||||
@ -68,7 +70,8 @@
|
||||
<li>
|
||||
<p class="lead">
|
||||
<!-- <i class="fas fa-check"></i> -->
|
||||
Built With Java And Spring</p>
|
||||
Built With Java And Spring
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
@ -55,7 +55,7 @@
|
||||
<legend>Please Sign In</legend> -->
|
||||
<h2 class="card-title">Please Sign In</h2>
|
||||
<div th:if="${param.error}" class="alert alert-danger">
|
||||
Invalid username or password.
|
||||
Error signing in. Please check your username and password.
|
||||
</div>
|
||||
<div th:if="${param.logout}" class="alert alert-success">
|
||||
You have been logged out.
|
||||
|
@ -1,18 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Insert title here</title>
|
||||
<div th:replace="fragments/head :: headFragment">
|
||||
<title id="pageTitle">Registration</title>
|
||||
</div>
|
||||
<script src="https://code.jquery.com/jquery-2.1.4.min.js" th:if="false"></script>
|
||||
<script src="http://blackpeppersoftware.github.io/thymeleaf-fragment.js/thymeleaf-fragment.js" defer="defer" th:if="false"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form action="#" th:action="@{/perform_registration}"
|
||||
th:object=${userDTO} method="POST">
|
||||
<label>Enter user name: </label> <input th:field="*{userName}"
|
||||
type="text" name="username" id="username"> <br> <br>
|
||||
<label>Enter password: </label> <input th:field="*{password}"
|
||||
type="password" name="password" id="password"> <br> <br>
|
||||
<input type="password" id="password-repeat">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
<div th:include="fragments/navbar :: navbarFragment"></div>
|
||||
<header>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm py-5">
|
||||
<!-- <h4 class="display-4 text-center py-2">Chat</h4> -->
|
||||
<div class="card text-white bg-primary mb-3 text-center card-form rounded mx-auto" id="login-card">
|
||||
|
||||
<div class="card-body rounded">
|
||||
<!-- <h4 class="card-title">Chat</h4> -->
|
||||
<!-- <div class="form-group">
|
||||
<textarea id="chatTextArea" class="form-control-lg py-2" disabled></textarea>
|
||||
</div> -->
|
||||
<!-- <form action="#" th:action="@{/seedstartermng}" th:object="${seedStarter}" method="post"> -->
|
||||
<!-- th:action="@{/api/chat}" -->
|
||||
|
||||
|
||||
<!-- <label>First Name</label>
|
||||
<div th:classappend="${#fields.hasErrors('firstName')} ? 'input-icon right' : ''">
|
||||
<i th:if="${#fields.hasErrors('firstName')}" class="fa fa-exclamation tooltips" data-original-title="please enter a valid first name" data-container="body"></i>
|
||||
<input type="text" class="form-control" maxlength="32" th:field="*{firstName}" placeholder="Between 1 and 32 characters" />
|
||||
<span th:if="${#fields.hasErrors('firstName')}" class="help-block" th:errors="*{firstName}"></span>
|
||||
</div> -->
|
||||
|
||||
<div class="card-text">
|
||||
<h2 class="card-title">Register</h2>
|
||||
<form action="#" th:action="@{/perform_registration}" th:object=${userRegistrationDTO} method="POST">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Enter username: </label>
|
||||
<div th:classappend="${#fields.hasErrors('userName')} ? 'input-icon right' : ''">
|
||||
<i th:if="${#fields.hasErrors('userName')}" class="fa fa-exclamation tooltips" data-original-title="please enter a valid username" data-container="body"></i>
|
||||
<input class="form-control" th:field="*{userName}" type="text" name="username" id="username" required>
|
||||
<span th:if="${#fields.hasErrors('userName')}" class="help-block" th:errors="*{userName}"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Enter password: </label>
|
||||
<i th:if="${#fields.hasErrors('password')}" class="fa fa-exclamation tooltips" data-original-title="please enter a valid first name" data-container="body"></i>
|
||||
<input class="form-control" th:field="*{password}" type="password" name="password" id="password" required>
|
||||
<span th:if="${#fields.hasErrors('password')}" class="help-block" th:errors="*{password}"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password-repeat">Repeat password: </label>
|
||||
<input class="form-control" type="password" id="password-repeat" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input class="form-control btn btn-secondary" type="submit" value="Submit">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user