reduce a.php and c.php

change structure
This commit is contained in:
François 2025-01-26 13:47:33 +01:00
parent 68c5fa5b86
commit 61269d6ce3
15 changed files with 1317 additions and 348 deletions

View File

@ -2,7 +2,6 @@
/*
* Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
* create un archive for a set of file or update file deadline
* version : 2.22 (2024-12-09)
a.php?r=email => track
a.php?p=email => period
@ -14,118 +13,7 @@
action: a=login a=logout a=r[on|off] a=p[minute|hour|day|week|month|quarter|semester]
*/
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
define ('JIRAFEAU_ROOT', dirname (__FILE__) . '/');
require (JIRAFEAU_ROOT . 'lib/settings.php');
require (JIRAFEAU_ROOT . 'lib/functions.php');
require (JIRAFEAU_ROOT . 'lib/lang.php');
define ('VAR_TOKENS', $cfg ['var_root'].'tokens/');
define ('VAR_MODE', $cfg ['var_root'].'mode/');
define ('VAR_TRACKS', $cfg ['var_root'].'tracks/');
define ('VAR_PERIOD', $cfg ['var_root'].'period/');
define ('VAR_LANG', $cfg ['var_root'].'lang/');
define ('VAR_FAKE', $cfg ['var_root'].'fake/');
define ('VAR_ADMIN', $cfg ['var_root'].'admin/');
define ('VAR_CONFIG', $cfg ['var_root'].'config/');
define ('FILE_CONFIG', VAR_CONFIG.'default.php');
$domain="kaz.local";
if (preg_match ("%^.*//([^/]*)/?.*$%", $cfg ['web_root'], $matches))
$domain = $matches [1];
define ('MAX_VALID_UPLOAD_TIME', 60);
define ('TOKEN_USE_LIMIT', "-2 hours");
define ('TOKEN_LOGIN_LIMIT', "-15 minutes");
define ('TOKEN_LOGOUT_LIMIT', "-8 hours");
if (!file_exists (VAR_CONFIG))
mkdir (VAR_CONFIG, 0755);
if (!file_exists (FILE_CONFIG)) {
file_put_contents (FILE_CONFIG, "<?php".NL.
"/* if error with DEFAULT_MODE, DEFAULT_PERIOD or DEFAULT_LANG then remove this file. */".NL.
"define ('DEFAULT_MODE', 'footer');".NL.
"define ('DEFAULT_PERIOD', 'month');".NL.
"define ('DEFAULT_LANG', 'fr');".NL.NL);
define ('DEFAULT_MODE', 'footer');
define ('DEFAULT_PERIOD', 'month');
define ('DEFAULT_LANG', 'fr');
} else
require (FILE_CONFIG);
define ('E_BAD_ARCHIVE_NAME', 'Bad archive name format');
define ('E_CREATE_ZIP', "Impossible de cr&eacute;er l'archive.");
define ('E_OPEN_ZIP', "Impossible d'ouvrir l'archive.");
define ('M_BAD_KEY', "Mauvaise clef pour ");
define ('M_BAD_SENDER_NAME', 'Votre m&eacute;l est incorrect');
define ('M_BAD_TOKEN', "Vous n'utilisez pas le bon jeton (consultez votre messagerie).");
define ('M_TOO_LONG_BEFORE_LOGGED', "Jeton de connexion trop ancien.");
define ('M_TOO_LONG_LOGGED', "Temps de connexion d&eacute;pass&eacute;.");
define ('M_EMAIL_CONTENT', "Bonjour,<br/><br/>Ceci est un message automatique, car vous venez de cliquer sur une demande de consultation de vos pi&egrave;ces jointes.<br/><br/>!!! Si vous n'&ecirc;tes pas &agrave; l'origine de cette demande, ne cliquez sur aucun lien de ce message. !!!<br/><br/>Le lien de connexion suivant est valable 15 minutes.<br/><a href=\"___LINK___\">___LINK___</a><br/><br/>Vous pouvez signaler des abus aupr&egrave;s de Kaz en faisant suivre ce message qui contient les traces de son &eacute;metteur (___IP___, ___DATE___).<br/><br/>Bonne navigation.<br/>.");
define ('M_DOWNLOAD', "T&eacute;l&eacute;charger");
define ('M_UPDATE', "Prolonger");
define ('M_EMAIL_SUBJECT', "Lien de consultation des envois sur ".$domain.".");
define ('M_FILE', " fichier.");
define ('M_FILES', " fichiers.");
define ('M_FILES_NOT_FOUND', " fichiers sont expirés.");
define ('M_FILES_RENAMED', " fichiers renommés.");
define ('M_FILE_NOT_FOUND', " fichier est expiré.");
define ('M_FILE_RENAMED', " fichier renommé.");
define ('M_INTRO_FORM', "Quelles sont les informations me concernant ?");
define ('M_MEL', "votre m&eacute;l");
define ('M_NO_FILENAME', 'SansNom');
define ('M_NO_SENDER', 'kaz-');
define ('M_NEW_ATTACHEMENT_DIRNAME', "nouveau");
define ('M_OLD_ATTACHEMENT_DIRNAME', "ancien");
define ('M_SEND', "Connexion");
define ('M_LOGOUT', 'Deconnecter');
define ('M_REFRESH', 'Actualiser');
define ('M_LOGOUT_TOKEN', "Vous n'&ecirc;tes plus connect&eacute;.");
define ('M_SEND_TOKEN', "<br/><p>Vous allez recevoir un <b>lien d'acc&egrave;s temporaire</b> &agrave; vos donn&eacute;es.</p>");
define ('M_WELCOME', "<p>Informations concernant le compte : <b>___SENDER___</b>___ADMIN___<br/>(page actualis&eacute;e &agrave; ___DATE___)</p>");
define ('M_INCONSISTENT_DATES',
" (dates incoh&eacute;antes avec ___FILENAME___ : ___DIRTIME___ != ___FILETIME___)");
define ('A_ACTION', 'a'); // action : T_LOGIN, T_LOGOUT, A_MODE(none|footer|attachment|both), A_RECORD+(on|off), A_PERIOD(minute|hour|day|week|month|quarter|semester), A_LANG(fr|en|br)
define ('A_GET', 'g'); // get archive
define ('A_HASH', 'h'); // file to update or delete
define ('A_OPEN_TOKEN', 'o'); // ask token
define ('A_SENDER', 's'); // session sender
define ('A_TOKEN', 't'); // session token
define ('A_UPDATE', 'u'); // update perriod for file or archive
define ('A_MODE', 'm'); // get mode status
define ('A_RECORD', 'r'); // get track status
define ('A_PERIOD', 'p'); // get period status
define ('A_LANG', 'l'); // get lang status
define ('A_DELETE', 'd'); // delete file ou archive + (sender+token)
define ('T_BAD_PASW', 'bad_psw');
define ('T_CREATE', "create");
define ('T_CRYPTED', 'crypted');
define ('T_CRYPT_KEY', 'crypt_key');
define ('T_ENTRIES', 'entries');
define ('T_FILENAME', 'file_name');
define ('T_HASH', 'hash');
define ('T_LOGGED', "logged");
define ('T_NEW', 'new');
define ('T_SIGN', 'sign');
define ('T_NOT_FOUND', 'not_found');
define ('T_OLD', 'old');
define ('T_RENAME', 'rename');
define ('T_LOGIN', 'login');
define ('T_LOGOUT', 'logout');
define ('T_SENDER', 'sender');
define ('T_TIME', 'time');
define ('T_ID', 'id');
define ('T_TOKEN', "token");
define ('T_WARNING_FILENAME', "-Avertissement.txt");
define ('T_ZIP_EXT', ".zip");
define ('T_ARCHIVE_TITLE', "archive_content");
define ('T_ARCHIVE_MIME', "text/kaz_email_archive");
require ("lib/attach-setup.php");
$modeText = ['none' => "sans", 'footer' => "pied de page", 'attachment' => "pi&egrave;ce jointe", 'both' => "les deux"];
$trackText = ['on' => "oui", 'off' => "non"];
@ -139,14 +27,6 @@ $periodButton = ['hour' => ["&#128336;", ">1 heure"], // 1F550
];
$langText = ['fr' => "Francais", 'br' => "Breton", 'en' => "english"];
$doLogout = '';
$message = '';
/* Operations may take a long time.
* Be sure PHP's safe mode is off.
*/
@set_time_limit (0);
/* Remove errors. */
@error_reporting (0);
// ========================================
if (isset ($_REQUEST [A_MODE]) && !empty ($_REQUEST [A_MODE])) {
@ -213,9 +93,9 @@ if (isset ($_REQUEST [A_GET]) && !empty ($_REQUEST [A_GET])) {
// ========================================
function returnError ($msg) {
require (JIRAFEAU_ROOT.'lib/template/header.php');
echo '<div class="error"><p>' . $msg . '</p></div>';
require (JIRAFEAU_ROOT.'lib/template/footer.php');
displayHeadPage ("Gestion des pièces jointes");
echo '<div class="message-error">' . $msg . '</div>';
displayFootPage ();
exit;
}
@ -343,49 +223,6 @@ function getSenderLang ($sender) {
return DEFAULT_LANG;
}
// ========================================
function setSenderFake ($error, $sender, $owner, $dirLink, $fileLink) {
global $doLogout;
if (!file_exists (VAR_FAKE))
mkdir (VAR_FAKE, 0755);
$dirTime = $fileTime = $fileName = $fileType = $ip = '';
if (count ($dirLink) != 0) {
$dirTime = $dirLink ['upload_date'].date (" Y-m-d H:i:s", $dirLink ['upload_date']);
$ip = $dirLink ['ip'];
}
if (!$sender)
return;
if (count ($fileLink) != 0) {
$fileTime = $fileLink ['upload_date'].date (" Y-m-d H:i:s", $fileLink ['upload_date']);
$fileName = $link ['file_name'];
$fileType = $link ['mime_type'];
}
$content =
"time : ".time ().NL.
"date : ".date ("Y-m-d H:i:s").NL.
"error : ".$error.NL.
"sender : <".$sender.">".NL.
"owner : <".$owner.">".NL.
"dirLink : <".$dirLink.">".NL.
"dirTime : ".$dirTime.NL.
"dirIp : ".$ip.NL.
"fileTime: ".$fileTime.NL.
"fileType: <".$fileType.">".NL.
"fileName: <".$fileName.">".NL;
$log = $ip.$sender;
if ($log)
file_put_contents (VAR_FAKE.$log, $content);
// $doLogout = true;
// rmToken ($sender);
}
function getSenderFake ($sender) {
return false;
// return $sender && file_exists (VAR_FAKE.$sender);
}
// ========================================
function isKazArchive ($link) {
return
@ -474,98 +311,6 @@ function updateLink ($link_name, $link, $maxLimit) {
return $time_more;
}
// ========================================
function sendEMail ($receiver, $receiver_name, $subject, $body_string){
try {
// SERVER SETTINGS
$mail = new PHPMailer (true);
$mail->isSMTP ();
$mail->Host = 'smtp';
$mail->SMTPAuth = false;
$mail->SMTPAutoTLS = false;
$mail->SMTPSecure = "none";
$mail->Port = 25;
$mail->charSet = "UTF-8";
$mail->ContentType = 'text/html';
global $domain;
//Recipients (change this for every project)
$mail->setFrom ('no-reply@'.$domain, '');
$mail->addAddress ($receiver, $receiver_name);
//Content
$mail->isHTML (true);
$mail->Subject = $subject;
$mail->Body = $body_string;
//send the message, check for errors
if (!$mail->send ()) {
//echo 'Mailer Error: ' . $mail->ErrorInfo;
return 0;
} else {
//echo 'Message sent!';
return 1;
}
} catch (Exception $e) {
return 0;
}
}
// ========================================
function cleanToken () {
if (!file_exists (VAR_TOKENS))
mkdir (VAR_TOKENS, 0755);
$d = dir (VAR_TOKENS);
$oldest = strtotime (TOKEN_USE_LIMIT);
foreach (glob (VAR_TOKENS."*") as $file) {
if (filemtime ($file) <= $oldest)
unlink ($file);
}
}
function rmToken ($sender) {
if (!$sender)
return;
if (file_exists (VAR_TOKENS.$sender))
unlink (VAR_TOKENS.$sender);
}
function setToken ($sender) {
if (!$sender)
return;
$token = md5 (rand ());
if (file_put_contents (VAR_TOKENS.$sender, T_CREATE.": ".time ().NL.T_TOKEN.": ".$token.NL))
return $token;
return false;
}
function setLoggedToken ($sender, $token) {
if (!$sender || !$token)
return;
file_put_contents (VAR_TOKENS.$sender, T_CREATE.": ".time ().NL.T_TOKEN.": ".$token.NL.T_LOGGED.": ok".NL);
}
function getTokenVar ($sender, $varName) {
if (!$sender)
return;
if (!file_exists (VAR_TOKENS.$sender))
return false;
$content = file_get_contents (VAR_TOKENS.$sender);
if (preg_match ("/\b".$varName.":\s*([^\s]+)\n/", $content, $matches))
return $matches [1];
return false;
}
function getToken ($sender) {
return getTokenVar ($sender, T_TOKEN,);
}
function getCreateToken ($sender) {
return getTokenVar ($sender, T_CREATE);
}
function getLoggedToken ($sender) {
return getTokenVar ($sender, T_LOGGED);
}
function getTimeToken ($sender) {
if (!$sender || !file_exists (VAR_TOKENS.$sender))
return false;
return filemtime (VAR_TOKENS.$sender);
}
// ========================================
function setAdmin ($sender) {
if (!$sender)
@ -707,6 +452,8 @@ function deleteAction ($linkName) {
}
}
// ========================================
// main
// ========================================
if ($doUpdate) {
$maxTime = time ()+period2seconds ($_REQUEST [A_UPDATE]);
@ -736,19 +483,6 @@ if ($doUpdate) {
exit;
}
$sender = '';
$senderError = false;
if (isset ($_REQUEST [A_SENDER]) && !empty ($_REQUEST [A_SENDER])) {
// XXX
//if (!preg_match ("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/i", $_REQUEST [A_SENDER]))
if (!preg_match ("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/i", $_REQUEST [A_SENDER]))
$senderError = true;
else {
cleanToken ();
$sender = $_REQUEST [A_SENDER];
}
}
// ========================================
if ($doDownload) {
// check archive exist
@ -900,75 +634,26 @@ if ($doDownload) {
// ========================================
// form
$token = '';
if (isset ($_REQUEST [A_TOKEN]) && !empty ($_REQUEST [A_TOKEN])) {
if (!preg_match ("/^([0-9a-zA-Z_-]+)$/", $_REQUEST [A_TOKEN]))
return false;
$token = $_REQUEST [A_TOKEN];
}
$refToken = getToken ($sender);
$urlBase = $_SERVER ['HTTP_X_FORWARDED_PROTO']."://".$_SERVER ['HTTP_HOST'];
if (isset ($_REQUEST [A_ACTION]) && $_REQUEST [A_ACTION] == T_LOGIN && $sender) {
require (JIRAFEAU_ROOT . 'lib/template/header.php');
if (getSenderFake ($sender))
echo "Ce compte ne peut plus se connecter. Veuillez contacter les administrateurs.";
else {
$token = setToken ($sender);
// XXX test token
$url = $urlBase.$_SERVER ['SCRIPT_NAME']."?".A_SENDER."=".$sender."&".A_TOKEN."=".$token;
$result = sendEMail ($sender, "", M_EMAIL_SUBJECT,
str_replace (["___LINK___", "___IP___", "___DATE___"],
[$url, $_SERVER ['HTTP_X_REAL_IP'] , date ("Y-m-d H:i:s")], M_EMAIL_CONTENT));
if ($result)
echo M_SEND_TOKEN;
else
echo
"Erreur dans l'envoi. V&eacute;ritiez votre m&eacute;l.";
}
echo "<br/><br/><br/>";
require (JIRAFEAU_ROOT.'lib/template/footer.php');
exit;
}
if (! ($sender && $token && $token == $refToken &&
(getLoggedToken ($sender) || (getTimeToken ($sender) >= strtotime (TOKEN_LOGIN_LIMIT))) &&
(getCreateToken ($sender) >= strtotime (TOKEN_LOGOUT_LIMIT)))) {
// XXX temps de connexion
require (JIRAFEAU_ROOT . 'lib/template/header.php');
echo M_INTRO_FORM;
displayHeadPage ("Gestion des pièces jointes");
if ($senderError)
echo "<p>".M_BAD_SENDER_NAME."</p>";
$message .= '<div class="message-error">'.M_BAD_SENDER_NAME.'</div>'.NL;
else if (($token && !$refToken) || !getLoggedToken ($sender))
echo "<p>".M_TOO_LONG_BEFORE_LOGGED."</p>";
$message .= '<div class="message-error">'.M_TOO_LONG_BEFORE_LOGGED.'</div>'.NL;
else if ($token && $token != $refToken)
echo "<p>".M_BAD_TOKEN."</p>";
$message .= '<div class="message-error">'.M_BAD_TOKEN.'</div>'.NL;
else if (getCreateToken ($sender) < strtotime (TOKEN_LOGOUT_LIMIT))
echo "<p>".M_TOO_LONG_LOGGED."</p>";
$message .= '<div class="message-error">'.M_TOO_LONG_LOGGED.'</div>'.NL;
?>
<Form method="post" class="form login">
<fieldset>
<table>
<tr>
<td class="label"><label for="enter_password"><?php echo M_MEL . ' :'; ?></label>
</td>
</tr>
<tr>
<td class="field"><input type="text" name="<?php echo A_SENDER; ?>" size="40" value="<?php echo jirafeau_escape ($_REQUEST [A_SENDER]);?>"/>
</td>
</tr>
<tr class="nav">
<td class="nav next">
<input type="hidden" name="<?php echo A_ACTION; ?>" value="<?php echo T_LOGIN; ?>" />
<input type="submit" value="<?php echo M_SEND; ?>" />
</td>
</tr>
</table>
</fieldset>
</form>
<?php
require (JIRAFEAU_ROOT.'lib/template/footer.php');
if ($message)
echo $message;
displayLogin (M_LOGIN_CONFIG);
displayFootPage ();
exit;
}
@ -993,14 +678,14 @@ if (isset ($_REQUEST [A_DELETE])) {
// logout
if ($doLogout || (isset ($_REQUEST [A_ACTION]) && $_REQUEST [A_ACTION] == T_LOGOUT)) {
rmToken ($sender);
require (JIRAFEAU_ROOT . 'lib/template/header.php');
displayHeadPage ("Gestion des pièces jointes");
echo str_replace (["___SENDER___", "___ADMIN___", "___DATE___"],
[$sender, ($admin ? " (admin)" : ""), jirafeau_get_datetimefield (time ())],
M_WELCOME);
if ($message)
echo "<p>Info : ".$message."</p>";
echo '<div class="message-success">Info : '.$message.'</div>';
echo M_LOGOUT;
require (JIRAFEAU_ROOT.'lib/template/footer.php');
displayFootPage ();
exit;
}
@ -1009,7 +694,7 @@ if (isset ($_REQUEST [A_ACTION])) {
switch (true) {
case preg_match ("/^".A_MODE."(".implode ("|", array_keys ($modeText)).")$/i", $_REQUEST [A_ACTION], $matches):
setSenderMode ($sender, $matches [1]);
$message .= "Votre mode &agrave; &eacute;t&eacute; mise &agrave; jour.";
$message .= 'Votre mode &agrave; &eacute;t&eacute; mise &agrave; jour.';
break;
case preg_match ("/^".A_RECORD."(on|off)$/i", $_REQUEST [A_ACTION], $matches):
if ($matches [1] == "on")
@ -1060,12 +745,12 @@ while ( ($d = array_shift ($stack)) && $d != null) {
$archives [] = $archiveInfo;
}
}
require (JIRAFEAU_ROOT . 'lib/template/header.php');
displayHeadPage ("Gestion des pièces jointes");
echo str_replace (["___SENDER___", "___ADMIN___", "___DATE___"],
[$sender, ($admin ? " (admin)" : ""), jirafeau_get_datetimefield (time ())],
M_WELCOME);
if ($message)
echo "<p>Info : ".$message."</p>";
echo '<div class="message-success">Info : '.$message.'</div>';
echo '<script type="text/javascript">';
?>
function getURI (uri, params) {
@ -1126,7 +811,7 @@ $defaultChecked [getSenderPeriod ($sender)] = ' selected="selected"';
$defaultChecked [getSenderLang ($sender)] = ' selected="selected"';
echo
'<form method="post">'.
'Je veux que mes futurs envois soient d&eacute;pollu&eacute; en pla&ccedil;ant les liens de t&eacute;l&eacute;chargements '.
'Je veux que mes futurs envois soient d&eacute;pollu&eacute;s en pla&ccedil;ant les liens de t&eacute;l&eacute;chargements '.
'<select name="'.A_ACTION.'" style="width: auto !important;">';
foreach ($modeText as $item => $text)
echo ' <option value="'.A_MODE.$item.'"'.$defaultChecked [$item].'>'.$text.'</option>';
@ -1225,7 +910,7 @@ if ($archives) {
}
echo
'<p>Votre compte occupe <b>'.jirafeau_human_size ($userSise).'</b>.</p>'.
'<span>Votre compte occupe <b>'.jirafeau_human_size ($userSise).'</b>.</span>'.
'<form method="post">'.
'Je veux me '.
'<input type="hidden" name="'.A_ACTION.'" value="'.T_LOGOUT.'" />'.
@ -1238,9 +923,9 @@ if (count ($userTab)) {
echo $entry;
} else
echo
"<p>Il n'y a aucune information vous concernant.</p>";
"<span>Il n'y a aucune information vous concernant.</span>";
require (JIRAFEAU_ROOT.'lib/template/footer.php');
displayFootPage ();
exit;
// ========================================

205
src/Jirafeau/c.php Normal file
View File

@ -0,0 +1,205 @@
<?php
/*
* Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
* foward dowload to NextCloud API
c.php => config
c.php?s="sender"&t="token"
c.php?a={login|logout|forget_me} => edition/lecture
c.php?a={add_url, del_url, up_url, down_url} => manage list url
c.php?h=l&k=k => file
c.php?g=l~k => zip
*/
require ("lib/attach-setup.php");
// ========================================
function setUserProfile ($profile, $listUrl) {
if (!$profile)
return;
if (!file_exists (VAR_CLOUD))
mkdir (VAR_CLOUD, 0755);
if (empty ($listUrl)) {
rmUserProfile ($profile);
return;
}
return file_put_contents (VAR_CLOUD.$profile, json_encode ($listUrl, JSON_PRETTY_PRINT)) !== false;
}
function rmUserProfile ($profile) {
if (!$profile)
return;
if (file_exists (VAR_CLOUD.$profile))
unlink (VAR_CLOUD.$profile);
}
/**
* Récupère les données Nextcloud d'un utilisateur.
*
* @param string $profile Email de l'utilisateur.
* @return array Données Nextcloud de l'utilisateur.
*/
function getUserProfile ($profile) {
$listUrl = [];
if ($profile && file_exists (VAR_CLOUD.$profile))
$listUrl = json_decode (file_get_contents (VAR_CLOUD.$profile), true);
return $listUrl;
}
// ==============================================
// Fonctions utilitaires
// ==============================================
$name = '';
$url = '';
function manageUrl () {
global $sender, $message, $name, $url;
if (!isset ($_REQUEST [A_ACTION]))
return;
if (!in_array ($_REQUEST [A_ACTION], array (T_ADD_URL, T_DEL_URL, T_UP_URL, T_DOWN_URL) ))
return;
$listUrl = getUserProfile ($sender);
$name = filter_var ($_REQUEST [A_NAME], FILTER_SANITIZE_STRING);
if (empty ($name)) {
$message .= '<div class="message-error">nom vide</div>'.NL;
return;
}
switch ($_REQUEST [A_ACTION]) {
case T_ADD_URL:
$url = rtrim (filter_var ($_REQUEST [A_URL], FILTER_VALIDATE_URL), '/');
if (empty ($url)) {
$message .= '<div class="message-error">url vide</div>'.NL;
return;
}
$listUrl ["urls"][$name] = $url;
$message .= '<div class="message-success">'.M_URL_ADDED.'</div>'.NL;
break;
// XXX simplifier
case T_DEL_URL:
case T_UP_URL:
case T_DOWN_URL:
if (!(isset ($listUrl ["urls"]) && count ($listUrl ["urls"]) && isset ($listUrl ["urls"][$name])))
return;
$pos = array_search ($name, array_keys ($listUrl ["urls"]));
$url = $listUrl ["urls"][$name];
unset ($listUrl ["urls"][$name]);
switch ($_REQUEST [A_ACTION]) {
case T_DEL_URL:
$message .= '<div class="message-success">.M_URL_DELETED.</div>'.NL;
break;
case T_UP_URL:
$pos = max ($pos-1, 0);
break;
case T_DOWN_URL:
$pos = min ($pos+1, count ($listUrl ["urls"]));
break;
}
if ($_REQUEST [A_ACTION] != T_DEL_URL)
$listUrl ["urls"] = array_merge (
array_slice ($listUrl ["urls"], 0, $pos),
array ($name => $url),
array_slice ($listUrl["urls"], $pos)
);
break;
}
$name = $url = '';
setUserProfile ($sender, $listUrl);
}
// ==============================================
// main
// ==============================================
// XXX
session_start ();
//phpinfo ();
displayHeadPage ($title);
// logout
if (isset ($_REQUEST [A_ACTION]) && $_REQUEST [A_ACTION] == T_LOGOUT) {
$message .= '<div class="message-success">'.M_LOGOUT_TOKEN.'</div>'.NL;
if ($sender)
rmToken ($sender);
unset ($token);
}
$logged = false;
if (! (!empty ($sender) && !empty ($token) && $token == $refToken &&
(getLoggedToken ($sender) || (getTimeToken ($sender) >= strtotime (TOKEN_LOGIN_LIMIT))) &&
(getCreateToken ($sender) >= strtotime (TOKEN_LOGOUT_LIMIT)))) {
if ($senderError)
$message .= '<div class="message-error">'.M_BAD_SENDER_NAME.'</div>'.NL;
else if (($token && !$refToken) || !getLoggedToken ($sender))
//$message .= '<div class="message-error">'.M_TOO_LONG_BEFORE_LOGGED.' '.$token.'</div>'.NL;
;
else if ($token && $token != $refToken)
$message .= '<div class="message-error">'.M_BAD_TOKEN.'</div>'.NL;
else if (getCreateToken ($sender) < strtotime (TOKEN_LOGOUT_LIMIT))
$message .= '<div class="message-error">'.M_TOO_LONG_LOGGED.'</div>'.NL;
//$message .= '<div class="message-error">'.M_TIMEOUT_TOKEN.'</div>'.NL;
unset ($token);
cleanToken ();
} else {
$logged = true;
if (!getLoggedToken ($sender))
setLoggedToken ($sender, $token);
else
touch (VAR_TOKENS.$sender);
$_SESSION [T_PROFILE] = $sender;
}
// gestion list url
if ($logged) {
manageUrl ();
}
$profile='';
if (isset ($_SESSION [T_PROFILE]))
$profile = $_SESSION [T_PROFILE];
// forget
if (isset ($_REQUEST [A_ACTION]) && $_REQUEST [A_ACTION] == T_FORGETME) {
$message .= '<div class="message-success">'.M_CLOSE_PROFILE.'</div>'.NL;
unset ($_SESSION [T_PROFILE]);
unset ($profile);
}
$message .= '<div class="message">Version exp&eacute;rimentale. Ne fonctionne actuellement que pour les archives.</div>'.NL;
if ($message)
echo $message;
if (isset ($_REQUEST [A_GET]) || isset ($_REQUEST [A_HASH])) {
$query = $urlBase;
$cloud_app = $CLOUD_APP;
if (isset ($_REQUEST [A_GET])) {
$query .= '/a.php?'.http_build_query ([
A_GET => $_REQUEST [A_GET]
]);
$cloud_app .= $CLOUD_SEND_ZIP;
} else if (isset ($_REQUEST [A_HASH])) {
$query .= '/f.php?'.http_build_query ([
'd' => $_REQUEST ['d'],
A_HASH => $_REQUEST [A_HASH],
'k' => $_REQUEST ['k']
]);
$cloud_app .= $CLOUD_SEND_FILE;
}
// XXX revoir pour mettre ou non KAZ.
$listUrl = '';
if ($profile)
$listUrl = getUserProfile ($profile);
displayListUrl ($cloud_app.urlencode ($query), $listUrl);
//displayListUrl ($cloud_app.$query, $listUrl);
}
if (!($logged || empty ($profile))) {
displayProfileName (M_OPEN_PROFILE.$profile);
}
if ($logged) {
// Affiche menu organisation URL
$listUrl = getUserProfile ($sender);
displayFormProfile ($listUrl);
displayLogout (M_LOGOUT_PROFILE);
} else {
displayLogin (M_LOGIN_PROFILE);
}
displayFootPage ();

View File

@ -0,0 +1,416 @@
<?php
/*
* Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
* commun function for a.php and c.php
* version : 2.24 (2025-01-26)
*/
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
define ('JIRAFEAU_ROOT', dirname (__FILE__) . '/../');
require (JIRAFEAU_ROOT . 'lib/settings.php');
require (JIRAFEAU_ROOT . 'lib/functions.php');
require (JIRAFEAU_ROOT . 'lib/lang.php');
// ========================================
// FILES
define ('VAR_TOKENS', $cfg ['var_root'].'tokens/');
define ('VAR_MODE', $cfg ['var_root'].'mode/');
define ('VAR_TRACKS', $cfg ['var_root'].'tracks/');
define ('VAR_PERIOD', $cfg ['var_root'].'period/');
define ('VAR_LANG', $cfg ['var_root'].'lang/');
define ('VAR_FAKE', $cfg ['var_root'].'fake/');
define ('VAR_ADMIN', $cfg ['var_root'].'admin/');
define ('VAR_CONFIG', $cfg ['var_root'].'config/');
define ('VAR_CLOUD', $cfg['var_root'].'cloud/');
define ('FILE_CONFIG', VAR_CONFIG.'default.php');
$domain="kaz.local";
if (preg_match ("%^.*//([^/]*)/?.*$%", $cfg ['web_root'], $matches)) {
$domain = $matches [1];
}
if (preg_match ("%^depot\.(.*)$%", $domain, $matches)) {
$domain = $matches [1];
}
// XXX
$DEFAULT_CLOUD="https://cloud.".$domain;
$CLOUD_APP="/index.php/apps/webtransfer";
$CLOUD_SEND_ZIP="/zipDrop?subUrl=";
$CLOUD_SEND_FILE="/zipDrop?subUrl=";
#getZipFile
// ========================================
// CONSTANTES
define ('MAX_VALID_UPLOAD_TIME', 60);
define ('TOKEN_USE_LIMIT', "-2 hours");
define ('TOKEN_LOGIN_LIMIT', "-15 minutes");
define ('TOKEN_LOGOUT_LIMIT', "-8 hours");
if (!file_exists (VAR_CONFIG))
mkdir (VAR_CONFIG, 0755);
if (!file_exists (FILE_CONFIG)) {
file_put_contents (FILE_CONFIG, "<?php".NL.
"/* if error with DEFAULT_MODE, DEFAULT_PERIOD or DEFAULT_LANG then remove this file. */".NL.
"define ('DEFAULT_MODE', 'footer');".NL.
"define ('DEFAULT_PERIOD', 'month');".NL.
"define ('DEFAULT_LANG', 'fr');".NL.NL);
define ('DEFAULT_MODE', 'footer');
define ('DEFAULT_PERIOD', 'month');
define ('DEFAULT_LANG', 'fr');
} else
require (FILE_CONFIG);
// ========================================
// ERRORS
define ('E_BAD_ARCHIVE_NAME', 'Bad archive name format');
define ('E_CREATE_ZIP', "Impossible de cr&eacute;er l'archive.");
define ('E_OPEN_ZIP', "Impossible d'ouvrir l'archive.");
// ========================================
// MESSAGES
define ('M_BAD_KEY', "Mauvaise clef pour ");
define ('M_BAD_SENDER_NAME', 'Votre m&eacute;l est incorrect');
define ('M_BAD_TOKEN', "Vous n'utilisez pas le bon jeton (consultez votre messagerie).");
define ('M_TOO_LONG_BEFORE_LOGGED', "Jeton de connexion trop ancien.");
define ('M_TOO_LONG_LOGGED', "Temps de connexion d&eacute;pass&eacute;.");
define ('M_EMAIL_CONTENT', "Bonjour,<br/><br/>Ceci est un message automatique, car vous venez de cliquer sur une demande de consultation de vos pi&egrave;ces jointes.<br/><br/>!!! Si vous n'&ecirc;tes pas &agrave; l'origine de cette demande, ne cliquez sur aucun lien de ce message. !!!<br/><br/>Le lien de connexion suivant est valable 15 minutes.<br/><a href=\"___LINK___\">___LINK___</a><br/><br/>Vous pouvez signaler des abus aupr&egrave;s de Kaz en faisant suivre ce message qui contient les traces de son &eacute;metteur (___IP___, ___DATE___).<br/><br/>Bonne navigation.<br/>.");
define ('M_DOWNLOAD', "T&eacute;l&eacute;charger");
define ('M_UPDATE', "Prolonger");
define ('M_EMAIL_SUBJECT', "Lien de consultation des envois sur ".$domain.".");
define ('M_FILE', " fichier.");
define ('M_FILES', " fichiers.");
define ('M_FILES_NOT_FOUND', " fichiers sont expirés.");
define ('M_FILES_RENAMED', " fichiers renommés.");
define ('M_FILE_NOT_FOUND', " fichier est expiré.");
define ('M_FILE_RENAMED', " fichier renommé.");
define ('M_MEL', "votre m&eacute;l");
define ('M_NO_FILENAME', 'SansNom');
define ('M_NO_SENDER', 'kaz-');
define ('M_NEW_ATTACHEMENT_DIRNAME', "nouveau");
define ('M_OLD_ATTACHEMENT_DIRNAME', "ancien");
define ('M_SEND', "Connexion");
define ('M_LOGOUT', 'Deconnecter');
define ('M_REFRESH', 'Actualiser');
define ('M_OPEN_PROFILE', "Cette liste d'espace de stockage est personnelle. Penser à vous retirer si vous n'êtes pas ");
define ('M_CLOSE_PROFILE', "Votre profile est referm&eacute;.");
define ('M_LOGOUT_TOKEN', "Vous n'&ecirc;tes plus connect&eacute;.");
define ('M_TIMEOUT_TOKEN', "Votre session est expir&eacute;e.");
define ('M_SEND_TOKEN', "<br/><p>Vous allez recevoir un <b>lien d'acc&egrave;s temporaire</b> &agrave; vos donn&eacute;es.</p>");
define ('M_WELCOME', "<p>Informations concernant le compte : <b>___SENDER___</b>___ADMIN___<br/>(page actualis&eacute;e &agrave; ___DATE___)</p>");
define ('M_INCONSISTENT_DATES',
" (dates incoh&eacute;antes avec ___FILENAME___ : ___DIRTIME___ != ___FILETIME___)");
define ('M_LOGIN_CONFIG', "<p>Pour personnaliser vos envoie de pièce jointes, indiquez votre mél. Vous recevrez un lien de connexion sécurisé.</p>");
define ('M_LOGIN_PROFILE', "<p>Pour personnaliser la liste de vos espaces de stockage, ou retrouver les votres, indiquez votre mél. Vous recevrez un lien de connexion sécurisé.</p>");
define ('M_LOGOUT_PROFILE', "Quand vous avez fini la personnalisation, pensez à vous déconnecter.");
define ('M_URL_ADDED', "<p>Le lien vient d'être ajouté</p>");
define ('M_LIST_URL', "Choisisez un nuage pour stoker vos pièces jointes");
define ('M_NEW_URL', "Ou saisissez en un nouveau");
define ('M_CUSTOM_URL', "Personalisez la liste de vos espaces de stockage de pièces jointes.");
// ========================================
// PARAMETERS
define ('A_ACTION', 'a'); // action : T_LOGIN, T_LOGOUT, A_MODE(none|footer|attachment|both), A_RECORD+(on|off), A_PERIOD(minute|hour|day|week|month|quarter|semester), A_LANG(fr|en|br)
define ('A_OPEN_TOKEN', 'o'); // ask token
define ('A_TOKEN', 't'); // session token
define ('A_UPDATE', 'u'); // update perriod for file or archive
define ('A_MODE', 'm'); // get mode status
define ('A_RECORD', 'r'); // get track status
define ('A_PERIOD', 'p'); // get period status
define ('A_LANG', 'l'); // get lang status
define ('A_DELETE', 'd'); // delete file ou archive + (sender+token)
define ('A_SENDER', 's'); // session sender
define ('A_GET', 'g'); // get archive
define ('A_HASH', 'h'); // file to update or delete
define ('A_KEY', 'k'); // keyfile to update or delete
define ('A_NAME', "name");
define ('A_URL', "url");
// ========================================
// TOKENS
define ('T_BAD_PASW', 'bad_psw');
define ('T_CRYPTED', 'crypted');
define ('T_CRYPT_KEY', 'crypt_key');
define ('T_ENTRIES', 'entries');
define ('T_FILENAME', 'file_name');
define ('T_HASH', 'hash');
define ('T_NEW', 'new');
define ('T_SIGN', 'sign');
define ('T_NOT_FOUND', 'not_found');
define ('T_OLD', 'old');
define ('T_RENAME', 'rename');
define ('T_FORGETME', 'forget_me');
define ('T_LOGIN', 'login');
define ('T_LOGOUT', 'logout');
define ('T_PROFILE', 'profile');
define ('T_SENDER', 'sender');
define ('T_TIME', 'time');
define ('T_ID', 'id');
define ('T_WARNING_FILENAME', "-Avertissement.txt");
define ('T_ZIP_EXT', ".zip");
define ('T_ARCHIVE_TITLE', "archive_content");
define ('T_ARCHIVE_MIME', "text/kaz_email_archive");
define ('T_TOKEN', "token");
define ('T_CREATE', "create");
define ('T_LOGGED', "logged");
define ('T_ADD_URL', "add_url");
define ('T_DEL_URL', "del_url");
define ('T_UP_URL', "up_url");
define ('T_DOWN_URL', "down_url");
define ('T_URLS', "urls");
define ('L_ADD_URL', "&#9989;");
define ('L_DEL_URL', "&#x274C;");
define ('L_UP_URL', "&#x2191;");
define ('L_DOWN_URL', "&#x2193;");
/* Operations may take a long time.
* Be sure PHP's safe mode is off.
*/
// @set_time_limit (0);
/* Remove errors. */
// @error_reporting (0);
require (JIRAFEAU_ROOT . 'lib/template/page.php');
// ========================================
/**
* Supprime les autorisations de modification de profile de plus de 2 heures.
*/
function cleanToken () {
if (!file_exists (VAR_TOKENS))
mkdir (VAR_TOKENS, 0755);
$d = dir (VAR_TOKENS);
$oldest = strtotime (TOKEN_USE_LIMIT);
foreach (glob (VAR_TOKENS."*") as $file) {
if (file_exists ($file) && filemtime ($file) <= $oldest)
unlink ($file);
}
}
/**
* Supprime une autorisation spécifique (déconnexion)
*/
function rmToken ($sender) {
if (!$sender)
return;
if (file_exists (VAR_TOKENS.$sender))
unlink (VAR_TOKENS.$sender);
}
function setToken ($sender) {
if (!$sender)
return;
$token = md5 (rand ());
if (file_put_contents (VAR_TOKENS.$sender, T_CREATE.": ".time ().NL.T_TOKEN.": ".$token.NL))
return $token;
return false;
}
function setLoggedToken ($sender, $token) {
if (!$sender || !$token)
return;
file_put_contents (VAR_TOKENS.$sender, T_CREATE.": ".time ().NL.T_TOKEN.": ".$token.NL.T_LOGGED.": ok".NL);
}
/**
* Récupère une variable spécifique d'un token.
*
* @param string $sender Nom du token.
* @param string $varName Nom de la variable.
* @return string|false La valeur ou false.
*/
function getTokenVar ($sender, $varName) {
if (!$sender)
return;
if (!file_exists (VAR_TOKENS.$sender))
return false;
$content = file_get_contents (VAR_TOKENS.$sender);
if (preg_match ("/\b".$varName.":\s*([^\s]+)\n/", $content, $matches))
return $matches [1];
return false;
}
function getToken ($sender) {
return getTokenVar ($sender, T_TOKEN);
}
function getCreateToken ($sender) {
return getTokenVar ($sender, T_CREATE);
}
function getLoggedToken ($sender) {
return getTokenVar ($sender, T_LOGGED);
}
function getTimeToken ($sender) {
if (!$sender || !file_exists (VAR_TOKENS.$sender))
return false;
return filemtime (VAR_TOKENS.$sender);
}
// ========================================
/**
* Outils en cas de fraude
*/
function setSenderFake ($error, $sender, $owner, $dirLink, $fileLink) {
global $doLogout;
if (!file_exists (VAR_FAKE))
mkdir (VAR_FAKE, 0755);
$dirTime = $fileTime = $fileName = $fileType = $ip = '';
if (count ($dirLink) != 0) {
$dirTime = $dirLink ['upload_date'].date (" Y-m-d H:i:s", $dirLink ['upload_date']);
$ip = $dirLink ['ip'];
}
if (!$sender)
return;
if (count ($fileLink) != 0) {
$fileTime = $fileLink ['upload_date'].date (" Y-m-d H:i:s", $fileLink ['upload_date']);
$fileName = $link ['file_name'];
$fileType = $link ['mime_type'];
}
$content =
"time : ".time ().NL.
"date : ".date ("Y-m-d H:i:s").NL.
"error : ".$error.NL.
"sender : <".$sender.">".NL.
"owner : <".$owner.">".NL.
"dirLink : <".$dirLink.">".NL.
"dirTime : ".$dirTime.NL.
"dirIp : ".$ip.NL.
"fileTime: ".$fileTime.NL.
"fileType: <".$fileType.">".NL.
"fileName: <".$fileName.">".NL;
$log = $ip.$sender;
if ($log)
file_put_contents (VAR_FAKE.$log, $content);
// $doLogout = true;
// rmToken ($sender);
}
function getSenderFake ($sender) {
return false;
// return $sender && file_exists (VAR_FAKE.$sender);
}
// ========================================
/**
* Envoie un e-mail via PHPMailer.
*
* @param string $receiver Destinataire.
* @param string $receiver_name Nom du destinataire.
* @param string $subject Sujet de l'e-mail.
* @param string $body_string Corps de l'e-mail.
* @return bool Succes de l'envoi.
*/
function sendEMail ($receiver, $receiver_name, $subject, $body_string){
try {
// SERVER SETTINGS
$mail = new PHPMailer (true);
$mail->isSMTP ();
$mail->Host = 'smtp';
$mail->SMTPAuth = false;
$mail->SMTPAutoTLS = false;
$mail->SMTPSecure = "none";
$mail->Port = 25;
$mail->charSet = "UTF-8";
$mail->ContentType = 'text/html';
global $domain;
//Recipients (change this for every project)
$mail->setFrom ('no-reply@'.$domain, '');
$mail->addAddress ($receiver, $receiver_name);
//Content
$mail->isHTML (true);
$mail->Subject = $subject;
$mail->Body = $body_string;
//send the message, check for errors
if (!$mail->send ()) {
//echo 'Mailer Error: ' . $mail->ErrorInfo;
return 0;
} else {
//echo 'Message sent!';
return 1;
}
} catch (Exception $e) {
return 0;
}
}
// ========================================
// setup
$message = '';
$sender = '';
$senderError = false;
if (isset ($_REQUEST [A_SENDER]) && !empty ($_REQUEST [A_SENDER])) {
if (!preg_match ("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/i", $_REQUEST [A_SENDER]))
$senderError = true;
else {
cleanToken ();
$sender = filter_var ($_REQUEST [A_SENDER], FILTER_VALIDATE_EMAIL);
}
}
$token = '';
if (isset ($_REQUEST [A_TOKEN]) && !empty ($_REQUEST [A_TOKEN])) {
if (!preg_match ("/^([0-9a-zA-Z_-]+)$/", $_REQUEST [A_TOKEN]))
return false;
$token = $_REQUEST [A_TOKEN];
}
$refToken = getToken ($sender);
$urlBase = $_SERVER ['HTTP_X_FORWARDED_PROTO']."://".$_SERVER ['HTTP_HOST'];
if (isset ($_REQUEST [A_ACTION]) && $_REQUEST [A_ACTION] == T_LOGIN && $sender) {
displayHeadPage ("Erreur");
if (getSenderFake ($sender))
echo "Ce compte ne peut plus se connecter. Veuillez contacter les administrateurs.";
else {
$token = setToken ($sender);
// XXX test token
$url = $urlBase.$_SERVER ['SCRIPT_NAME']."?".A_SENDER."=".$sender."&".A_TOKEN."=".$token;
if (isset ($_REQUEST [A_GET]))
$url .= "&".A_GET."=".$_REQUEST [A_GET];
if (isset ($_REQUEST [A_HASH]))
$url .= "&".A_HASH."=".$_REQUEST [A_HASH];
$result = sendEMail ($sender, "", M_EMAIL_SUBJECT,
str_replace (["___LINK___", "___IP___", "___DATE___"],
[$url, $_SERVER ['HTTP_X_REAL_IP'], date ("Y-m-d H:i:s")], M_EMAIL_CONTENT));
if ($result)
echo M_SEND_TOKEN;
else
echo
"Erreur dans l'envoi. V&eacute;ritiez votre m&eacute;l.";
}
echo "<br/><br/><br/>";
displayFootPage ();
exit;
}
function getHiddenToken () {
global $sender, $token;
return
' <input type="hidden" name="'.A_SENDER.'" value="'.$sender.'">'.NL.
' <input type="hidden" name="'.A_TOKEN.'" value="'.$token.'">'.NL;
}
function getHiddenLink () {
$result = '';
if (isset ($_REQUEST [A_GET]))
$result .=
' <input type="hidden" name="'.A_GET.'" value="'.htmlspecialchars ($_REQUEST [A_GET]).'" />'.NL;
if (isset ($_REQUEST [A_HASH]))
$result .=
' <input type="hidden" name="'.A_HASH.'" value="'.htmlspecialchars ($_REQUEST [A_HASH]).'" />'.NL;
return $result;
if (isset ($_REQUEST [A_KEY]))
$result .=
' <input type="hidden" name="'.A_KEY.'" value="'.htmlspecialchars ($_REQUEST [A_KEY]).'" />'.NL;
}

View File

@ -0,0 +1,41 @@
const toggleTheme = document.getElementById('toggle-theme');
const body = document.body;
toggleTheme.addEventListener('change', () => {
if (toggleTheme.checked) {
body.classList.remove('light-theme');
body.classList.add('dark-theme');
} else {
body.classList.remove('dark-theme');
body.classList.add('light-theme');
}
document.cookie = "theme=" + (toggleTheme.checked ? "dark-theme" : "light-theme") + "; path=/; max-age=" + (60 * 60 * 24 * 30);
});
function forwardQuerry (form, query) {
try {
var urlBase = new URL (form ["url"].value);
// XXX test host non vide
url = urlBase+query;
var link = document.createElement ('a');
link.href = url;
document.body.appendChild (link);
link.click ();
} catch (_) {
alert ("url incorrecte");
return false;
}
}
function actionUrl (button, check, name, value) {
if (check && ! confirm("Êtes-vous sûr de vouloir supprimer ?"))
return;
form = button.parentElement;
input = document.createElement ('input');
input.setAttribute ('name', name);
input.setAttribute ('value', value);
input.setAttribute ('type', 'hidden');
form.appendChild(input);
form.submit ();
}

View File

@ -0,0 +1,138 @@
<?php
function displayHeadPage ($title) {
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title><?php echo $title; ?></title>
<link rel="stylesheet" href="media/kaz/attach.css">
</head>
<body class="<?php echo isset ($_COOKIE['theme']) ? htmlspecialchars ($_COOKIE['theme']) : 'light-theme'; ?>">
<div class="theme-toggle">
<input type="checkbox" id="toggle-theme" <?php echo (isset($_COOKIE['theme']) && $_COOKIE['theme'] === 'dark-theme') ? 'checked' : ''; ?>/>
<label for="toggle-theme" class="toggle-label">
<span class="toggle-dark">&#x1F319;</span>
<span class="toggle-light">&#x1F506;</span>
</label>
</div>
<div class="container">
<div class="main-box">
<div class="blocks">
<?php
}
function displayFootPage () { ?>
</div>
</div>
</div>
<script src="lib/attach.js"></script>
<div id="kaz"/>
</body>
</html>
<?php
}
function displayRefresh () { ?>
<form action="<?php echo $_SERVER ['SCRIPT_NAME']; ?>" method="POST">
<?php echo getHiddenToken (); ?><?php echo getHiddenLink (); ?>
<input type="submit" value="<?php echo M_REFRESH; ?>">
</form>
<?php
}
function displayLogin ($msg) { ?>
<div class="block">
<div class="block-info"><p><?php echo $msg; ?></p></div>
<div class="table">
<form class="tr" action="<?php echo $_SERVER ['SCRIPT_NAME']; ?>" method="POST">
<input type="email" name="<?php echo A_SENDER; ?>" size="40" value="<?php echo jirafeau_escape ($_REQUEST [A_SENDER]);?>" placeholder="Votre email" required="required"/>
<?php echo getHiddenLink (); ?>
<input type="hidden" name="<?php echo A_ACTION; ?>" value="<?php echo T_LOGIN; ?>" />
<input type="submit" value="<?php echo M_SEND; ?>" />
</form>
</div>
</div>
<?php
}
function displayLogout ($msg) { ?>
<div class="block">
<div class="block-info"><p><?php echo $msg; ?></p></div>
<div class="table">
<form class="tr" action="<?php echo $_SERVER ['SCRIPT_NAME']; ?>" method="POST">
<input type="hidden" name="<?php echo A_ACTION; ?>" value="<?php echo T_LOGOUT; ?>">
<?php echo getHiddenToken (); ?>
<?php echo getHiddenLink (); ?>
<button type="submit">D&eacute;connexion</button>
</form>
</div>
</div>
<?php
}
function displayProfileName ($msg) { ?>
<div class="block">
<div class="block-info"><p><?php echo $msg; ?></p></div>
<div class="table">
<form class="tr" action="<?php echo $_SERVER ['SCRIPT_NAME']; ?>" method="POST">
<input type="hidden" name="<?php echo A_ACTION; ?>" value="<?php echo T_FORGETME; ?>">
<?php echo getHiddenLink (); ?>
<button type="submit">Oubliez-moi</button>
</form>
</div>
</div>
<?php
}
function displayListUrl ($query, $listUrl) {
global $DEFAULT_CLOUD;
?>
<div class="block">
<div class="block-info"><p><?php echo M_LIST_URL; ?></p></div>
<div class="management-table cloud-list">
<div class="tr">
</div><?php if (isset ($listUrl['urls'])) foreach ($listUrl['urls'] as $name => $url) { ?>
<div class="tr">
<span class="td"><a href="<?php echo $url.$query; ?>" class="cloud-item"><?php echo htmlspecialchars ($name);?></a><span class="comment"> (<?php echo htmlspecialchars ($url); ?>)</span></span>
</div><?php } ?>
<form class="tr" onsubmit="return forwardQuerry (this,<?php echo "'".$query."'"; ?>);">
<span class="td"><span class="comment"><?php echo M_NEW_URL; ?></span><input name="url" type="text" value="<?php echo $DEFAULT_CLOUD; ?>" placeholder="https://..."/></span>
</form>
</div>
</div>
<?php
}
function displayFormProfile ($listUrl) {
global $name, $url;
?>
<div class="block">
<div class="block-info"><p><?php echo M_CUSTOM_URL; ?></p></div>
<div class="table"><?php if (isset ($listUrl['urls'])) foreach ($listUrl['urls'] as $name2 => $url2) { ?>
<form class="tr" action="<?php echo $_SERVER ['SCRIPT_NAME']; ?>" method="POST">
<span class="td">
<button class="btn btn-up" onclick="actionUrl (this, false, '<?php echo A_ACTION; ?>', '<?php echo T_UP_URL; ?>')" ><?php echo L_UP_URL; ?></button>
<button class="btn btn-down" onclick="actionUrl (this, false, '<?php echo A_ACTION; ?>', '<?php echo T_DOWN_URL; ?>')" ><?php echo L_DOWN_URL; ?></button>
</span>
<span class="td"><?php echo htmlspecialchars ($name2);?></span>
<span class="td"><?php echo htmlspecialchars ($url2);?></span>
<input name="<?php echo A_NAME;?>" type="hidden" value="<?php echo $name2;?>"/>
<?php echo getHiddenToken (); ?><?php echo getHiddenLink (); ?><span class="td">
<button class="btn btn-delete" onclick="actionUrl (this, true, '<?php echo A_ACTION; ?>', '<?php echo T_DEL_URL; ?>')" ><?php echo L_DEL_URL; ?></button>
</span>
</form><?php } ?>
<form class="tr" action="<?php echo $_SERVER ['SCRIPT_NAME']; ?>" method="POST">
<span class="td"></span>
<span class="td"><input name="<?php echo A_NAME;?>" type="text" value="<?php echo $name;?>" placeholder="Mon nuage"/></span>
<span class="td"><input name="<?php echo A_URL;?>" type="text" value="<?php echo $url;?>" placeholder="https://..."/></span>
<?php echo getHiddenToken (); ?><?php echo getHiddenLink (); ?>
<span class="td"><button class="btn btn-new" onclick="actionUrl (this, false, '<?php echo A_ACTION; ?>', '<?php echo T_ADD_URL; ?>')" ><?php echo L_ADD_URL; ?></button></span>
</form>
</div>
</div>
<?php
}

View File

@ -0,0 +1,484 @@
#kaz {
background: url('kaz.png') right bottom no-repeat;
position: fixed;
top: 0;
left: 10px;
height: 64px;
width: 64px;
clear:both;
}
body {
margin: 0;
padding: 0;
font-family: sans-serif;
transition: background-color 0.3s ease, color 0.3s ease;
}
body.light-theme {
background-color: #ffffff;
color: #000000;
}
body.dark-theme {
background-color: #2c2c2c;
color: #ffffff;
}
.theme-toggle {
position: absolute;
top: 20px;
right: 20px;
}
#toggle-theme {
display: none;
}
.toggle-label {
cursor: pointer;
display: inline-block;
width: 60px;
height: 30px;
background: #ddd;
border-radius: 30px;
position: relative;
transition: background 0.3s;
}
.toggle-label::after {
content: "";
position: absolute;
top: 3px;
left: 3px;
width: 24px;
height: 24px;
background: #ffffff;
border-radius: 50%;
transition: transform 0.3s, background 0.3s;
}
#toggle-theme:checked + .toggle-label {
background: #666;
}
#toggle-theme:checked + .toggle-label::after {
transform: translateX(30px);
}
.toggle-dark, .toggle-light {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 0.8rem;
width: 20px;
text-align: center;
}
.toggle-dark {
left: 5px;
}
.toggle-light {
right: 5px;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
box-sizing: border-box;
padding: 60px 20px;
}
.main-box {
display: flex;
flex-direction: column;
align-items: stretch;
background: #ddd;
border-radius: 10px;
padding: 20px;
min-width: 33%;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
transition: background 0.3s;
}
body.dark-theme .main-box {
background: #444;
}
.blocks {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.block {
min-width: 350px;
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 5px rgba(0,0,0,0.1);
transition: background 0.3s;
}
body.dark-theme .block {
background: #555;
}
.block-info {
background: #ddd;
padding: 0 5px;
border-radius: 8px;
box-shadow: 0 0 5px rgba(0,0,0,0.1);
transition: background 0.3s;
}
body.dark-theme .block-info {
background: #444;
}
.block-list-compact {
padding: 10px;
}
.cloud-list {
/*display: flex;
flex-direction: column;*/
gap: 10px;
}
.cloud-item {
/*display: flex;
align-items: center;
justify-content: space-between;
border-radius: 5px;*/
margin: 10px;
padding: 10px;
font-weight: bold;
color: #2c2c2c;
text-decoration: none;
transition: opacity 0.3s;
}
body.dark-theme .cloud-item {
color: #fff;
}
.cloud-item:hover {
opacity: 0.8;
}
.block-list-compact .cloud-item {
padding: 5px 10px;
font-size: 0.9rem;
}
.comment {
font-style: italic;
opacity: 0.33;
}
input {
padding: 5px;
border: 1px solid #ccc;
border-radius: 5px;
/*outline: none;*/
font-size: 1rem;
color: #000000;
}
body.dark-theme input {
color: #000000;
}
.management-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.management-table th, .management-table td {
border: 1px solid #ccc;
padding: 10px;
text-align: left;
}
.management-table th {
background-color: #f2f2f2;
}
body.dark-theme .management-table th {
background-color: #555;
color: #fff;
border-color: #666;
}
.btn {
padding: 1px;
margin-right: 5px;
border: none;
border-radius: 3px;
cursor: pointer;
transition: background-color 0.3s;
font-size: 0.9rem;
}
.btn-new:hover {
background-color: #3dc35a;
}
.btn-delete:hover {
background-color: #ff7882;
}
.btn-up:hover, .btn-down:hover {
background-color: #16adc1;
}
.add-form {
display: flex;
flex-direction: column;
gap: 10px;
}
.add-form button {
padding: 10px;
padding-top : 20;
background: #000;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
font-size: 1rem;
transition: background 0.3s;
}
.add-form button:hover {
background: #333;
}
body.dark-theme .add-form button {
background: #999;
color: #000;
}
body.dark-theme .add-form button:hover {
background: #bbb;
}
h1 {
font-size: 3rem;
margin-bottom: 20px;
}
.image-container img {
width: 200px;
height: auto;
margin-bottom: 20px;
}
.form-section {
width: 100%;
margin-bottom: 20px;
}
.form-section h3 {
margin-bottom: 10px;
}
.form-section form {
display: flex;
flex-direction: column;
}
.form-section input {
padding: 10px;
margin-bottom: 10px;
border: none;
border-radius: 5px;
outline: none;
font-size: 1rem;
}
.form-section button {
padding: 10px;
background: #000;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
font-size: 1rem;
transition: background 0.3s;
}
.form-section button:hover {
background: #333;
}
body.dark-theme .form-section button {
background: #999;
color: #000;
}
body.dark-theme .form-section button:hover {
background: #bbb;
}
.message {
font-size: 1rem;
text-align: center;
line-height: 1.4em;
}
.message span {
display: block;
margin-top: 10px;
font-size: 0.9rem;
}
.message-error, .message-success {
width: 100%;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
text-align: center;
font-size: 1rem;
}
.message-error {
color: #f44336;
background-color: #ffebee;
border: 1px solid #f44336;
}
.message-success {
color: #4caf50;
background-color: #e8f5e9;
border: 1px solid #4caf50;
}
.message-container {
text-align: center;
font-size: 2rem;
padding: 20px;
border: 2px solid #f44336;
border-radius: 10px;
background-color: #ffffff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
body.dark-theme .message-container {
background-color: #444444;
border-color: #f44336;
}
.message-container a {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
background-color: #f44336;
color: white;
text-decoration: none;
border-radius: 5px;
}
.message-container a:hover {
background-color: #d32f2f;
}
@media (max-width: 768px) {
.blocks {
flex-direction: column;
}
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 500px;
border-radius: 10px;
position: relative;
}
.close {
color: #aaa;
position: absolute;
top: 10px;
right: 25px;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover, .close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
.top-bar {
display: flex;
justify-content: center;
align-items: center;
margin-top: 60px;
}
.tabs {
display: inline-flex;
border-radius: 20px;
overflow: hidden;
background: #ccc;
box-shadow: 0 0 5px rgba(0,0,0,0.1);
}
.tab {
padding: 10px 20px;
cursor: pointer;
background: #ccc;
color: #000;
transition: background 0.3s;
display: flex;
align-items: center;
justify-content: center;
min-width: 120px;
text-align: center;
font-weight: bold;
}
.tab.active {
background: #999;
}
.form-box {
background: #ddd;
border-radius: 10px;
padding: 20px;
margin-top: 40px;
width: 300px;
text-align: center;
box-shadow: 0 0 5px rgba(0,0,0,0.1);
transition: background 0.3s, color 0.3s;
}
body.dark-theme .form-box {
background: #444;
}
.form-box h2 {
margin-top: 0;
margin-bottom: 20px;
font-size: 1.5rem;
}
.form-box input {
width: 90%;
padding: 10px;
margin-bottom: 10px;
border: none;
border-radius: 5px;
outline: none;
font-size: 0.9rem;
}
.form-box button {
width: 100%;
padding: 10px;
background: #000;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
font-size: 1rem;
transition: background 0.3s;
}
body.light-theme .form-box button:hover {
background: #333;
}
body.dark-theme .form-box button {
background: #999;
color: #000;
}
body.dark-theme .form-box button:hover {
background: #bbb;
}
.hidden {
display: none;
}
.nextcloud-btn {
display: block;
width: 300px;
margin: 20px auto 0;
padding: 10px;
background-color: #2ec2b3;
color: white;
text-align: center;
border: none;
border-radius: 5px;
text-decoration: none;
font-weight: bold;
cursor: pointer;
transition: background-color 0.3s;
}
.nextcloud-btn:hover {
background-color: #28a89d;
}
div.table {
display:table;
}
form.tr, div.tr {
display:table-row;
}
span.td {
padding: 0 10px;
display:table-cell;
}

View File

@ -2,7 +2,7 @@
/*
* Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
* only upload file for restricted acces purpose
* version : 2.22 (2024-12-09)
* version : 2.24 (2025-01-26)
*/
use PHPMailer\PHPMailer\PHPMailer;

View File

@ -33,7 +33,7 @@
# knowledge of the CeCILL-B license and that you accept its terms. #
##########################################################################
# Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
# version : 2.23 (2025-01-07)
# version : 2.24 (2025-01-26)
##########################################################################
# - installer l'utilitaire apg pour génération de mot de passes

View File

@ -33,7 +33,7 @@
# knowledge of the CeCILL-B license and that you accept its terms. #
##########################################################################
# Kaz addon (see https://git.kaz.bzh/KAZ/depollueur for information)
# version : 2.23 (2025-01-07)
# version : 2.24 (2025-01-26)
PRG=$(basename $0)

View File

@ -74,7 +74,7 @@ static const string KAZ_PLAIN_WARNING ("Attention : Kaz a dépollué ce
static const string KAZ_PLAIN_DOWLOAD_ONE ("Vos pièces jointes sont à télécharger individuellement ici :");
static const string KAZ_PLAIN_DOWLOAD_OTHER ("(Contenu dans des messages précédents)");
static const string KAZ_PLAIN_DOWLOAD_ALL ("Vous pouvez télécharger l'ensemble dans une archive là :");
static const string KAZ_PLAIN_DOWLOAD_CLOUD ("Vous pouvez classer les pièces jointes dans votre cloud là :");
static const string KAZ_PLAIN_DOWLOAD_CLOUD ("Expérimental : vous pouvez classer les pièces jointes dans votre cloud là :");
static const string HEAD ("<head>");
static const string HEAD_END ("</head>");
@ -99,7 +99,7 @@ static const string KAZ_HTML_DONT_TOUCH ("(conservez cette partie intacte dans
static const string KAZ_HTML_DOWLOAD_ONE ("Vos pi&egrave;ces jointes sont &agrave; t&eacute;l&eacute;charger individuellement ici :");
static const string KAZ_HTML_DOWLOAD_OTHER ("(Contenu dans des messages pr&eacute;c&eacute;dents)");
static const string KAZ_HTML_DOWLOAD_ALL ("Vous pouvez t&eacute;l&eacute;charger l'ensemble dans une archive l&agrave; :");
static const string KAZ_HTML_DOWLOAD_CLOUD ("Vous pouvez classer les pi&egrave;ces jointes dans votre cloud l&agrave; :");
static const string KAZ_HTML_DOWLOAD_CLOUD ("Expérimental : vous pouvez classer les pi&egrave;ces jointes dans votre cloud l&agrave; :");
static const string KAZ_HTML_ARCHIVE ("archive");
static const string KAZ_HTML_CLOUD ("cloud");

View File

@ -33,8 +33,8 @@
////////////////////////////////////////////////////////////////////////////
#include "version.hpp"
const std::string kaz::LAST_VERSION_NUM ("2.23");
const std::string kaz::LAST_VERSION_DATE ("2025-01-07");
const std::string kaz::LAST_VERSION_NUM ("2.24");
const std::string kaz::LAST_VERSION_DATE ("2025-01-26");
const std::string kaz::LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" eMailShrinker");
#include <iostream>