Commit 71417f26 by chenith Committed by Harsh Shah

Added password reset option to admin portal.

parent 6f8284b6
<?xml version="1.0" encoding="UTF-8"?>
<!-- @AutoRun -->
<OBJECTS name="" xmlns:oneit="http://www.1iT.com.au"><NODE name="Script" factory="Vector">
<NODE name="DDL" factory="Participant" class="oneit.sql.transfer.DefineTableOperation">
<tableName factory="String">oneit_sec_user_extension</tableName>
<column name="object_id" type="Long" nullable="false" length="11"/>
<column name="object_last_updated_date" type="Date" nullable="false" length="22"/>
<column name="object_created_date" type="Date" nullable="false" length="22"/>
<column name="object_type" type="String" nullable="false" length="30"/>
<column name="forgot_password_mail_send_date" type="Date" nullable="true"/>
<column name="forgot_password_key" type="String" nullable="true" length="10"/>
<column name="user_id" type="Long" length="11" nullable="true"/>
</NODE>
<NODE name="INDEX" factory="Participant" class="oneit.sql.transfer.DefineIndexOperation" tableName="oneit_sec_user_extension" indexName="idx_oneit_sec_user_extension_user_id" isUnique="false"><column name="user_id"/></NODE>
</NODE></OBJECTS>
\ No newline at end of file
-- DROP TABLE oneit_sec_user_extension;
CREATE TABLE oneit_sec_user_extension (
object_id int NOT NULL ,
object_last_updated_date datetime DEFAULT getdate() NOT NULL ,
object_created_date datetime DEFAULT getdate() NOT NULL
, object_type varchar(30) NOT NULL ,
forgot_password_mail_send_date datetime NULL,
forgot_password_key varchar(10) NULL,
user_id numeric(12) NULL
);
ALTER TABLE oneit_sec_user_extension ADD
CONSTRAINT PK_oneit_sec_user_extension PRIMARY KEY
(
object_id
) ;
CREATE INDEX idx_oneit_sec_user_extension_user_id
ON oneit_sec_user_extension (user_id);
-- DROP TABLE oneit_sec_user_extension;
CREATE TABLE oneit_sec_user_extension (
object_id number(12) NOT NULL ,
object_last_updated_date date DEFAULT SYSDATE NOT NULL ,
object_created_date date DEFAULT SYSDATE NOT NULL
, object_type varchar2(30) NOT NULL ,
forgot_password_mail_send_date date NULL,
forgot_password_key varchar2(10) NULL,
user_id number(12) NULL
);
ALTER TABLE oneit_sec_user_extension ADD
CONSTRAINT PK_oneit_sec_user_extension PRIMARY KEY
(
object_id
) ;
CREATE INDEX idx_oneit_sec_user_extension_user_id
ON oneit_sec_user_extension (user_id);
-- @AutoRun
-- drop table oneit_sec_user_extension;
CREATE TABLE oneit_sec_user_extension (
object_id numeric(12) NOT NULL ,
object_last_updated_date timestamp DEFAULT NOW() NOT NULL ,
object_created_date timestamp DEFAULT NOW() NOT NULL
, object_type varchar(30) NOT NULL ,
forgot_password_mail_send_date timestamp NULL,
forgot_password_key varchar(10) NULL,
user_id numeric(12) NULL
);
ALTER TABLE oneit_sec_user_extension ADD
CONSTRAINT pk_oneit_sec_user_extension PRIMARY KEY
(
object_id
) ;
CREATE INDEX idx_oneit_sec_user_extension_user_id
ON oneit_sec_user_extension (user_id);
package performa.form;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.components.ParticipantInitialisationContext;
import oneit.email.ConfigurableEmailer;
import oneit.logging.*;
import oneit.net.LoopbackHTTP;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.StorageException;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.security.SecUser;
import oneit.security.SecUserExtension;
import oneit.servlets.forms.*;
import oneit.servlets.process.*;
import oneit.utils.*;
import oneit.utils.transform.MapTransform;
import oneit.utils.transform.param.ErrorTransform;
import oneit.utils.transform.param.ORMTransform;
import oneit.utils.transform.param.PrefixCompoundTransform;
import performa.orm.AdminUser;
public class ForgotPasswordFP extends SaveFP
{
private static LoggingArea LOG = LoggingArea.createLoggingArea("ForgotPasswordFP");
protected int DEFAULT_PASSWORD_LENGTH = 6;
protected ConfigurableEmailer resetCodeEmailer;
@Override
public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException
{
HttpServletRequest request = submission.getRequest();
ObjectTransaction objTran = process.getTransaction();
String email = (String) request.getParameter("email");
Debug.assertion(email != null, "Email not avaialble");
LogMgr.log(LOG, LogLevel.PROCESSING1, "Started to send pasword reset link email.", email);
SecUser secUser = SecUser.searchNAME (process.getTransaction(), email);
if(secUser==null)
{
SecUser[] userSearch = SecUser.SearchByALL().andEmail(new EqualsFilter<>(email)).search(objTran);
if(userSearch.length>0)
{
secUser = userSearch[0];
}
}
if(secUser!=null)
{
LogMgr.log(LOG, LogLevel.PROCESSING1, "Inside ForgotPasswordFP for send reset pasword link mail to ", email);
AdminUser adminUser = secUser.getExtensionOrCreate(AdminUser.REFERENCE_AdminUser);
if(adminUser.getForgotPasswordKey()==null)
{
String resetCode = new RandomStringGen().generateHumanAlphaNum(new Integer(DEFAULT_PASSWORD_LENGTH));
adminUser.setForgotPasswordKey(resetCode);
}
adminUser.setForgotPasswordMailSendDate(new Date());
Map emailParams = CollectionUtils.mapEntry("resetcode", adminUser.getForgotPasswordKey())
.mapEntry("url", LoopbackHTTP.getRemoteAccessURL()
+ "/extensions/adminportal/reset_password.jsp"
+ "?id=" + adminUser.getID()
+ "&key=" + adminUser.getForgotPasswordKey()).toMap();
PrefixCompoundTransform compoundTransform = new PrefixCompoundTransform();
ObjectTransform defaultTransform = new MapTransform(emailParams);
compoundTransform.setDefault(defaultTransform);
compoundTransform.add("user", new ORMTransform(secUser));
ObjectTransform transform = new StringUtils.NullToBlankPostTransform(new ErrorTransform(compoundTransform));
try
{
resetCodeEmailer.sendMail(transform, new String[] { email });
LogMgr.log(LOG, LogLevel.PROCESSING1, "Mail has been sent from " + ForgotPasswordFP.class + " to :: ", email);
}
catch(Exception e)
{
LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING1, e, "Error while sending email");
throw new BusinessException("Mail can not be sent. Please contact administrator.");
}
}
else
{
throw new BusinessException("Sorry, we don't recognize that email address.");
}
return super.processForm(process, submission, params);
}
public void init(ParticipantInitialisationContext context) throws InitialisationException
{
super.init(context);
resetCodeEmailer = (ConfigurableEmailer)(context.getSingleChild("ResetCodeEmailer"));
}
}
\ No newline at end of file
package performa.form;
import java.util.Map;
import oneit.logging.*;
import oneit.objstore.StorageException;
import oneit.objstore.parser.BusinessObjectParser;
import oneit.security.SecUser;
import oneit.servlets.forms.*;
import oneit.servlets.process.*;
import oneit.utils.*;
import performa.orm.AdminUser;
import performa.utils.Utils;
public class ResetPasswordFP extends ORMProcessFormProcessor
{
private static LoggingArea LOG = LoggingArea.createLoggingArea("ResetPasswordFP");
@Override
public SuccessfulResult processForm(ORMProcessState process, SubmissionDetails submission, Map params) throws BusinessException, StorageException
{
SecUser user = (SecUser) process.getAttribute("SecUser");
AdminUser adminUser = user.getExtension(AdminUser.REFERENCE_AdminUser);
if(adminUser != null)
{
LogMgr.log(LOG, LogLevel.PROCESSING1, "Inside ResetPasswordFP for reset pasword to ", user);
adminUser.setForgotPasswordKey(null);
}
return Utils.processSuccessfulLogin(process, submission, params, user);
}
@Override
public void validate(ORMProcessState process, SubmissionDetails submission, MultiException exceptions, Map params) throws StorageException
{
super.validate(process, submission, exceptions, params);
SecUser user = (SecUser) process.getAttribute("SecUser");
Debug.assertion(user != null, "No user found for rest password. Call from " + getClass().getName());
BusinessObjectParser.assertFieldCondition(user.getPassword().length() >= 8, user, SecUser.FIELD_Password, exceptions, true, submission.getRequest());
}
}
\ No newline at end of file
package performa.orm;
import oneit.objstore.ObjectTransaction;
import oneit.security.SecUser;
import oneit.utils.CollectionUtils;
import oneit.utils.StringUtils;
public class AdminUser extends BaseAdminUser
{
private static final long serialVersionUID = 0L;
// This constructor should not be called
public AdminUser ()
{
// Do not add any code to this, always put it in initialiseNewObject
}
public static AdminUser getAdminUserForForgotPassword(ObjectTransaction transaction, String userIDStr, String code)
{
userIDStr = StringUtils.subBlanks(userIDStr);
code = StringUtils.subBlanks(code);
if(userIDStr != null && code!=null)
{
AdminUser adminUser = AdminUser.getAdminUserByID(transaction, Long.parseLong(userIDStr));
if(adminUser != null && CollectionUtils.equals(adminUser.getForgotPasswordKey(), code))
{
return adminUser;
}
}
return null;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ROOT xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='http://www.oneit.com.au/schemas/5.2/BusinessObject.xsd'>
<BUSINESSCLASS name="AdminUser" package="performa.orm" superclass="SecUserExtension">
<IMPORT value="oneit.security.*" />
<TABLE name="oneit_sec_user_extension" tablePrefix="object" polymorphic="TRUE">
<ATTRIB name="ForgotPasswordMailSendDate" type="Date" dbcol="forgot_password_mail_send_date" />
<ATTRIB name="ForgotPasswordKey" type="String" dbcol="forgot_password_key" length="10"/>
<SINGLEREFERENCE name="User" type="SecUser" dbcol="user_id" backreferenceName="Extensions" inSuper='TRUE'/>
</TABLE>
<SEARCH type="All" paramFilter="oneit_sec_user_extension.object_id is not null" >
</SEARCH>
<SEARCH type="IdPin" paramFilter="oneit_sec_user_extension.object_id is not null" singleton="TRUE">
<PARAM name="ID" type="Long" paramFilter="object_id = ${ID} " />
<PARAM name="Pin" type="String" paramFilter="verification_key = ${Pin}" />
</SEARCH>
</BUSINESSCLASS>
</ROOT>
\ No newline at end of file
......@@ -2,6 +2,7 @@ package performa.utils;
import java.util.*;
import javax.activation.DataSource;
import javax.servlet.http.*;
import oneit.email.ConfigurableArticleTemplateEmailer;
import oneit.email.ConfigurableEmailerException;
import oneit.logging.LogLevel;
......@@ -17,6 +18,13 @@ import performa.orm.*;
import performa.orm.types.Importance;
import performa.orm.types.JobSortOption;
import oneit.objstore.utils.*;
import oneit.security.jsp.PasswordDIHandler;
import oneit.servlets.forms.RedirectResult;
import oneit.servlets.forms.SubmissionDetails;
import oneit.servlets.forms.SuccessfulResult;
import oneit.servlets.orm.DataMap;
import oneit.servlets.process.ORMProcessState;
import oneit.servlets.security.SessionSecUserDecorator;
import oneit.utils.*;
import oneit.utils.filter.CollectionFilter;
import oneit.utils.filter.Filter;
......@@ -232,4 +240,30 @@ public class Utils
LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING1, "Mail sent from Utils class to " + Arrays.toString(emails));
}
public static String getPwdKeyOfSecUser(HttpServletRequest request, SecUser user, boolean mandatoryPwd)
{
if(user != null)
{
DataMap dm = DataMap.getDataMap(request, true);
return dm.storeORMHandler(new PasswordDIHandler(user, "md5:" + SecUser.FIELD_Password, mandatoryPwd), user, "md5:" + SecUser.FIELD_Password);
}
return "";
}
public static SuccessfulResult processSuccessfulLogin(ORMProcessState process, SubmissionDetails submission, Map params, SecUser user) throws BusinessException
{
HttpServletRequest request = submission.getRequest();
request.getSession().setAttribute (SecUser.SEC_USER_ID, user);
request.getSession().setAttribute (SessionSecUserDecorator.REFRESH_SECURITY, Boolean.TRUE);
process.completeAndRestart();
return new RedirectResult((String) request.getAttribute("nextPage"), null);
}
}
......@@ -40,6 +40,7 @@ public class WebUtils
public static final String UNSUITABLE_APPS = "UnsuitableApps";
public static final String VIEW_APPLICANTS_GRID = "ViewApplicantsGrid";
public static final String APPLICANT_ACCOUNT_VERIFICATION = "ApplicantAccountVerification";
public static final String RESET_PASSWORD_ARTICLE = "ResetPasswordEmail";
public static String getArticleLink(HttpServletRequest request, ObjectTransaction objTran, String articleShortcut, String renderMode)
......
......@@ -54,6 +54,18 @@
<!--<FORM name="*.linkedinOAuthLogin" factory="Participant" class="performa.form.LinkedInOAuthLoginFP"/>-->
</NODE>
<NODE name="forgot_password_jsp" factory="Participant">
<INHERITS factory="Named" nodename="CoreORMAdminNoPriv"/>
<FORM name="*.forgotPassword" factory="Participant" class="performa.form.ForgotPasswordFP">
<ResetCodeEmailer factory="Participant" class="oneit.email.ConfigurableArticleTemplateEmailer" templateShortcut="ResetCodeEmail"/>
</FORM>
</NODE>
<NODE name="reset_password_jsp" factory="Participant">
<INHERITS factory="Named" nodename="CoreORMAdminNoPriv"/>
<FORM name="*.resetPassword" factory="Participant" class="performa.form.ResetPasswordFP"/>
</NODE>
<NODE name="ORMErrorConfig::ADMIN_PORTAL" factory="Participant" class="oneit.servlets.forms.ErrorReportConfig">
<format item="field.*.error.pageHeader_performa_errorPrefix">
<![CDATA[<div class="error-message message-common"><img src="${contextRoot}/images/error-alert.png" class="alert-icon" /><span class="message-txt" style="font-weight: bold">${translateLabel:Errors_Occurred:Errors occurred, please correct them and try again}</span><br/>]]>
......
<%@ page extends="oneit.servlets.jsp.FormJSP" %>
<%@ include file="/setuprequest.jsp" %>
<%@ include file="/inc/stdimports50.jsp" %><%-- This is in cougar --%>
<%@ include file="/extensions/performa/inc/stdimports.jsp" %>
<%! protected String getName (ServletConfig config) { return "forgot_password_jsp"; } %>
<html lang="en">
<head>
<meta charset="utf-8"></meta>
<meta http-equiv="X-UA-Compatible" content="IE=edge"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1"></meta>
<title>Talentology</title>
<%@include file="/inc/std_imports.jsp" %>
</head>
<body class="bg-color">
<script type="text/javascript">
$(document).ready(function() {
validate();
$('input').on('change keyup', function() { validate() });
});
function validate() {
var empty = false;
$('input[required]').each(function() {
if ($( this ).val() == '') {
empty = true;
if ($( this ).css('background-color') == 'rgb(250, 255, 189)') {
empty = false;
}
}
});
if (empty) {
$('.send-btn').attr('disabled', 'disabled');
} else {
$('.send-btn').removeAttr('disabled');
}
}
</script>
<style>
button[disabled] {
opacity: 0.6;
background-color: #0582ba;
}
</style>
<div class="container">
<div class="row">
<div class="main-verify-identity">
<div class="login-logo"><img src="<%= request.getContextPath() %>/images/logo.svg" /></div>
<oneit:form name="forgotPassword" method="post">
<oneit:dynInclude page="/extensions/applicantportal/inc/multifieldtext.jsp" data="<%= CollectionUtils.EMPTY_MAP%>"/>
<div class="main-box-layout login-box">
<div class="text-left">
<p >
Enter your email address below. If we find a matching account, then you'll receive an email with a password reset link.
</p>
</div>
<div>&nbsp;</div>
<div class="form-group text-left">
<label>Email Address</label>
<input type="email" class="form-control" name="email" required>
</div>
<div class="form-group">
<oneit:button value="Send" name="forgotPassword" cssClass="box-btn send-btn"
requestAttribs="<%= CollectionUtils.mapEntry("nextPage", "sign_in.jsp?sent=true")
.mapEntry(NotificationUtils.NOTIFICATION_MSG_PARAM, "resetPasswordEmailSent")
.toMap() %>"/>
</div>
</div>
</oneit:form>
</div>
</div>
</div>
</body>
</html>
\ No newline at end of file
......@@ -2,3 +2,4 @@
#exceedMaxShortlisted = Selected number of applications exceed maximum shortlist application count
#saveTemplateFirst = Please save template first, before proceeding to the next step
#passwordNotMatch = The password does not match. Please try again.
#resetPasswordEmailSent = A password rest email has been sent to you. Please check your email.
\ No newline at end of file
<%@ page extends="oneit.servlets.jsp.FormJSP" %>
<%@ include file="/setuprequest.jsp" %>
<%@ include file="/inc/stdimports50.jsp" %><%-- This is in cougar --%>
<%@ include file="/extensions/performa/inc/stdimports.jsp" %>
<%! protected String getName (ServletConfig config) { return "reset_password_jsp"; } %>
<%
ORMProcessState process = (ORMProcessState)ProcessDecorator.getDefaultProcess(request);
String adminUserID = (String) process.getAttribute("adminUserID"); //request.getParameter("id");
String forgotpasswordCode = (String) process.getAttribute("forgotpasswordCode"); //request.getParameter("key");
SecUser user = (SecUser) process.getAttribute("SecUser");
Article home = WebUtils.getArticleByShortCut(process.getTransaction(), WebUtils.ADMIN_HOME);
String nextPage = home.getLink(request);
if(request.getParameter("id")!=null)
{
adminUserID = request.getParameter("id");
process.setAttribute("adminUserID", adminUserID);
}
if(request.getParameter("key")!=null)
{
forgotpasswordCode = request.getParameter("key");
process.setAttribute("forgotpasswordCode", forgotpasswordCode);
}
if(StringUtils.subBlanks(adminUserID) != null)
{
AdminUser adminUser = AdminUser.getAdminUserForForgotPassword(process.getTransaction(), adminUserID, forgotpasswordCode);
if(adminUser != null)
{
user = adminUser.getUser();
if(StringUtils.subBlanks(forgotpasswordCode) != null)
{
RandomStringGen random = new RandomStringGen();
user.setAttribute("md5:Password", random.generateAlphaNum(8));
}
process.setAttribute("SecUser", user);
}
}
%>
<html lang="en">
<head>
<meta charset="utf-8"></meta>
<meta http-equiv="X-UA-Compatible" content="IE=edge"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1"></meta>
<title>Talentology</title>
<%@include file="/inc/std_imports.jsp" %>
</head>
<body class="bg-color">
<script type="text/javascript">
$(document).ready(function() {
validate();
$('input').on('change keyup', function() { validate() });
});
function validate() {
var empty = false;
$('.password-field').each(function() {
if ($( this ).val() == '') {
empty = true;
}
});
if (empty) {
$('.reset-btn').attr('disabled', 'disabled');
} else {
$('.reset-btn').removeAttr('disabled');
}
}
</script>
<style>
button[disabled] {
opacity: 0.6;
background-color: #0582ba;
}
</style>
<div class="container">
<div class="row">
<div class="main-verify-identity">
<div class="login-logo"><img src="<%= request.getContextPath() %>/images/logo.svg" /></div>
<oneit:form name="resetPassword" method="post">
<oneit:dynInclude page="/extensions/applicantportal/inc/multifieldtext.jsp" data="<%= CollectionUtils.EMPTY_MAP%>"/>
<%
if(user!=null)
{
String key = Utils.getPwdKeyOfSecUser(request, user, true);
%>
<div class="main-box-layout login-box">
<div class="text-left">
<p >
Please enter a new password below.
</p>
</div>
<div>&nbsp;</div>
<div class="form-group text-left">
<label>Password *</label>
<oneit:input type="password" name="<%= key %>" class="form-control password-field"/>
</div> <!-- form-group -->
<div class="form-group text-left">
<label>Confirm Password *</label>
<oneit:input type="password" name="<%= key + 2 %>" class="form-control password-field"/>
</div> <!-- form-group -->
<div class="col-sm-12" style="text-align: right">
<oneit:button value="Set New Password" name="resetPassword" cssClass="box-btn reset-btn"
requestAttribs="<%= CollectionUtils.mapEntry("nextPage", nextPage).toMap() %>"/>
</div>
</div>
<%
}
else
{
%>
<h3 class="text-danger">Invalid User or this link has been expired, generate new link to access this page.</h3>
<%
}
%>
</oneit:form>
</div>
</div>
</div>
</body>
</html>
......@@ -63,6 +63,8 @@
<oneit:form name="login" method="post">
<oneit:dynInclude page="/extensions/applicantportal/inc/multifieldtext.jsp" data="<%= CollectionUtils.EMPTY_MAP%>"/>
<div class="main-box-layout login-box">
<div class="form-group text-left">
<label>Email Address</label>
<input type="text" class="form-control" name="username" required>
......@@ -72,8 +74,9 @@
<input type="password" class="form-control" name="password" required>
</div>
<div class="form-group">
<a href="#" class="forgot-pass" style="display: none">Forgot password?</a>
<oneit:button value="Forgot password?" name="gotoPage" cssClass="forgot-pass" skin="link"
requestAttribs="<%= CollectionUtils.mapEntry("nextPage", "forgot_password.jsp")
.toMap() %>"></oneit:button>
<oneit:button value="Sign in" name="login" cssClass="box-btn login-btn"
requestAttribs="<%= CollectionUtils.EMPTY_MAP%>"/>
......@@ -105,6 +108,7 @@
</ul>
</oneit:form>
</div>
</oneit:form>
<footer class="power-footer">
<div class="footer-link text-center">
<ul>
......
<?xml version="1.0" encoding="UTF-8"?>
<!-- @AutoRun -->
<OBJECTS xmlns:oneit="http://www.1iT.com.au" name="">
<NODE factory="Vector" name="Script"><NODE class="oneit.appservices.upgrade.cms.CMSArticleUpdateOperation" factory="Participant" name="Reset Code Email">
<createSpecificIdentifier factory='String' value='WFDXIOQKNEMOGB6ZGPF8XV08WZZAHO'/>
<articleIdentifiers factory="Array" class="java.lang.String">
<NODE factory="String" value="WFDXIOQKNEMOGB6ZGPF8XV08WZZAHO"/>
</articleIdentifiers>
<createdLabel factory="String" value="WFDXIOQKNEMOGB6ZGPF8XV08WZZAHO"/>
<articleAttributeChanges factory="Map">
<NODE name="EmailTo" factory="Null"/>
<NODE name="EmailFrom" factory="String" value="info@talentology.com.au"/>
<NODE name="EmailSubject" factory="String" value="Password reset code"/>
<NODE name="Shortcuts" factory="String" value="ResetCodeEmail"/>
<NODE name="EmailCC" factory="Null"/>
<NODE name="EmailBCC" factory="Null"/>
</articleAttributeChanges>
<ormAttributeChanges factory="Map">
<NODE name="PublishDate" factory="Date" value="2016-02-05 00:00:00"/>
<NODE name="WithdrawDate" factory="Date" value="2066-02-05 16:00:00"/>
<NODE name="Title" factory="String" value="Reset Code Email"/>
<NODE name="ShortTitle" factory="String" value="Reset Code Email"/>
<NODE name="SortOrder" factory="Integer" value="-200926"/>
<NODE name="Type" factory="Enumerated" class="oneit.business.content.ArticleType" value="ARTICLE"/>
<NODE name="Template" factory="Enumerated" class="oneit.business.content.ArticleTemplate" value="EMAIL_TEMPLATE"/>
</ormAttributeChanges>
<content factory="Map"> <NODE name="EmailBody" factory="Map">
<NODE name="Content" factory="String"><![CDATA[<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="HTML Tidy, see www.w3.org" name="generator">
<title></title>
</head>
<body>
<p>Hello,</p>
<p>We have received request&nbsp;to reset your&nbsp;account&nbsp;password.</p>
<p>Click below link to reset your password.</p>
<p>
<a href="${url}">Reset Passsword</a>
</p>
<p>Thank You.</p>
</body>
</html>
]]></NODE>
<NODE name="TransformedContent" factory="String"><![CDATA[<p>Hello,</p><p>We have received request&nbsp;to reset your&nbsp;account&nbsp;password.</p><p>Click below link to reset your password.</p><p>
<a href="${url}">Reset Passsword</a>
</p><p>Thank You.</p>
]]></NODE>
<NODE name="IncludeContent" factory="Boolean" value="true"/>
</NODE>
<NODE name="" factory="Map">
<NODE name="Content" factory="String"><![CDATA[
<p></p>
]]></NODE>
<NODE name="IncludeContent" factory="Boolean" value="true"/>
</NODE>
</content>
</NODE>
</NODE>
</OBJECTS>
\ No newline at end of file
......@@ -17,6 +17,7 @@
<MAP code="TestInput" class="performa.orm.TestInput"/>
<MAP code="JobApplication" class="performa.orm.JobApplication"/>
<MAP code="Candidate" class="performa.orm.Candidate"/>
<MAP code="AdminUser" class="performa.orm.AdminUser"/>
</NODE>
</OBJECTS>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment