Browse Source

add bootstrap to web front-end

master
Rohan Sircar 5 years ago
parent
commit
2625cf7865
  1. 0
      chatto/.attach_pid30353
  2. 1
      chatto/config/application.properties
  3. 1
      chatto/config/messages.properties
  4. 2
      chatto/message.properties
  5. 2
      chatto/messages.properties
  6. 40
      chatto/pom.xml
  7. 16
      chatto/src/main/java/org/ros/chatto/BeanConfigurations.java
  8. 15
      chatto/src/main/java/org/ros/chatto/ChattoApplication.java
  9. 2
      chatto/src/main/java/org/ros/chatto/RESTAuthenticationEntryPoint.java
  10. 73
      chatto/src/main/java/org/ros/chatto/WebSecurityConfiguration.java
  11. 47
      chatto/src/main/java/org/ros/chatto/config/CacheConfig.java
  12. 19
      chatto/src/main/java/org/ros/chatto/config/CustomCacheEventLogger.java
  13. 9
      chatto/src/main/java/org/ros/chatto/controller/ChatMessageController.java
  14. 26
      chatto/src/main/java/org/ros/chatto/controller/Home.java
  15. 5
      chatto/src/main/java/org/ros/chatto/model/ChatUser.java
  16. 3
      chatto/src/main/java/org/ros/chatto/repository/UserRoleRepository.java
  17. 138
      chatto/src/main/java/org/ros/chatto/security/MyUserDetailsService.java
  18. 54
      chatto/src/main/java/org/ros/chatto/service/DBInitializerService.java
  19. 6
      chatto/src/main/resources/application.properties
  20. 44
      chatto/src/main/resources/ehcache.xml
  21. 1
      chatto/src/main/resources/messages.properties
  22. 322
      chatto/src/main/resources/static/css/colors.css
  23. 128
      chatto/src/main/resources/static/css/master.css
  24. BIN
      chatto/src/main/resources/static/img/home.jpg
  25. 25
      chatto/src/main/resources/static/js/chat.js
  26. 22
      chatto/src/main/resources/static/js/chatStatic.js
  27. 17
      chatto/src/main/resources/templates/NewFile.html
  28. 111
      chatto/src/main/resources/templates/chat.html
  29. 34
      chatto/src/main/resources/templates/fragments/head.html
  30. 60
      chatto/src/main/resources/templates/fragments/navbar.html
  31. 112
      chatto/src/main/resources/templates/home.html
  32. 121
      chatto/src/main/resources/templates/login.html
  33. 57
      chatto/src/main/resources/templates/user/home.html

0
chatto/.attach_pid30353

1
chatto/config/application.properties

@ -5,3 +5,4 @@ spring.datasource.username = chatto_user
spring.datasource.password = password
database-name = chatto_db2
website-url = 192.168.1.13
test.bindAddress=192.168.1.106

1
chatto/config/messages.properties

@ -0,0 +1 @@
test.bindAddress=192.168.1.106

2
chatto/message.properties

@ -0,0 +1,2 @@
#Sat Oct 12 01:13:02 IST 2019
test.bindAddress=192.168.1.106

2
chatto/messages.properties

@ -0,0 +1,2 @@
#Sat Oct 12 01:15:41 IST 2019
test.bindAddress=192.168.1.106

40
chatto/pom.xml

@ -84,6 +84,46 @@
<version>2.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ehcache/ehcache -->
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.cache/cache-api -->
<dependency>
<groupId>javax.cache</groupId>
<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 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
<!-- <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId>
</dependency> -->
<!-- <dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId>
<version>1.1.0</version> </dependency> -->
</dependencies>
<build>

16
chatto/src/main/java/org/ros/chatto/BeanConfigurations.java

@ -1,15 +1,13 @@
package org.ros.chatto;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.modelmapper.ModelMapper;
import org.ros.chatto.security.AuthenticationSuccessHandlerImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@PropertySource(value = "classpath:queries.properties")
@ -36,6 +34,16 @@ public class BeanConfigurations {
return modelMapper;
}
@Bean
public MessageSource messageSource() {
final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames("classpath:/messages,file:./config/messages");
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(5);
return messageSource;
}
// @Bean
// public Connection connection() throws SQLException
// {

15
chatto/src/main/java/org/ros/chatto/ChattoApplication.java

