From 883e5e0dcc15203f715a0b57d8442bd14c1594a5 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Wed, 29 Nov 2017 11:01:48 +0100 Subject: [PATCH] LDAP sync, PHP code updated with dev, webpack 3, balancing --- copyright.txt => LICENSE | 0 README.md | 3 + app.js | 21 ++-- debian/changelog | 2 +- debian/install | 3 + forms/ecomerce/catalog/catalog.js | 2 +- forms/ecomerce/checkout/checkout.js | 2 +- forms/ecomerce/checkout/ui.xml | 24 +---- js/hedera/basket-checker.js | 2 +- package.json | 19 +++- pages/main/analytics.html | 9 -- pages/main/head.php | 17 ---- pages/main/ui.php | 17 +++- pages/tpv/locale/ca.json | 4 - pages/tpv/locale/en.json | 4 - pages/tpv/locale/es.json | 4 - pages/tpv/locale/fr.json | 4 - pages/tpv/locale/mn.json | 4 - pages/tpv/locale/pt.json | 4 - pages/tpv/style.css | 16 --- pages/tpv/ui.php | 22 ---- pages/update-browser/ui.php | 1 - pages/version-menu/ui.php | 1 - rest/core/account.php | 13 ++- rest/misc/access-version.php | 1 - rest/misc/exchange-rate.php | 1 - rest/misc/mail.php | 49 ++------- rest/misc/sms.php | 2 - rest/misc/visits-sync.php | 1 - web/db-session-handler.php | 5 +- web/html-service.php | 51 +++------- web/html.php | 66 ++++++++++++ web/json-service.php | 14 +-- web/jwt.php | 1 - web/mailer.php | 40 +++++--- web/report.php | 4 +- web/rest-request.php | 1 - web/rest-service.php | 52 +++++++++- web/service.php | 150 ++++++++++++---------------- web/unavailable.html | 17 ++-- web/util.php | 3 +- webpack.config.js | 85 +++++++++++----- webpack.config.json | 8 ++ 43 files changed, 380 insertions(+), 369 deletions(-) rename copyright.txt => LICENSE (100%) create mode 100644 README.md delete mode 100755 pages/main/analytics.html delete mode 100755 pages/main/head.php delete mode 100755 pages/tpv/locale/ca.json delete mode 100755 pages/tpv/locale/en.json delete mode 100755 pages/tpv/locale/es.json delete mode 100755 pages/tpv/locale/fr.json delete mode 100755 pages/tpv/locale/mn.json delete mode 100644 pages/tpv/locale/pt.json delete mode 100755 pages/tpv/style.css delete mode 100755 pages/tpv/ui.php create mode 100644 web/html.php create mode 100644 webpack.config.json diff --git a/copyright.txt b/LICENSE similarity index 100% rename from copyright.txt rename to LICENSE diff --git a/README.md b/README.md new file mode 100644 index 00000000..6537493b --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Hedera + +Hedera is the main page for Verdnatura. diff --git a/app.js b/app.js index 8291c1fb..28b7aaf2 100644 --- a/app.js +++ b/app.js @@ -1,18 +1,21 @@ -var host = window.location.host.split(':')[0]; +var assetsPath; if (_DEV_MODE) - host = host +':9000'; +{ + var host = window.location.host.split(':')[0]; + assetsPath = 'http://'+ host +':'+ _DEV_SERVER_PORT +'/'+ _PUBLIC_PATH; +} +else + assetsPath = _PUBLIC_PATH; -__webpack_public_path__ = '//'+ host +'/build/'; +__webpack_public_path__ = assetsPath; require ('hedera/hedera'); window.onload = function () { - Vn.Locale.init (); - var lang = Vn.Locale.language; - loadLocale (lang, main); + loadLocale (main); } function main (req) @@ -26,8 +29,11 @@ function main (req) hederaWeb.run (); } -function loadLocale (lang, cb) +function loadLocale (cb) { + Vn.Locale.init (); + var lang = Vn.Locale.language; + switch (lang) { case 'ca': @@ -55,4 +61,3 @@ function loadLocale (lang, cb) cb (require.context ('js', true, /locale\/en.json$/)); }); } } - diff --git a/debian/changelog b/debian/changelog index e9cc1fb4..aa5e925b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -hedera-web (1.405.18) stable; urgency=low +hedera-web (1.405.23) stable; urgency=low * Initial Release. diff --git a/debian/install b/debian/install index ddaaaa78..be45025c 100644 --- a/debian/install +++ b/debian/install @@ -12,3 +12,6 @@ index.php usr/share/hedera-web package.json usr/share/hedera-web build usr/share/hedera-web manifest.json usr/share/hedera-web +LICENSE usr/share/hedera-web +README.md usr/share/hedera-web +webpack.config.json usr/share/hedera-web diff --git a/forms/ecomerce/catalog/catalog.js b/forms/ecomerce/catalog/catalog.js index 524baf9d..0326669f 100644 --- a/forms/ecomerce/catalog/catalog.js +++ b/forms/ecomerce/catalog/catalog.js @@ -17,7 +17,7 @@ Hedera.Catalog = new Class } else { - var query = 'CALL basket_configure_for_guest ()'; + var query = 'CALL basketConfigureForGuest'; this.conn.execQuery (query, this.loadUi.bind (this)); } } diff --git a/forms/ecomerce/checkout/checkout.js b/forms/ecomerce/checkout/checkout.js index 38df9c65..5d8bce26 100644 --- a/forms/ecomerce/checkout/checkout.js +++ b/forms/ecomerce/checkout/checkout.js @@ -56,7 +56,7 @@ Hedera.Checkout = new Class { this.disableButtons (true); - var query = 'CALL basket_configure (#date, #method, #agency, #address)'; + var query = 'CALL basketConfigure (#date, #method, #agency, #address)'; var batch = new Sql.Batch (); batch.addParam ('method', this.$('method')); diff --git a/forms/ecomerce/checkout/ui.xml b/forms/ecomerce/checkout/ui.xml index 3ec793fc..a5467f96 100755 --- a/forms/ecomerce/checkout/ui.xml +++ b/forms/ecomerce/checkout/ui.xml @@ -21,17 +21,9 @@ - + - CALL agency_list_from_date (#date, #address); - SELECT a.Id_Agencia, a.description - FROM t_agency t - JOIN vn2008.Agencias a ON a.Id_Agencia = t.agency_id - JOIN vn2008.Vistas v ON a.Vista = v.vista_id - WHERE a.web != FALSE - AND v.code = 'AGENCY' - ORDER BY a.description; - DROP TEMPORARY TABLE t_agency; + CALL vn.agencyListForMethod(#date, #address, 'AGENCY') @@ -40,17 +32,9 @@ - + - CALL agency_list_from_date (#date, #address); - SELECT a.Id_Agencia, a.description - FROM t_agency t - JOIN vn2008.Agencias a ON a.Id_Agencia = t.agency_id - JOIN vn2008.Vistas v ON a.Vista = v.vista_id - WHERE a.web != FALSE - AND v.code = 'PICKUP' - ORDER BY a.description; - DROP TEMPORARY TABLE t_agency; + CALL vn.agencyListForMethod(#date, #address, 'PICKUP') diff --git a/js/hedera/basket-checker.js b/js/hedera/basket-checker.js index cc3d8930..c67e0bd5 100644 --- a/js/hedera/basket-checker.js +++ b/js/hedera/basket-checker.js @@ -3,7 +3,7 @@ module.exports = { check: function (conn, callback) { - conn.execQuery ('CALL basket_check ()', + conn.execQuery ('CALL basketCheck', this._onBasketCheck.bind (this, callback)); } diff --git a/package.json b/package.json index 051cdc02..66ca4f13 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,26 @@ { "name": "hedera-web", - "version": "1.0.0", + "version": "1.405.23", "description": "Verdnatura web page", + "license": "GPL-3.0", + "repository": { + "type": "git", + "url": "https://git.verdnatura.es/hedera-web" + }, "devDependencies": { + "assets-webpack-plugin": "^3.5.1", "bundle-loader": "^0.5.4", "css-loader": "^0.25.0", + "eslint": "^3.16.1", "file-loader": "^0.9.0", "json-loader": "^0.5.4", "raw-loader": "^0.5.1", - "style-loader": "^0.13.1", + "style-loader": "^0.19.0", "url-loader": "^0.5.7", - "webpack": "^1.13.3", - "webpack-dev-server": "^1.16.2" + "webpack": "^3.6.0", + "webpack-chunk-hash": "^0.5.0", + "webpack-dev-server": "^2.9.1", + "webpack-merge": "^4.1.0" }, "dependencies": { "mootools": "^1.5.2", @@ -19,7 +28,7 @@ }, "scripts": { "dev": "webpack-dev-server --progress --colors --hot", - "build": "rm -f build/* ; webpack --progress --colors", + "build": "rm -rf build/ ; webpack --progress --colors", "clean": "rm -rf build/" } } diff --git a/pages/main/analytics.html b/pages/main/analytics.html deleted file mode 100755 index 22fa2837..00000000 --- a/pages/main/analytics.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/pages/main/head.php b/pages/main/head.php deleted file mode 100755 index 51aecfc1..00000000 --- a/pages/main/head.php +++ /dev/null @@ -1,17 +0,0 @@ -'."\n\t\t"; - -if ($result = $db->query ('SELECT name, content FROM metatag')) -{ - while ($row = $result->fetch_assoc ()) - echo "\n\t\t"; - - $result->free (); -} - -$url = _DEV_MODE ? "http://{$_SERVER['SERVER_NAME']}:9000/" : ''; -$this->includeJs ("{$url}build/hedera-web.js"); - diff --git a/pages/main/ui.php b/pages/main/ui.php index 65006b62..65a7a283 100755 --- a/pages/main/ui.php +++ b/pages/main/ui.php @@ -1,5 +1,10 @@ - +query ('SELECT name, content FROM metatag'); + +?> + @@ -11,7 +16,15 @@ - + + + fetch_object ()): ?> + + + + + + Verdnatura diff --git a/pages/tpv/locale/ca.json b/pages/tpv/locale/ca.json deleted file mode 100755 index 58ac070e..00000000 --- a/pages/tpv/locale/ca.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "PaymentComplete": "Pagament acabat, ja pots tornar a la nostra pàgina web." - ,"ReturnToWeb": "Tornar a Verdnatura" -} diff --git a/pages/tpv/locale/en.json b/pages/tpv/locale/en.json deleted file mode 100755 index 4e04b791..00000000 --- a/pages/tpv/locale/en.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "PaymentComplete": "Payment completed, you can return to our website." - ,"ReturnToWeb": "Back to Verdnatura" -} diff --git a/pages/tpv/locale/es.json b/pages/tpv/locale/es.json deleted file mode 100755 index ec4c2a75..00000000 --- a/pages/tpv/locale/es.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "PaymentComplete": "Pago terminado, ya puedes volver a nuestra página web." - ,"ReturnToWeb": "Volver a Verdnatura" -} diff --git a/pages/tpv/locale/fr.json b/pages/tpv/locale/fr.json deleted file mode 100755 index 46c0940c..00000000 --- a/pages/tpv/locale/fr.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "PaymentComplete": "Paiement terminé, merci par votre confiance, maintenant vous pouvez revenir à notre site." - ,"ReturnToWeb": "Retour au Verdnatura" -} diff --git a/pages/tpv/locale/mn.json b/pages/tpv/locale/mn.json deleted file mode 100755 index 4e04b791..00000000 --- a/pages/tpv/locale/mn.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "PaymentComplete": "Payment completed, you can return to our website." - ,"ReturnToWeb": "Back to Verdnatura" -} diff --git a/pages/tpv/locale/pt.json b/pages/tpv/locale/pt.json deleted file mode 100644 index 621bd916..00000000 --- a/pages/tpv/locale/pt.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "PaymentComplete": "Pagamento terminado, já podes voltar a nossa página web." - ,"ReturnToWeb": "Voltar a Verdnatura" -} diff --git a/pages/tpv/style.css b/pages/tpv/style.css deleted file mode 100755 index b43a1ce8..00000000 --- a/pages/tpv/style.css +++ /dev/null @@ -1,16 +0,0 @@ -* -{ - font-family: 'Roboto'; - font-size: 10pt; -} -div -{ - position: absolute; - width: 48em; - height: 10em; - margin-left: -24em; - margin-top: -5em; - top: 50%; - left: 50%; - text-align: center; -} diff --git a/pages/tpv/ui.php b/pages/tpv/ui.php deleted file mode 100755 index 6ceea6a0..00000000 --- a/pages/tpv/ui.php +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - Verdnatura - - -
- Verdnatura -

- -

-

- -

-
- - diff --git a/pages/update-browser/ui.php b/pages/update-browser/ui.php index 98114b5a..62f59301 100755 --- a/pages/update-browser/ui.php +++ b/pages/update-browser/ui.php @@ -1,5 +1,4 @@ - diff --git a/pages/version-menu/ui.php b/pages/version-menu/ui.php index f479aa2e..2e8c5a41 100755 --- a/pages/version-menu/ui.php +++ b/pages/version-menu/ui.php @@ -1,5 +1,4 @@ - diff --git a/rest/core/account.php b/rest/core/account.php index fc59d918..c924b823 100755 --- a/rest/core/account.php +++ b/rest/core/account.php @@ -75,10 +75,19 @@ class Account [$userName] ); + $nameArgs = explode (' ', $user->nickname); + $givenName = $nameArgs[0]; + + if (count ($nameArgs) > 1) + $sn = $nameArgs[1]; + if (empty ($sn)) + $sn = 'Empty'; + $info = [ - 'cn' => $userName, - 'sn' => $userName, + 'cn' => $user->nickname, 'displayName' => $user->nickname, + 'givenName' => $givenName, + 'sn' => $sn, 'mail' => "$userName@{$domain}", 'userPassword' => sshaEncode ($password), 'preferredLanguage' => $user->lang diff --git a/rest/misc/access-version.php b/rest/misc/access-version.php index 2ccfd746..b8ac47a8 100755 --- a/rest/misc/access-version.php +++ b/rest/misc/access-version.php @@ -73,4 +73,3 @@ class AccessVersion extends Vn\Web\JsonRequest return TRUE; } } - diff --git a/rest/misc/exchange-rate.php b/rest/misc/exchange-rate.php index ad4e06d8..5fdb0658 100755 --- a/rest/misc/exchange-rate.php +++ b/rest/misc/exchange-rate.php @@ -43,4 +43,3 @@ class ExchangeRate extends Vn\Lib\Method $db->queryFromFile (__DIR__.'/exrate-add'); } } - diff --git a/rest/misc/mail.php b/rest/misc/mail.php index eec5547d..c6da11d5 100755 --- a/rest/misc/mail.php +++ b/rest/misc/mail.php @@ -9,60 +9,25 @@ class Mail extends Vn\Lib\Method $db->selectDb ('vn2008'); $db->query ('START TRANSACTION'); - $conf = $db->getRow ( - 'SELECT host, port, secure, sender, sender_name, user, password - FROM hedera.mail_config' - ); + $mailer = new Vn\Web\Mailer ($db); $res = $db->query ( 'SELECT * FROM mail WHERE sent = 0 ORDER BY DATE_ODBC DESC LIMIT 20 FOR UPDATE'); $count = 0; - while ($row = $res->fetch_assoc ()) + while ($row = $res->fetch_object ()) { $sent = 1; $status = 'OK'; try { - //if (!preg_match ('/^[\w\._%-]+@[\w\.-]+\.[A-Za-z]{2,4}$/', $mailTo)) - // throw new Exception ('Destination mail has invalid sintax'); + $mail = $mailer->createObject ($row->to, $row->text, $row->subject); + $mail->AddReplyTo ($row->reply_to, $conf->sender_name); - $mail = new PHPMailer (); - $mail->isSMTP (); - $mail->Host = $conf['host']; - - if (!empty ($conf['user'])) + if (!empty ($row->path)) { - $mail->SMTPAuth = TRUE; - $mail->Username = $conf['user']; - $mail->Password = base64_decode ($conf['password']); - } - else - $mail->SMTPAuth = FALSE; - - if ($conf['secure']) - { - $mail->SMTPSecure = 'ssl'; - $mail->Port = 465; - } - - $mail->setFrom ($conf['sender'], $conf['sender_name']); - $mail->AddReplyTo ($row['reply_to'], $conf['sender_name']); - - $mailList = explode (',', $row['to']); - - foreach ($mailList as $to) - $mail->AddAddress ($to); - - $mail->IsHTML (TRUE); - $mail->Subject = $row['subject']; - $mail->Body = ' '. $row['text']; - $mail->CharSet = 'UTF-8'; - - if (!empty ($row['path'])) - { - $attachment = '/mnt/cluster/pdfs/'. $row['path']; + $attachment = '/mnt/cluster/pdfs/'. $row->path; if (file_exists ($attachment)) $mail->AddAttachment ($attachment, ''); @@ -89,5 +54,3 @@ class Mail extends Vn\Lib\Method echo "Total $count mails sent\n"; } } - - diff --git a/rest/misc/sms.php b/rest/misc/sms.php index c31996e4..17f000cc 100644 --- a/rest/misc/sms.php +++ b/rest/misc/sms.php @@ -48,5 +48,3 @@ class Sms extends Vn\Web\JsonRequest return TRUE; } } - - diff --git a/rest/misc/visits-sync.php b/rest/misc/visits-sync.php index bf6951e6..61c10a5c 100644 --- a/rest/misc/visits-sync.php +++ b/rest/misc/visits-sync.php @@ -50,4 +50,3 @@ class VisitsSync extends Vn\Lib\Method $result->free (); } } - diff --git a/web/db-session-handler.php b/web/db-session-handler.php index 8e421e33..72e563f1 100755 --- a/web/db-session-handler.php +++ b/web/db-session-handler.php @@ -23,9 +23,8 @@ class DbSessionHandler implements \SessionHandlerInterface function read ($sessionId) { - $this->db->query ('DO GET_LOCK(#, 10)', [$sessionId]); $sessionData = $this->db->getValue ( - 'SELECT data FROM userSession WHERE ssid = # FOR UPDATE', [$sessionId]); + 'SELECT data FROM userSession WHERE ssid = #', [$sessionId]); return isset ($sessionData) ? $sessionData : ''; } @@ -37,7 +36,6 @@ class DbSessionHandler implements \SessionHandlerInterface ON DUPLICATE KEY UPDATE data = VALUES(data), lastUpdate = VALUES(lastUpdate)', [$sessionId, $sessionData]); - $this->db->query ('DO RELEASE_LOCK(#)', [$sessionId]); return TRUE; } @@ -56,4 +54,3 @@ class DbSessionHandler implements \SessionHandlerInterface return TRUE; } } - diff --git a/web/html-service.php b/web/html-service.php index 0f3f5a10..1600ee7d 100644 --- a/web/html-service.php +++ b/web/html-service.php @@ -2,21 +2,31 @@ namespace Vn\Web; +require_once __DIR__.'/html.php'; + use Vn\Lib\Locale; /** * Base class for services that sends response as HTML format. - **/ + */ class HtmlService extends Service { function run () { + $eFlag = + E_ERROR + | E_USER_ERROR; + + set_error_handler ([$this, 'errorHandler'], $eFlag); + set_exception_handler ([$this, 'errorHandler']); + + $this->init (); $db = $this->db; if (!$this->isHttps () && $db->getValue ('SELECT https FROM config') && !_DEV_MODE) { - header ("Location: https://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}"); + header ("Location: https://{$this->getUri()}"); exit (0); } @@ -94,44 +104,12 @@ class HtmlService extends Service //header ("Content-Security-Policy: default-src *; img-src *;"); } - function globalErrorHandler () + function errorHandler () { $this->printHeader (); include (__DIR__.'/unavailable.html'); exit (0); - } - - function getUrl ($fileName) - { -/* if (file_exists ($fileName)) - $mTime = '?'. strftime ('%G%m%d%H%M%S', filemtime ($fileName)); - else -*/ $mTime = '?'. $this->getVersion (); - - return $fileName.$mTime; - } - - function includeJs ($fileName) - { - echo ''."\n\t\t"; - } - - function includeLib ($libName) - { - $args = func_get_args (); - - $localeJs = 'locale/'. Locale::get () .'/js/'. $libName .'.js'; - - if (file_exists ($localeJs)) - $this->includeJs ($localeJs); - - for ($i = 1; $i < count ($args); $i++) - $this->includeJs ("js/$libName/{$args[$i]}.js"); - } - - function includeCss ($fileName) - { - echo ''."\n\t\t"; + return FALSE; } function isMobile () @@ -140,4 +118,3 @@ class HtmlService extends Service return preg_match ($re, $_SERVER['HTTP_USER_AGENT']); } } - diff --git a/web/html.php b/web/html.php new file mode 100644 index 00000000..5f1df6dc --- /dev/null +++ b/web/html.php @@ -0,0 +1,66 @@ +getVersion (); + + return $fileName.$mTime; +} + +function js ($fileName) +{ + return ''."\n"; +} + +function css ($fileName) +{ + return ''."\n"; +} + +function getWebpackAssets () +{ + $wpConfig = json_decode (file_get_contents ('webpack.config.json')); + $buildDir = $wpConfig->buildDir; + $devServerPort = $wpConfig->devServerPort; + + $host = $_SERVER['SERVER_NAME']; + $assets = new stdClass(); + + if (!_DEV_MODE) + { + $wpAssets = json_decode (file_get_contents ("$buildDir/webpack-assets.json")); + + $manifestJs = $wpAssets->manifest->js; + $mainJs = $wpAssets->main->js; + unset ($wpAssets->manifest); + unset ($wpAssets->main); + + foreach ($wpAssets as $name => $asset) + if (property_exists ($asset, 'js')) + $assets->$name = $asset->js; + } + else + { + $devServerPath = "http://$host:$devServerPort/$buildDir"; + $manifestJs = "$devServerPath/manifest.js"; + $mainJs = "$devServerPath/main.js"; + + unset ($wpConfig->entry->main); + + foreach ($wpConfig->entry as $asset => $files) + $assets->$asset = "$devServerPath/$asset.js"; + } + + $jsFiles = []; + $jsFiles[] = $manifestJs; + + foreach ($assets as $jsFile) + $jsFiles[] = $jsFile; + + $jsFiles[] = $mainJs; + + return $jsFiles; +} diff --git a/web/json-service.php b/web/json-service.php index be4cdf9e..b8cb98ac 100644 --- a/web/json-service.php +++ b/web/json-service.php @@ -6,7 +6,7 @@ use Vn\Lib; /** * Base class for JSON application. - **/ + */ class JsonService extends RestService { private $warnings = NULL; @@ -17,16 +17,9 @@ class JsonService extends RestService set_error_handler ([$this, 'errorHandler'], E_ALL); set_exception_handler ([$this, 'exceptionHandler']); + $this->init (); $this->startSession (); - - // Checks the client version - - if (!empty ($_COOKIE['vnVersion'])) - $clientVersion = (int) $_COOKIE['vnVersion']; - - if (isset ($clientVersion) - && $clientVersion < $this->getVersion ()) - throw new OutdatedVersionException (); + $this->checkVersion (); $json = $this->loadMethod (__NAMESPACE__.'\JsonRequest'); $this->replyJson ($json); @@ -117,4 +110,3 @@ class JsonService extends RestService throw $e; } } - diff --git a/web/jwt.php b/web/jwt.php index 74b530fa..562b20e3 100755 --- a/web/jwt.php +++ b/web/jwt.php @@ -86,4 +86,3 @@ class Jwt return base64_decode (str_pad ($data, $remainder, '=', STR_PAD_RIGHT)); } } - diff --git a/web/mailer.php b/web/mailer.php index 815ea72c..0b6b5f20 100755 --- a/web/mailer.php +++ b/web/mailer.php @@ -8,46 +8,58 @@ use Vn\Lib\UserException; class Mailer { - static function send ($db, $mailTo, $body, $subject) + private $conf; + + function __construct ($db) { - $conf = $db->getRow ( + $this->conf = $db->getObject ( 'SELECT host, port, secure, sender, sender_name, user, password - FROM mail_config' + FROM hedera.mail_config' ); + } + + function createObject ($mailTo, $body, $subject) + { + $conf = $this->conf; $mail = new \PHPMailer (); $mail->isSMTP (); - $mail->Host = $conf['host']; + $mail->Host = $conf->host; - if (!empty ($conf['user'])) + if (!empty ($conf->user)) { $mail->SMTPAuth = TRUE; - $mail->Username = $conf['user']; - $mail->Password = base64_decode ($conf['password']); + $mail->Username = $conf->user; + $mail->Password = base64_decode ($conf->password); } else $mail->SMTPAuth = FALSE; - if ($conf['secure']) + if ($conf->secure) { $mail->SMTPSecure = 'ssl'; $mail->Port = 465; } - $mail->setFrom ($conf['sender'], $conf['sender_name']); + $mail->setFrom ($conf->sender, $conf->sender_name); + $mail->IsHTML (TRUE); + $mail->Subject = $subject; + $mail->Body = $body; + $mail->CharSet = 'UTF-8'; $mailList = explode (',', $mailTo); foreach ($mailList as $to) $mail->AddAddress ($to); - $mail->IsHTML (TRUE); - $mail->Subject = $subject; - $mail->Body = $body; - $mail->CharSet = 'UTF-8'; + return $mail; + } + + function send ($mailTo, $body, $subject) + { + $mail = $this->createObject ($mailTo, $body, $subject); if (!$mail->Send ()) throw new UserException ('Send error: '.$mail->ErrorInfo); } } - diff --git a/web/report.php b/web/report.php index a7f42ba8..8a376c71 100755 --- a/web/report.php +++ b/web/report.php @@ -38,7 +38,7 @@ class Report function sendMail ($mail) { - Mailer::send ($this->db, $mail, $this->html, $this->title); + $mailer = new Mailer ($this->db); + $mailer->send ($mail, $this->html, $this->title); } } - diff --git a/web/rest-request.php b/web/rest-request.php index 01cd11d6..ef1412da 100644 --- a/web/rest-request.php +++ b/web/rest-request.php @@ -18,4 +18,3 @@ abstract class RestRequest extends \Vn\Lib\Method var $service; } - diff --git a/web/rest-service.php b/web/rest-service.php index d510dd43..68154412 100644 --- a/web/rest-service.php +++ b/web/rest-service.php @@ -3,10 +3,12 @@ namespace Vn\Web; use Vn\Lib; +use Vn\Lib\Locale; +use Vn\Lib\UserException; /** * Base class for REST application. - **/ + */ class RestService extends Service { function run () @@ -15,9 +17,56 @@ class RestService extends Service set_error_handler ([$this, 'errorHandler'], E_ALL); set_exception_handler ([$this, 'exceptionHandler']); + $this->init (); $this->startSession (); $this->loadMethod (__NAMESPACE__.'\RestRequest'); } + + /** + * Runs a REST method. + */ + function loadMethod ($class) + { + $db = $this->db; + $this->login (); + + $method = $this->app->loadMethod ( + $_REQUEST['method'], $class, './rest'); + $method->service = $this; + + if ($method::SECURITY == Security::DEFINER) + { + $isAuthorized = $db->getValue ('SELECT userCheckRestPriv (#)', + [$_REQUEST['method']]); + + if (!$isAuthorized) + throw new UserException (s('You don\'t have enough privileges')); + + $methodDb = $db; + } + else + $methodDb = $this->getUserDb ($_SESSION['user']); + + if ($method::PARAMS !== NULL && !$method->checkParams ($_REQUEST, $method::PARAMS)) + throw new UserException (s('Missing parameters')); + + Locale::addPath ('rest/'. dirname ($_REQUEST['method'])); + + $res = NULL; + + try { + $res = $method->run ($methodDb); + } + catch (Db\Exception $e) + { + if ($e->getCode () == 1644) + throw new UserException (s($e->getMessage ())); + } + + $db->query ('CALL account.userLogout ()'); + + return $res; + } function statusFromException ($e) { @@ -58,4 +107,3 @@ class RestService extends Service throw $e; } } - diff --git a/web/service.php b/web/service.php index 88381a45..a74d4193 100755 --- a/web/service.php +++ b/web/service.php @@ -13,22 +13,22 @@ const WEEK = 7 * DAY; /** * Thrown when user credentials could not be fetched. - **/ + */ class SessionExpiredException extends UserException {} /** * Thrown when user credentials are invalid. - **/ + */ class BadLoginException extends UserException {} /** * Thrown when client version is outdated. - **/ + */ class OutdatedVersionException extends UserException {} /** * Main class for web applications. - **/ + */ abstract class Service { protected $app; @@ -38,15 +38,19 @@ abstract class Service function __construct ($app) { $this->app = $app; - $this->db = $app->getSysConn (); + } + + function init () + { + $this->db = $this->app->getSysConn (); } /** * Starts the user session. - **/ + */ function startSession () { - $db = $this->db; + $db = $this->app->getSysConn (); ini_set ('session.cookie_secure', $this->isHttps ()); ini_set ('session.hash_function', 'sha256'); @@ -131,7 +135,7 @@ abstract class Service * using base64_decode(). * * return Db\Conn The database connection - **/ + */ function login () { $db = $this->db; @@ -148,7 +152,10 @@ abstract class Service catch (Db\Exception $e) { if ($e->getMessage () == 'INVALID_CREDENTIALS') + { + sleep (3); throw new BadLoginException (); + } else throw $e; } @@ -211,7 +218,7 @@ abstract class Service /** * Logouts the current user. Cleans the last saved used credentials. - **/ + */ function logout () { unset ($_SESSION['user']); @@ -222,7 +229,7 @@ abstract class Service * is the current logged user. * * @return {Db\Conn} The database connection - **/ + */ function getUserDb ($user) { if ($this->userDb) @@ -240,7 +247,7 @@ abstract class Service * @param {boolean} $remember Wether to create long live token * @param {boolean} $recover Wether to enable recovery mode on login * @return {string} The JWT generated token - **/ + */ function createToken ($user, $remember = FALSE, $recover = FALSE) { if ($remember) @@ -259,100 +266,75 @@ abstract class Service $key = $this->db->getValue ('SELECT jwtKey FROM config'); return Jwt::encode ($payload, $key); } + + /** + * Obtains the application version number. It is extracted and + * cached from package.json file. + * + * @return string The version number + */ + function getVersion () + { + $appName = $this->app->getName (); + $version = apc_fetch("$appName.version", $success); + + if (!$success) + { + if (file_exists ('package.json')) + { + $package = json_decode (file_get_contents ('package.json')); + $version = $package->version; + } + else + $version = '0.0.0'; + + apc_store ("$appName.version", $version); + } + + return $version; + } /** - * Runs a method. - **/ - function loadMethod ($class) + * Checks the client version. + */ + function checkVersion () { - $db = $this->db; - $this->login (); + if (!empty ($_COOKIE['vnVersion'])) + $clientVersion = $_COOKIE['vnVersion']; - $method = $this->app->loadMethod ( - $_REQUEST['method'], $class, './rest'); - $method->service = $this; - - if ($method::SECURITY == Security::DEFINER) - { - $isAuthorized = $db->getValue ('SELECT userCheckRestPriv (#)', - [$_REQUEST['method']]); - - if (!$isAuthorized) - throw new UserException (s('You don\'t have enough privileges')); - - $methodDb = $db; - } - else - $methodDb = $this->getUserDb ($_SESSION['user']); - - if ($method::PARAMS !== NULL && !$method->checkParams ($_REQUEST, $method::PARAMS)) - throw new UserException (s('Missing parameters')); - - Locale::addPath ('rest/'. dirname ($_REQUEST['method'])); - - $res = NULL; - - try { - $res = $method->run ($methodDb); - } - catch (Db\Exception $e) - { - if ($e->getCode () == 1644) - throw new UserException (s($e->getMessage ())); - } - - $db->query ('CALL account.userLogout ()'); - - return $res; + if (isset ($clientVersion) + && $clientVersion < $this->getVersion ()) + throw new OutdatedVersionException (); } /** * Checks if the HTTP connection is secure. * * @return boolean Return %TRUE if its secure, %FALSE otherwise - **/ + */ function isHttps () { return isset ($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'; } + + /** + * Returns the current URI without the GET part. + * + * @return string The current URI + */ + function getUri () + { + return "{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}"; + } /** * Returns the current URL without the GET part. * * @return string The current URL - **/ + */ function getUrl () { $proto = $this->isHttps () ? 'https' : 'http'; - return "$proto://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}"; - } - - /** - * Obtains the application version number. It is based on de last - * modification date of the main script. - * - * @return string The version number - **/ - function getVersion () - { - return (int) strftime ('%G%m%d%H%M%S', - filectime ($_SERVER['SCRIPT_FILENAME'])); - } - - /** - * Obtains the relative path to document root from an absolute path. - * - * @return string The relative path - **/ - function getDir ($absoluteDir) - { - error_log ("Absolute: $absoluteDir"); - error_log ("Root: {$_SERVER['DOCUMENT_ROOT']}"); - error_log ("Script: {$_SERVER['SCRIPT_FILENAME']}"); - error_log ("Self: {$_SERVER['PHP_SELF']}"); - - $rootLen = strlen ($_SERVER['DOCUMENT_ROOT']); - return substr ($absoluteDir, $rootLen); + return "$proto://{$this->getUri()}"; } } - diff --git a/web/unavailable.html b/web/unavailable.html index 5d882273..af574787 100755 --- a/web/unavailable.html +++ b/web/unavailable.html @@ -3,36 +3,41 @@ - No disponible - Verdnatura + Not available - Verdnatura

- Estamos teniendo problemas; por favor, - espera unos minutos e inténtalo de nuevo. + We are having problems; Please wait a few minutes and try again.

- Intentarlo de nuevo + Try it again
diff --git a/web/util.php b/web/util.php index b5ae3918..bd502b0d 100644 --- a/web/util.php +++ b/web/util.php @@ -9,7 +9,7 @@ class Util * * @param string file The file path * @param boolean useXsendfile Wether to use the apache module Xsendfile - **/ + */ static function printFile ($file, $useXsendfile = FALSE) { if (!file_exists ($file)) @@ -41,4 +41,3 @@ class Util } } } - diff --git a/webpack.config.js b/webpack.config.js index 9c20e105..e3a19003 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,21 +1,23 @@ - -var webpack = require ('webpack'); var path = require ('path'); +var webpack = require ('webpack'); +var AssetsWebpackPlugin = require ('assets-webpack-plugin'); +var WebpackChunkHash = require ('webpack-chunk-hash'); +var merge = require ('webpack-merge'); +var wpConfig = require ('./webpack.config.json'); var devMode = process.env.NODE_ENV !== 'production'; +var outputPath = path.join (__dirname, wpConfig.buildDir); +var publicPath = wpConfig.buildDir +'/'; -var config = { - entry: ['./app.js'], +var baseConfig = { + entry: wpConfig.entry, output: { - path: path.join (__dirname, 'build'), - filename: 'hedera-web.js', - chunkFilename: 'chunk.[id].[chunkhash].js', - publicPath: 'build/' + path: outputPath, + publicPath: publicPath }, module: { rules: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, - { test: /\.json$/, loader: 'json-loader' }, { test: /\.xml$/, loader: 'raw-loader' }, { test: /\.ttf$/, loader: 'file-loader' } ] @@ -28,28 +30,59 @@ var config = { '/usr/lib/node_modules' ] }, - plugins: [ - new webpack.DefinePlugin ({ _DEV_MODE: devMode }) - ], - devServer: { - inline: true, - host: '0.0.0.0', - port: '9000', - headers: { "Access-Control-Allow-Origin": "*" } + node: { + __dirname: true }, - devtool: 'eval-source-map' + plugins: [ + new webpack.DefinePlugin ({ + _DEV_MODE: devMode, + _DEV_SERVER_PORT: wpConfig.devServerPort, + _PUBLIC_PATH: JSON.stringify (publicPath) + }), + new webpack.optimize.CommonsChunkPlugin ({ + names: ['vendor', 'manifest'] + }) + ], + watchOptions: { + ignored: /node_modules/ + } }; -if (!devMode) -{ - config.plugins.push ( +var prodConfig = { + output: { + filename: '[name].[chunkhash].js', + chunkFilename: 'chunk.[id].[chunkhash].js' + }, + plugins: [ new webpack.optimize.UglifyJsPlugin ({ minimize: true, compress: { warnings: false } - }) - ); - config.devtool = 'source-map'; -} + }), + new AssetsWebpackPlugin ({ + path: outputPath + }), + new webpack.HashedModuleIdsPlugin (), + new WebpackChunkHash () + ], + devtool: 'source-map' +}; -module.exports = config; +var devConfig = { + output: { + filename: '[name].js', + chunkFilename: 'chunk.[id].js' + }, + plugins: [ + new webpack.NamedModulesPlugin () + ], + devServer: { + host: '0.0.0.0', + port: wpConfig.devServerPort, + headers: { 'Access-Control-Allow-Origin': '*' }, + stats: { chunks: false } + }, + devtool: 'eval' +}; +var mrgConfig = devMode ? devConfig : prodConfig; +module.exports = merge (baseConfig, mrgConfig); diff --git a/webpack.config.json b/webpack.config.json new file mode 100644 index 00000000..1e418dfa --- /dev/null +++ b/webpack.config.json @@ -0,0 +1,8 @@ +{ + "buildDir": "build", + "devServerPort": 9000, + "entry": { + "main": "./app.js", + "vendor": "mootools" + } +} \ No newline at end of file