Hi All,
Just came back to record what I did as the final solution.
First - Turn on Log login/logout actions to the database in the Security > Locking and Audit options.
Second - Record the last password changed date in the session by adding the following to the Login Page > After Successful Login event
$_SESSION["last_password_change"] = getLastPasswordChange($conn, $username);
Third - Calculate against the last password change to ensure it is less than 60 days by adding this code to the After Application Initialized event.
function getLastPasswordChange($conn, $username){
$str = "SELECT MAX(`datetime`) as last_password_change FROM `audit` WHERE '".$username."' = `audit`.`user` AND `audit`.`action` = 'change password';";
$rs = db_query($str,$conn);
while($row = db_fetch_array($rs)) {
return $row["last_password_change"];
}
return "";
}
function curPageName() {
return substr($_SERVER["SCRIPT_NAME"],strrpos($_SERVER["SCRIPT_NAME"],"/")+1);
}
//Set password rotation interval
$password_change_interval = 60;
//If a user is logged in
if(isset($_SESSION["UserID"])) {
// Check if the last password change was more than X days ago.
$password_expired = true;
if($_SESSION["last_password_change"] == ""){
$password_expired = false;
}
if($password_expired) {
$lpc = new DateTime($_SESSION["last_password_change"]);
$now = new DateTime();
$diff = ($now->getTimestamp() - $lpc->getTimestamp()) / (24 * 60 * 60);
//echo $now->format('Y-m-d H:i:s') . " - " . $lpc->format('Y-m-d H:i:s') . " " . $diff;
if($diff < $password_change_interval) {
$password_expired = false;
}
}
if($password_expired){
if(curPageName() != "changepwd.php") {
header("Location: changepwd.php?expired=true");
exit();
}
}
}
Fourth, update the session variable on change by adding this code to the Change Password Page > After password changed event
$_SESSION["last_password_change"] = date_format(new DateTime(),"Y-m-d H:i:s");
Fifth, give a message to the user letting them know their password expired by adding this code to the Change Password Page > Before display event. I also added a display of complexity requirements.
//Set the custom message for expiration password change.
$msg = $xt->xt_vars["message"] . "<br /><br />";
if(isset($_GET["expired"])){
$msg .= "Your password has expired.<br /><br />";
}
$msg .= "Your new password must:<br />Be at least 8 characters<br />Contain at least 4 unique characters<br />Contain at least 2 digits or symbols<br />Contain letters in both upper and lower case<br />";
$xt->assign("message", $msg);
$xt->assign("message_block",true);
Sixth (Optional), the Change Password Page successful page is pretty worthless with just a back button, so I replaced it with the back to menu button in the style editor. To do this I had to add the menubutton brick to the bricks.xml file, because it wasn't listed before.