@ -1,31 +1,38 @@
package org.ros.chatto;
import java.sql.SQLException;
import org.ros.chatto.service.DBInitializerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
@EnableAutoConfiguration
@SpringBootApplication
//@EnableCaching
public class ChattoApplication extends SpringBootServletInitializer {
// @Value("${spring.datasource.url}")
// private static String url;
public static void main(String[] args) {
public static void main(String[] args) throws SQLException {
SpringApplication application = new SpringApplication(ChattoApplication.class);
addInitHooks(application);
// SpringApplication.run(ChattoApplication.class, args);
application.run(args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ChattoApplication.class);
}
static void addInitHooks(SpringApplication application) {
static void addInitHooks(SpringApplication application) throws SQLException {
// TBD
// System.out.println("Hello world very loooooooooooooooooooooooooooooooooooooong string");
// String url = environment.getProperty("spring.datasource.url");

2
chatto/src/main/java/org/ros/chatto/RestAuthenticationEntryPoint.java → chatto/src/main/java/org/ros/chatto/RESTAuthenticationEntryPoint.java

@ -12,7 +12,7 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationEn
import org.springframework.stereotype.Component;
@Component
public final class RestAuthenticationEntryPoint
public final class RESTAuthenticationEntryPoint
extends BasicAuthenticationEntryPoint {
// @Override

73
chatto/src/main/java/org/ros/chatto/WebSecurityConfiguration.java

@ -5,14 +5,19 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@ -25,13 +30,15 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private MyUserDetailsService myUserDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserCache userCache;
// @SuppressWarnings("deprecation")
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(myUserDetailsService);
provider.setUserCache(userCache);
provider.setPasswordEncoder(passwordEncoder);
return provider;
}
@ -40,30 +47,24 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Configuration
@Order(1)
public static class ApiWebSecurity extends WebSecurityConfigurerAdapter {
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
private RESTAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.and()
http.csrf().disable().exceptionHandling()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// .cors().and()
.antMatcher("/api/**")
.authorizeRequests()
.antMatcher("/api/**").authorizeRequests()
// .antMatchers("/perform-login").permitAll()
.anyRequest()
// .hasAnyRole("USER", "ADMIN", "SUPER_USER")
.authenticated()
.and().httpBasic()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.authenticated().and().httpBasic().authenticationEntryPoint(authenticationEntryPoint)
// .and()
// .logout().invalidateHttpSession(true).clearAuthentication(true)
// .logoutRequestMatcher(new AntPathRequestMatcher("/api/perform_logout"))
@ -79,8 +80,19 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
}
// @Override
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.eraseCredentials(false);
// }
//
// public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
//
// }
}
@Configuration
@Order(2)
public static class FormWebSecurity extends WebSecurityConfigurerAdapter {
@ -89,12 +101,12 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
// .antMatchers(HttpMethod.POST, "/api/**").permitAll()
.antMatchers("/", "perform_login","/login*", "/registration", "/perform_registration", "/css/**", "/js/**",
"/images/**")
.antMatchers("/", "perform_login","/logout**" ,"/favicon.ico","/login*", "/registration", "/perform_registration", "/css/**",
"/js/**", "/img/**")
.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")
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN", "SUPER_USER").antMatchers("/admin/**")
.hasAnyRole("ADMIN", "SUPER_USER")
// .and()
// .antMatcher("/api/**")
// .authorizeRequests()
@ -102,19 +114,18 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
.and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/login")
.formLogin().loginPage("/login").permitAll().loginProcessingUrl("/perform_login")
// .successHandler(authenticationSuccessHandler)
// .failureUrl("/?login_error")
.and()
.logout().invalidateHttpSession(true).clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/perform_logout"))
// .and()
// .logout().invalidateHttpSession(true)
// .clearAuthentication(true)
// .logoutRequestMatcher(new AntPathRequestMatcher("/perform_logout"))
// .logoutSuccessUrl("/").permitAll()
// .and().httpBasic();
// .and().cors()
// .and().csrf().disable();
;
.and().csrf().disable();
;
// httpSecurity
// .csrf().disable()
// .authorizeRequests().antMatchers("login").permitAll()
@ -129,7 +140,17 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
// .logoutSuccessUrl("/").permitAll();
}
// @Override
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.eraseCredentials(false);
// }
}
// @Override
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.eraseCredentials(false);
// }
// @Override
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {

47
chatto/src/main/java/org/ros/chatto/config/CacheConfig.java

@ -0,0 +1,47 @@
package org.ros.chatto.config;
import org.ros.chatto.security.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.cache.SpringCacheBasedUserCache;
@EnableCaching
@Configuration
public class CacheConfig {
@Autowired
private CacheManager cacheManager;
@Bean
public UserCache userCache() throws Exception {
// return new EhCacheBasedUserCache();
// Cache cache = (Cache) cacheManager().getCache("userCache");
Cache cache = cacheManager.getCache("chatUser");
return new SpringCacheBasedUserCache(cache);
}
// private net.sf.ehcache.CacheManager cacheManager;
// @PreDestroy
// public void destroy() {
// cacheManager.shutdown();
// }
//
// @Bean
// public CacheManager cacheManager() {
//// log.debug("Starting Ehcache");
// cacheManager = net.sf.ehcache.CacheManager.create();
// cacheManager.getConfiguration().setMaxBytesLocalHeap("16M");
// EhCacheCacheManager ehCacheManager = new EhCacheCacheManager();
// ehCacheManager.setCacheManager(cacheManager);
// return ehCacheManager;
// }
}

19
chatto/src/main/java/org/ros/chatto/config/CustomCacheEventLogger.java

@ -0,0 +1,19 @@
package org.ros.chatto.config;
import org.ehcache.event.CacheEvent;
import org.ehcache.event.CacheEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
//@Component
public class CustomCacheEventLogger implements CacheEventListener<Object, Object> {
private static final Logger LOG = LoggerFactory.getLogger(CustomCacheEventLogger.class);
@Override
public void onEvent(CacheEvent<? extends Object, ? extends Object> cacheEvent) {
LOG.info("custom Caching event {} key = {} old {} new {} ", cacheEvent.getType(), cacheEvent.getKey(),
cacheEvent.getOldValue(), cacheEvent.getNewValue());
}
}

9
chatto/src/main/java/org/ros/chatto/controller/ChatMessageController.java

@ -10,6 +10,7 @@ import java.util.List;
import org.ros.chatto.dto.ChatMessageDTO;
import org.ros.chatto.model.MessageCipher;
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;
@ -26,6 +27,9 @@ 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
@ -64,6 +68,11 @@ public class ChatMessageController {
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) {

26
chatto/src/main/java/org/ros/chatto/controller/Home.java

@ -34,23 +34,27 @@ public class Home {
@Autowired
private UserService userService;
@Autowired
private DBInitializerService dbInitializerService;
// @Autowired
// private DBInitializerService dbInitializerService;
private boolean installationChecked = false;
// private boolean installationChecked = false;
@RequestMapping("/")
public ModelAndView showPage(Principal principal) throws SQLException {
ModelAndView mv = new ModelAndView("home");
mv.addObject("message", "Welcome!");
String welcomeMesage = String.format("Welcome to chatto");
if (principal != null) {
welcomeMesage = String.format("Welcome back %s!", principal.getName());
}
mv.addObject("message", welcomeMesage);
// mv.addObject("userNames", userService.findAllOtherUsers(principal.getName()));
if (!installationChecked) {
dbInitializerService.connectDB();
if(dbInitializerService.getNumTables() == 0)
dbInitializerService.populateDB();
dbInitializerService.closeConnection();
installationChecked = true;
}
// if (!installationChecked) {
// dbInitializerService.connectDB();
// if(dbInitializerService.getNumTables() == 0)
// dbInitializerService.populateDB();
// dbInitializerService.closeConnection();
// installationChecked = true;
// }
return mv;
}

5
chatto/src/main/java/org/ros/chatto/model/ChatUser.java

@ -45,8 +45,9 @@ public class ChatUser {
// @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@JsonBackReference
private Set<UserRole> userRoles = new HashSet<UserRole>();
// private Set<UserRole> userRoles = new HashSet<UserRole>();
private Set<UserRole> userRoles;
public int getUserID() {
return userID;
}

3
chatto/src/main/java/org/ros/chatto/repository/UserRoleRepository.java

@ -11,4 +11,7 @@ import org.springframework.stereotype.Repository;
public interface UserRoleRepository extends JpaRepository<UserRole, Long>{
@Query("select ur from UserRole ur where ur.user.userID = ?1")
public List<UserRole> findByUser(int userID);
@Query("select ur from UserRole ur where ur.user.userName = ?1")
public List<UserRole> findByUser(String username);
}

138
chatto/src/main/java/org/ros/chatto/security/MyUserDetailsService.java

@ -1,8 +1,11 @@
package org.ros.chatto.security;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.validation.constraints.Size;
import org.ros.chatto.model.ChatUser;
import org.ros.chatto.model.UserRole;
@ -10,7 +13,11 @@ import org.ros.chatto.repository.RoleRepository;
import org.ros.chatto.repository.UserRepository;
import org.ros.chatto.repository.UserRoleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@ -19,57 +26,102 @@ import org.springframework.web.context.WebApplicationContext;
@Service
public class MyUserDetailsService implements UserDetailsService {
// @Autowired
// private WebApplicationContext applicationContext;
@Autowired
private UserRepository userRepository;
@Autowired
private UserRepository userRepository;
// @Autowired
// private RoleRepository roleRepository;
@Autowired
private UserRoleRepository userRoleRepository;
@Autowired
private UserRoleRepository userRoleRepository;
// @Autowired
// private UserCache userCache;
@Autowired
private CacheManager cacheManager;
// @Autowired
// private UserCache userCache;
// @PostConstruct
// public void completeSetup() {
// userRepository = applicationContext.getBean(UserRepository.class);
// }
public MyUserDetailsService() {
super();
}
@Override
public UserDetails loadUserByUsername(String username) {
ChatUser user = userRepository.findByUserName(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
System.out.println("Found useeeeeeeeeeeeeeeeeeeeeeeeeeeeeeer " + user.getUserName() + user.getPassword());
List<UserRole> userRoles = userRoleRepository.findByUser(user.getUserID());
System.out.println("User role iddddddddddddddddd = " + userRoles.get(0).getRole().getName());
public MyUserDetailsService() {
super();
}
@Override
// @Cacheable(value="chatUser")
public UserDetails loadUserByUsername(String username) {
// ChatUser user = userRepository.findByUserName(username);
List<UserRole> userRoles = userRoleRepository.findByUser(username);
// @SuppressWarnings("unchecked")
// List<UserRole> userRoles = (List<UserRole>)cacheManager.getCache(username);
// if((userRoles == null)) {
// userRoles = userRoleRepository.findByUser(username);
// }
// UserDetails userDetails = (UserDetails) cacheManager.getCache(username);
// if((userDetails == null)) {
// user = userRoleRepository.findByUser(username);
// }
System.out.println("Test from userdetails");
ValueWrapper valueWrapper = cacheManager.getCache("chatUser").get("hmm");
if (valueWrapper != null) {
UserDetails userDetails = (UserDetails) valueWrapper.get();
if (userDetails != null) {
System.out.println("cache username = " + userDetails.getUsername());
System.out.println("cache password = " + userDetails.getPassword());
}
}
if (userRoles.size() == 0) {
throw new UsernameNotFoundException(username);
}
// System.out.println("Found useeeeeeeeeeeeeeeeeeeeeeeeeeeeeeer " + user.getUserName() + user.getPassword());
// ChatUser user2 = userRoles.get(0).getUser();
// System.out.println("User role iddddddddddddddddd = " + userRoles.get(0).getRole().getName());
// System.out.println(userRoles.);
// return new MyUserPrincipal(user);
return toUserDetails(new UserObject(user.getUserName(), user.getPassword(), userRoles.get(0).getRole().getName()));
}
private UserDetails toUserDetails(UserObject userObject) {
return User.withUsername(userObject.name)
.password(userObject.password)
.roles(userObject.role).build();
}
private static class UserObject {
private String name;
private String password;
private String role;
public UserObject(String name, String password, String role) {
this.name = name;
this.password = password;
this.role = role;
}
}
// return toUserDetails(new UserObject(user.getUserName(), user.getPassword(), userRoles.get(0).getRole().getName()));
// return User.withUsername(user.getUserName()).password(user.getPassword())
// .roles(
// user.getUserRoles()
// .stream()
// .map(userRole -> {
// System.out.println("role = " + userRole.getRole().getName());
// return userRole.getRole().getName();
// })
// .toArray(size -> new String[size])
// )
// .build();
ChatUser user = userRoles.get(0).getUser();
return User.withUsername(user.getUserName()).password(user.getPassword())
.roles(userRoles.stream().map(userRole -> {
System.out.println("role = " + userRole.getRole().getName());
return userRole.getRole().getName();
}).toArray(size -> new String[size])).build();
}
private UserDetails toUserDetails(UserObject userObject) {
return User.withUsername(userObject.name).password(userObject.password).roles(userObject.role).build();
}
private static class UserObject {
private String name;
private String password;
private String role;
public UserObject(String name, String password, String role) {
this.name = name;
this.password = password;
this.role = role;
}
}
}

54
chatto/src/main/java/org/ros/chatto/service/DBInitializerService.java

@ -1,14 +1,22 @@
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;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.ros.chatto.ChattoApplication;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.event.EventListener;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
@ -38,6 +46,9 @@ public class DBInitializerService {
@Value("${num-tables}")
private String numTablesQuery;
@Value("${test.bindAddress}")
private String bindAddress;
private Connection connection;
// public DBInitializerService(Connection connection) {
@ -111,7 +122,18 @@ public class DBInitializerService {
return numTables;
}
public void populateDB() throws SQLException {
@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");
connectDB();
if (getNumTables() == 0)
populateDB();
closeConnection();
}
public void populateDB() throws SQLException, IOException {
// System.out.println("Database name = " + dbName);
// String sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '" + dbName + "' and TABLE_TYPE='BASE TABLE' ";
// String sql = numTablesQuery;
@ -139,6 +161,36 @@ public class DBInitializerService {
// connection.close();
}
public void setProperties() throws IOException {
// InputStream input = ChattoApplication.class.getClassLoader().getResourceAsStream("messages.properties");
OutputStream outputStream = new FileOutputStream("messages.properties");
// FileInputStream in = new FileInputStream("First.properties");
// Properties props = new Properties();
// props.load(in);
// in.close();
//
// FileOutputStream out = new FileOutputStream("First.properties");
// props.setProperty("country", "america");
// props.store(out, null);
// 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);
// input.close();
outputStream.close();
// prop.store(object, comments);
}
public void closeConnection() throws SQLException {
connection.close();
}

6
chatto/src/main/resources/application.properties

@ -20,4 +20,8 @@ logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
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/**
#spring.mvc.static-path-pattern=/static/**
#spring.cache.type=ehcache3
spring.cache.jcache.config=classpath:ehcache.xml
logging.level.org.springframework.cache = DEBUG
#test.bindAddress=192.168.1.106

44
chatto/src/main/resources/ehcache.xml

@ -0,0 +1,44 @@
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xmlns:jsr107='http://www.ehcache.org/v3/jsr107'>
<service>
<jsr107:defaults enable-statistics="true" />
</service>
<cache alias="chatUser">
<key-type>java.lang.String</key-type>
<value-type>org.springframework.security.core.userdetails.UserDetails</value-type>
<expiry>
<ttl unit="seconds">600</ttl>
</expiry>
<listeners>
<listener>
<class>org.ros.chatto.config.CustomCacheEventLogger</class>
<event-firing-mode>ASYNCHRONOUS</event-firing-mode>
<event-ordering-mode>UNORDERED</event-ordering-mode>
<events-to-fire-on>CREATED</events-to-fire-on>
<events-to-fire-on>UPDATED</events-to-fire-on>
<events-to-fire-on>EXPIRED</events-to-fire-on>
<events-to-fire-on>REMOVED</events-to-fire-on>
<events-to-fire-on>EVICTED</events-to-fire-on>
</listener>
</listeners>
<resources>
<heap unit="entries">2000</heap>
<offheap unit="MB">100</offheap>
</resources>
</cache>
<!-- <cache alias="user"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="300" timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache> -->
</config>

1
chatto/src/main/resources/messages.properties

@ -0,0 +1 @@
#test.bindAddress=192.168.1.106

322
chatto/src/main/resources/static/css/colors.css

@ -0,0 +1,322 @@
/*------------------------------------
- COLOR primary
------------------------------------*/
/*
.alert-primary {
color: #191d21;
background-color: #b8c1c9;
border-color: #adb6c0;
}
.alert-primary hr {
border-top-color: #9eaab5;
}
.alert-primary .alert-link {
color: #030404;
}
.badge-primary {
color: #fff;
background-color: #4f5b67;
}
.badge-primary[href]:hover,
.badge-primary[href]:focus {
color: #fff;
background-color: #38414a;
}
.bg-primary {
background-color: #4f5b67 !important;
}
a.bg-primary:hover,
a.bg-primary:focus,
button.bg-primary:hover,
button.bg-primary:focus {
background-color: #38414a !important;
}
.border-primary {
border-color: #4f5b67 !important;
}
.btn-primary {
color: #fff;
background-color: #4f5b67;
border-color: #4f5b67;
}
.btn-primary:hover {
color: #fff;
background-color: #3f4952;
border-color: #38414a;
}
.btn-primary:focus,
.btn-primary.focus {
box-shadow: 0 0 0 0.2rem rgba(79, 91, 103, 0.5);
}
.btn-primary.disabled,
.btn-primary:disabled {
color: #fff;
background-color: #4f5b67;
border-color: #4f5b67;
}
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active,
.show>.btn-primary.dropdown-toggle {
color: #fff;
background-color: #38414a;
border-color: #323941;
}
.btn-primary:not(:disabled):not(.disabled):active:focus,
.btn-primary:not(:disabled):not(.disabled).active:focus,
.show>.btn-primary.dropdown-toggle:focus {
box-shadow: 0 0 0 0.2rem rgba(79, 91, 103, 0.5);
}
.btn-outline-primary {
color: #4f5b67;
background-color: transparent;
border-color: #4f5b67;
}
.btn-outline-primary:hover {
color: #fff;
background-color: #4f5b67;
border-color: #4f5b67;
}
.btn-outline-primary:focus,
.btn-outline-primary.focus {
box-shadow: 0 0 0 0.2rem rgba(79, 91, 103, 0.5);
}
.btn-outline-primary.disabled,
.btn-outline-primary:disabled {
color: #4f5b67;
background-color: transparent;
}
.btn-outline-primary:not(:disabled):not(.disabled):active,
.btn-outline-primary:not(:disabled):not(.disabled).active,
.show>.btn-outline-primary.dropdown-toggle {
color: #fff;
background-color: #4f5b67;
border-color: #4f5b67;
}
.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
.show>.btn-outline-primary.dropdown-toggle:focus {
box-shadow: 0 0 0 0.2rem rgba(79, 91, 103, 0.5);
}
.list-group-item-primary {
color: #191d21;
background-color: #adb6c0;
}
.list-group-item-primary.list-group-item-action:hover,
.list-group-item-primary.list-group-item-action:focus {
color: #191d21;
background-color: #9eaab5;
}
.list-group-item-primary.list-group-item-action.active {
color: #fff;
background-color: #191d21;
border-color: #191d21;
}
.table-primary,
.table-primary>th,
.table-primary>td {
background-color: #adb6c0;
}
.table-hover .table-primary:hover {
background-color: #9eaab5;
}
.table-hover .table-primary:hover>td,
.table-hover .table-primary:hover>th {
background-color: #9eaab5;
}
.text-primary {
color: #4f5b67 !important;
}
a.text-primary:hover,
a.text-primary:focus {
color: #38414a !important;
} */
/*------------------------------------
- COLOR primary
------------------------------------*/
.alert-primary {
color: #14171b;
background-color: #b1bbc4;
border-color: #a5b0bb;
}
.alert-primary hr {
border-top-color: #97a4b0;
}
.alert-primary .alert-link {
color: #000000;
}
.badge-primary {
color: #fff;
background-color: #495561;
}
.badge-primary[href]:hover,
.badge-primary[href]:focus {
color: #fff;
background-color: #333b43;
}
.bg-primary {
background-color: #495561 !important;
}
a.bg-primary:hover,
a.bg-primary:focus,
button.bg-primary:hover,
button.bg-primary:focus {
background-color: #333b43 !important;
}
.border-primary {
border-color: #495561 !important;
}
.btn-primary {
color: #fff;
background-color: #495561;
border-color: #495561;
}
.btn-primary:hover {
color: #fff;
background-color: #39434c;
border-color: #333b43;
}
.btn-primary:focus,
.btn-primary.focus {
box-shadow: 0 0 0 0.2rem rgba(73, 85, 97, 0.5);
}
.btn-primary.disabled,
.btn-primary:disabled {
color: #fff;
background-color: #495561;
border-color: #495561;
}
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active,
.show>.btn-primary.dropdown-toggle {
color: #fff;
background-color: #333b43;
border-color: #2c333b;
}
.btn-primary:not(:disabled):not(.disabled):active:focus,
.btn-primary:not(:disabled):not(.disabled).active:focus,
.show>.btn-primary.dropdown-toggle:focus {
box-shadow: 0 0 0 0.2rem rgba(73, 85, 97, 0.5);
}
.btn-outline-primary {
color: #495561;
background-color: transparent;
border-color: #495561;
}
.btn-outline-primary:hover {
color: #fff;
background-color: #495561;
border-color: #495561;
}
.btn-outline-primary:focus,
.btn-outline-primary.focus {
box-shadow: 0 0 0 0.2rem rgba(73, 85, 97, 0.5);
}
.btn-outline-primary.disabled,
.btn-outline-primary:disabled {
color: #495561;
background-color: transparent;
}
.btn-outline-primary:not(:disabled):not(.disabled):active,
.btn-outline-primary:not(:disabled):not(.disabled).active,
.show>.btn-outline-primary.dropdown-toggle {
color: #fff;
background-color: #495561;
border-color: #495561;
}
.btn-outline-primary:not(:disabled):not(.disabled):active:focus,
.btn-outline-primary:not(:disabled):not(.disabled).active:focus,
.show>.btn-outline-primary.dropdown-toggle:focus {
box-shadow: 0 0 0 0.2rem rgba(73, 85, 97, 0.5);
}
.list-group-item-primary {
color: #14171b;
background-color: #a5b0bb;
}
.list-group-item-primary.list-group-item-action:hover,
.list-group-item-primary.list-group-item-action:focus {
color: #14171b;
background-color: #97a4b0;
}
.list-group-item-primary.list-group-item-action.active {
color: #fff;
background-color: #14171b;
border-color: #14171b;
}
.table-primary,
.table-primary>th,
.table-primary>td {
background-color: #a5b0bb;
}
.table-hover .table-primary:hover {
background-color: #97a4b0;
}
.table-hover .table-primary:hover>td,
.table-hover .table-primary:hover>th {
background-color: #97a4b0;
}
.text-primary {
color: #495561 !important;
}
a.text-primary:hover,
a.text-primary:focus {
color: #333b43 !important;
}

128
chatto/src/main/resources/static/css/master.css

@ -1,24 +1,126 @@
.myClass {
/* .myClass {
color: red;
} */
/* https://arcusiridis.com/images/background.jpg */
body {
background: #333;
color: #ffffff;
/* background-image: url('https://bluestnight.com/images/background_lg.jpg'); */
}
#body-container {
/* #body-container {
margin: 0 auto 0 auto;
max-width: 80%;
/* vertical-align: auto; */
}
.shadow-sm {
width: 50%;
}
input[type="radio"]{
/*position:fixed;*/
opacity:0;
vertical-align: auto;
}
*/
input[type="radio"] {
/*position:fixed;*/
opacity: 0;
}
input[type=radio]+label {
font-weight: normal;
font-weight: normal;
}
input[type=radio]:checked+label {
font-weight: bold;
font-weight: bold;
background-color: #566069;
}
input[type=radio]:focus+label {
border: 1px dotted #000;
border: 1px dotted #000;
}
#home-section {
background-image: url('../img/home.jpg');
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
min-height: 900px;
height: auto;
}
#home-section .home-inner {
padding-top: 75px;
/* padding-bottom: 10px; */
/* background: #333; */
}
/* #home-section .card-form {
opacity: 0.8;
} */
#home-section .dark-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
min-height: 900px;
background: rgba(0, 0, 0, 0.7);
}
#chat-section {
/* background-image: url('../img/home.jpg'); */
background: #495561;
/* background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed; */
min-height: 500px;
}
#chat-section .chat-inner {
padding-top: 75px;
/* background: #333; */
}
#chat-section .dark-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
min-height: 600px;
/* background: rgba(0, 0, 0, 0.7); */
}
textarea {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
}
#chatTextArea {
min-height: 300px;
}
/* .container {
width: 50%;
} */
.my-form-inputs {
width: 80%;
}
#login-card {
width: 40%;
/* margin: 0 auto; */
/* Added */
/* float: none; */
/* Added */
/* margin-bottom: 10px; */
/* Added */
}
@media only screen and (max-width: 600px) {
#login-card {
width: 90%;
}
}

