keycloak-aplcache

Details

diff --git a/server-spi/src/main/java/org/keycloak/services/managers/ClientSessionCode.java b/server-spi/src/main/java/org/keycloak/services/managers/ClientSessionCode.java
index 5e24681..91c388f 100755
--- a/server-spi/src/main/java/org/keycloak/services/managers/ClientSessionCode.java
+++ b/server-spi/src/main/java/org/keycloak/services/managers/ClientSessionCode.java
@@ -65,6 +65,7 @@ public class ClientSessionCode {
         ClientSessionCode code;
         boolean clientSessionNotFound;
         boolean illegalHash;
+        ClientSessionModel clientSession;
 
         public ClientSessionCode getCode() {
             return code;
@@ -77,6 +78,10 @@ public class ClientSessionCode {
         public boolean isIllegalHash() {
             return illegalHash;
         }
+
+        public ClientSessionModel getClientSession() {
+            return clientSession;
+        }
     }
 
     public static ParseResult parseResult(String code, KeycloakSession session, RealmModel realm) {
@@ -89,19 +94,19 @@ public class ClientSessionCode {
             String[] parts = code.split("\\.");
             String id = parts[1];
 
-            ClientSessionModel clientSession = session.sessions().getClientSession(realm, id);
-            if (clientSession == null) {
+            result.clientSession = session.sessions().getClientSession(realm, id);
+            if (result.clientSession == null) {
                 result.clientSessionNotFound = true;
                 return result;
             }
 
-            String hash = createHash(realm, clientSession);
+            String hash = createHash(realm, result.clientSession);
             if (!hash.equals(parts[0])) {
                 result.illegalHash = true;
                 return result;
             }
 
-            result.code = new ClientSessionCode(realm, clientSession);
+            result.code = new ClientSessionCode(realm, result.clientSession);
             return result;
         } catch (RuntimeException e) {
             result.illegalHash = true;
diff --git a/services/src/main/java/org/keycloak/services/messages/Messages.java b/services/src/main/java/org/keycloak/services/messages/Messages.java
index ca1db96..71238b7 100755
--- a/services/src/main/java/org/keycloak/services/messages/Messages.java
+++ b/services/src/main/java/org/keycloak/services/messages/Messages.java
@@ -151,6 +151,8 @@ public class Messages {
 
     public static final String INVALID_CODE = "invalidCodeMessage";
 
+    public static final String STALE_VERIFY_EMAIL_LINK = "staleEmailVerificationLink";
+
     public static final String IDENTITY_PROVIDER_UNEXPECTED_ERROR = "identityProviderUnexpectedErrorMessage";
 
     public static final String IDENTITY_PROVIDER_NOT_FOUND = "identityProviderNotFoundMessage";
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index e46cbca..e23f9df 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -169,6 +169,7 @@ public class LoginActionsService {
     private class Checks {
         ClientSessionCode clientCode;
         Response response;
+        ClientSessionCode.ParseResult result;
 
         boolean verifyCode(String code, String requiredAction, ClientSessionCode.ActionType actionType) {
             if (!verifyCode(code)) {
@@ -213,7 +214,7 @@ public class LoginActionsService {
                 response = ErrorPage.error(session, Messages.REALM_NOT_ENABLED);
                 return false;
             }
-            ClientSessionCode.ParseResult result = ClientSessionCode.parseResult(code, session, realm);
+            result = ClientSessionCode.parseResult(code, session, realm);
             clientCode = result.getCode();
             if (clientCode == null) {
                 if (result.isClientSessionNotFound()) { // timeout
@@ -654,6 +655,9 @@ public class LoginActionsService {
         if (key != null) {
             Checks checks = new Checks();
             if (!checks.verifyCode(code, ClientSessionModel.Action.REQUIRED_ACTIONS.name(), ClientSessionCode.ActionType.USER)) {
+                if (checks.clientCode == null && checks.result.isClientSessionNotFound() || checks.result.isIllegalHash()) {
+                   return ErrorPage.error(session, Messages.STALE_VERIFY_EMAIL_LINK);
+                }
                 return checks.response;
             }
             ClientSessionCode accessCode = checks.clientCode;
@@ -661,7 +665,7 @@ public class LoginActionsService {
             if (!ClientSessionModel.Action.VERIFY_EMAIL.name().equals(clientSession.getNote(AuthenticationManager.CURRENT_REQUIRED_ACTION))) {
                 logger.reqdActionDoesNotMatch();
                 event.error(Errors.INVALID_CODE);
-                throw new WebApplicationException(ErrorPage.error(session, Messages.INVALID_CODE));
+                throw new WebApplicationException(ErrorPage.error(session, Messages.STALE_VERIFY_EMAIL_LINK));
             }
 
             UserSessionModel userSession = clientSession.getUserSession();
diff --git a/themes/src/main/resources/theme/base/login/messages/messages_en.properties b/themes/src/main/resources/theme/base/login/messages/messages_en.properties
old mode 100644
new mode 100755
index 0641230..cc3f410
--- a/themes/src/main/resources/theme/base/login/messages/messages_en.properties
+++ b/themes/src/main/resources/theme/base/login/messages/messages_en.properties
@@ -205,6 +205,7 @@ identityProviderLinkSuccess=Your account was successfully linked with {0} accoun
 realmSupportsNoCredentialsMessage=Realm does not support any credential type.
 identityProviderNotUniqueMessage=Realm supports multiple identity providers. Could not determine which identity provider should be used to authenticate with.
 emailVerifiedMessage=Your email address has been verified.
+staleEmailVerificationLink=The link you clicked is a old stale link and is no longer valid.  Maybe you have already verified your email?
 
 locale_ca=Catal\u00E0
 locale_de=Deutsch