diff --git a/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java b/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java index 430ef5ea..2cb59c9d 100644 --- a/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java +++ b/src/main/java/stirling/software/SPDF/config/CleanUrlInterceptor.java @@ -24,7 +24,7 @@ import org.springframework.web.servlet.ModelAndView; public class CleanUrlInterceptor implements HandlerInterceptor { - private static final List ALLOWED_PARAMS = Arrays.asList("lang", "endpoint", "endpoints", "logout", "error"); + private static final List ALLOWED_PARAMS = Arrays.asList("lang", "endpoint", "endpoints", "logout", "error", "file"); @Override @@ -40,11 +40,9 @@ public class CleanUrlInterceptor implements HandlerInterceptor { String[] queryParameters = queryString.split("&"); for (String param : queryParameters) { String[] keyValue = param.split("="); - System.out.print("astirli " + keyValue[0]); if (keyValue.length != 2) { continue; } - System.out.print("astirli2 " + keyValue[0]); if (ALLOWED_PARAMS.contains(keyValue[0])) { parameters.put(keyValue[0], keyValue[1]); diff --git a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java index 11d63a61..4f4cef35 100644 --- a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java @@ -15,7 +15,11 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import stirling.software.SPDF.repository.JPATokenRepositoryImpl; + import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; @Configuration public class SecurityConfiguration { @@ -43,7 +47,7 @@ public class SecurityConfiguration { if(loginEnabledValue) { - http.csrf().disable(); + http.csrf(csrf -> csrf.disable()); http .formLogin(formLogin -> formLogin .loginPage("/login") @@ -55,8 +59,12 @@ public class SecurityConfiguration { .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/login?logout=true") .invalidateHttpSession(true) // Invalidate session - .deleteCookies("JSESSIONID") - ) + .deleteCookies("JSESSIONID", "remember-me") + ).rememberMe(rememberMeConfigurer -> rememberMeConfigurer // Use the configurator directly + .key("uniqueAndSecret") + .tokenRepository(persistentTokenRepository()) + .tokenValiditySeconds(1209600) // 2 weeks + ) .authorizeHttpRequests(authz -> authz .requestMatchers(req -> req.getRequestURI().startsWith("/login") || req.getRequestURI().endsWith(".svg") || req.getRequestURI().startsWith("/register") || req.getRequestURI().startsWith("/error") || req.getRequestURI().startsWith("/images/") || req.getRequestURI().startsWith("/public/") || req.getRequestURI().startsWith("/css/") || req.getRequestURI().startsWith("/js/")) .permitAll() @@ -65,8 +73,7 @@ public class SecurityConfiguration { .userDetailsService(userDetailsService) .authenticationProvider(authenticationProvider()); } else { - http - .csrf().disable() + http.csrf(csrf -> csrf.disable()) .authorizeHttpRequests(authz -> authz .anyRequest().permitAll() ); @@ -84,7 +91,12 @@ public class SecurityConfiguration { return authProvider; } + @Bean + public PersistentTokenRepository persistentTokenRepository() { + return new JPATokenRepositoryImpl(); + } + } diff --git a/src/main/java/stirling/software/SPDF/model/PersistentLogin.java b/src/main/java/stirling/software/SPDF/model/PersistentLogin.java new file mode 100644 index 00000000..f42a3d8e --- /dev/null +++ b/src/main/java/stirling/software/SPDF/model/PersistentLogin.java @@ -0,0 +1,60 @@ +package stirling.software.SPDF.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import java.util.Date; + +@Entity +@Table(name = "persistent_logins") +public class PersistentLogin { + + @Id + @Column(name = "series") + private String series; + + @Column(name = "username", length = 64, nullable = false) + private String username; + + @Column(name = "token", length = 64, nullable = false) + private String token; + + @Column(name = "last_used", nullable = false) + private Date lastUsed; + + public String getSeries() { + return series; + } + + public void setSeries(String series) { + this.series = series; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Date getLastUsed() { + return lastUsed; + } + + public void setLastUsed(Date lastUsed) { + this.lastUsed = lastUsed; + } + + + // Getters, setters, etc. +} diff --git a/src/main/java/stirling/software/SPDF/repository/JPATokenRepositoryImpl.java b/src/main/java/stirling/software/SPDF/repository/JPATokenRepositoryImpl.java new file mode 100644 index 00000000..2ba13265 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/repository/JPATokenRepositoryImpl.java @@ -0,0 +1,53 @@ +package stirling.software.SPDF.repository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken; +import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; +import stirling.software.SPDF.model.PersistentLogin; +import stirling.software.SPDF.repository.PersistentLoginRepository; + +import java.util.Date; + +public class JPATokenRepositoryImpl implements PersistentTokenRepository { + + @Autowired + private PersistentLoginRepository persistentLoginRepository; + + @Override + public void createNewToken(PersistentRememberMeToken token) { + PersistentLogin newToken = new PersistentLogin(); + newToken.setSeries(token.getSeries()); + newToken.setUsername(token.getUsername()); + newToken.setToken(token.getTokenValue()); + newToken.setLastUsed(token.getDate()); + persistentLoginRepository.save(newToken); + } + + @Override + public void updateToken(String series, String tokenValue, Date lastUsed) { + PersistentLogin existingToken = persistentLoginRepository.findById(series).orElse(null); + if (existingToken != null) { + existingToken.setToken(tokenValue); + existingToken.setLastUsed(lastUsed); + persistentLoginRepository.save(existingToken); + } + } + + @Override + public PersistentRememberMeToken getTokenForSeries(String seriesId) { + PersistentLogin token = persistentLoginRepository.findById(seriesId).orElse(null); + if (token != null) { + return new PersistentRememberMeToken(token.getUsername(), token.getSeries(), token.getToken(), token.getLastUsed()); + } + return null; + } + + @Override + public void removeUserTokens(String username) { + for (PersistentLogin token : persistentLoginRepository.findAll()) { + if (token.getUsername().equals(username)) { + persistentLoginRepository.delete(token); + } + } + } +} diff --git a/src/main/java/stirling/software/SPDF/repository/PersistentLoginRepository.java b/src/main/java/stirling/software/SPDF/repository/PersistentLoginRepository.java new file mode 100644 index 00000000..0ac8ab9d --- /dev/null +++ b/src/main/java/stirling/software/SPDF/repository/PersistentLoginRepository.java @@ -0,0 +1,7 @@ +package stirling.software.SPDF.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import stirling.software.SPDF.model.PersistentLogin; + +public interface PersistentLoginRepository extends JpaRepository { +} diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index c9fad5e4..bd81fad2 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -299,6 +299,10 @@ home.showJS.title=Show Javascript home.showJS.desc=Searches and displays any JS injected into a PDF showJS.tags=JS +home.autoRedact.title=Auto Redact +home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text +showJS.tags=Redact,Hide,black out,black,marker,hidden + ########################### # # # WEB PAGES # @@ -307,6 +311,14 @@ showJS.tags=JS #auto-redact autoRedact.title=Auto Redact autoRedact.header=Auto Redact +autoRedact.textsToRedactLabel=Text to Redact (line-separated) +autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret +autoRedact.useRegexLabel=Use Regex +autoRedact.wholeWordSearchLabel=Whole Word Search +autoRedact.customPaddingLabel=Custom Extra Padding +autoRedact.convertPDFToImageLabel=Convert PDF to Image +autoRedact.submitButton=Submit + #showJS showJS.title=Show Javascript diff --git a/src/main/resources/static/images/eraser-fill.svg b/src/main/resources/static/images/eraser-fill.svg new file mode 100644 index 00000000..10959b3d --- /dev/null +++ b/src/main/resources/static/images/eraser-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/templates/fragments/langAndDarkMode.html b/src/main/resources/templates/fragments/langAndDarkMode.html index b587e88e..8c6b0ea3 100644 --- a/src/main/resources/templates/fragments/langAndDarkMode.html +++ b/src/main/resources/templates/fragments/langAndDarkMode.html @@ -3,73 +3,73 @@ - + - + \ No newline at end of file diff --git a/src/main/resources/templates/fragments/navbar.html b/src/main/resources/templates/fragments/navbar.html index 1f034384..d54b198e 100644 --- a/src/main/resources/templates/fragments/navbar.html +++ b/src/main/resources/templates/fragments/navbar.html @@ -104,7 +104,7 @@
- +
@@ -137,7 +137,7 @@ -