BIN
chatto/src/main/resources/static/img/home.jpg

After

Width: 1920  |  Height: 1280  |  Size: 307 KiB

25
chatto/src/main/resources/static/js/chat.js

@ -14,14 +14,19 @@ if(!ischecked_method) { //payment method button is not checked
var toUserRadios = document.getElementsByName('toUser');
var isCheckedUser = false;
var chatTextArea = document.getElementById('chatTextArea');
var passphraseInput = document.getElementById('passphrase');
var postNewMessageUrl = "http://localhost:8080/api/chat/post/message";
var getAllMessagesUrl = "http://localhost:8080/api/chat/get/messages/";
var getNewMessagesUrl = "http://localhost:8080/api/chat/get/messages/";
var postNewMessageUrl = `http://${hostAddress}/api/chat/post/message`; //hostAddress variable is set in the thymeleaf head fragment
var getAllMessagesUrl = `http://${hostAddress}/api/chat/get/messages/`;
var getNewMessagesUrl = `http://${hostAddress}/api/chat/get/messages/`;
// var postNewMessageUrl = "http://localhost:8080/api/chat/post/message";
// var getAllMessagesUrl = "http://localhost:8080/api/chat/get/messages/";
// var getNewMessagesUrl = "http://localhost:8080/api/chat/get/messages/";
// var messageLog = [];
var username = sessionStorage.getItem('username');
var password = sessionStorage.getItem('password');
var authToken = 'Basic ' + btoa(username + ":" + password);
var iterations = 100000;
// var lastMessageTimeStamp;
// console.log(authToken);
@ -60,8 +65,9 @@ function handleChatForm() {
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);
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);
@ -75,6 +81,7 @@ function handleChatForm() {
messageSend(JSON.stringify(chatMessageDTO));
// sessionStorage.setItem('passphrase', passphraseInput.value);
// console.log(sessionStorage.getItem('passphrase'));
})
}
@ -215,6 +222,7 @@ parent.addDelegatedListener("click", "input[type='radio']", function (event) {
// chatTextArea.append(obj.fromUser + ": " + message + "\n");
chatTextArea.append(messageLine + '\n');
messageLog[i++] = messageLine;
chatTextArea.scrollTop = chatTextArea.scrollHeight;
// console.log('Message log = ' + messageLog);
@ -255,7 +263,7 @@ parent.addDelegatedListener("click", "input[type='radio']", function (event) {
console.log(messageLine);
// chatTextArea.append(obj.fromUser + ": " + message + "\n");
chatTextArea.append(messageLine + '\n');
chatTextArea.scrollTop = chatTextArea.scrollHeight;
storedMessages.push(messageLine);
})
@ -264,12 +272,15 @@ parent.addDelegatedListener("click", "input[type='radio']", function (event) {
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 = '';
}
chatTextArea.textContent = '';
console.log("Stored messages 2 = " + storedMessages);
storedMessages.forEach(function (messageLine) {
chatTextArea.append(messageLine + '\n');
chatTextArea.scrollTop = chatTextArea.scrollHeight;
})
}
});

