From 4877e8ebade5dd67c77a84c85082ddafeed95d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilhem=20Semp=C3=A9r=C3=A9?= Date: Wed, 21 Aug 2024 17:16:56 +0200 Subject: [PATCH] Merged password recovery feature --- .gitignore | 3 + bundle_files/osx/updateGigwa.command | 4 +- bundle_files/ubuntu/updateGigwa.sh | 4 +- bundle_files/windows/updateGigwa.bat | 4 +- .../security/ResetCodeExpirationFilter.java | 30 ---- .../cirad/service/PasswordResetService.java | 163 +++++++++++++----- .../GigwaAuthenticationController.java | 46 +++-- src/main/resources/.gitignore | 4 +- src/main/resources/applicationContext-MVC.xml | 10 +- src/main/webapp/.gitignore | 1 + src/main/webapp/WEB-INF/jsp/login.jsp | 35 ++-- src/main/webapp/WEB-INF/jsp/lostPassword.jsp | 10 +- src/main/webapp/WEB-INF/jsp/resetPassword.jsp | 28 +-- src/main/webapp/WEB-INF/web.xml | 9 - src/main/webapp/js/.gitignore | 0 15 files changed, 210 insertions(+), 141 deletions(-) create mode 100644 .gitignore delete mode 100644 src/main/java/fr/cirad/security/ResetCodeExpirationFilter.java create mode 100644 src/main/webapp/.gitignore create mode 100644 src/main/webapp/js/.gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..893514f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target/ +/.externalToolBuilders/ +/.settings/ diff --git a/bundle_files/osx/updateGigwa.command b/bundle_files/osx/updateGigwa.command index b9381c2d..649c41f4 100755 --- a/bundle_files/osx/updateGigwa.command +++ b/bundle_files/osx/updateGigwa.command @@ -34,7 +34,7 @@ if [ -d "$1" ]; then #copy configuration files from saved folder to new gigwa folder cp -av $3/$backup_dir.$DATE/WEB-INF/classes/applicationContext-data.xml $2/WEB-INF/classes/applicationContext-data.xml -# cp -av $3/$backup_dir.$DATE/WEB-INF/classes/applicationContext-security.xml $2/WEB-INF/classes/applicationContext-security.xml + cp -av $3/$backup_dir.$DATE/WEB-INF/classes/applicationContext-MVC.xml $2/WEB-INF/classes/applicationContext-MVC.xml cp -av $3/$backup_dir.$DATE/WEB-INF/classes/datasources.properties $2/WEB-INF/classes/datasources.properties cp -av $3/$backup_dir.$DATE/WEB-INF/classes/users.properties $2/WEB-INF/classes/users.properties cp -av $3/$backup_dir.$DATE/WEB-INF/classes/config.properties $2/WEB-INF/classes/config.properties @@ -62,4 +62,4 @@ fi chmod -R 755 $2 echo ------------------------------- -echo "Update complete. You may want to apply chown -R on the updated folder." \ No newline at end of file +echo "Update complete. You may want to apply chown -R on the updated folder." diff --git a/bundle_files/ubuntu/updateGigwa.sh b/bundle_files/ubuntu/updateGigwa.sh index 5dc5b815..05951408 100755 --- a/bundle_files/ubuntu/updateGigwa.sh +++ b/bundle_files/ubuntu/updateGigwa.sh @@ -34,7 +34,7 @@ if [ -d "$1" ]; then #copy configuration files from saved folder to new gigwa folder cp -avr $3/$backup_dir.$DATE/WEB-INF/classes/applicationContext-data.xml $2/WEB-INF/classes/applicationContext-data.xml -# cp -avr $3/$backup_dir.$DATE/WEB-INF/classes/applicationContext-security.xml $2/WEB-INF/classes/applicationContext-security.xml + cp -avr $3/$backup_dir.$DATE/WEB-INF/classes/applicationContext-MVC.xml $2/WEB-INF/classes/applicationContext-MVC.xml cp -avr $3/$backup_dir.$DATE/WEB-INF/classes/datasources.properties $2/WEB-INF/classes/datasources.properties cp -avr $3/$backup_dir.$DATE/WEB-INF/classes/users.properties $2/WEB-INF/classes/users.properties cp -avr $3/$backup_dir.$DATE/WEB-INF/classes/config.properties $2/WEB-INF/classes/config.properties @@ -61,4 +61,4 @@ fi chmod -R 755 $2 echo ------------------------------- -echo "Update complete. You may want to apply chown -R on the updated folder." \ No newline at end of file +echo "Update complete. You may want to apply chown -R on the updated folder." diff --git a/bundle_files/windows/updateGigwa.bat b/bundle_files/windows/updateGigwa.bat index 07ceec17..33d160b3 100644 --- a/bundle_files/windows/updateGigwa.bat +++ b/bundle_files/windows/updateGigwa.bat @@ -55,7 +55,7 @@ xcopy /seyi %1 %2 ::copy configuration files from saved folder to new gigwa folder xcopy /seyi "%3\%backup_dir%.%d%\WEB-INF\classes\applicationContext-data.xml" "%2\WEB-INF\classes\applicationContext-data.xml" -::xcopy /seyi "%3\%backup_dir%.%d%\WEB-INF\classes\applicationContext-security.xml" "%2\WEB-INF\classes\applicationContext-security.xml" +xcopy /seyi "%3\%backup_dir%.%d%\WEB-INF\classes\applicationContext-MVC.xml" "%2\WEB-INF\classes\applicationContext-MVC.xml" xcopy /seyi "%3\%backup_dir%.%d%\WEB-INF\classes\datasources.properties" "%2\WEB-INF\classes\datasources.properties" xcopy /seyi "%3\%backup_dir%.%d%\WEB-INF\classes\users.properties" "%2\WEB-INF\classes\users.properties" xcopy /seyi "%3\%backup_dir%.%d%\WEB-INF\classes\config.properties" "%2\WEB-INF\classes\config.properties" @@ -74,4 +74,4 @@ powershell -Command "$previousPE = $(Select-String -Path %3\%backup_dir%.%d%\WEB echo ------------------------------- echo Update complete. -:eof \ No newline at end of file +:eof diff --git a/src/main/java/fr/cirad/security/ResetCodeExpirationFilter.java b/src/main/java/fr/cirad/security/ResetCodeExpirationFilter.java deleted file mode 100644 index 2774ee89..00000000 --- a/src/main/java/fr/cirad/security/ResetCodeExpirationFilter.java +++ /dev/null @@ -1,30 +0,0 @@ -package fr.cirad.security; - -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import java.io.IOException; -import java.time.LocalDateTime; - -public class ResetCodeExpirationFilter implements Filter { - - private static final String RESET_EXPIRATION_KEY = "resetExpiration"; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletRequest httpRequest = (HttpServletRequest) request; - HttpSession session = httpRequest.getSession(false); - - if (session != null) { - LocalDateTime expiration = (LocalDateTime) session.getAttribute(RESET_EXPIRATION_KEY); - if (expiration != null && expiration.isBefore(LocalDateTime.now())) { - // Clear expired reset information - session.removeAttribute("resetCode"); - session.removeAttribute("resetEmail"); - session.removeAttribute(RESET_EXPIRATION_KEY); - } - } - - chain.doFilter(request, response); - } -} \ No newline at end of file diff --git a/src/main/java/fr/cirad/service/PasswordResetService.java b/src/main/java/fr/cirad/service/PasswordResetService.java index 12a62ff0..d45e4bad 100644 --- a/src/main/java/fr/cirad/service/PasswordResetService.java +++ b/src/main/java/fr/cirad/service/PasswordResetService.java @@ -1,105 +1,176 @@ package fr.cirad.service; -import fr.cirad.security.ReloadableInMemoryDaoImpl; -import fr.cirad.security.UserWithMethod; -import fr.cirad.tools.AppConfig; -import fr.cirad.web.controller.BackOfficeController; +import java.io.IOException; +import java.net.Socket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.time.LocalDateTime; + +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.mail.SimpleMailMessage; -import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import java.io.IOException; -import java.time.LocalDateTime; +import fr.cirad.security.ReloadableInMemoryDaoImpl; +import fr.cirad.security.UserWithMethod; +import fr.cirad.tools.AppConfig; +import fr.cirad.web.controller.BackOfficeController; +import fr.cirad.web.controller.GigwaAuthenticationController; @Service public class PasswordResetService { private static final Logger LOG = Logger.getLogger(PasswordResetService.class); - private static final String RESET_CODE_KEY = "resetCode"; - private static final String RESET_EMAIL_KEY = "resetEmail"; - private static final String RESET_EXPIRATION_KEY = "resetExpiration"; + public static final String RESET_CODE_KEY = "resetCode"; + public static final String RESET_EMAIL_KEY = "resetEmail"; + public static final String RESET_EXPIRATION_KEY = "resetExpiration"; - @Autowired - private JavaMailSender mailSender; + @Autowired(required=false) + private JavaMailSenderImpl mailSender; @Autowired private AppConfig appConfig; @Autowired private ReloadableInMemoryDaoImpl userDao; + + public boolean seemsProperlyConfigured() { + try (Socket socket = new Socket(mailSender.getHost(), mailSender.getPort())) { + return true; + } catch (Exception e) { + if (mailSender != null) { + LOG.error("JavaMailSenderImpl not properly configured", e); + mailSender = null; // only log this error once + } + return false; + } + } public String generateResetCode() { return String.format("%08d", new java.util.Random().nextInt(100000000)); } - public boolean sendResetPasswordEmail(String email, HttpSession session, HttpServletRequest request) { + public boolean sendResetPasswordEmail(String email, HttpSession session, HttpServletRequest request) throws MessagingException, SocketException, UnknownHostException { UserWithMethod user = userDao.getUserWithMethodByEmailAddress(email); if (user == null) { return true; // We return true to not disclose if the email exists } String resetCode = generateResetCode(); + String sWebAppRoot = request.getHeader("referer"); + if (sWebAppRoot != null) + sWebAppRoot = sWebAppRoot.replaceFirst(GigwaAuthenticationController.LOGIN_LOST_PASSWORD_URL, ""); + else { + sWebAppRoot = appConfig.get("enforcedWebapRootUrl"); + if (sWebAppRoot == null) { + String computedBaseURL = BackOfficeController.determinePublicHostName(request); + if (computedBaseURL != null) + sWebAppRoot = computedBaseURL + request.getContextPath(); + } + } + if (sWebAppRoot == null) + LOG.warn("Unable to determine password reset link. None will be mentioned in the e-mail!"); + + String subject = "Gigwa - Password reset request"; + String emailContent = "Hello,\n\nYou have requested to reset your password" + + (sWebAppRoot == null ? "" : " for the following Gigwa instance: " + sWebAppRoot + GigwaAuthenticationController.LOGIN_RESET_PASSWORD_URL) + + ".\nYour password reset code is: " + resetCode + "\nPlease enter this code in the application to reset your password. This code will expire in 5 minutes.\n"; + + MimeMessage message = mailSender.createMimeMessage(); + MimeMultipart multipart = new MimeMultipart("alternative"); + MimeBodyPart messageTxtBody = new MimeBodyPart(); + + messageTxtBody.setContent(emailContent, "text/plain; charset=" + mailSender.getDefaultEncoding()); + + multipart.addBodyPart(messageTxtBody); + + message.setContent(multipart); + message.setSentDate(new java.util.Date()); + String adminEmail = appConfig.get("adminEmail"); + message.addFrom(new InternetAddress[] {new InternetAddress(adminEmail != null ? adminEmail : getNoReplyAddress(mailSender))}); + + message.setSubject(subject); + message.addRecipient(Message.RecipientType.TO, new InternetAddress(email)); + message.saveChanges(); + + mailSender.send(message); + session.setAttribute(RESET_CODE_KEY, resetCode); session.setAttribute(RESET_EMAIL_KEY, email); session.setAttribute(RESET_EXPIRATION_KEY, LocalDateTime.now().plusMinutes(5)); + return true; + } + + public static String getNoReplyAddress(JavaMailSenderImpl mailSender) throws IllegalArgumentException{ + String host = mailSender.getHost(); + + // Try regex replacement for common prefixes + String cleanedHost = host.replaceFirst("^(smtp|mail)\\.", ""); + + // If regex didn't change the host, fall back to string manipulation + if (cleanedHost.equals(host)) { + int secondLastDotIndex = host.lastIndexOf('.', host.lastIndexOf('.') - 1); + if (secondLastDotIndex != -1) + cleanedHost = host.substring(secondLastDotIndex + 1); + } - try { - SimpleMailMessage message = new SimpleMailMessage(); - - String sWebAppRoot = appConfig.get("enforcedWebapRootUrl"); - String enforcedWebapRootUrl = (sWebAppRoot == null ? BackOfficeController.determinePublicHostName(request) + request.getContextPath() : sWebAppRoot); - if (enforcedWebapRootUrl == null || enforcedWebapRootUrl.trim().isEmpty()) - LOG.warn("enforcedWebapRootUrl is not set in the application.properties file. Using the default value."); + // Construct the "noreply" email address + String noReplyAddress = "noreply@" + cleanedHost; - String subject = "Gigwa - Password reset request"; - String emailContent = "Hello,\n\nYou have requested to reset your password for the following Gigwa instance: " + enforcedWebapRootUrl + "\nYour password reset code is: " + resetCode + "\nPlease enter this code in the application to reset your password. This code will expire in 5 minutes.\n"; + // Validate the email address + if (!isValidEmailAddress(noReplyAddress)) + throw new IllegalArgumentException("Generated noreply address is not valid: " + noReplyAddress); - message.setTo(email); - message.setSubject(subject); - message.setText(emailContent); + return noReplyAddress; + } - mailSender.send(message); - return true; - } catch (Exception e) { - LOG.error("Unable to send password reset email", e); - return false; - } + private static boolean isValidEmailAddress(String email) { + // Simple email validation regex + String emailRegex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$"; + return email.matches(emailRegex); } public boolean validateResetCode(String code, HttpSession session) { - String storedCode = (String) session.getAttribute(RESET_CODE_KEY); LocalDateTime expiration = (LocalDateTime) session.getAttribute(RESET_EXPIRATION_KEY); - if (storedCode == null || !storedCode.equals(code) || expiration == null) { + String storedCode = (String) session.getAttribute(RESET_CODE_KEY); + if (expiration == null || storedCode == null || expiration.isBefore(LocalDateTime.now())) { // Clear expired or invalid reset information + session.removeAttribute(RESET_CODE_KEY); + session.removeAttribute(RESET_EMAIL_KEY); + session.removeAttribute(RESET_EXPIRATION_KEY); return false; } - return expiration.isAfter(LocalDateTime.now()); + if (!storedCode.equals(code)) + return false; // failed attempt + + return true; } public boolean updatePassword(String code, String newPassword, HttpSession session) { - if (!validateResetCode(code, session)) { + if (!validateResetCode(code, session)) return false; - } String email = (String) session.getAttribute(RESET_EMAIL_KEY); UserWithMethod user = userDao.getUserWithMethodByEmailAddress(email); - if (user == null) { + if (user == null) return false; - } try { - userDao.saveOrUpdateUser(user.getUsername(), newPassword, - user.getAuthorities(), - user.isEnabled(), user.getMethod(), user.getEmail()); - } catch (IOException e) { - e.printStackTrace(); + userDao.saveOrUpdateUser(user.getUsername(), newPassword, user.getAuthorities(), user.isEnabled(), user.getMethod(), user.getEmail()); + } + catch (IOException e) { + LOG.error("Error while overriding user password", e); return false; } diff --git a/src/main/java/fr/cirad/web/controller/GigwaAuthenticationController.java b/src/main/java/fr/cirad/web/controller/GigwaAuthenticationController.java index c923c87e..1328c217 100644 --- a/src/main/java/fr/cirad/web/controller/GigwaAuthenticationController.java +++ b/src/main/java/fr/cirad/web/controller/GigwaAuthenticationController.java @@ -4,12 +4,12 @@ import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.Random; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.web.savedrequest.SavedRequest; import org.springframework.stereotype.Controller; @@ -17,14 +17,18 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; import fr.cirad.security.GigwaAuthenticationSuccessHandler; import fr.cirad.service.PasswordResetService; @Controller public class GigwaAuthenticationController { - private static final String LOGIN_LOST_PASSWORD_URL = "/lostPassword.do"; - private static final String LOGIN_RESET_PASSWORD_URL = "/resetPassword.do"; + + private static final Logger LOG = Logger.getLogger(GigwaAuthenticationController.class); + + public static final String LOGIN_LOST_PASSWORD_URL = "/lostPassword.do"; + public static final String LOGIN_RESET_PASSWORD_URL = "/resetPassword.do"; private static final String LOGIN_CAS_URL = "/login/cas.do"; private static final String LOGIN_FORM_URL = "/login.do"; @@ -35,7 +39,7 @@ public class GigwaAuthenticationController { private GigwaAuthenticationSuccessHandler authenticationSuccessHandler; @GetMapping(LOGIN_FORM_URL) - public String loginFormPath(HttpServletRequest request, HttpServletResponse response) { + public ModelAndView loginFormPath(HttpServletRequest request, HttpServletResponse response) { SavedRequest savedRequest = authenticationSuccessHandler.getRequestCache().getRequest(request, response); if (savedRequest != null) { String targetUrl = savedRequest.getRedirectUrl(); @@ -44,7 +48,9 @@ public String loginFormPath(HttpServletRequest request, HttpServletResponse resp request.setAttribute("loginOrigin", redirectUrl); } catch (UnsupportedEncodingException ignored) {} } - return "login"; + ModelAndView mav = new ModelAndView(); + mav.addObject("resetPasswordEnabled", passwordResetService.seemsProperlyConfigured()); + return mav; } @GetMapping(LOGIN_CAS_URL) @@ -61,31 +67,41 @@ public String casLoginPath(@RequestParam(name="url", required=false) String redi } @GetMapping(LOGIN_LOST_PASSWORD_URL) - public String lostPasswordForm() { - return "lostPassword"; + public void lostPasswordForm() { } @PostMapping(LOGIN_LOST_PASSWORD_URL) public String sendResetPasswordEmail(@RequestParam String email, HttpSession session, HttpServletRequest request, Model model) { - passwordResetService.sendResetPasswordEmail(email, session, request); - model.addAttribute("message", "If this e-mail address matches a user account, a 5-minute valid code has just been sent to it."); - return "resetPassword"; + try { + passwordResetService.sendResetPasswordEmail(email, session, request); + model.addAttribute("message", "If this e-mail address matches a user account, a 5-minute valid code has just been sent to it."); + return "redirect:" + LOGIN_RESET_PASSWORD_URL; + } + catch (Exception e) { + LOG.error("Unable to send password reset email", e); + model.addAttribute("error", "An error occured while sending e-mail. If problem persists please contact administrator."); + return "redirect:" + LOGIN_LOST_PASSWORD_URL; + } + } + + @GetMapping(LOGIN_RESET_PASSWORD_URL) + public void resetPasswordForm() { } @PostMapping(LOGIN_RESET_PASSWORD_URL) public String resetPassword(@RequestParam String code, @RequestParam String newPassword, HttpSession session, Model model) { if (newPassword.length() > 20) { model.addAttribute("error", "Password must not exceed 20 characters."); - return "resetPassword"; + return "redirect:" + LOGIN_RESET_PASSWORD_URL; } boolean updated = passwordResetService.updatePassword(code, newPassword, session); if (updated) { - model.addAttribute("message", "Password updated successfully. You can now login."); - return "login"; + model.addAttribute("message", "Password updated successfully. You may now login."); + return "redirect:" + LOGIN_FORM_URL; } else { model.addAttribute("error", "Invalid or expired code. Please try again."); - return "resetPassword"; + return "redirect:" + LOGIN_RESET_PASSWORD_URL; } } -} +} \ No newline at end of file diff --git a/src/main/resources/.gitignore b/src/main/resources/.gitignore index 625e8a22..6e69e891 100644 --- a/src/main/resources/.gitignore +++ b/src/main/resources/.gitignore @@ -1,3 +1,5 @@ /applicationContext-data.xml /config.properties -/datasources.properties \ No newline at end of file +/datasources.properties +/users.properties +/applicationContext-MVC.xml diff --git a/src/main/resources/applicationContext-MVC.xml b/src/main/resources/applicationContext-MVC.xml index 53080e36..95e83098 100644 --- a/src/main/resources/applicationContext-MVC.xml +++ b/src/main/resources/applicationContext-MVC.xml @@ -46,13 +46,13 @@ - - - - + + + + - mail.debug=true + mail.debug=false mail.smtp.auth=false mail.smtp.starttls.enable=false mail.smtp.ssl.enable=false diff --git a/src/main/webapp/.gitignore b/src/main/webapp/.gitignore new file mode 100644 index 00000000..3385916d --- /dev/null +++ b/src/main/webapp/.gitignore @@ -0,0 +1 @@ +/META-INF/ diff --git a/src/main/webapp/WEB-INF/jsp/login.jsp b/src/main/webapp/WEB-INF/jsp/login.jsp index 26a4fc4e..66cc1e7a 100644 --- a/src/main/webapp/WEB-INF/jsp/login.jsp +++ b/src/main/webapp/WEB-INF/jsp/login.jsp @@ -15,7 +15,7 @@ * Public License V3. --%> -<%@ page language="java" contentType="text/html; charset=utf-8" import="fr.cirad.web.controller.ga4gh.Ga4ghRestController,fr.cirad.web.controller.gigwa.GigwaRestController" %> +<%@ page language="java" contentType="text/html; charset=utf-8" import="fr.cirad.web.controller.GigwaAuthenticationController" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> @@ -63,7 +63,9 @@
- Lost your password? + + Lost your password? +
"> @@ -74,17 +76,24 @@ ${casOrganization}organization account - -
-   - - -
-
+ + +
+   + + +
+
+ + +

