From d7061ab633b2ab039123ee6e6b427d80512e3445 Mon Sep 17 00:00:00 2001
From: Mike McKay <mfmckay@wustl.edu>
Date: Wed, 25 May 2016 17:09:49 -0500
Subject: [PATCH] Moved notifications stuff to NotificationsPreferences.

---
 .../nrg/pipeline/XnatPipelineLauncher.java    |   4 +-
 .../java/org/nrg/viewer/QCImageCreator.java   |   2 +-
 .../rest/notifications/NotificationsApi.java  | 172 ++++++++++++------
 .../java/org/nrg/xnat/archive/Transfer.java   |   2 +-
 .../configuration/NotificationsConfig.java    |  22 ++-
 .../xnat/configuration/SchedulerConfig.java   |  21 +--
 .../SiteConfigPreferenceHandler.java          |  89 +--------
 .../AliasTokenPreferenceHandlerMethod.java    |  12 +-
 .../InactivityBeforeLockoutHandlerMethod.java |  64 +++++++
 .../ResetFailedLoginsHandlerMethod.java       |  63 +++++++
 .../restlet/actions/TriggerPipelines.java     |   2 +-
 .../resources/ProjtExptPipelineResource.java  |   4 +-
 .../modules/actions/ManagePipeline.java       |   2 +-
 .../modules/actions/PipelineActions.java      |   2 +-
 .../turbine/modules/actions/QDECAction.java   |   2 +-
 .../xnat/turbine/utils/ArcSpecManager.java    |  72 ++++----
 .../xnat/spawner/site-admin-elements.yaml     |  12 +-
 .../webapp/scripts/project/settingsTabMgmt.js |   2 +-
 18 files changed, 325 insertions(+), 224 deletions(-)
 create mode 100644 src/main/java/org/nrg/xnat/event/listeners/methods/InactivityBeforeLockoutHandlerMethod.java
 create mode 100644 src/main/java/org/nrg/xnat/event/listeners/methods/ResetFailedLoginsHandlerMethod.java

diff --git a/src/main/java/org/nrg/pipeline/XnatPipelineLauncher.java b/src/main/java/org/nrg/pipeline/XnatPipelineLauncher.java
index 30b67854..022aae13 100644
--- a/src/main/java/org/nrg/pipeline/XnatPipelineLauncher.java
+++ b/src/main/java/org/nrg/pipeline/XnatPipelineLauncher.java
@@ -625,7 +625,7 @@ public class XnatPipelineLauncher {
         xnatPipelineLauncher.setParameter("useremail", user.getEmail());
         xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user));
         xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail());
-        xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+        xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
         xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName());
 
         xnatPipelineLauncher.setId(imageSession.getId());
@@ -662,7 +662,7 @@ public class XnatPipelineLauncher {
         xnatPipelineLauncher.setParameter("useremail", user.getEmail());
         xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user));
         xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail());
-        xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+        xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
         xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName());
 
         xnatPipelineLauncher.setId(imageSession.getId());
diff --git a/src/main/java/org/nrg/viewer/QCImageCreator.java b/src/main/java/org/nrg/viewer/QCImageCreator.java
index 821ee534..ca8090f3 100644
--- a/src/main/java/org/nrg/viewer/QCImageCreator.java
+++ b/src/main/java/org/nrg/viewer/QCImageCreator.java
@@ -51,7 +51,7 @@ public class QCImageCreator {
         xnatPipelineLauncher.setParameter("session", mrSession.getId() );
         xnatPipelineLauncher.setParameter("notify", "0" );
 	    xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName());
-	    xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+	    xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
 	    xnatPipelineLauncher.setParameter("useremail", user.getEmail());
 	    xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail());
 
diff --git a/src/main/java/org/nrg/xapi/rest/notifications/NotificationsApi.java b/src/main/java/org/nrg/xapi/rest/notifications/NotificationsApi.java
index 71cd31ba..5f489efb 100644
--- a/src/main/java/org/nrg/xapi/rest/notifications/NotificationsApi.java
+++ b/src/main/java/org/nrg/xapi/rest/notifications/NotificationsApi.java
@@ -13,19 +13,20 @@ import org.nrg.notify.entities.*;
 import org.nrg.notify.exceptions.DuplicateDefinitionException;
 import org.nrg.notify.exceptions.DuplicateSubscriberException;
 import org.nrg.notify.services.NotificationService;
+import org.nrg.prefs.exceptions.InvalidPreferenceName;
+import org.nrg.xapi.exceptions.InitializationException;
 import org.nrg.xdat.XDAT;
-import org.nrg.xdat.preferences.SiteConfigPreferences;
+import org.nrg.xdat.preferences.NotificationsPreferences;
 import org.nrg.xdat.rest.AbstractXnatRestApi;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.mail.javamail.JavaMailSenderImpl;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.*;
 
 import javax.inject.Inject;
 import java.util.*;