22
chatto/src/main/resources/static/js/chatStatic.js

@ -0,0 +1,22 @@
var chatTextArea = document.getElementById('chatTextArea');
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 = localDate.toLocaleDateString() + localDate.toLocaleTimeString() + 'fromUser' + ': ' + messageContent;
chatTextArea.append(messageLine + "\n");
chatTextArea.scrollTop = chatTextArea.scrollHeight;
})
}
handleChatForm();

17
chatto/src/main/resources/templates/NewFile.html

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<div th:replace="fragments/head :: headFragment">
<meta charset="UTF-8">
<title id="pageTitle">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" defer="defer"
th:if="false"></script>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
</html>

111
chatto/src/main/resources/templates/chat.html

@ -2,37 +2,104 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:replace="fragments/head :: headFragment">
<meta charset="UTF-8">
<title id="pageTitle">Chat</title>
</div>
<!-- <script th:src="@{js/my_Crypto.js}" type="text/javascript"></script> -->
<link th:href="@{/css/master.css}" href="../static/css/master.css" rel="stylesheet">
</link>
<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>
<div th:replace="fragments/head :: headFragment">
<meta charset="UTF-8">
<title id="pageTitle">Chat</title>
</div>
<!-- <script th:src="@{js/my_Crypto.js}" type="text/javascript"></script> -->
</head>
<body>
<textarea id="chatTextArea" cols="80" rows="20" disabled></textarea>
<!-- <form action="#" th:action="@{/seedstartermng}" th:object="${seedStarter}" method="post"> -->
<!-- th:action="@{/api/chat}" -->
<form action="#" th:object="${chatMessageDTO}" method="post" id="chatMessageForm">
<label for="toUser">User to send to: </label>
<th:block th:each="userName: ${userNames}">
<input type="radio" th:field="*{toUser}" th:value="${userName}">
<label th:for="${#ids.prev('toUser')}" th:text="${userName}">DemoUser</label>
</th:block> <br>
<label for="chatInput">Your message: </label>
<input type="text" id="chatInput"> <br>
<label for="passphrase">Passphrase: </label>
<input type="password" id="passphrase">
<input type="submit" value="Send">
</form>
<div th:include="fragments/navbar :: navbarFragment"></div>
<header id="chat-section">
<div class="dark-overlay">
<div class="chat-inner container bg-primary">
<div class="row">
<div class="col-sm d-lg-block">
<h1 class="display-4">Chat with your friends</h1>
<div class="d-flex">
<div class="p-4 align-self-start">
</div>
<div class="p-4 align-self-end">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Laboriosam dolorem nostrum consequatur eos voluptates. Ipsam ullam quos illo qui. Quaerat corrupti nisi numquam rerum quasi nesciunt deserunt fugit commodi consequatur!
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<section>
<div class="container">
<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-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}" -->
<div class="card-text">
</div>
<form action="#" th:object="${chatMessageDTO}" method="post" id="chatMessageForm">
<div class="row">
<div class="col-3">
<div class="form-group">
<label class="lead" for="toUser">User to send to: </label>
<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>
</th:block>
</div>
</div>
<div class="col">
<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>
</div>
<div class="form-group">
<label for="passphrase">Passphrase: </label>
<input class="form-control" type="password" id="passphrase">
</div>
<div class="form-group">
<input class="form-control btn btn-secondary" type="submit" value="Send">
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
<script th:src="@{js/chat.js}" type="text/javascript"></script>
<script src="../static/js/chatStatic.js" th:if="false"></script>
</html>
<!-- <div th:include="::frag (${value1},${value2})">...</div>

