fixes #2404 notify users of impending API key expiration

Adds logic to detect when an API key is about to expire and sends a notification email to the user if the key expires within 7 days and no recent notification was sent. Introduces a new 'last_notified_on' column to the user_auth_keys table to track notification timing.
This commit is contained in:
Linty
2025-09-04 17:21:53 +02:00
parent c078cffb8b
commit dbec498287
5 changed files with 124 additions and 13 deletions
+24
View File
@@ -253,6 +253,30 @@ if (isset($page['auth_key_invalid']) and $page['auth_key_invalid'])
;
}
// check if we need to notified user about api_key expiration
if (isset($page['notify_api_key_expiration']) and is_array($page['notify_api_key_expiration']))
{
$is_mail_send = notification_api_key_expiration(
$user['username'],
$user['email'],
$page['notify_api_key_expiration']['days_left']
);
if ($is_mail_send)
{
single_update(
USER_AUTH_KEYS_TABLE,
array('last_notified_on' => $page['notify_api_key_expiration']['dbnow']),
array(
'user_id' => $user['id'],
'auth_key' => $page['notify_api_key_expiration']['auth_key']
),
);
}
unset($page['notify_api_key_expiration']);
}
// template instance
if (defined('IN_ADMIN') and IN_ADMIN )
{// Admin template
+66 -13
View File
@@ -1694,7 +1694,10 @@ function auth_key_login($auth_key, $connection_by_header=false)
SELECT
*,
'.$conf['user_fields']['username'].' AS username,
NOW() AS dbnow
'.$conf['user_fields']['email'].' AS email,
NOW() AS dbnow,
DATEDIFF(uak.expired_on, NOW()) AS days_left,
SUBDATE(NOW(), INTERVAL 48 HOUR) AS 48h_ago
FROM '.USER_AUTH_KEYS_TABLE.' AS uak
JOIN '.USER_INFOS_TABLE.' AS ui ON uak.user_id = ui.user_id
JOIN '.USERS_TABLE.' AS u ON u.'.$conf['user_fields']['id'].' = ui.user_id
@@ -1709,6 +1712,19 @@ SELECT
$key = $keys[0];
// is the key still valid?
if (strtotime($key['expired_on']) < strtotime($key['dbnow']))
{
$page['auth_key_invalid'] = true;
return false;
}
// admin/webmaster/guest can't get connected with authentication keys
if ('auth_key' === $valid_key and !in_array($key['status'], array('normal','generic')))
{
return false;
}
// the key is an api_key
if ('api_key' === $valid_key)
{
@@ -1723,19 +1739,24 @@ SELECT
{
return false;
}
}
// is the key still valid?
if (strtotime($key['expired_on']) < strtotime($key['dbnow']))
{
$page['auth_key_invalid'] = true;
return false;
}
// admin/webmaster/guest can't get connected with authentication keys
if ('auth_key' === $valid_key and !in_array($key['status'], array('normal','generic')))
{
return false;
// check if we need to notificate the user
$days_left = intval($key['days_left']);
if (
$days_left <= 7 // the key expire in max 7 days
and !empty($key['email']) // the user have an email
and (
null === $key['last_notified_on'] // we never send an email for this key
or strtotime($key['last_notified_on']) < strtotime($key['48h_ago']) // OR when the last email was sent more than 48 hours ago
)
)
{
$page['notify_api_key_expiration'] = array(
'days_left' => $days_left,
'dbnow' => $key['dbnow'],
'auth_key' => $key['auth_key']
);
}
}
$user['id'] = $key['user_id'];
@@ -2655,4 +2676,36 @@ function connected_with_pwg_ui()
}
return false;
}
/**
* Notify an user when his api key is about to expire
*
* @since 16
* @return bool
*/
function notification_api_key_expiration($username, $email, $days_left)
{
global $conf;
include_once(PHPWG_ROOT_PATH . 'include/functions_mail.inc.php');
$days_left_str = $days_left <= 1 ?
l10n('Your API key will expire in %d day.', $days_left)
: l10n('Your API key will expire in %d days.', $days_left);
$message = '<p style="margin: 20px 0">' . l10n('Hello %s,', $username) . '</p>';
$message .= '<p style="margin: 20px 0">' . $days_left_str . '</p>';
$message .= '<p style="margin: 20px 0">' . l10n('To continue using the API, please renew your key before it expires.') . '</p>';
$message .= '<p style="margin: 20px 0">' . l10n('You can manage your API keys in your <a href="%s">account settings.</a>', get_absolute_root_url().'profile.php') . '</p>';
$result = @pwg_mail(
$email,
array(
'subject' => '[' . $conf['gallery_title'] . '] ' . l10n('Your API key will expire soon'),
'content' => $message,
'content_format' => 'text/html',
)
);
return $result;
}
?>
+24
View File
@@ -0,0 +1,24 @@
<?php
// +-----------------------------------------------------------------------+
// | This file is part of Piwigo. |
// | |
// | For copyright and license information, please view the COPYING.txt |
// | file that was distributed with this source code. |
// +-----------------------------------------------------------------------+
if (!defined('PHPWG_ROOT_PATH'))
{
die('Hacking attempt!');
}
$upgrade_description = 'Modification to the user_auth_key table to add last_notified_on';
// For API KEY, add a column last_notified_on, to know when the last email (for the moment)
// notifying of an upcoming expiration date was sent.
pwg_query(
'ALTER TABLE `'.PREFIX_TABLE.'user_auth_keys`
ADD COLUMN `last_notified_on` datetime DEFAULT NULL
;');
echo "\n".$upgrade_description."\n";
?>
+5
View File
@@ -518,3 +518,8 @@ $lang['Do you really want to revoke the "%s" API key?'] = 'Do you really want to
$lang['To manage your API keys, please log in with your username/password.'] = 'To manage your API keys, please log in with your username/password.';
$lang['3xlarge'] = '3XL - extra huge';
$lang['4xlarge'] = '4XL - gigantic';
$lang['Your API key will expire soon'] = 'Your API key will expire soon';
$lang['Your API key will expire in %d day.'] = 'Your API key will expire in %d day.';
$lang['Your API key will expire in %d days.'] = 'Your API key will expire in %d days.';
$lang['To continue using the API, please renew your key before it expires.'] = 'To continue using the API, please renew your key before it expires.';
$lang['You can manage your API keys in your <a href="%s">account settings.</a>'] = 'You can manage your API keys in your <a href="%s">account settings.</a>';
+5
View File
@@ -517,3 +517,8 @@ $lang['Do you really want to revoke the "%s" API key?'] = 'Voulez-vous vraiment
$lang['To manage your API keys, please log in with your username/password.'] = 'Pour gérer vos clés API, veuillez vous connecter avec votre nom d\'utilisateur/mot de passe.';
$lang['3xlarge'] = '3XL - très énorme';
$lang['4xlarge'] = '4XL - gigantesque';
$lang['Your API key will expire soon'] = 'Votre clé API va bientôt expirer';
$lang['Your API key will expire in %d day.'] = 'Votre clé API expirera dans %d jour.';
$lang['Your API key will expire in %d days.'] = 'Votre clé API expirera dans %d jours.';
$lang['To continue using the API, please renew your key before it expires.'] = 'Pour continuer à utiliser l\'API, veuillez renouveler votre clé avant son expiration.';
$lang['You can manage your API keys in your <a href="%s">account settings.</a>'] = 'Vous pouvez gérer vos clés API dans les <a href="%s">paramètres de votre compte.</a>';