@@ -49,6 +50,88 @@ public class NotificationsApi extends AbstractXnatRestApi {
                                                        + "modify the existing server configuration. You can completely replace the configuration "
                                                        + "by calling the POST version of this method.";
 
+    @ApiOperation(value = "Sets a map of notifications properties.", notes = "Sets the notifications properties specified in the map.", response = Void.class)
+    @ApiResponses({@ApiResponse(code = 200, message = "Notifications properties successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set notifications properties."), @ApiResponse(code = 500, message = "Unexpected error")})
+    @RequestMapping(value = "batch", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
+    public ResponseEntity<Void> setBatchNotificationsProperties(@ApiParam(value = "The map of notifications properties to be set.", required = true) @RequestBody final Map<String, String> properties) throws InitializationException {
+        final HttpStatus status = isPermitted();
+        if (status != null) {
+            return new ResponseEntity<>(status);
+        }
+
+        if (_log.isInfoEnabled()) {
+            final StringBuilder message = new StringBuilder("User ").append(getSessionUser().getUsername()).append(" is setting the values for the following properties:\n");
+            for (final String name : properties.keySet()) {
+                message.append(" * ").append(name).append(": ").append(properties.get(name)).append("\n");
+            }
+            _log.info(message.toString());
+        }
+
+        for (final String name : properties.keySet()) {
+            try {
+                _notificationsPrefs.set(properties.get(name), name);
+                if (_log.isInfoEnabled()) {
+                    _log.info("Set property {} to value: {}", name, properties.get(name));
+                }
+            } catch (InvalidPreferenceName invalidPreferenceName) {
+                _log.error("Got an invalid preference name error for the preference: " + name + ", which is weird because the site configuration is not strict");
+            }
+        }
+//        ArcSpecManager initializaton not required for notifications since none of their properties are set in the ArcSpec.
+//        if (properties.containsKey("initialized") && StringUtils.equals("true", properties.get("initialized"))) {
+//            initialize();
+//        }
+
+        return new ResponseEntity<>(HttpStatus.OK);
+    }
+
+    @ApiOperation(value = "Sets a map of notifications properties for mail.", notes = "Sets the notifications properties for mail specified in the map.", response = Void.class)
+    @ApiResponses({@ApiResponse(code = 200, message = "Notifications properties for mail successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set notifications properties for mail."), @ApiResponse(code = 500, message = "Unexpected error")})
+    @RequestMapping(value = "batchMail", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
+    public ResponseEntity<Void> setBatchNotificationsPropertiesForMail(@ApiParam(value = "The map of notifications properties for mail to be set.", required = true) @RequestBody final Map<String, String> properties) throws InitializationException {
+        final HttpStatus status = isPermitted();
+        if (status != null) {
+            return new ResponseEntity<>(status);
+        }
+
+        if (_log.isInfoEnabled()) {
+            final StringBuilder message = new StringBuilder("User ").append(getSessionUser().getUsername()).append(" is setting the values for the following properties:\n");
+            for (final String name : properties.keySet()) {
+                message.append(" * ").append(name).append(": ").append(properties.get(name)).append("\n");
+            }
+            _log.info(message.toString());
+        }
+
+        for (final String name : properties.keySet()) {
+            try {
+                _notificationsPrefs.set(properties.get(name), name);
+                if (_log.isInfoEnabled()) {
+                    _log.info("Set property {} to value: {}", name, properties.get(name));
+                }
+            } catch (InvalidPreferenceName invalidPreferenceName) {
+                _log.error("Got an invalid preference name error for the preference: " + name + ", which is weird because the site configuration is not strict");
+            }
+        }
+
+
+        final Properties javaMailProperties = new Properties();
+        if (properties != null) {
+            for (final String property : properties.keySet()) {
+                final String value = properties.get(property);
+                if (StringUtils.isNotBlank(value)) {
+                    javaMailProperties.setProperty(property, value);
+                }
+            }
+        }
+        logConfigurationSubmit(_javaMailSender.getHost(),_javaMailSender.getPort(),_javaMailSender.getUsername(),_javaMailSender.getPassword(),_javaMailSender.getProtocol(), properties);
+        _javaMailSender.setJavaMailProperties(javaMailProperties);
+
+        setSmtp();
+
+        return new ResponseEntity<>(HttpStatus.OK);
+    }
+
+
     @ApiOperation(value = "Returns the full SMTP server configuration.", notes = "Returns the configuration as a map of the standard Java mail sender properties&ndash;host, port, protocol, username, and password&ndash;along with any extended properties required for the configuration, e.g. configuring SSL- or TLS-secured SMTP services.", response = Properties.class)
     @ApiResponses({@ApiResponse(code = 200, message = "SMTP service configuration properties successfully retrieved."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set site configuration properties."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = "smtp", produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
@@ -262,7 +345,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Help email message successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the help email message."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"messages/help"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Void> setHelpContactInfo(@ApiParam(value = "The email message for contacting help.", required = true) @RequestParam final String message) {
-        _siteConfigPrefs.setHelpContactInfo(message);
+        _notificationsPrefs.setHelpContactInfo(message);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -270,7 +353,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "User registration email message successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the user registration email message."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"messages/registration"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setEmailMessageUserRegistration(@ApiParam(value = "The email message for user registration.", required = true) @RequestParam final String message) {
-        _siteConfigPrefs.setEmailMessageUserRegistration(message);
+        _notificationsPrefs.setEmailMessageUserRegistration(message);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -278,7 +361,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Forgot username email message successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the forgot username email message."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"messages/forgotusername"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setEmailMessageForgotUsernameRequest(@ApiParam(value = "The email message for forgot username.", required = true) @RequestParam final String message) {
-        _siteConfigPrefs.setEmailMessageForgotUsernameRequest(message);
+        _notificationsPrefs.setEmailMessageForgotUsernameRequest(message);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -286,7 +369,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Password reset message successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the password reset message."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"messages/passwordreset"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setEmailMessageForgotPasswordReset(@ApiParam(value = "The email message for password reset.", required = true) @RequestParam final String message) {
-        _siteConfigPrefs.setEmailMessageForgotPasswordReset(message);
+        _notificationsPrefs.setEmailMessageForgotPasswordReset(message);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -294,35 +377,35 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Email message for contacting help successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for contacting help."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"messages/help"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<String> getHelpContactInfo() {
-        return new ResponseEntity<>(_siteConfigPrefs.getHelpContactInfo(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getHelpContactInfo(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns the email message for user registration.", notes = "This returns the email message that people should receive when they register. Link for email validation is auto-populated.", response = String.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Email message for user registration successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for user registration."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"messages/registration"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<String> getEmailMessageUserRegistration() {
-        return new ResponseEntity<>(_siteConfigPrefs.getEmailMessageUserRegistration(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getEmailMessageUserRegistration(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns the email message for forgot username.", notes = "This returns the email message that people should receive when they click that they forgot their username.", response = String.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Email message for forgot username successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for forgot username."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"messages/forgotusername"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<String> getEmailMessageForgotUsernameRequest() {
-        return new ResponseEntity<>(_siteConfigPrefs.getEmailMessageForgotUsernameRequest(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getEmailMessageForgotUsernameRequest(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns the email message for password reset.", notes = "This returns the email message that people should receive when they click to reset their password.  Link for password reset is auto-populated.", response = String.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Email message for password reset successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for password reset."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"messages/passwordreset"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<String> getEmailMessageForgotPasswordReset() {
-        return new ResponseEntity<>(_siteConfigPrefs.getEmailMessageForgotPasswordReset(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getEmailMessageForgotPasswordReset(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Sets whether admins should be notified of user registration.", notes = "Sets whether admins should be notified of user registration.", response = String.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Whether admins should be notified of user registration successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether admins should be notified of user registration."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"notify/registration"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Void> setNotifyAdminUserRegistration(@ApiParam(value = "Whether admins should be notified of user registration successfully set.", required = true) @RequestParam final boolean notify) {
-        _siteConfigPrefs.setNotifyAdminUserRegistration(notify);
+        _notificationsPrefs.setNotifyAdminUserRegistration(notify);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -330,7 +413,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Whether admins should be notified of pipeline processing submit successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether admins should be notified of pipeline processing submit."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"notify/pipeline"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setNotifyAdminPipelineEmails(@ApiParam(value = "Whether admins should be notified of pipeline processing submit successfully set.", required = true) @RequestParam final boolean notify) {
-        _siteConfigPrefs.setNotifyAdminPipelineEmails(notify);
+        _notificationsPrefs.setNotifyAdminPipelineEmails(notify);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -338,7 +421,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Whether admins should be notified of project access requests successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether admins should be notified of project access requests."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"notify/par"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setNotifyAdminProjectAccessRequest(@ApiParam(value = "Whether admins should be notified of project access requests successfully set.", required = true) @RequestParam final boolean notify) {
-        _siteConfigPrefs.setNotifyAdminProjectAccessRequest(notify);
+        _notificationsPrefs.setNotifyAdminProjectAccessRequest(notify);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -346,7 +429,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Whether admins should be notified of session transfer successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether admins should be notified of session transfer."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"notify/transfer"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setNotifyAdminSessionTransfer(@ApiParam(value = "Whether admins should be notified of session transfer successfully set.", required = true) @RequestParam final boolean notify) {
-        _siteConfigPrefs.setNotifyAdminSessionTransfer(notify);
+        _notificationsPrefs.setNotifyAdminSessionTransfer(notify);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -354,35 +437,35 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Email message for contacting help successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for contacting help."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"notify/registration"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<Boolean> getNotifyAdminUserRegistration() {
-        return new ResponseEntity<>(_siteConfigPrefs.getNotifyAdminUserRegistration(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getNotifyAdminUserRegistration(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns whether admins should be notified of pipeline processing submit.", notes = "This returns whether admins should be notified of pipeline processing submit.", response = Boolean.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Email message for user registration successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for user registration."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"notify/pipeline"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<Boolean> getNotifyAdminPipelineEmails() {
-        return new ResponseEntity<>(_siteConfigPrefs.getNotifyAdminPipelineEmails(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getNotifyAdminPipelineEmails(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns whether admins should be notified of project access requests.", notes = "This returns whether admins should be notified of project access requests.", response = Boolean.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Email message for forgot username successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for forgot username."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"notify/par"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<Boolean> getNotifyAdminProjectAccessRequest() {
-        return new ResponseEntity<>(_siteConfigPrefs.getNotifyAdminProjectAccessRequest(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getNotifyAdminProjectAccessRequest(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns whether admins should be notified of session transfer.", notes = "This returns whether admins should be notified of session transfer.", response = Boolean.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Email message for password reset successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for password reset."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"notify/transfer"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<Boolean> getNotifyAdminSessionTransfer() {
-        return new ResponseEntity<>(_siteConfigPrefs.getNotifyAdminSessionTransfer(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getNotifyAdminSessionTransfer(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Sets whether non-users should be able to subscribe to notifications.", notes = "Sets whether non-users should be able to subscribe to notifications.", response = String.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Whether non-users should be able to subscribe to notifications."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether non-users should be able to subscribe to notifications."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"allow/nonusersubscribers/{setting}"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setEmailAllowNonuserSubscribers(@ApiParam(value = "Whether non-users should be able to subscribe to notifications.", required = true) @PathVariable final boolean setting) {
-        _siteConfigPrefs.setEmailAllowNonuserSubscribers(setting);
+        _notificationsPrefs.setEmailAllowNonuserSubscribers(setting);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -390,7 +473,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Whether non-users should be able to subscribe to notifications successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get whether non-users should be able to subscribe to notifications."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"allow/nonusersubscribers"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<Boolean> getEmailAllowNonuserSubscribers() {
-        return new ResponseEntity<>(_siteConfigPrefs.getEmailAllowNonuserSubscribers(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getEmailAllowNonuserSubscribers(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Sets the email addresses for error notifications.", notes = "Sets the email addresses that should be subscribed to error notifications.", response = Properties.class)
@@ -398,7 +481,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @RequestMapping(value = {"subscribers/error"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Void> setErrorSubscribers(@ApiParam(value = "The values to set for email addresses for error notifications.", required = true) @RequestParam final String subscribers) {
         setSubscribersForNotificationType(NotificationType.Error, subscribers);
-        _siteConfigPrefs.setEmailRecipientErrorMessages(subscribers);
+        _notificationsPrefs.setEmailRecipientErrorMessages(subscribers);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -407,7 +490,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @RequestMapping(value = {"subscribers/issue"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setIssueSubscribers(@ApiParam(value = "The values to set for email addresses for issue notifications.", required = true) @RequestParam final String subscribers) {
         setSubscribersForNotificationType(NotificationType.Issue, subscribers);
-        _siteConfigPrefs.setEmailRecipientIssueReports(subscribers);
+        _notificationsPrefs.setEmailRecipientIssueReports(subscribers);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -416,7 +499,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @RequestMapping(value = {"subscribers/newuser"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setNewUserSubscribers(@ApiParam(value = "The values to set for email addresses for new user notifications.", required = true) @RequestParam final String subscribers) {
         setSubscribersForNotificationType(NotificationType.NewUser, subscribers);
-        _siteConfigPrefs.setEmailRecipientNewUserAlert(subscribers);
+        _notificationsPrefs.setEmailRecipientNewUserAlert(subscribers);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -425,7 +508,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @RequestMapping(value = {"subscribers/update"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST})
     public ResponseEntity<Properties> setUpdateSubscribers(@ApiParam(value = "The values to set for email addresses for update notifications.", required = true) @RequestParam final String subscribers) {
         setSubscribersForNotificationType(NotificationType.Update, subscribers);
-        _siteConfigPrefs.setEmailRecipientUpdate(subscribers);
+        _notificationsPrefs.setEmailRecipientUpdate(subscribers);
         return new ResponseEntity<>(HttpStatus.OK);
     }
 
@@ -433,28 +516,28 @@ public class NotificationsApi extends AbstractXnatRestApi {
     @ApiResponses({@ApiResponse(code = 200, message = "Error notification subscribers successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get subscribers for email notifications."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"subscribers/error"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<String> getErrorSubscribers() {
-        return new ResponseEntity<>(_siteConfigPrefs.getEmailRecipientErrorMessages(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getEmailRecipientErrorMessages(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns list of email addresses subscribed to issue notifications.", notes = "This returns a list of all the email addresses that are subscribed to receive issue notifications.", response = String.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Issue notification subscribers successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get subscribers for email notifications."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"subscribers/issue"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<String> getIssueSubscribers() {
-        return new ResponseEntity<>(_siteConfigPrefs.getEmailRecipientIssueReports(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getEmailRecipientIssueReports(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns list of email addresses subscribed to new user notifications.", notes = "This returns a list of all the email addresses that are subscribed to receive new user notifications.", response = String.class)
     @ApiResponses({@ApiResponse(code = 200, message = "New user notification subscribers successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get subscribers for email notifications."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"subscribers/newuser"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<String> getNewUserSubscribers() {
-        return new ResponseEntity<>(_siteConfigPrefs.getEmailRecipientNewUserAlert(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getEmailRecipientNewUserAlert(), HttpStatus.OK);
     }
 
     @ApiOperation(value = "Returns list of email addresses subscribed to update notifications.", notes = "This returns a list of all the email addresses that are subscribed to receive update notifications.", response = String.class)
     @ApiResponses({@ApiResponse(code = 200, message = "Update notification subscribers successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get subscribers for email notifications."), @ApiResponse(code = 500, message = "Unexpected error")})
     @RequestMapping(value = {"subscribers/update"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
     public ResponseEntity<String> getUpdateSubscribers() {
-        return new ResponseEntity<>(_siteConfigPrefs.getEmailRecipientUpdate(), HttpStatus.OK);
+        return new ResponseEntity<>(_notificationsPrefs.getEmailRecipientUpdate(), HttpStatus.OK);
     }
 
     private void setSmtp() {
@@ -476,7 +559,7 @@ public class NotificationsApi extends AbstractXnatRestApi {
                 smtp.put(property, properties.getProperty(property));
             }
         }
-        _siteConfigPrefs.setSmtpServer(smtp);
+        _notificationsPrefs.setSmtpServer(smtp);
     }
 
     private void cleanProperties(final Map<String, String> properties) {
@@ -605,31 +688,12 @@ public class NotificationsApi extends AbstractXnatRestApi {
         }
     }
 
-//    private List<String> getSubscribersForNotificationType(NotificationType notificationType){
-//        List<String> subscriberEmails = new ArrayList<String>();
-//        Category category = _notificationService.getCategoryService().newEntity();
-//        category.setScope(CategoryScope.Site);
-//        category.setEvent(notificationType.id());
-//        Definition definition1 = null;
-//        try {
-//            definition1 = _notificationService.getDefinitionService().getDefinitionForCategoryAndEntity(category,1L);
-//            List<Subscription> subscriptions = definition1.getSubscriptions();
-//            for(Subscription subscription : subscriptions){
-//                for(String email : subscription.getSubscriber().getEmailList()){
-//                    subscriberEmails.add(email);
-//                }
-//            }
-//        } catch (DuplicateDefinitionException e) {
-//            _log.error("Multiple definitions for this scope, event, and entity exist.",e);
-//        }
-//        return subscriberEmails;
-//    }
-
     private static final Logger _log    = LoggerFactory.getLogger(NotificationsApi.class);
     private static final String NOT_SET = "NotSet";
 
-    @Inject
-    private SiteConfigPreferences _siteConfigPrefs;
+    @Autowired
+    @Lazy
+    private NotificationsPreferences _notificationsPrefs;
 
     @Inject
     private JavaMailSenderImpl _javaMailSender;
diff --git a/src/main/java/org/nrg/xnat/archive/Transfer.java b/src/main/java/org/nrg/xnat/archive/Transfer.java
index 7fc86549..36c9995e 100644
--- a/src/main/java/org/nrg/xnat/archive/Transfer.java
+++ b/src/main/java/org/nrg/xnat/archive/Transfer.java
@@ -131,7 +131,7 @@ public class Transfer {
             xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user));
             xnatPipelineLauncher.setParameter("adminemail", admin_email);
             xnatPipelineLauncher.setParameter("xnatserver", system);
-            xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+            xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
             xnatPipelineLauncher.setParameter("sessionType", mr.getXSIType());
             xnatPipelineLauncher.setParameter("xnat_project", mr.getProject());
             xnatPipelineLauncher.setParameter("logDir", XDAT.getSiteConfigPreferences().getCachePath() + "logs" + "/" + "transfer");
diff --git a/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java b/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java
index ff21b027..888f8c18 100644
--- a/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java
@@ -27,17 +27,19 @@ public class NotificationsConfig {
     public JavaMailSenderImpl mailSender() throws IOException, SiteConfigurationException {
         final Map<String, String> smtp = _preferences.getSmtpServer();
         final JavaMailSenderImpl sender = new JavaMailSenderImpl();
-        sender.setHost(StringUtils.defaultIfBlank(smtp.remove("host"), "localhost"));
-        sender.setPort(Integer.parseInt(StringUtils.defaultIfBlank(smtp.remove("port"), "25")));
-        sender.setUsername(StringUtils.defaultIfBlank(smtp.remove("username"), ""));
-        sender.setPassword(StringUtils.defaultIfBlank(smtp.remove("password"), ""));
-        sender.setProtocol(StringUtils.defaultIfBlank(smtp.remove("protocol"), "smtp"));
-        if (smtp.size() > 0) {
-            final Properties properties = new Properties();
-            for (final String property : smtp.keySet()) {
-                properties.setProperty(property, smtp.get(property));
+        if(smtp!=null) {
+            sender.setHost(StringUtils.defaultIfBlank(smtp.remove("host"), "localhost"));
+            sender.setPort(Integer.parseInt(StringUtils.defaultIfBlank(smtp.remove("port"), "25")));
+            sender.setUsername(StringUtils.defaultIfBlank(smtp.remove("username"), ""));
+            sender.setPassword(StringUtils.defaultIfBlank(smtp.remove("password"), ""));
+            sender.setProtocol(StringUtils.defaultIfBlank(smtp.remove("protocol"), "smtp"));
+            if (smtp.size() > 0) {
+                final Properties properties = new Properties();
+                for (final String property : smtp.keySet()) {
+                    properties.setProperty(property, smtp.get(property));
+                }
+                sender.setJavaMailProperties(properties);
             }
-            sender.setJavaMailProperties(properties);
         }
         return sender;
     }
diff --git a/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java b/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java
index 2fc83765..5f6253bf 100644
--- a/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java
@@ -1,19 +1,13 @@
 package org.nrg.xnat.configuration;
 
 import org.nrg.config.exceptions.SiteConfigurationException;
-import org.nrg.framework.exceptions.NrgServiceError;
-import org.nrg.framework.exceptions.NrgServiceRuntimeException;
 import org.nrg.framework.services.NrgEventService;
 import org.nrg.mail.services.EmailRequestLogService;
 import org.nrg.xdat.XDAT;
 import org.nrg.xdat.preferences.InitializerSiteConfiguration;
-import org.nrg.xdat.preferences.SiteConfigPreferenceEvent;
-import org.nrg.xdat.preferences.SiteConfigPreferences;
+import org.nrg.xdat.preferences.PreferenceEvent;
 import org.nrg.xnat.helpers.prearchive.SessionXMLRebuilder;
-import org.nrg.xnat.security.DisableInactiveUsers;
 import org.nrg.xnat.security.ResetEmailRequests;
-import org.nrg.xnat.security.ResetFailedLogins;
-import org.nrg.xnat.security.alias.ClearExpiredAliasTokens;
 import org.nrg.xnat.utils.XnatUserProvider;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
@@ -21,21 +15,14 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jms.core.JmsTemplate;
-import org.springframework.scheduling.Trigger;
-import org.springframework.scheduling.TriggerContext;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.SchedulingConfigurer;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.scheduling.config.ScheduledTaskRegistrar;
 import org.springframework.scheduling.config.TriggerTask;
-import org.springframework.scheduling.support.CronTrigger;
 import org.springframework.scheduling.support.PeriodicTrigger;
 
 import javax.inject.Inject;
-import java.sql.SQLException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
 import java.util.List;
 
 @Configuration
@@ -104,9 +91,9 @@ public class SchedulerConfig implements SchedulingConfigurer {
 //        taskRegistrar.addTriggerTask(resetEmailRequests());
 //        taskRegistrar.addTriggerTask(clearExpiredAliasTokens());
 //        taskRegistrar.addTriggerTask(rebuildSessionXmls());
-        XDAT.getContextService().getBean(NrgEventService.class).triggerEvent(new SiteConfigPreferenceEvent("aliasTokenTimeout", String.valueOf(XDAT.getSiteConfigPreferences().getAliasTokenTimeout())));
-        XDAT.getContextService().getBean(NrgEventService.class).triggerEvent(new SiteConfigPreferenceEvent("inactivityBeforeLockout", String.valueOf(XDAT.getSiteConfigPreferences().getInactivityBeforeLockout())));
-        XDAT.getContextService().getBean(NrgEventService.class).triggerEvent(new SiteConfigPreferenceEvent("maxFailedLoginsLockoutDuration", String.valueOf(XDAT.getSiteConfigPreferences().getMaxFailedLoginsLockoutDuration())));
+        XDAT.getContextService().getBean(NrgEventService.class).triggerEvent(new PreferenceEvent("aliasTokenTimeout", String.valueOf(XDAT.getSiteConfigPreferences().getAliasTokenTimeout())));
+        XDAT.getContextService().getBean(NrgEventService.class).triggerEvent(new PreferenceEvent("inactivityBeforeLockout", String.valueOf(XDAT.getSiteConfigPreferences().getInactivityBeforeLockout())));
+        XDAT.getContextService().getBean(NrgEventService.class).triggerEvent(new PreferenceEvent("maxFailedLoginsLockoutDuration", String.valueOf(XDAT.getSiteConfigPreferences().getMaxFailedLoginsLockoutDuration())));
         for (final TriggerTask triggerTask : _triggerTasks) {
             taskRegistrar.addTriggerTask(triggerTask);
         }
diff --git a/src/main/java/org/nrg/xnat/event/listeners/SiteConfigPreferenceHandler.java b/src/main/java/org/nrg/xnat/event/listeners/SiteConfigPreferenceHandler.java
index 2eb63876..f7fa2c7a 100644
--- a/src/main/java/org/nrg/xnat/event/listeners/SiteConfigPreferenceHandler.java
+++ b/src/main/java/org/nrg/xnat/event/listeners/SiteConfigPreferenceHandler.java
@@ -1,114 +1,31 @@
 package org.nrg.xnat.event.listeners;
 
-import org.apache.commons.codec.binary.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.nrg.framework.event.entities.EventSpecificFields;
 import org.nrg.prefs.events.AbstractPreferenceHandler;
-import org.nrg.prefs.events.PreferenceHandlerMethod;
-import org.nrg.xdat.XDAT;
-import org.nrg.xdat.preferences.SiteConfigPreferenceEvent;
+import org.nrg.xdat.preferences.PreferenceEvent;
 import org.nrg.xdat.preferences.SiteConfigPreferences;
-import org.nrg.xnat.security.DisableInactiveUsers;
-import org.nrg.xnat.security.ResetFailedLogins;
-import org.nrg.xnat.security.alias.ClearExpiredAliasTokens;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
-import org.springframework.scheduling.support.CronTrigger;
 import org.springframework.stereotype.Service;
-import reactor.bus.Event;
 import reactor.bus.EventBus;
-import reactor.fn.Consumer;
 
 import javax.inject.Inject;
-import java.util.*;
-import java.util.concurrent.ScheduledFuture;
 
 @Service
-public class SiteConfigPreferenceHandler extends AbstractPreferenceHandler<SiteConfigPreferenceEvent> {
+public class SiteConfigPreferenceHandler extends AbstractPreferenceHandler<PreferenceEvent> {
 
 	@Inject
 	public SiteConfigPreferenceHandler(final EventBus eventBus){
 		super(SiteConfigPreferences.SITE_CONFIG_TOOL_ID, eventBus);
 	}
 
-//		if (StringUtils.equals(field.getFieldName(), "aliasTokenTimeout")) {
-//			updateAliasTokenTimeout(e);
-//		}
-//		else if (StringUtils.equals(field.getFieldName(), "aliasTokenTimeoutSchedule")) {
-//			updateAliasTokenTimeout(e);
-//		}
-//		else if (StringUtils.equals(field.getFieldName(), "inactivityBeforeLockout")) {
-//			updateInactivityBeforeLockout(e);
-//		}
-//		else if (StringUtils.equals(field.getFieldName(), "inactivityBeforeLockoutSchedule")) {
-//			updateInactivityBeforeLockout(e);
-//		}
-//		else if (StringUtils.equals(field.getFieldName(), "maxFailedLoginsLockoutDuration")) {
-//			updateResetFailedLogins(e);
-//		}
-//		else if (StringUtils.equals(field.getFieldName(), "resetFailedLoginsSchedule")) {
-//			updateResetFailedLogins(e);
-//		}
-//
-//	}
-//
-//	private void updateAliasTokenTimeout(SiteConfigPreferenceEvent e){
-//		try {
-//			XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true);
-//			Iterator<Runnable> iter = XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().getQueue().iterator();
-//
-//			for(ScheduledFuture temp: scheduledAliasTokenTimeouts){
-//				temp.cancel(false);
-//			}
-//
-//			scheduledAliasTokenTimeouts.add(XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").schedule(new ClearExpiredAliasTokens(_template),new CronTrigger(XDAT.getSiteConfigPreferences().getAliasTokenTimeoutSchedule())));
-//
-//		} catch (Exception e1) {
-//			_log.error("", e1);
-//		}
-//	}
-//
-//	private void updateInactivityBeforeLockout(SiteConfigPreferenceEvent e){
-//		try {
-//			XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true);
-//			Iterator<Runnable> iter = XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().getQueue().iterator();
-//
-//			for(ScheduledFuture temp: scheduledInactivityBeforeLockout){
-//				temp.cancel(false);
-//			}
-//
-//			scheduledInactivityBeforeLockout.add(XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").schedule(new DisableInactiveUsers((new Long(SiteConfigPreferences.convertPGIntervalToSeconds(XDAT.getSiteConfigPreferences().getInactivityBeforeLockout()))).intValue(),(new Long(SiteConfigPreferences.convertPGIntervalToSeconds(XDAT.getSiteConfigPreferences().getMaxFailedLoginsLockoutDuration()))).intValue()),new CronTrigger(XDAT.getSiteConfigPreferences().getInactivityBeforeLockoutSchedule())));
-//
-//		} catch (Exception e1) {
-//			_log.error("", e1);
-//		}
-//	}
-//
-//	private void updateResetFailedLogins(SiteConfigPreferenceEvent e){
-//		try {
-//			XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true);
-//			Iterator<Runnable> iter = XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().getQueue().iterator();
-//
-//			for(ScheduledFuture temp: scheduledResetFailedLogins){
-//				temp.cancel(false);
-//			}
-//
-//			scheduledResetFailedLogins.add(XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").schedule(new ResetFailedLogins(_template,XDAT.getSiteConfigPreferences().getMaxFailedLoginsLockoutDuration()),new CronTrigger(XDAT.getSiteConfigPreferences().getResetFailedLoginsSchedule())));
-//
-//		} catch (Exception e1) {
-//			_log.error("", e1);
-//		}
-//	}
-
 	@Autowired
 	@Lazy
 	private JdbcTemplate _template;
 
 	private static final Log _log = LogFactory.getLog(SiteConfigPreferenceHandler.class);
-	private ArrayList<ScheduledFuture> scheduledInactivityBeforeLockout = new ArrayList<ScheduledFuture>();
 
-	private ArrayList<ScheduledFuture> scheduledResetFailedLogins = new ArrayList<ScheduledFuture>();
+
 }
diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/AliasTokenPreferenceHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/AliasTokenPreferenceHandlerMethod.java
index b7b068b3..c4e681bc 100644
--- a/src/main/java/org/nrg/xnat/event/listeners/methods/AliasTokenPreferenceHandlerMethod.java
+++ b/src/main/java/org/nrg/xnat/event/listeners/methods/AliasTokenPreferenceHandlerMethod.java
@@ -1,9 +1,7 @@
 package org.nrg.xnat.event.listeners.methods;
 
 import com.google.common.collect.ImmutableList;
-import org.nrg.prefs.events.PreferenceHandlerMethod;
 import org.nrg.xdat.XDAT;
-import org.nrg.xdat.preferences.SiteConfigPreferenceEvent;
 import org.nrg.xnat.security.alias.ClearExpiredAliasTokens;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -26,15 +24,19 @@ public class AliasTokenPreferenceHandlerMethod extends AbstractSiteConfigPrefere
 
     @Override
     public void handlePreferences(final Map<String, String> values) {
-
+        if (!Collections.disjoint(PREFERENCES, values.keySet())) {
+            updateAliasTokenTimeout();
+        }
     }
 
     @Override
     public void handlePreference(final String preference, final String value) {
-
+        if(PREFERENCES.contains(preference)){
+            updateAliasTokenTimeout();
+        }
     }
 
-    private void updateAliasTokenTimeout(SiteConfigPreferenceEvent e){
+    private void updateAliasTokenTimeout(){
         try {
             XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true);
             Iterator<Runnable> iter = XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().getQueue().iterator();
diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/InactivityBeforeLockoutHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/InactivityBeforeLockoutHandlerMethod.java
new file mode 100644
index 00000000..7f81283b
--- /dev/null
+++ b/src/main/java/org/nrg/xnat/event/listeners/methods/InactivityBeforeLockoutHandlerMethod.java
@@ -0,0 +1,64 @@
+package org.nrg.xnat.event.listeners.methods;
+
+import com.google.common.collect.ImmutableList;
+import org.nrg.xdat.XDAT;
+import org.nrg.xdat.preferences.SiteConfigPreferences;
+import org.nrg.xnat.security.DisableInactiveUsers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.scheduling.support.CronTrigger;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.ScheduledFuture;
+
+@Component
+public class InactivityBeforeLockoutHandlerMethod extends AbstractSiteConfigPreferenceHandlerMethod {
+    @Override
+    public List<String> getHandledPreferences() {
+        return PREFERENCES;
+    }
+
+    @Override
+    public void handlePreferences(final Map<String, String> values) {
+        if (!Collections.disjoint(PREFERENCES, values.keySet())) {
+            updateInactivityBeforeLockout();
+        }
+    }
+
+    @Override
+    public void handlePreference(final String preference, final String value) {
+        if(PREFERENCES.contains(preference)){
+            updateInactivityBeforeLockout();
+        }
+    }
+
+	private void updateInactivityBeforeLockout(){
+		try {
+			XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true);
+			Iterator<Runnable> iter = XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().getQueue().iterator();
+
+			for(ScheduledFuture temp: scheduledInactivityBeforeLockout){
+				temp.cancel(false);
+			}
+
+			scheduledInactivityBeforeLockout.add(XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").schedule(new DisableInactiveUsers((new Long(SiteConfigPreferences.convertPGIntervalToSeconds(XDAT.getSiteConfigPreferences().getInactivityBeforeLockout()))).intValue(),(new Long(SiteConfigPreferences.convertPGIntervalToSeconds(XDAT.getSiteConfigPreferences().getMaxFailedLoginsLockoutDuration()))).intValue()),new CronTrigger(XDAT.getSiteConfigPreferences().getInactivityBeforeLockoutSchedule())));
+
+		} catch (Exception e1) {
+			_log.error("", e1);
+		}
+	}
+
+    private static final Logger       _log        = LoggerFactory.getLogger(InactivityBeforeLockoutHandlerMethod.class);
+    private static final List<String> PREFERENCES = ImmutableList.copyOf(Arrays.asList("aliasTokenTimeout", "aliasTokenTimeoutSchedule"));
+
+    @Autowired
+    @Lazy
+    private JdbcTemplate _template;
+
+    private              ArrayList<ScheduledFuture> scheduledInactivityBeforeLockout = new ArrayList<>();
+}
diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/ResetFailedLoginsHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/ResetFailedLoginsHandlerMethod.java
new file mode 100644
index 00000000..1460e841
--- /dev/null
+++ b/src/main/java/org/nrg/xnat/event/listeners/methods/ResetFailedLoginsHandlerMethod.java
@@ -0,0 +1,63 @@
+package org.nrg.xnat.event.listeners.methods;
+
+import com.google.common.collect.ImmutableList;
+import org.nrg.xdat.XDAT;
+import org.nrg.xnat.security.ResetFailedLogins;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.scheduling.support.CronTrigger;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.ScheduledFuture;
+
+@Component
+public class ResetFailedLoginsHandlerMethod extends AbstractSiteConfigPreferenceHandlerMethod {
+    @Override
+    public List<String> getHandledPreferences() {
+        return PREFERENCES;
+    }
+
+    @Override
+    public void handlePreferences(final Map<String, String> values) {
+        if (!Collections.disjoint(PREFERENCES, values.keySet())) {
+            updateResetFailedLogins();
+        }
+    }
+
+    @Override
+    public void handlePreference(final String preference, final String value) {
+        if(PREFERENCES.contains(preference)){
+            updateResetFailedLogins();
+        }
+    }
+
+    private void updateResetFailedLogins(){
+		try {
+			XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true);
+			Iterator<Runnable> iter = XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").getScheduledThreadPoolExecutor().getQueue().iterator();
+
+			for(ScheduledFuture temp: scheduledResetFailedLogins){
+				temp.cancel(false);
+			}
+
+			scheduledResetFailedLogins.add(XDAT.getContextService().getBeansOfType(ThreadPoolTaskScheduler.class).get("taskScheduler").schedule(new ResetFailedLogins(_template,XDAT.getSiteConfigPreferences().getMaxFailedLoginsLockoutDuration()),new CronTrigger(XDAT.getSiteConfigPreferences().getResetFailedLoginsSchedule())));
+
+		} catch (Exception e1) {
+			_log.error("", e1);
+		}
+	}
+
+    private static final Logger       _log        = LoggerFactory.getLogger(ResetFailedLoginsHandlerMethod.class);
+    private static final List<String> PREFERENCES = ImmutableList.copyOf(Arrays.asList("aliasTokenTimeout", "aliasTokenTimeoutSchedule"));
+
+    @Autowired
+    @Lazy
+    private JdbcTemplate _template;
+
+    private              ArrayList<ScheduledFuture> scheduledResetFailedLogins = new ArrayList<>();
+}
diff --git a/src/main/java/org/nrg/xnat/restlet/actions/TriggerPipelines.java b/src/main/java/org/nrg/xnat/restlet/actions/TriggerPipelines.java
index e0d04488..fd9e516a 100644
--- a/src/main/java/org/nrg/xnat/restlet/actions/TriggerPipelines.java
+++ b/src/main/java/org/nrg/xnat/restlet/actions/TriggerPipelines.java
@@ -65,7 +65,7 @@ public class TriggerPipelines implements Callable<Boolean> {
         xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user));
         xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail());
         xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName());
-        xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+        xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
         xnatPipelineLauncher.setParameter("sessionType", expt.getXSIType());
         xnatPipelineLauncher.setParameter("xnat_project", expt.getProject());
 
diff --git a/src/main/java/org/nrg/xnat/restlet/resources/ProjtExptPipelineResource.java b/src/main/java/org/nrg/xnat/restlet/resources/ProjtExptPipelineResource.java
index 7ebc5b72..6f6a2e2a 100644
--- a/src/main/java/org/nrg/xnat/restlet/resources/ProjtExptPipelineResource.java
+++ b/src/main/java/org/nrg/xnat/restlet/resources/ProjtExptPipelineResource.java
@@ -276,7 +276,7 @@ public class ProjtExptPipelineResource extends SecureResource {
         hasParams.add("userfullname");
         xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail());
         hasParams.add("adminemail");
-        xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+        xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
         hasParams.add("mailhost");
         xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName());
         hasParams.add("xnatserver");
@@ -389,7 +389,7 @@ public class ProjtExptPipelineResource extends SecureResource {
         xnatPipelineLauncher.setParameter("useremail", user.getEmail());
 	    xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user));
 	    xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail());
-	    xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+	    xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
 	    xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName());
 
 
diff --git a/src/main/java/org/nrg/xnat/turbine/modules/actions/ManagePipeline.java b/src/main/java/org/nrg/xnat/turbine/modules/actions/ManagePipeline.java
index 0ac76f4e..747d8377 100644
--- a/src/main/java/org/nrg/xnat/turbine/modules/actions/ManagePipeline.java
+++ b/src/main/java/org/nrg/xnat/turbine/modules/actions/ManagePipeline.java
@@ -381,7 +381,7 @@ public class ManagePipeline extends SecureAction {
             xnatPipelineLauncher.setParameter("useremail", user.getEmail());
             xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user));
             xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail());
-            xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+            xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
             xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName());
             xnatPipelineLauncher.setPipelineName(pipeline_path);
             String exptLabel = item.getStringProperty("label");
diff --git a/src/main/java/org/nrg/xnat/turbine/modules/actions/PipelineActions.java b/src/main/java/org/nrg/xnat/turbine/modules/actions/PipelineActions.java
index dc2d33e1..3898a4d2 100644
--- a/src/main/java/org/nrg/xnat/turbine/modules/actions/PipelineActions.java
+++ b/src/main/java/org/nrg/xnat/turbine/modules/actions/PipelineActions.java
@@ -206,7 +206,7 @@ public class PipelineActions extends SecureAction{
         xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user));
         xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail());
         xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName());
-        xnatPipelineLauncher.setParameter("mailhost", XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+        xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
 
         String emailsStr =  ((String)org.nrg.xdat.turbine.utils.TurbineUtils.GetPassedParameter("emailField",data));
         if (emailsStr != null) {
diff --git a/src/main/java/org/nrg/xnat/turbine/modules/actions/QDECAction.java b/src/main/java/org/nrg/xnat/turbine/modules/actions/QDECAction.java
index 8d7262a6..f24a5568 100644
--- a/src/main/java/org/nrg/xnat/turbine/modules/actions/QDECAction.java
+++ b/src/main/java/org/nrg/xnat/turbine/modules/actions/QDECAction.java
@@ -210,7 +210,7 @@ public class QDECAction extends ListingAction{
         
         param = parameters.addNewParameter();
         param.setName("mailhost");
-        param.addNewValues().setUnique( XDAT.getSiteConfigPreferences().getSmtpServer().get("host"));
+        param.addNewValues().setUnique( XDAT.getNotificationsPreferences().getSmtpServer().get("host"));
         
         return parameters;
         
diff --git a/src/main/java/org/nrg/xnat/turbine/utils/ArcSpecManager.java b/src/main/java/org/nrg/xnat/turbine/utils/ArcSpecManager.java
index 35fffe55..b1bbe208 100644
--- a/src/main/java/org/nrg/xnat/turbine/utils/ArcSpecManager.java
+++ b/src/main/java/org/nrg/xnat/turbine/utils/ArcSpecManager.java
@@ -13,6 +13,7 @@ package org.nrg.xnat.turbine.utils;
 import org.apache.commons.lang3.StringUtils;
 import org.nrg.xdat.XDAT;
 import org.nrg.xdat.om.ArcArchivespecification;
+import org.nrg.xdat.preferences.NotificationsPreferences;
 import org.nrg.xdat.preferences.SiteConfigPreferences;
 import org.nrg.xft.event.EventDetails;
 import org.nrg.xft.event.EventUtils;
@@ -94,29 +95,30 @@ public class ArcSpecManager {
 
     public synchronized static ArcArchivespecification initialize(final UserI user) throws Exception {
         arcSpec = new ArcArchivespecification(user);
-        final SiteConfigPreferences preferences = XDAT.getSiteConfigPreferences();
-        if (StringUtils.isNotBlank(preferences.getAdminEmail())) {
+        final SiteConfigPreferences siteConfigPreferences = XDAT.getSiteConfigPreferences();
+        final NotificationsPreferences notificationsPreferences = XDAT.getNotificationsPreferences();
+        if (StringUtils.isNotBlank(siteConfigPreferences.getAdminEmail())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting site admin email to: {}", preferences.getAdminEmail());
+                logger.info("Setting site admin email to: {}", siteConfigPreferences.getAdminEmail());
             }
-            arcSpec.setSiteAdminEmail(preferences.getAdminEmail());
+            arcSpec.setSiteAdminEmail(siteConfigPreferences.getAdminEmail());
         }
 
-        if (StringUtils.isNotBlank(preferences.getSiteId())) {
+        if (StringUtils.isNotBlank(siteConfigPreferences.getSiteId())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting site ID to: {}", preferences.getSiteId());
+                logger.info("Setting site ID to: {}", siteConfigPreferences.getSiteId());
             }
-            arcSpec.setSiteId(preferences.getSiteId());
+            arcSpec.setSiteId(siteConfigPreferences.getSiteId());
         }
 
-        if (StringUtils.isNotBlank(preferences.getSiteUrl())) {
+        if (StringUtils.isNotBlank(siteConfigPreferences.getSiteUrl())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting site URL to: {}", preferences.getSiteUrl());
+                logger.info("Setting site URL to: {}", siteConfigPreferences.getSiteUrl());
             }
-            arcSpec.setSiteUrl(preferences.getSiteUrl());
+            arcSpec.setSiteUrl(siteConfigPreferences.getSiteUrl());
         }
 
-        final Map<String, String> smtpServer = preferences.getSmtpServer();
+        final Map<String, String> smtpServer = notificationsPreferences.getSmtpServer();
         if (smtpServer != null && smtpServer.containsKey("host")) {
             if (logger.isInfoEnabled()) {
                 logger.info("Setting SMTP host to: {}", smtpServer.get("host"));
@@ -125,61 +127,61 @@ public class ArcSpecManager {
         }
 
         if (logger.isInfoEnabled()) {
-            logger.info("Setting enable new registrations to: {}", preferences.getUserRegistration());
+            logger.info("Setting enable new registrations to: {}", siteConfigPreferences.getUserRegistration());
         }
-        arcSpec.setEnableNewRegistrations(preferences.getUserRegistration());
+        arcSpec.setEnableNewRegistrations(siteConfigPreferences.getUserRegistration());
 
         if (logger.isInfoEnabled()) {
-            logger.info("Setting reguire login to: {}", preferences.getRequireLogin());
+            logger.info("Setting reguire login to: {}", siteConfigPreferences.getRequireLogin());
         }
-        arcSpec.setRequireLogin(preferences.getRequireLogin());
+        arcSpec.setRequireLogin(siteConfigPreferences.getRequireLogin());
 
-        if (StringUtils.isNotBlank(preferences.getPipelinePath())) {
+        if (StringUtils.isNotBlank(siteConfigPreferences.getPipelinePath())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting pipeline path to: {}", preferences.getPipelinePath());
+                logger.info("Setting pipeline path to: {}", siteConfigPreferences.getPipelinePath());
             }
-            arcSpec.setProperty("globalPaths/pipelinePath", preferences.getPipelinePath());
+            arcSpec.setProperty("globalPaths/pipelinePath", siteConfigPreferences.getPipelinePath());
         }
 
-        if (StringUtils.isNotBlank(preferences.getArchivePath())) {
+        if (StringUtils.isNotBlank(siteConfigPreferences.getArchivePath())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting archive path to: {}", preferences.getArchivePath());
+                logger.info("Setting archive path to: {}", siteConfigPreferences.getArchivePath());
             }
-            arcSpec.setProperty("globalPaths/archivePath", preferences.getArchivePath());
+            arcSpec.setProperty("globalPaths/archivePath", siteConfigPreferences.getArchivePath());
         }
 
-        if (StringUtils.isNotBlank(preferences.getPrearchivePath())) {
+        if (StringUtils.isNotBlank(siteConfigPreferences.getPrearchivePath())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting prearchive path to: {}", preferences.getPrearchivePath());
+                logger.info("Setting prearchive path to: {}", siteConfigPreferences.getPrearchivePath());
             }
-            arcSpec.setProperty("globalPaths/prearchivePath", preferences.getPrearchivePath());
+            arcSpec.setProperty("globalPaths/prearchivePath", siteConfigPreferences.getPrearchivePath());
         }
 
-        if (StringUtils.isNotBlank(preferences.getCachePath())) {
+        if (StringUtils.isNotBlank(siteConfigPreferences.getCachePath())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting cache path to: {}", preferences.getCachePath());
+                logger.info("Setting cache path to: {}", siteConfigPreferences.getCachePath());
             }
-            arcSpec.setProperty("globalPaths/cachePath", preferences.getCachePath());
+            arcSpec.setProperty("globalPaths/cachePath", siteConfigPreferences.getCachePath());
         }
 
-        if (StringUtils.isNotBlank(preferences.getFtpPath())) {
+        if (StringUtils.isNotBlank(siteConfigPreferences.getFtpPath())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting FTP path to: {}", preferences.getFtpPath());
+                logger.info("Setting FTP path to: {}", siteConfigPreferences.getFtpPath());
             }
-            arcSpec.setProperty("globalPaths/ftpPath", preferences.getFtpPath());
+            arcSpec.setProperty("globalPaths/ftpPath", siteConfigPreferences.getFtpPath());
         }
 
-        if (StringUtils.isNotBlank(preferences.getBuildPath())) {
+        if (StringUtils.isNotBlank(siteConfigPreferences.getBuildPath())) {
             if (logger.isInfoEnabled()) {
-                logger.info("Setting build path to: {}", preferences.getBuildPath());
+                logger.info("Setting build path to: {}", siteConfigPreferences.getBuildPath());
             }
-            arcSpec.setProperty("globalPaths/buildPath", preferences.getBuildPath());
+            arcSpec.setProperty("globalPaths/buildPath", siteConfigPreferences.getBuildPath());
         }
 
         if (logger.isInfoEnabled()) {
-            logger.info("Setting enable CSRF token to: {}", preferences.getEnableCsrfToken());
+            logger.info("Setting enable CSRF token to: {}", siteConfigPreferences.getEnableCsrfToken());
         }
-        arcSpec.setEnableCsrfToken(preferences.getEnableCsrfToken());
+        arcSpec.setEnableCsrfToken(siteConfigPreferences.getEnableCsrfToken());
 
         if (logger.isInfoEnabled()) {
             // logger.info("Saving arcspec: {}", displayArcSpec(arcSpec));
diff --git a/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml b/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml
index 07488ecb..36f43919 100644
--- a/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml
+++ b/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml
@@ -446,10 +446,10 @@ securityServices:
 emailServerSettings:
     kind: panel.form
     method: POST
-    action: /xapi/siteConfig/smtpServer
+    action: /xapi/notifications/batchMail
     contentType: json
-    load: ?? XNAT.data.siteConfig.smtpServer
-    refresh: /xapi/siteConfig/smtpServer
+    load: ?? XNAT.data.notifications.batchMail
+    refresh: /xapi/notifications/batchMail
     name: emailServerSettings
     label: Mail Server Settings
     contents:
@@ -510,11 +510,11 @@ notifications:
     kind: panel.form
     name: notifications
     label: Notifications
-    action: /xapi/siteConfig/batch
+    action: /xapi/notifications/batch
     method: POST
     contentType: json
-    load: ?? XNAT.data.siteConfig
-    refresh: /xapi/siteConfig
+    load: ?? XNAT.data.notifications
+    refresh: /xapi/notifications
     contents:
         helpContactInfo:
             kind: panel.input.email
diff --git a/src/main/webapp/scripts/project/settingsTabMgmt.js b/src/main/webapp/scripts/project/settingsTabMgmt.js
index 37d20620..1192fae2 100644
--- a/src/main/webapp/scripts/project/settingsTabMgmt.js
+++ b/src/main/webapp/scripts/project/settingsTabMgmt.js
@@ -64,7 +64,7 @@ function fullConfigHandler() {
         , 'enableCsrfToken', 'enableCsrfEmail', 'restrictUserListAccessToAdmins', 'UI.allow-non-admin-project-creation', 'requireSaltedPasswords', 'passwordExpirationType', 'passwordExpirationInterval', 'passwordExpirationDate'
         , 'archivePath', 'checksums', 'prearchivePath', 'cachePath', 'ftpPath', 'buildPath', 'pipelinePath'
         , 'requireLogin', 'enableNewRegistrations', 'emailVerification'
-        , 'error', 'issue', 'newUser', 'update', 'emailAllowNonuserSubscribers', 'smtp.enabled'
+        , 'error', 'issue', 'newUser', 'update', 'emailAllowNonuserSubscribers', 'smt.enabled'
         , 'anonScript', 'anonEnabled'
         , 'applet'
         , 'dcmPort', 'dcmAe', 'enableDicomReceiver'
-- 
GitLab