34
chatto/src/main/resources/templates/fragments/head.html

@ -2,17 +2,31 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:fragment="headFragment">
<script th:src="@{js/scljs.js}" type="text/javascript"></script>
<!--<script th:src="@{js/my_Crypto.js}" type="text/javascript"></script>-->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.css" rel="stylesheet"
type="text/css">
<th:block th:fragment="headFragment">
<script th:src="@{js/scljs.js}" type="text/javascript"></script>
<!--<script th:src="@{js/my_Crypto.js}" type="text/javascript"></script>-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/sprintf/1.1.2/sprintf.min.js" type="text/javascript"></script>
<meta charset="UTF-8">
<!-- <title th:text="${title}">Page</title> -->
<title th:include=":: #pageTitle">Layout Generic Title</title>
</th:block>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sprintf/1.1.2/sprintf.min.js" type="text/javascript"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.15.0/esm/popper.js" type="module"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css">
<link th:href="@{/css/master.css}" href="../static/css/master.css" rel="stylesheet">
<link th:href="@{/css/colors.css}" href="../static/css/colors.css" rel="stylesheet">
</link>
<script th:inline="javascript">
var hostAddress = window.location.host;
/* var hostAddress2 = [[#{test.bindAddress}]]; */
console.log("hostname" + window.location.host);
</script>
<meta charset="UTF-8">
<!-- <title th:text="${title}">Page</title> -->
<title th:include=":: #pageTitle">Layout Generic Title</title>
</th:block>
</head>
<body>

