diff --git a/modules/account/daos/account_idp.dao.xml b/modules/account/daos/account_idp.dao.xml index 7ac9ba1..fe5b0b0 100644 --- a/modules/account/daos/account_idp.dao.xml +++ b/modules/account/daos/account_idp.dao.xml @@ -16,6 +16,7 @@ + @@ -40,5 +41,18 @@ + + + + + + + + + + + + + diff --git a/modules/account/install/sql/add_inactivity_notification.sql b/modules/account/install/sql/add_inactivity_notification.sql new file mode 100644 index 0000000..0d2b391 --- /dev/null +++ b/modules/account/install/sql/add_inactivity_notification.sql @@ -0,0 +1 @@ +ALTER TABLE account_idp ADD COLUMN inactivity_notification_sended integer; diff --git a/modules/account/install/upgrade_042.php b/modules/account/install/upgrade_042.php new file mode 100644 index 0000000..1b9062d --- /dev/null +++ b/modules/account/install/upgrade_042.php @@ -0,0 +1,19 @@ +database()->execSQLScript('sql/add_inactivity_notification.sql'); + } +} diff --git a/modules/account/lib/Manager.php b/modules/account/lib/Manager.php index 33ffb81..bd681d3 100644 --- a/modules/account/lib/Manager.php +++ b/modules/account/lib/Manager.php @@ -4,11 +4,15 @@ * @copyright 2021-2024 Laurent Jouanneau and other contributors * @license MIT */ + namespace Jelix\Authentication\Account; +use DateInterval; +use DateTimeImmutable; use jAuthentication; use Jelix\Authentication\Core\AuthSession\AuthUser; use Jelix\Authentication\Core\IdentityProviderInterface; +use Jelix\Core\Infos\AppInfos; class Manager { @@ -172,6 +176,7 @@ public static function searchAccountByIdp($idpId, $authUserId, $markUsage = fals } $accIdp->last_used = date('Y-m-d H:i:s'); $accIdp->usage_count++; + $accIdp->inactivity_notification_sended = 0; $daoIdp->update($accIdp); } @@ -250,4 +255,78 @@ public static function detachAccountFromIdp($accountId, $idpId, $authUserId) $daoIdp->delete([$idpId, $authUserId, $accountId]); } -} \ No newline at end of file + /** + * return delay value form app config param named $paramName, ensure is integer > 0 + * + * @param string $paramName the param name + * + * @return bool|integer + */ + protected static function getInactiveDelayValue(string $paramName) + { + $config = \jApp::config()->authentication; + if (isset($config[$paramName]) && $config[$paramName]) { + $inactiveDelay = $config[$paramName]; + if ($inactiveDelay == 'none') { + + return false; + } + if (filter_var($inactiveDelay, FILTER_VALIDATE_INT, ['min_range' => 1])) { + + return $inactiveDelay; + } + trigger_error('Invalid value for '.$inactiveDelay.' must be > 0', E_USER_NOTICE); + + return false; + } + + return false; + } + + public static function notifyOrDropInactive() + { + $inactiveNotificationDelay = self::getInactiveDelayValue('inactiveNotificationDelay'); + $inactiveDeletionDelay = self::getInactiveDelayValue('inactiveDeletionDelay'); + + $now = new DateTimeImmutable(); + if (is_int($inactiveDeletionDelay)) { + $inactiveNotificationDelay = $now->sub(new DateInterval('P'.$inactiveNotificationDelay.'D')); + + $daoIdp = \jDao::get(self::$daoIdp, self::$daoProfile); + + $inactiveUsersToNotif = ($daoIdp->findInactiveNotNotified($inactiveNotificationDelay->format('Y-m-d'))); + $appInfos = AppInfos::load(); + $appName = $appInfos->getLabel(); + + foreach($inactiveUsersToNotif as $user) { + // send email + $email = $user->idp_user_email; + $mailer = new \jMailer(); + $tpl = $mailer->Tpl('account~mailBodyInactivity', true); + $mailer->addAddress($email); + $mailer->Subject = \jLocale::get('account~account.email.inactivity.subject', [$appName]); + $tpl->assign('lastUsedDate', $user->last_used); + $tpl->assign('appName', $appName); + $tpl->assign('deletionDate', $inactiveNotificationDelay->format('Y-m-d')); + try { + $mailer->send(); + } catch (\Exception $e) { + // + continue; + } + // mail sended : update user field + $user->inactivity_notification_sended = 1; + $daoIdp->update($user); + } + } + if (is_int($inactiveDeletionDelay)) { + $notifDeletionDate = $now->sub(new DateInterval('P'.$inactiveDeletionDelay.'D')); + + $inactiveUsersToDelete = ($daoIdp->findInactiveToDelete($notifDeletionDate->format('Y-m-d'))); + foreach($inactiveUsersToDelete as $user) { + $user->enabled = 0; + $daoIdp->update($user); + } + } + } +} diff --git a/modules/account/locales/en_US/account.UTF-8.properties b/modules/account/locales/en_US/account.UTF-8.properties index d2572f6..8bf2688 100644 --- a/modules/account/locales/en_US/account.UTF-8.properties +++ b/modules/account/locales/en_US/account.UTF-8.properties @@ -24,3 +24,4 @@ cancel.and.back.to.profile = Cancel and back to your profile back.to.profile = Back to your profile error.no.account=Sorry, there is no account with the login %s into this application. +email.inactivity.subject=Inactive account on application %s diff --git a/modules/account/locales/fr_FR/account.UTF-8.properties b/modules/account/locales/fr_FR/account.UTF-8.properties index 6342917..dfecb37 100644 --- a/modules/account/locales/fr_FR/account.UTF-8.properties +++ b/modules/account/locales/fr_FR/account.UTF-8.properties @@ -24,3 +24,4 @@ cancel.and.back.to.profile = Annuler et retourner à votre profil back.to.profile = Retourner à votre profil error.no.account=Désolé, il n'y a pas de compte avec l'identifiant %s dans cette application. +email.inactivity.subject=Compte inactif sur l'application %s diff --git a/modules/account/module.xml b/modules/account/module.xml index b7f70c1..2738a73 100644 --- a/modules/account/module.xml +++ b/modules/account/module.xml @@ -1,7 +1,7 @@ - 0.4.0 + 0.4.2 All rights reserved diff --git a/modules/account/templates/en_US/mailBodyInactivity.tpl b/modules/account/templates/en_US/mailBodyInactivity.tpl new file mode 100644 index 0000000..8ecff1e --- /dev/null +++ b/modules/account/templates/en_US/mailBodyInactivity.tpl @@ -0,0 +1,5 @@ +

Hello

+

+Your account on {$appName} application is inactive since {$lastUsedDate}, unless you log in in the meantime +it will be deactivated on {$deletionDate} +

diff --git a/modules/account/templates/fr_FR/mailBodyInactivity.tpl b/modules/account/templates/fr_FR/mailBodyInactivity.tpl new file mode 100644 index 0000000..1bb745f --- /dev/null +++ b/modules/account/templates/fr_FR/mailBodyInactivity.tpl @@ -0,0 +1,4 @@ +

Bonjour

+

Votre compte sur l'application {$appName} est inactif depuis le {$lastUsedDate}, +à moins que vous vous connectiez entre temps, il sera désactivé la date {$deletionDate}. +