${param.message}

+
+
+
"> diff --git a/src/main/webapp/WEB-INF/jsp/lostPassword.jsp b/src/main/webapp/WEB-INF/jsp/lostPassword.jsp index 777512c9..4ac2f1fd 100644 --- a/src/main/webapp/WEB-INF/jsp/lostPassword.jsp +++ b/src/main/webapp/WEB-INF/jsp/lostPassword.jsp @@ -1,6 +1,6 @@ -<%@ page language="java" contentType="text/html; charset=utf-8" %> +<%@ page language="java" contentType="text/html; charset=utf-8" import="fr.cirad.web.controller.GigwaAuthenticationController" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> @@ -21,10 +21,10 @@
Gigwa
RESET PASSWORD
-
+ - -

${error}

+ +

${param.error}

@@ -35,4 +35,4 @@
- + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/resetPassword.jsp b/src/main/webapp/WEB-INF/jsp/resetPassword.jsp index af58bb74..0bd36b54 100644 --- a/src/main/webapp/WEB-INF/jsp/resetPassword.jsp +++ b/src/main/webapp/WEB-INF/jsp/resetPassword.jsp @@ -1,5 +1,6 @@ -<%@ page language="java" contentType="text/html; charset=utf-8" %> + +<%@ page language="java" contentType="text/html; charset=utf-8" import="fr.cirad.web.controller.GigwaAuthenticationController" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> @@ -32,19 +33,24 @@
-
-
+
+
Gigwa
RESET PASSWORD
-
+ - - -

${error}

-
- -

${message}

-
+ + + + +

${param.error}

+
+ + +

${param.message}

+
+
+
Return to login page diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 0e79bd7e..b74c6040 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -10,15 +10,6 @@ - - resetCodeExpirationFilter - fr.cirad.security.ResetCodeExpirationFilter - - - resetCodeExpirationFilter - /* - - forwardedHeaderFilter org.springframework.web.filter.ForwardedHeaderFilter diff --git a/src/main/webapp/js/.gitignore b/src/main/webapp/js/.gitignore new file mode 100644 index 00000000..e69de29b