Commit ce15dd73 authored by Pierre-Jean CHANCELLIER's avatar Pierre-Jean CHANCELLIER
Browse files

Merge branch 'master' into 'master'

Security fix, multiple nodes, cache

See merge request !8
parents b26e40ac 29e8203d
......@@ -8,5 +8,5 @@ Générateur de barre de financement intégrable dans une page web pour suivre l
* Déposez l'ensemble des fichiers dans un dossier sur votre serveur
* Paramétrez votre serveur web (Apache ou Nginx) pour rendre le dossier accessible depuis le web
* Le dossier img/qrcodes doit être accessible en écriture pour le compte utilisé par votre serveur web (en général www-data)
* Le générateur sera alors accessible via http(s)://votredomaine.com/votre_chemin/generate.php
\ No newline at end of file
* Les dossiers `img/qrcodes` et `cache` doivent être accessibles en écriture pour le compte utilisé par votre serveur web (en général `www-data`)
* Le générateur sera alors accessible via http(s)://votredomaine.com/votre_chemin/generate.php
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles/w3.css">
<link rel="stylesheet" href="styles/font_awesome.min.css">
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="styles/w3.css"/>
<link rel="stylesheet" href="styles/font_awesome.min.css"/>
<link rel="stylesheet" href="styles/gh-fork-ribbon.min.css" />
<link rel="stylesheet" href="styles/generator.css">
<link rel="stylesheet" href="styles/generator.css"/>
<title>Génération de votre barre de financement</title>
</head>
<body>
<a class="github-fork-ribbon" href="https://git.duniter.org/paidge/barre-de-financement-int-grable" data-ribbon="Fork me on Gitlab" title="Fork me on Duniter's Gitlab">Fork me on Duniter's Gitlab</a>
<a class="github-fork-ribbon" href="https://git.duniter.org/paidge/barre-de-financement-int-grable" data-ribbon="Fork me on Gitlab" title="Fork me on Duniter's GitLab">Fork me on Duniter's GitLab</a>
<header>
<div class="w3-panel w3-padding-16 w3-display-middle w3-center w3-theme-d2">
<h1 class="w3-jumbo">Générez votre barre de financement</h1>
......@@ -32,7 +32,7 @@
</select>
</p>
<p class="field">
<label for="pubkey">Pubkey&nbsp;:</label>
<label for="pubkey">Clé publique&nbsp;:</label>
<input id="pubkey" name="pubkey" type="text" class="w3-input w3-border w3-animate-input" required placeholder="27b1j7BPssdjbXmGNMYU2JJrRotqrZMruu5p5AWowUEy" pattern="^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{43,44}$" />
</p>
<p class="field">
......@@ -58,12 +58,12 @@
<select id="lang" name="lang" class="w3-select w3-border">
<option value="fr" selected>français</option>
<option value="en">anglais</option>
<option value="eo">esperanto</option>
<option value="eo">espéranto</option>
</select>
</p>
<p class="field">
<label for="node">Nœud duniter&nbsp;:</label>
<input id="node" name="node" type="text" class="w3-input w3-border w3-animate-input" placeholder="g1.duniter.org" pattern="^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,6}$" />
<label for="node">Nœuds Duniter (séparés par un espace)&nbsp;:</label>
<input id="node" name="node" type="text" class="w3-input w3-border w3-animate-input" placeholder="https://g1.duniter.org" pattern="^(https?:\/\/(\[[a-fA-F0-9:]+\]|(\w|[._-])+[^.])(:\d{1,5})?(\s+|$))+$" />
</p>
<fieldset class="w3-theme-l5">
<legend class="w3-theme-d5 w3-padding-small w3-xlarge">Période de financement</legend>
......@@ -87,7 +87,7 @@
<fieldset class="w3-theme-l5">
<legend class="w3-theme-d5 w3-padding-small w3-xlarge">Options d'affichage</legend>
<p class="field">
<label for="display_pubkey">Affichage de la pubkey&nbsp;:</label>
<label for="display_pubkey">Affichage de la clé publique&nbsp;:</label>
<input id="display_pubkey" name="display_pubkey" type="checkbox" class="w3-check" />
</p>
<p class="field">
......@@ -143,15 +143,15 @@
</section>
<section id="display_result" class="w3-padding-32 w3-container w3-theme-d1">
<div class="w3-content">
<h2>Résultat :</h2>
<p>Copier-coller le code suivant pour l'intégrer sur votre site web/blog/forum :</p>
<h2>Résultat</h2>
<p>Copier-coller le code suivant pour l'intégrer sur votre site web/blog/forum&nbsp;:</p>
<textarea id="result" onclick="select();" onfocus="select();" readonly></textarea>
<div id="buttons" class="w3-bar w3-center w3-hide">
<div class="tooltip"><button id="copy" class="w3-btn w3-theme-l5 w3-padding-large w3-large w3-margin-top w3-hover-theme" onclick="copyToClipboard('#result')">Copier</button>
<span class="tooltiptext">Copié !</span></div>
<span class="tooltiptext">Copié&#8239;!</span></div>
<button id="reset" class="w3-btn w3-theme-l5 w3-padding-large w3-large w3-margin-top w3-hover-theme">Réinitialiser</button>
</div>
<h2 id="preview_label" class="w3-hide">Prévisualisation :</h2>
<h2 id="preview_label" class="w3-hide">Prévisualisation</h2>
<div id="preview" class="w3-margin-top w3-center">
</div>
</div>
......@@ -160,13 +160,13 @@
<i class="fa fa-angle-double-up" aria-hidden="true"></i>
</div>
<footer class="w3-container w3-padding-16 w3-center w3-theme-d5">
<p>Code source disponible sur <a href="https://git.duniter.org" target="_blank">le Gitlab Duniter</a></p>
<p>Code source disponible sur <a href="https://git.duniter.org/paidge/barre-de-financement-int-grable" target="_blank">le GitLab Duniter</a></p>
<p>Développé par <a href="https://g1.duniter.fr/#/app/wot/27b1j7BPssdjbXmGNMYU2JJrRotqrZMruu5p5AWowUEy/" target="_blank">Paidge</a></p>
<div class="w3-xlarge">
<a href="https://www.facebook.com/pjchancellier" target="_blank"><i class="fab fa-facebook-f w3-margin-right"></i></a>
<a href="https://diaspora.normandie-libre.fr/people/97f6cd801bcf01365ebe002564b8841f" target="_blank"><i class="fab fa-diaspora w3-margin-right"></i></a>
<a href="https://www.youtube.com/watch?v=SjoYIz_3JLI&list=PLmKEBjWrttOu93a92v62EWnjcs_fX6I7C" target="_blank"><i class="fab fa-youtube w3-margin-right"></i></a>
<a href="https://normandie-libre.fr" target="_blank"><i class="fas fa-globe"></i></a>
<a href="https://www.facebook.com/pjchancellier" target="_blank" title="Facebook" aria-label="Facebook"><i class="fab fa-facebook-f w3-margin-right"></i></a>
<a href="https://diaspora.normandie-libre.fr/people/97f6cd801bcf01365ebe002564b8841f" target="_blank" title="Diaspora" aria-label="Diaspora"><i class="fab fa-diaspora w3-margin-right"></i></a>
<a href="https://www.youtube.com/watch?v=SjoYIz_3JLI&list=PLmKEBjWrttOu93a92v62EWnjcs_fX6I7C" target="_blank" title="Youtube" aria-label="Youtube"><i class="fab fa-youtube w3-margin-right"></i></a>
<a href="https://normandie-libre.fr" target="_blank" title="Normandie Libre" aria-label="Normandie Libre"><i class="fas fa-globe"></i></a>
</div>
</footer>
<script>
......@@ -182,4 +182,4 @@ function copyToClipboard(element) {
}
</script>
</body>
</html>
\ No newline at end of file
</html>
<?php
// CONFIG
$CACHE_TXS = 3600; // txs cache duration in seconds (0 to disable)
$CACHE_UD = 86400; // UD cache duration in seconds (0 to disable)
$CACHE_DIR = 'cache/';
$ALLOW_CLIENT_NODE = false; // set true is security problem
$NODE = array('https://g1.duniter.org', 'https://g1.librelois.fr', 'https://g1.cgeek.fr', 'https://duniter.normandie-libre.fr', 'https://g1.presles.fr', 'https://g1.mithril.re');
$FONT_COLOR = '#212529';
$BG_COLOR = '#FFF';
$BORDER_COLOR = '#343a40';
$PROGRESS_COLOR = '#ffc107';
if(($CACHE_TXS != 0 or $CACHE_UD != 0) and !file_exists($CACHE_DIR))
mkdir($CACHE_DIR);
if(isset($_GET['lang'])) {
if(empty($_GET['lang'])) $langdetect = true;
else $lang = $_GET['lang'];
......@@ -18,11 +33,11 @@
}
// Vérification du node et des couleurs
$node = (!empty($_GET['node'])) ? $_GET['node'] : 'g1.duniter.org';
$font_color = (!empty($_GET['font_color'])) ? '#' . $_GET['font_color'] : '#212529';
$background_color = (!empty($_GET['background_color'])) ? '#' . $_GET['background_color'] : '#FFF';
$border_color = (!empty($_GET['border_color'])) ? '#' . $_GET['border_color'] : '#343a40';
$progress_color = (!empty($_GET['progress_color'])) ? '#' . $_GET['progress_color'] : '#ffc107';
$nodes = ($ALLOW_CLIENT_NODE and isset($_GET['node']) and !empty($_GET['node']))? explode(' ', $_GET['node']) : $NODE;
$font_color = (!empty($_GET['font_color'])) ? '#' . $_GET['font_color'] : $FONT_COLOR;
$background_color = (!empty($_GET['background_color'])) ? '#' . $_GET['background_color'] : $BG_COLOR;
$border_color = (!empty($_GET['border_color'])) ? '#' . $_GET['border_color'] : $BORDER_COLOR;
$progress_color = (!empty($_GET['progress_color'])) ? '#' . $_GET['progress_color'] : $PROGRESS_COLOR;
// Vérification des dates et calcul du nombre de jours entre la date du jour et la date de fin
if (!empty($_GET['start_date'])){
......@@ -71,7 +86,7 @@
// Génération du QRcode
$display_qrcode = (!empty($_GET['display_qrcode']));
$qrcode_path = 'img/qrcodes/' . $pubkey . '.png';
if (($display_qrcode) && (!file_exists($qrcode_path))) {
if ($display_qrcode && !file_exists($qrcode_path)) {
QRcode::png($pubkey, $qrcode_path);
}
}
......@@ -98,16 +113,34 @@
echo '<div>'.tr('error_target_missing').'</div>';
exit;
}
// Récupération des transactions entrantes entre la date de début et la date du jour
$start_timestamp = $start_date->getTimestamp();
$today_timestamp = $today->getTimestamp();
$url_json = 'https://' . $node . '/tx/history/' . $pubkey . '/times/' . $start_timestamp . '/' . $today_timestamp;
$json = @file_get_contents($url_json);
if ($json === false){
echo '<div>'.tr('error_connect_node').'</div>';
exit;
$json = null;
$cache_filename = $CACHE_DIR . $pubkey . '_' . $start_timestamp . '.json';
if($CACHE_TXS != 0 and file_exists($cache_filename) and time()-filemtime($cache_filename) < $CACHE_TXS) {
$json = file_get_contents($cache_filename);
}
if(!$json) {
$url_json = '/tx/history/' . $pubkey . '/times/' . $start_timestamp . '/' . $today_timestamp;
shuffle($nodes); // shuffle for load balancing
foreach($nodes as &$node) {
// Test each node and keep the first which works
$json = @file_get_contents($node . $url_json, false, stream_context_create(array('http'=>array('timeout'=>10.0))));
if($json !== false)
break;
}
if ($json === false){
echo '<div>'.tr('error_connect_node').'</div>';
exit;
}
if($CACHE_UD != 0) {
file_put_contents($cache_filename, $json);
}
}
$json = json_decode($json);
$transactions = $json->history->received;
$total = 0;
......@@ -143,7 +176,7 @@
}
$donors = count($donneurs);
if ($display_graph){
// On complète le tableau avec la derniere transaction et pour la date de visualisation du graph
// On complète le tableau avec la dernière transaction et pour la date de visualisation du graphe
array_push($array_final, ['t'=>$tmp_timestamp*1000, 'y'=>(string) $total]);
array_push($array_final, ['t'=>$today_timestamp*1000, 'y'=>(string) $total]);
$array_line = [['t'=>$start_timestamp*1000, 'y'=>(string) $target],['t'=>$today_timestamp*1000, 'y'=>(string) $target]];
......@@ -161,17 +194,43 @@
// Si l'unité est relative
if ($unit == 'relative'){
// On récupère le dernier block qui contient le DU
$url_json = 'https://' . $node . '/blockchain/with/ud';
$json = file_get_contents($url_json);
$json = json_decode($json);
$last_block_with_ud = end($json->result->blocks);
$ud = null;
if($CACHE_UD != 0 and file_exists($CACHE_DIR . 'ud.txt') and time()-filemtime($CACHE_DIR . 'ud.txt') < $CACHE_UD) {
$ud = floatval(file_get_contents($CACHE_DIR . 'ud.txt'));
}
if(!$ud) {
// On récupère le dernier bloc qui contient le DU
$url_json = $node . '/blockchain/with/ud';
if(isset($node))
$json = file_get_contents($url_json);
else {
shuffle($nodes); // shuffle for load balancing
foreach($nodes as &$node) {
// Test each node and keep the first which works
$json = @file_get_contents($node . $url_json, false, stream_context_create(array('http'=>array('timeout'=>10.0))));
if($json !== false)
break;
}
if ($json === false){
echo '<div>'.tr('error_connect_node').'</div>';
exit;
}
}
$json = json_decode($json);
$last_block_with_ud = end($json->result->blocks);
// Puis on récupère le montant du DU pour mettre à jour les données
$url_json = $node . '/blockchain/block/' . $last_block_with_ud;
$json = file_get_contents($url_json);
$json = json_decode($json);
$ud = $json->dividend/100;
if($CACHE_UD != 0) {
file_put_contents($CACHE_DIR . 'ud.txt', strval($ud));
}
}
// Puis on récupère le montant du DU pour mettre à jour les données
$url_json = 'https://' . $node . '/blockchain/block/' . $last_block_with_ud;
$json = file_get_contents($url_json);
$json = json_decode($json);
$ud = $json->dividend/100;
$total = round($total/$ud);
if ($display_graph){
for($i=0;$i<count($array_final);$i++){
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment