diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql
index aa60afa4..09db0c57 100644
--- a/WebsitePanel/Database/update_db.sql
+++ b/WebsitePanel/Database/update_db.sql
@@ -9598,6 +9598,121 @@ UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordExpirationLetterT
GO
+-- USER PASSWORD RESET EMAIL TEMPLATE
+
+
+
+IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'From' )
+BEGIN
+INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'From', N'support@HostingCompany.com')
+END
+GO
+
+DECLARE @UserPasswordResetLetterHtmlBody nvarchar(2500)
+
+Set @UserPasswordResetLetterHtmlBody = N'
+
+ Password expiration notification
+
+
+
+
+
+
Password reset notification
+
+
+
+Hello #user.FirstName#,
+
+
+
+
+We received a request to reset the password for your account. If you made this request, click the link below. If you did not make this request, you can ignore this email.
+
+
+
#passwordResetLink#
+
+
+
+If you have any questions regarding your hosting account, feel free to contact our support department at any time.
+
+
+
+Best regards
+
+
+';
+
+IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'HtmlBody' )
+BEGIN
+INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'HtmlBody', @UserPasswordResetLetterHtmlBody)
+END
+ELSE
+UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetLetterHtmlBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'HtmlBody'
+GO
+
+
+IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'Priority' )
+BEGIN
+INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'Priority', N'Normal')
+END
+GO
+IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'Subject' )
+BEGIN
+INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'Subject', N'Password reset notification')
+END
+GO
+IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'LogoUrl' )
+BEGIN
+INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'LogoUrl', N'https://controlpanel.virtuworks.net/App_Themes/Default/Images/logo.png')
+END
+GO
+
+
+DECLARE @UserPasswordResetLetterTextBody nvarchar(2500)
+
+Set @UserPasswordResetLetterTextBody = N'=========================================
+ Password reset notification
+=========================================
+
+
+Hello #user.FirstName#,
+
+
+We received a request to reset the password for your account. If you made this request, click the link below. If you did not make this request, you can ignore this email.
+
+#passwordResetLink#
+
+If you have any questions regarding your hosting account, feel free to contact our support department at any time.
+
+Best regards'
+
+IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'TextBody' )
+BEGIN
+INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'TextBody', @UserPasswordResetLetterTextBody)
+END
+ELSE
+UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetLetterTextBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'TextBody'
+GO
+
+
+
+
-- ORGANIZATION USER PASSWORD RESET TOKENS
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserSettings.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserSettings.cs
index f6780cf5..3d163d59 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserSettings.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Users/UserSettings.cs
@@ -66,6 +66,7 @@ namespace WebsitePanel.EnterpriseServer
public const string RDS_SETUP_LETTER = "RDSSetupLetter";
public const string RDS_POLICY = "RdsPolicy";
public const string USER_PASSWORD_EXPIRATION_LETTER = "UserPasswordExpirationLetter";
+ public const string USER_PASSWORD_RESET_LETTER = "UserPasswordResetLetter";
public const string HOSTED_ORGANIZATION_PASSWORD_POLICY = "MailboxPasswordPolicy";
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
index e87226ba..f615daaf 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/HostedSolution/OrganizationController.cs
@@ -1538,23 +1538,40 @@ namespace WebsitePanel.EnterpriseServer
throw new Exception(string.Format("Organization not found (ItemId = {0})", itemId));
}
+ Organizations orgProxy = GetOrganizationProxy(org.ServiceId);
+
+
UserInfo owner = PackageController.GetPackageOwner(org.PackageId);
OrganizationUser user = OrganizationController.GetAccount(itemId, accountId);
+ OrganizationUser settings = orgProxy.GetUserGeneralSettings(user.AccountName, org.OrganizationId);
+
+ user.PasswordExpirationDateTime = settings.PasswordExpirationDateTime;
+
if (string.IsNullOrEmpty(mailTo))
{
mailTo = user.PrimaryEmailAddress;
}
- SendResetUserPasswordEmail(owner, user, mailTo, reason, string.Empty);
+ var generalSettings = OrganizationController.GetOrganizationGeneralSettings(itemId);
+
+ var logoUrl = generalSettings != null ? generalSettings.OrganizationLogoUrl : string.Empty;
+
+ SendUserPasswordEmail(owner, user, reason, mailTo, logoUrl, UserSettings.USER_PASSWORD_RESET_LETTER, "USER_PASSWORD_RESET_LETTER");
}
- public static void SendResetUserPasswordEmail(UserInfo owner, OrganizationUser user, string reason, string mailTo, string logoUrl)
+ public static void SendUserExpirationPasswordEmail(UserInfo owner, OrganizationUser user, string reason,
+ string mailTo, string logoUrl)
+ {
+ SendUserPasswordEmail(owner, user, reason, user.PrimaryEmailAddress, logoUrl, UserSettings.USER_PASSWORD_EXPIRATION_LETTER, "USER_PASSWORD_EXPIRATION_LETTER");
+ }
+
+ public static void SendUserPasswordEmail(UserInfo owner, OrganizationUser user, string reason, string mailTo, string logoUrl, string settingsName, string taskName)
{
UserSettings settings = UserController.GetUserSettings(owner.UserId,
- UserSettings.USER_PASSWORD_EXPIRATION_LETTER);
+ settingsName);
- TaskManager.StartTask("ORGANIZATION", "SEND_PASSWORD_RESET_EMAIL", user.ItemId);
+ TaskManager.StartTask("ORGANIZATION", "SEND_" + taskName, user.ItemId);
try
{
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/SchedulerTasks/UserPasswordExpirationNotificationTask.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/SchedulerTasks/UserPasswordExpirationNotificationTask.cs
index 4508a845..bda161b1 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/SchedulerTasks/UserPasswordExpirationNotificationTask.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/SchedulerTasks/UserPasswordExpirationNotificationTask.cs
@@ -41,6 +41,8 @@ namespace WebsitePanel.EnterpriseServer
var generalSettings = OrganizationController.GetOrganizationGeneralSettings(organization.Id);
+ var logoUrl = generalSettings != null ? generalSettings.OrganizationLogoUrl : string.Empty;
+
foreach (var user in usersWithExpiredPasswords)
{
user.ItemId = organization.Id;
@@ -51,7 +53,7 @@ namespace WebsitePanel.EnterpriseServer
continue;
}
- OrganizationController.SendResetUserPasswordEmail(owner, user, "Scheduler Password Expiration Notification", user.PrimaryEmailAddress, generalSettings.OrganizationLogoUrl);
+ OrganizationController.SendUserExpirationPasswordEmail(owner, user, "Scheduler Password Expiration Notification", user.PrimaryEmailAddress, logoUrl);
}
}
}
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution/OrganizationProvider.cs b/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution/OrganizationProvider.cs
index ddeeba63..752509c1 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution/OrganizationProvider.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution/OrganizationProvider.cs
@@ -490,6 +490,11 @@ namespace WebsitePanel.Providers.HostedSolution
{
var result = new List();
+ if (string.IsNullOrEmpty(organizationId))
+ {
+ return result;
+ }
+
var maxPasswordAgeSpan = GetMaxPasswordAge();
var searchRoot = new DirectoryEntry(GetOrganizationPath(organizationId));
@@ -513,7 +518,7 @@ namespace WebsitePanel.Providers.HostedSolution
var expirationDate = pwdLastSetDate.AddDays(maxPasswordAgeSpan.Days);
- if (pwdLastSetDate > expirationDate.AddDays(-daysBeforeExpiration))
+ if (expirationDate.AddDays(-daysBeforeExpiration) < DateTime.Now)
{
var user = new OrganizationUser();
@@ -866,9 +871,22 @@ namespace WebsitePanel.Providers.HostedSolution
retUser.UserPrincipalName = (string)entry.InvokeGet(ADAttributes.UserPrincipalName);
retUser.UserMustChangePassword = GetUserMustChangePassword(entry);
+ retUser.PasswordExpirationDateTime = GetPasswordExpirationDate(entry);
+
return retUser;
}
+ private DateTime GetPasswordExpirationDate(DirectoryEntry entry)
+ {
+ var maxPasswordAgeSpan = GetMaxPasswordAge();
+
+ var pwdLastSetTicks = ConvertADSLargeIntegerToInt64(entry.Properties[ADAttributes.PwdLastSet].Value);
+
+ var pwdLastSetDate = DateTime.FromFileTimeUtc(pwdLastSetTicks);
+
+ return pwdLastSetDate.AddDays(maxPasswordAgeSpan.Days);
+ }
+
private string GetDomainName(string username)
{
string domain = ActiveDirectoryUtils.GetNETBIOSDomainName(RootDomain);
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SettingsUserPasswordResetLetter.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SettingsUserPasswordResetLetter.ascx.resx
new file mode 100644
index 00000000..d0758d63
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SettingsUserPasswordResetLetter.ascx.resx
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ High
+
+
+ Low
+
+
+ Normal
+
+
+ From:
+
+
+ HTML Body:
+
+
+ Logo Url:
+
+
+ No Changes HTML Body:
+
+
+ No Changes Text Body:
+
+
+ Priority:
+
+
+ Subject:
+
+
+ Text Body:
+
+
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/UserAccountMailTemplateSettings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/UserAccountMailTemplateSettings.ascx.resx
index 1ea4b782..cedcfc35 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/UserAccountMailTemplateSettings.ascx.resx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/UserAccountMailTemplateSettings.ascx.resx
@@ -151,6 +151,9 @@
RDS Setup Letter
- User Password Expiration Letter
+ Organization User Password Expiration Letter
+
+
+ Organization User Password Reset Letter
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/OrganizationUserResetPassword.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/OrganizationUserResetPassword.ascx.resx
index 521750a1..adb7dc30 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/OrganizationUserResetPassword.ascx.resx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/App_LocalResources/OrganizationUserResetPassword.ascx.resx
@@ -118,7 +118,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- Sent Password Reset Email
+ Send Password Reset Email
Email:
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx
index b49be890..7da8a076 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ExchangeServer/OrganizationUserResetPassword.ascx
@@ -36,7 +36,7 @@
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx
new file mode 100644
index 00000000..48251fb0
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx
@@ -0,0 +1,45 @@
+<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SettingsUserPasswordResetLetter.ascx.cs" Inherits="WebsitePanel.Portal.SettingsUserPasswordResetLetter" %>
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ High
+ Normal
+ Low
+
+ |
+
+
+ |
+
+ |
+
+
+
|
+
+
+
+ |
+
+
+
|
+
+
+
+ |
+
+
+
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.cs
new file mode 100644
index 00000000..12cb669b
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using WebsitePanel.EnterpriseServer;
+
+namespace WebsitePanel.Portal
+{
+ public partial class SettingsUserPasswordResetLetter : WebsitePanelControlBase, IUserSettingsEditorControl
+ {
+ public void BindSettings(UserSettings settings)
+ {
+ txtFrom.Text = settings["From"];
+ txtSubject.Text = settings["Subject"];
+ Utils.SelectListItem(ddlPriority, settings["Priority"]);
+ txtHtmlBody.Text = settings["HtmlBody"];
+ txtTextBody.Text = settings["TextBody"];
+ txtLogoUrl.Text = settings["LogoUrl"];
+ }
+
+ public void SaveSettings(UserSettings settings)
+ {
+ settings["From"] = txtFrom.Text;
+ settings["Subject"] = txtSubject.Text;
+ settings["Priority"] = ddlPriority.SelectedValue;
+ settings["HtmlBody"] = txtHtmlBody.Text;
+ settings["TextBody"] = txtTextBody.Text;
+ settings["LogoUrl"] = txtLogoUrl.Text;
+ }
+ }
+}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.designer.cs
new file mode 100644
index 00000000..84c322e1
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SettingsUserPasswordResetLetter.ascx.designer.cs
@@ -0,0 +1,123 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace WebsitePanel.Portal {
+
+
+ public partial class SettingsUserPasswordResetLetter {
+
+ ///
+ /// lblFrom control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.Label lblFrom;
+
+ ///
+ /// txtFrom control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.TextBox txtFrom;
+
+ ///
+ /// lblSubject control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.Label lblSubject;
+
+ ///
+ /// txtSubject control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.TextBox txtSubject;
+
+ ///
+ /// lblPriority control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.Label lblPriority;
+
+ ///
+ /// ddlPriority control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.DropDownList ddlPriority;
+
+ ///
+ /// lblLogoUrl control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.Label lblLogoUrl;
+
+ ///
+ /// txtLogoUrl control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.TextBox txtLogoUrl;
+
+ ///
+ /// lblHtmlBody control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.Label lblHtmlBody;
+
+ ///
+ /// txtHtmlBody control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.TextBox txtHtmlBody;
+
+ ///
+ /// lblTextBody control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.Label lblTextBody;
+
+ ///
+ /// txtTextBody control.
+ ///
+ ///
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ ///
+ protected global::System.Web.UI.WebControls.TextBox txtTextBody;
+ }
+}
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserAccountMailTemplateSettings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserAccountMailTemplateSettings.ascx
index 9df60dfc..f74b84f9 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserAccountMailTemplateSettings.ascx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/UserAccountMailTemplateSettings.ascx
@@ -46,6 +46,10 @@
+
+
+