60
chatto/src/main/resources/templates/fragments/navbar.html

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:replace="fragments/head :: headFragment">
<meta charset="UTF-8">
<title id="pageTitle">Navbar Fragment</title>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.15.0/esm/popper.js" type="module" th:if="false"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.css" th:if="false" rel="stylesheet" type="text/css">
<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>
<th:block th:fragment="navbarFragment">
<!-- <div class="container"> -->
<nav class="navbar navbar-expand-sm bg-dark navbar-dark fixed-top">
<div class="container">
<a href="home.html" th:href="@{/}" class="navbar-brand">Chatto</a>
<div class="navbar-header">
<button class="navbar-toggler" data-toggle="collapse" data-target="#navbarCollapse">
<!-- <span class="navbar-toggle-icon">Menu</span> -->
<!-- Menu -->
<!-- <i class="fas fa-angle-double-up"></i> -->
<!-- <i class="glyphicon glyphicon-align-left"></i> -->
<i class="fas fa-chevron-down"></i>
</button>
</div>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<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>
</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>
</li>
<li class="nav-item">
<a href="#" class="nav-link">About</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- </div> -->
</th:block>
</body>
</html>

112
chatto/src/main/resources/templates/home.html

@ -1,19 +1,107 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Title</title>
<div th:replace="fragments/head :: headFragment">
<meta charset="UTF-8">
<title id="pageTitle">Home</title>
</div>
<!-- <script th:src="@{js/my_Crypto.js}" type="text/javascript"></script> -->
<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>
</link>
</head>
<body>
<div>
Web Application. Passed parameter : <span th:text="${message}"></span>
</div>
<!-- <p th:if="${chatUser}" th:text="'username: ' + ${chatUser.userName}">You need to login</p>
<th:block th:each="userName: ${userNames}">
<div th:text="${userName}"></div>
</th:block> -->
<p>Welcome to home page. Please login to access any features.</p>
<a href="login">login</a>
<div th:include="fragments/navbar :: navbarFragment"></div>
<header id="home-section">
<div class="dark-overlay">
<div class="home-inner container">
<div class="row">
<div class="col-lg-8 col-md-6 d-lg-block ">
<!-- <div class="jumbotron bg-primary"> -->
<div class="d-flex rounded">
<div class="p-4 align-self-end">
<h1 class="display-4">Chatto - Self Hosted, Minimal E2E Chat</h1>
<!-- <p th:if="${chatUser}" th:text="'username: ' + ${chatUser.userName}">You need to login</p>
<th:block th:each="userName: ${userNames}">
<div th:text="${userName}"></div>
</th:block> -->
<span th:if="${message}"> Welcome <span th:text="${message}"></span></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>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="card bg-primary text-justified">
<h2 class="card-header text-center">Features</h2>
<div class="card-body ">
<p class="card-text lead">
<ul class="">
<li>
<p class="lead">
<!-- <i class="fas fa-check"></i> -->
Self Hosted</p>
</li>
<li>
<p class="lead">
<!-- <i class="fas fa-check"></i> -->
End To End Encrypted Messaging</p>
</li>
<li>
<p class="lead">
<!-- <i class="fas fa-check"></i> -->
Free Software (AGPLv3 Licensed)</p>
</li>
<li>
<p class="lead">
<!-- <i class="fas fa-check"></i> -->
Built With Java And Spring</p>
</li>
</ul>
</p>
<!-- <p class="card-text">
Open Source
</p>
<p class="card-text">
Built with Java
</p> -->
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<section id="my-section">
<div class="container">
<div class="row">
<div class="col text-center py-5">
<h1 class="display-4">
<p class="lead">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Aliquid illum ea accusamus animi voluptate. Quam temporibus aperiam, similique in labore sint quasi harum. Praesentium enim iste dicta quaerat perspiciatis eos.</p>
</h1>
<a href="#" class="btn btn-secondary">Find out more</a>
</div>
</div>
</div>
</section>
<script>
console.log(hostAddress);
/* console.log(hostAddress2); */
</script>
</body>
</html>

