diff --git a/magic-link/src/main/java/org/keycloak/experimental/magic/MagicLinkFormAuthenticator.java b/magic-link/src/main/java/org/keycloak/experimental/magic/MagicLinkFormAuthenticator.java index 228f7fe..ac646bc 100755 --- a/magic-link/src/main/java/org/keycloak/experimental/magic/MagicLinkFormAuthenticator.java +++ b/magic-link/src/main/java/org/keycloak/experimental/magic/MagicLinkFormAuthenticator.java @@ -16,21 +16,26 @@ */ package org.keycloak.experimental.magic; +import java.util.HashMap; +import org.keycloak.email.freemarker.beans.ProfileBean; +import java.util.Map; +import java.util.Collections; import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.AuthenticationFlowError; import org.keycloak.authentication.Authenticator; import org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator; import org.keycloak.common.util.KeycloakUriBuilder; -import org.keycloak.email.EmailException; +import org.keycloak.email.freemarker.FreeMarkerEmailTemplateProvider; import org.keycloak.email.EmailSenderProvider; +import org.keycloak.email.EmailTemplateProvider; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; +import org.keycloak.theme.FreeMarkerUtil; import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; /** * @author Stian Thorgersen @@ -40,39 +45,63 @@ public class MagicLinkFormAuthenticator extends AbstractUsernameFormAuthenticato @Override public void action(AuthenticationFlowContext context) { MultivaluedMap formData = context.getHttpRequest().getDecodedFormParameters(); - String email = formData.getFirst("email"); - - UserModel user = context.getSession().users().getUserByEmail(email, context.getRealm()); - if (user == null) { - // Register user - user = context.getSession().users().addUser(context.getRealm(), email); - user.setEnabled(true); - user.setEmail(email); - - // Uncomment the following line to require user to update profile on first login - // user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE); - } - - String key = KeycloakModelUtils.generateId(); - context.getAuthenticationSession().setAuthNote("email-key", key); - - String link = KeycloakUriBuilder.fromUri(context.getRefreshExecutionUrl()).queryParam("key", key).build().toString(); - String body = "Click to login"; - try { - context.getSession().getProvider(EmailSenderProvider.class).send(context.getRealm().getSmtpConfig(), user, "Login link", null, body); - } catch (EmailException e) { - e.printStackTrace(); - } - - context.setUser(user); - context.challenge(context.form().createForm("view-email.ftl")); + String email = formData.getFirst("email").trim(); + System.out.println(email); + System.out.println(context.getRealm().getName()); + String realmName = context.getRealm().getName() ; + + // Uncomment this block if you want to filter // + // the keycloack access to a specific email domaine // + + /*if ( + (!email.endsWith("@gruion.com") && realmName.equals("gruion.com")) + ){ + context.challenge(context.form().createForm("view-error-domain.ftl")); + return; + }else{*/ + UserModel user = context.getSession().users().getUserByEmail(email, context.getRealm()); + if (user == null) { + // Register user + user = context.getSession().users().addUser(context.getRealm(), email); + user.setEnabled(true); + user.setEmail(email); + + // Uncomment the following line to require user to update profile on first login + // user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE); + } + + String key = KeycloakModelUtils.generateId(); + context.getAuthenticationSession().setAuthNote("email-key", key); + + String link = KeycloakUriBuilder.fromUri(context.getRefreshExecutionUrl()).queryParam("key", key).build().toString(); + try { + + Map attributes = new HashMap<>(); + attributes.put("realmName", realmName); + attributes.put("link", link); + FreeMarkerEmailTemplateProvider emailTemplateProvider = new FreeMarkerEmailTemplateProvider(context.getSession(), new FreeMarkerUtil()); + emailTemplateProvider.setRealm(context.getRealm()); + emailTemplateProvider.setUser(user); + String subject = "Login to " + realmName; + emailTemplateProvider.send(subject,Collections.emptyList(), "email-magic-link.ftl", attributes); + + } catch (Exception e) { + context.challenge(context.form().createForm("view-error.ftl")); + e.printStackTrace(); + return; + } + + context.setUser(user); + context.challenge(context.form().createForm("view-email.ftl")); + + //} } @Override public void authenticate(AuthenticationFlowContext context) { String sessionKey = context.getAuthenticationSession().getAuthNote("email-key"); if (sessionKey != null) { - String requestKey = context.getHttpRequest().getUri().getQueryParameters().getFirst("key"); + String requestKey = context.getUriInfo().getQueryParameters().getFirst("key"); if (requestKey != null) { if (requestKey.equals(sessionKey)) { context.success(); diff --git a/magic-link/src/main/resources/theme-resources/messages/messages_en.properties b/magic-link/src/main/resources/theme-resources/messages/messages_en.properties new file mode 100755 index 0000000..9172af5 --- /dev/null +++ b/magic-link/src/main/resources/theme-resources/messages/messages_en.properties @@ -0,0 +1,3 @@ +TitleEmail=Welcome to {0} +FooterEmail=
Best regards,

Magic Link
code source
+LogoEmail=https://www.keycloak.org/resources/favicon.ico \ No newline at end of file diff --git a/magic-link/src/main/resources/theme-resources/templates/html/email-magic-link.ftl b/magic-link/src/main/resources/theme-resources/templates/html/email-magic-link.ftl new file mode 100644 index 0000000..b867059 --- /dev/null +++ b/magic-link/src/main/resources/theme-resources/templates/html/email-magic-link.ftl @@ -0,0 +1,310 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + +
+ +
+ +
+ + + + + +
+ + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + +
+ +
+ +
+ ${kcSanitize(msg("TitleEmail",realmName))?no_esc} +
+ +
+ +
+ Hello

+ Thank you for signing up for ${realmName}. We're really happy to have you! Click the link below to login to your account: +
+ +
+ + + + + +
+

Login to Your Account + +

+
+ +
+ + ${kcSanitize(msg("FooterEmail"))?no_esc} + + +
+ +
+ + +
+ +
+ + + + + +
+ + + + + + + +
+ + + + + +
+ +
+ + + + + +
+ + + + \ No newline at end of file diff --git a/magic-link/src/main/resources/theme-resources/templates/text/email-magic-link.ftl b/magic-link/src/main/resources/theme-resources/templates/text/email-magic-link.ftl new file mode 100644 index 0000000..b762655 --- /dev/null +++ b/magic-link/src/main/resources/theme-resources/templates/text/email-magic-link.ftl @@ -0,0 +1,7 @@ +<#ftl output_format="plainText"> + +${kcSanitize(msg("TitleEmail",realmName))} +Hello +Thank you for signing up for ${realmName}. We're really happy to have you! Click the link below to login to your account: +Login to Your Account +Best regards, diff --git a/magic-link/src/main/resources/theme-resources/templates/view-email.ftl b/magic-link/src/main/resources/theme-resources/templates/view-email.ftl index 650b279..4cff3e5 100644 --- a/magic-link/src/main/resources/theme-resources/templates/view-email.ftl +++ b/magic-link/src/main/resources/theme-resources/templates/view-email.ftl @@ -6,7 +6,10 @@ ${msg("loginTitleHtml",(realm.displayNameHtml!''))?no_esc} <#elseif section = "form"> <#if realm.password> - View email +
+ Please, read your email inbox and follow the instruction +
+ ${auth.attemptedUsername} diff --git a/magic-link/src/main/resources/theme-resources/templates/view-error-domain.ftl b/magic-link/src/main/resources/theme-resources/templates/view-error-domain.ftl new file mode 100644 index 0000000..b6c5deb --- /dev/null +++ b/magic-link/src/main/resources/theme-resources/templates/view-error-domain.ftl @@ -0,0 +1,23 @@ +<#import "template.ftl" as layout> +<@layout.registrationLayout displayInfo=social.displayInfo; section> + <#if section = "title"> + ${msg("loginTitle",(realm.displayName!''))} + <#elseif section = "header"> + ${msg("loginTitleHtml",(realm.displayNameHtml!''))?no_esc} + <#elseif section = "form"> + <#if realm.password> +
+ Error : The email submitted is not valid. +
+ Please use an email using the domain @${msg(realm.displayName)} +
+ + + + + + + diff --git a/magic-link/src/main/resources/theme-resources/templates/view-error.ftl b/magic-link/src/main/resources/theme-resources/templates/view-error.ftl new file mode 100644 index 0000000..4f03e69 --- /dev/null +++ b/magic-link/src/main/resources/theme-resources/templates/view-error.ftl @@ -0,0 +1,24 @@ +<#import "template.ftl" as layout> +<@layout.registrationLayout displayInfo=social.displayInfo; section> + <#if section = "title"> + ${msg("loginTitle",(realm.displayName!''))} + <#elseif section = "header"> + ${msg("loginTitleHtml",(realm.displayNameHtml!''))?no_esc} + <#elseif section = "form"> + <#if realm.password> +
+ Error : The email submitted is not valid. +
+ The email is not valid. + Please, make sure that the email is correct or contact support +
+ + + + + + + diff --git a/pom.xml b/pom.xml index faebb52..a42cbba 100644 --- a/pom.xml +++ b/pom.xml @@ -36,8 +36,8 @@ - 9.0.2 - 1.2.2.Final + 16.1.0 + 2.1.0.Final