121
chatto/src/main/resources/templates/login.html

@ -2,50 +2,103 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:replace="fragments/head :: headFragment">
<title id="pageTitle">Login</title>
</div>
<div th:replace="fragments/head :: headFragment">
<title id="pageTitle">Login</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>
<div id="body-container" class="shadow-sm p-3 mb-5 bg-white rounded">
<!-- <div>Login Page</div> -->
<form action="#" th:action="@{/login}" method="POST" id="loginForm">
<fieldset>
<!-- <form action="#" th:action="@{/greeting}" th:object="${greeting}" method="post">
<div th:include="fragments/navbar :: navbarFragment"></div>
<!-- <header id="chat-section" class="bg-secondary">
<div class="dark-overlay">
<div class="chat-inner container">
<div class="row">
<div class="col-sm d-lg-block">
<h1 class="display-4">Chat with your friends</h1>
<div class="d-flex">
<div class="p-4 align-self-start">
</div>
<div class="p-4 align-self-end">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Laboriosam dolorem nostrum consequatur eos voluptates. Ipsam ullam quos illo qui. Quaerat corrupti nisi numquam rerum quasi nesciunt deserunt fugit commodi consequatur!
</div>
</div>
</div>
</div>
</div>
</div>
</header> -->
<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}" -->
<div class="card-text">
<form action="#" th:action="@{/perform_login}" method="POST" id="loginForm">
<!-- <fieldset>
<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.
</div>
<div th:if="${param.logout}" class="alert alert-success">
You have been logged out.
</div>
<div class="form-group">
<label for="username">Enter user name: </label>
<input class="form-control" type="text" name="username" id="username">
</div>
<div class="form-group">
<label for="password">Enter password: </label>
<input class="form-control" type="password" name="password" id="password">
</div>
<div class="form-group">
<button class="form-control btn btn-secondary" type="submit">Login</button>
</div>
<!-- </fieldset> -->
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<script src="../js/loginPage.js" type="text/javascript"></script>
</body>
</html>
<!-- form th:action="@{/login.html}" method="post" -->
<!-- <form action="#" th:action="@{/greeting}" th:object="${greeting}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p>Message: <input type="text" th:field="*{content}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form> -->
<!-- <form action="#" th:action="@{/perform_login}" th:object=${user} method="POST">
<!-- <form action="#" th:action="@{/perform_login}" th:object=${user} 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="username"> <br> <br>
<input type="submit" value="Submit">
</form>
-->
<legend>Please Login</legend>
<div th:if="${param.error}" class="alert alert-error">
Invalid username or password.
</div>
<div th:if="${param.logout}" class="alert alert-success">
You have been logged out.
</div>
<label for="username">Enter user name: </label>
<input type="text" name="username" id="username">
<br> <br>
<label for="password">Enter password: </label>
<input type="password" name="password" id="password">
<br> <br>
<button type="submit" class="btn btn-primary">Login</button>
</fieldset>
</form>
</div>
<script src="../js/loginPage.js" type="text/javascript"></script>
</body>
</html>
-->

57
chatto/src/main/resources/templates/user/home.html

@ -1,13 +1,58 @@
<!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">User 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>
<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>
<body>
user 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 ">
<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">
<h1 class="display-4">User Page</h1>
<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}" -->
<div class="card-text">
<div class="form-group">
<form action="#" th:action="@{/logout}" method="POST">
<!-- <input type="submit" value="logout"> -->
<!-- <input type="hidden" th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" /> -->
<button class="btn btn-secondary form-control">Logout</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
</body>
</html>
Loading…
Cancel
Save