test #4
|
@ -16,11 +16,13 @@ pipeline {
|
||||||
switch (env.BRANCH_NAME) {
|
switch (env.BRANCH_NAME) {
|
||||||
case 'master':
|
case 'master':
|
||||||
env.NODE_ENV = 'production'
|
env.NODE_ENV = 'production'
|
||||||
env.REPLICAS = 3
|
env.MAIN_REPLICAS = 3
|
||||||
|
env.CRON_REPLICAS = 1
|
||||||
break
|
break
|
||||||
case 'test':
|
case 'test':
|
||||||
env.NODE_ENV = 'test'
|
env.NODE_ENV = 'test'
|
||||||
env.REPLICAS = 1
|
env.MAIN_REPLICAS = 1
|
||||||
|
env.CRON_REPLICAS = 0
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
Options -Indexes -FollowSymLinks
|
Options -Indexes -FollowSymLinks
|
||||||
AllowOverride None
|
AllowOverride None
|
||||||
Require all granted
|
Require all granted
|
||||||
|
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
|
||||||
|
|
||||||
<FilesMatch "\.(css|js|json|yml|php|xml|html|svg)$">
|
<FilesMatch "\.(css|js|json|yml|php|xml|html|svg)$">
|
||||||
SetOutputFilter DEFLATE
|
SetOutputFilter DEFLATE
|
||||||
|
|
75
app.js
75
app.js
|
@ -1,71 +1,60 @@
|
||||||
|
__webpack_public_path__ = _PUBLIC_PATH;
|
||||||
|
|
||||||
var assetsPath;
|
require('hedera/hedera');
|
||||||
|
|
||||||
if (_DEV_MODE)
|
window.onload = function() {
|
||||||
{
|
loadLocale(main);
|
||||||
var host = window.location.host.split(':')[0];
|
|
||||||
assetsPath = 'http://'+ host +':'+ _DEV_SERVER_PORT +'/'+ _PUBLIC_PATH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
assetsPath = _PUBLIC_PATH;
|
|
||||||
|
|
||||||
__webpack_public_path__ = assetsPath;
|
|
||||||
|
|
||||||
require ('hedera/hedera');
|
|
||||||
|
|
||||||
window.onload = function ()
|
|
||||||
{
|
|
||||||
loadLocale (main);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function main (req)
|
function main(req) {
|
||||||
{
|
|
||||||
if (req)
|
if (req)
|
||||||
onLocaleLoad (req);
|
onLocaleLoad(req);
|
||||||
|
|
||||||
hederaWeb = new Hedera.App ();
|
hederaWeb = new Hedera.App();
|
||||||
hederaWeb.run ();
|
hederaWeb.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadLocale (cb)
|
function loadLocale(cb) {
|
||||||
{
|
Vn.Locale.init();
|
||||||
Vn.Locale.init ();
|
|
||||||
var lang = Vn.Locale.language;
|
var lang = Vn.Locale.language;
|
||||||
|
|
||||||
var req = require.context ('js', true, /locale\/en.yml$/);
|
var req = require.context('js', true, /locale\/en.yml$/);
|
||||||
onLocaleLoad (req);
|
onLocaleLoad(req);
|
||||||
|
|
||||||
switch (lang)
|
switch (lang) {
|
||||||
{
|
|
||||||
case 'ca':
|
case 'ca':
|
||||||
require ([], function () {
|
require([], function() {
|
||||||
cb (require.context ('js', true, /locale\/ca.yml$/)); });
|
cb(require.context('js', true, /locale\/ca.yml$/));
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case 'es':
|
case 'es':
|
||||||
require ([], function () {
|
require([], function() {
|
||||||
cb (require.context ('js', true, /locale\/es.yml$/)); });
|
cb(require.context('js', true, /locale\/es.yml$/));
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case 'fr':
|
case 'fr':
|
||||||
require ([], function () {
|
require([], function() {
|
||||||
cb (require.context ('js', true, /locale\/fr.yml$/)); });
|
cb(require.context('js', true, /locale\/fr.yml$/));
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case 'mn':
|
case 'mn':
|
||||||
require ([], function () {
|
require([], function() {
|
||||||
cb (require.context ('js', true, /locale\/mn.yml$/)); });
|
cb(require.context('js', true, /locale\/mn.yml$/));
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case 'pt':
|
case 'pt':
|
||||||
require ([], function () {
|
require([], function() {
|
||||||
cb (require.context ('js', true, /locale\/pt.yml$/)); });
|
cb(require.context('js', true, /locale\/pt.yml$/));
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cb ();
|
cb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onLocaleLoad (req)
|
function onLocaleLoad(req) {
|
||||||
{
|
var keys = req.keys();
|
||||||
var keys = req.keys ();
|
|
||||||
|
|
||||||
for (var i = 0; i < keys.length; i++)
|
for (var i = 0; i < keys.length; i++)
|
||||||
Vn.Locale.add (req (keys[i]));
|
Vn.Locale.add(req(keys[i]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
CREATE OR REPLACE
|
|
||||||
ALGORITHM = UNDEFINED
|
|
||||||
DEFINER=`root`@`%`
|
|
||||||
VIEW `hedera`.`myTicketService` AS
|
|
||||||
select
|
|
||||||
`s`.`id` AS `id`,
|
|
||||||
`s`.`description` AS `description`,
|
|
||||||
`s`.`quantity` AS `quantity`,
|
|
||||||
`s`.`price` AS `price`,
|
|
||||||
`s`.`taxClassFk` AS `taxClassFk`,
|
|
||||||
`s`.`ticketFk` AS `ticketFk`,
|
|
||||||
`s`.`ticketServiceTypeFk` AS `ticketServiceTypeFk`
|
|
||||||
from
|
|
||||||
(`vn`.`ticketService` `s`
|
|
||||||
join `hedera`.`myTicket` `t` on
|
|
||||||
(`s`.`ticketFk` = `t`.`id`)) WITH CASCADED CHECK OPTION;
|
|
||||||
|
|
||||||
GRANT SELECT ON TABLE hedera.myTicketService TO account@'localhost';
|
|
|
@ -1,18 +0,0 @@
|
||||||
|
|
||||||
DROP PROCEDURE IF EXISTS hedera.myTicket_getServices;
|
|
||||||
DELIMITER $$
|
|
||||||
CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`myTicket_getServices`(vSelf INT)
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Returns a current user ticket services.
|
|
||||||
*
|
|
||||||
* @param vSelf The ticket identifier
|
|
||||||
* @select The ticket services
|
|
||||||
*/
|
|
||||||
SELECT id, description, quantity, price
|
|
||||||
FROM myTicketService
|
|
||||||
WHERE ticketFk = vSelf;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
||||||
|
|
||||||
GRANT EXECUTE ON PROCEDURE hedera.myTicket_getServices TO account@'localhost';
|
|
|
@ -1 +0,0 @@
|
||||||
CALL account.role_sync;
|
|
|
@ -1,4 +1,4 @@
|
||||||
hedera-web (1.407.66) stable; urgency=low
|
hedera-web (1.407.68) stable; urgency=low
|
||||||
|
|
||||||
* Initial Release.
|
* Initial Release.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ services:
|
||||||
- /mnt/appdata/image:/var/lib/hedera-web/image-db
|
- /mnt/appdata/image:/var/lib/hedera-web/image-db
|
||||||
- /mnt/appdata/vn-access:/var/lib/hedera-web/vn-access
|
- /mnt/appdata/vn-access:/var/lib/hedera-web/vn-access
|
||||||
deploy:
|
deploy:
|
||||||
replicas: ${REPLICAS:?}
|
replicas: ${MAIN_REPLICAS:?}
|
||||||
placement:
|
placement:
|
||||||
constraints:
|
constraints:
|
||||||
- node.role == worker
|
- node.role == worker
|
||||||
|
@ -31,6 +31,7 @@ services:
|
||||||
- /mnt/appdata:/mnt/storage
|
- /mnt/appdata:/mnt/storage
|
||||||
- /mnt/appdata/image:/var/lib/hedera-web/image-db
|
- /mnt/appdata/image:/var/lib/hedera-web/image-db
|
||||||
deploy:
|
deploy:
|
||||||
|
replicas: ${CRON_REPLICAS:?}
|
||||||
placement:
|
placement:
|
||||||
constraints:
|
constraints:
|
||||||
- node.role == worker
|
- node.role == worker
|
||||||
|
|
|
@ -5,8 +5,6 @@ Hedera.Conf = new Class({
|
||||||
,activate: function() {
|
,activate: function() {
|
||||||
this.$('user-model').setInfo('c', 'myClient', 'hedera');
|
this.$('user-model').setInfo('c', 'myClient', 'hedera');
|
||||||
|
|
||||||
console.log(this.hash.get('verificationToken'));
|
|
||||||
|
|
||||||
if (this.hash.get('verificationToken'))
|
if (this.hash.get('verificationToken'))
|
||||||
this.onPassChangeClick();
|
this.onPassChangeClick();
|
||||||
}
|
}
|
||||||
|
@ -45,17 +43,20 @@ Hedera.Conf = new Class({
|
||||||
this.conn.send('core/restore-password', params,
|
this.conn.send('core/restore-password', params,
|
||||||
this._onPassChange.bind(this));
|
this._onPassChange.bind(this));
|
||||||
} else {
|
} else {
|
||||||
|
let userId = this.gui.user.id;
|
||||||
params.oldPassword = oldPassword;
|
params.oldPassword = oldPassword;
|
||||||
this.conn.send('core/change-password', params,
|
this.conn.lbSend('PATCH',
|
||||||
this._onPassChange.bind(this));
|
`Accounts/${userId}/changePassword`, params,
|
||||||
|
this._onPassChange.bind(this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Htk.Toast.showError(e.message);
|
Htk.Toast.showError(e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onPassChange: function(json, error) {
|
,_onPassChange: function(json, error) {
|
||||||
if (json) {
|
if (!error) {
|
||||||
this.$('change-password').hide();
|
this.$('change-password').hide();
|
||||||
this.hash.unset('verificationToken');
|
this.hash.unset('verificationToken');
|
||||||
Htk.Toast.showMessage(_('Password changed!'));
|
Htk.Toast.showMessage(_('Password changed!'));
|
||||||
|
|
|
@ -1,52 +1,44 @@
|
||||||
|
|
||||||
Hedera.Connections = new Class
|
Hedera.Connections = new Class({
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
Extends: Hedera.Form
|
||||||
|
|
||||||
,_timeoutId: null
|
,_timeoutId: null
|
||||||
|
|
||||||
,onModelStatusChange: function (model, status)
|
,onModelStatusChange: function(model) {
|
||||||
{
|
|
||||||
if (!model.ready)
|
if (!model.ready)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._timeoutId)
|
if (this._timeoutId)
|
||||||
clearTimeout (this._timeoutId);
|
clearTimeout(this._timeoutId);
|
||||||
|
|
||||||
this._timeoutId = setTimeout (this.onRefreshClick.bind (this), 60000);
|
this._timeoutId = setTimeout(this.onRefreshClick.bind(this), 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
,deactivate: function ()
|
,deactivate: function() {
|
||||||
{
|
clearTimeout(this._timeoutId);
|
||||||
clearTimeout (this._timeoutId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,onRefreshClick: function ()
|
,onRefreshClick: function() {
|
||||||
{
|
this.$('sessions').refresh();
|
||||||
this.$('sessions').refresh ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,onAccessLogClick: function (button, form)
|
,onAccessLogClick: function(button, form) {
|
||||||
{
|
this.hash.set({
|
||||||
this.hash.set ({
|
form: 'admin/access-log'
|
||||||
'form': 'admin/access-log'
|
,user: form.get('userId')
|
||||||
,'user': form.get ('userId')
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
,onChangeUserClick: function (button, form)
|
,onChangeUserClick: function(button, form) {
|
||||||
{
|
this.gui.supplantUser(form.get('user'),
|
||||||
this.gui.supplantUser (form.get ('user'),
|
this._onUserSupplant.bind(this));
|
||||||
this._onUserSupplant.bind (this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onUserSupplant: function (userName)
|
,_onUserSupplant: function() {
|
||||||
{
|
this.hash.set({form: 'ecomerce/orders'});
|
||||||
this.hash.set ({'form': 'ecomerce/orders'});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,sessionsFunc: function ()
|
,sessionsFunc: function() {
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<htk-text form="iter" column="value7"/>
|
<htk-text form="iter" column="value7"/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@<htk-text form="iter" column="id"/>
|
#<htk-text form="iter" column="id"/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<htk-text form="iter" column="image"/>
|
<htk-text form="iter" column="image"/>
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<htk-text form="iter" column="nickname"/>
|
<htk-text form="iter" column="nickname"/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@<htk-text form="iter" column="id"/> -
|
#<htk-text form="iter" column="id"/> -
|
||||||
<htk-text form="iter" column="name"/>
|
<htk-text form="iter" column="name"/>
|
||||||
</p>
|
</p>
|
||||||
<div class="clear"/>
|
<div class="clear"/>
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
|
|
||||||
Hedera.Users = new Class
|
Hedera.Users = new Class({
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
Extends: Hedera.Form
|
||||||
|
|
||||||
,onAccessLogClick: function (button, form)
|
,onAccessLogClick: function(button, form) {
|
||||||
{
|
this.hash.set({
|
||||||
this.hash.set ({
|
|
||||||
'form': 'admin/access-log'
|
'form': 'admin/access-log'
|
||||||
,'user': form.get ('id')
|
,'user': form.get('id')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
,rendererFunc: function (scope, form)
|
,rendererFunc: function(scope, form) {
|
||||||
{
|
|
||||||
var isEnabled = form.get('active')
|
var isEnabled = form.get('active')
|
||||||
scope.$('disabled').style.display = isEnabled ?
|
scope.$('disabled').style.display = isEnabled ?
|
||||||
'none' : 'block';
|
'none' : 'block';
|
||||||
|
@ -20,15 +17,13 @@ Hedera.Users = new Class
|
||||||
'block' : 'none';
|
'block' : 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
,onChangeUserClick: function (button, form)
|
,onChangeUserClick: function(button, form) {
|
||||||
{
|
this.gui.supplantUser(form.get('name'),
|
||||||
this.gui.supplantUser (form.get ('name'),
|
this.onUserSupplant.bind(this));
|
||||||
this.onUserSupplant.bind (this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,onUserSupplant: function ()
|
,onUserSupplant: function() {
|
||||||
{
|
this.hash.set({form: 'ecomerce/orders'});
|
||||||
this.hash.set ({form: 'ecomerce/orders'});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -406,7 +406,7 @@
|
||||||
<htk-text form="card" column="subName"/>
|
<htk-text form="card" column="subName"/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@<htk-text form="card" column="id"/>
|
#<htk-text form="card" column="id"/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<htk-text form="card" column="stems" format="_%.0d Units"/>
|
<htk-text form="card" column="stems" format="_%.0d Units"/>
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
<htk-text form="iter" column="landed" format="%D"/>
|
<htk-text form="iter" column="landed" format="%D"/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@<htk-text form="iter" column="id"/>
|
#<htk-text form="iter" column="id"/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<htk-text form="iter" column="nickname"/>
|
<htk-text form="iter" column="nickname"/>
|
||||||
|
|
|
@ -19,11 +19,15 @@ Hedera.Ticket = new Class({
|
||||||
},
|
},
|
||||||
|
|
||||||
onPrintClick: function() {
|
onPrintClick: function() {
|
||||||
var batch = new Sql.Batch();
|
let params = Vn.Url.makeUri({
|
||||||
batch.addValue('ticket', this.$('ticket-id').value);
|
authorization: this.conn.token,
|
||||||
this.gui.openReport('delivery-note', batch);
|
ticketId: this.$('ticket-id').value,
|
||||||
|
recipientId: this.gui.user.id,
|
||||||
|
type: 'deliveryNote'
|
||||||
|
});
|
||||||
|
window.open(`/api/report/delivery-note?${params}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
repeaterFunc: function(res, form) {
|
repeaterFunc: function(res, form) {
|
||||||
var discount = res.$('discount');
|
var discount = res.$('discount');
|
||||||
discount.style.display = form.get('discount') ? 'inline' : 'none';
|
discount.style.display = form.get('discount') ? 'inline' : 'none';
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<htk-loader class="head" form="ticket">
|
<htk-loader class="head" form="ticket">
|
||||||
<div>
|
<div>
|
||||||
<p class="important ticket-id">
|
<p class="important ticket-id">
|
||||||
@<htk-text column="id" form="ticket"/>
|
#<htk-text column="id" form="ticket"/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<t>Preparation</t> <htk-text form="ticket" column="shipped" format="%D"/>
|
<t>Preparation</t> <htk-text form="ticket" column="shipped" format="%D"/>
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
<htk-text form="iter" column="name"/>
|
<htk-text form="iter" column="name"/>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
@<htk-text form="iter" column="id"/>
|
#<htk-text form="iter" column="id"/>
|
||||||
</p>
|
</p>
|
||||||
<p class="amount">
|
<p class="amount">
|
||||||
<htk-text form="iter" column="quantity"/>
|
<htk-text form="iter" column="quantity"/>
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
|
|
||||||
var Result = require ('./result');
|
var Result = require('./result');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class stores the database results.
|
* This class stores the database results.
|
||||||
**/
|
**/
|
||||||
module.exports = new Class
|
module.exports = new Class({
|
||||||
({
|
|
||||||
results: null
|
results: null
|
||||||
,error: null
|
,error: null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initilizes the resultset object.
|
* Initilizes the resultset object.
|
||||||
**/
|
**/
|
||||||
,initialize: function (results, error)
|
,initialize: function(results, error) {
|
||||||
{
|
|
||||||
this.results = results;
|
this.results = results;
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
|
@ -23,19 +21,17 @@ module.exports = new Class
|
||||||
*
|
*
|
||||||
* @return {Db.Err} the error or null if no errors hapened
|
* @return {Db.Err} the error or null if no errors hapened
|
||||||
**/
|
**/
|
||||||
,getError: function ()
|
,getError: function() {
|
||||||
{
|
|
||||||
return this.error;
|
return this.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
,fetch: function ()
|
,fetch: function() {
|
||||||
{
|
|
||||||
if (this.error)
|
if (this.error)
|
||||||
throw this.error;
|
throw this.error;
|
||||||
|
|
||||||
if (this.results !== null
|
if (this.results !== null
|
||||||
&& this.results.length > 0)
|
&& this.results.length > 0)
|
||||||
return this.results.shift ();
|
return this.results.shift();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -45,14 +41,12 @@ module.exports = new Class
|
||||||
*
|
*
|
||||||
* @return {Db.Result} the result or %null if error or there are no more results
|
* @return {Db.Result} the result or %null if error or there are no more results
|
||||||
**/
|
**/
|
||||||
,fetchResult: function ()
|
,fetchResult: function() {
|
||||||
{
|
var result = this.fetch();
|
||||||
var result = this.fetch ();
|
|
||||||
|
|
||||||
if (result !== null)
|
if (result !== null) {
|
||||||
{
|
|
||||||
if (result.data instanceof Array)
|
if (result.data instanceof Array)
|
||||||
return new Result (result);
|
return new Result(result);
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -65,9 +59,8 @@ module.exports = new Class
|
||||||
*
|
*
|
||||||
* @return {Array} the row if success, %null otherwise
|
* @return {Array} the row if success, %null otherwise
|
||||||
**/
|
**/
|
||||||
,fetchRow: function ()
|
,fetchRow: function() {
|
||||||
{
|
var result = this.fetch();
|
||||||
var result = this.fetch ();
|
|
||||||
|
|
||||||
if (result !== null
|
if (result !== null
|
||||||
&& result.data instanceof Array
|
&& result.data instanceof Array
|
||||||
|
@ -77,14 +70,29 @@ module.exports = new Class
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
,fetchObject: function() {
|
||||||
|
var result = this.fetch();
|
||||||
|
|
||||||
|
if (result !== null
|
||||||
|
&& result.data instanceof Array
|
||||||
|
&& result.data.length > 0) {
|
||||||
|
var row = result.data[0];
|
||||||
|
var object = {};
|
||||||
|
for(var i = 0; i < row.length; i++)
|
||||||
|
object[result.columns[i].name] = row[i];
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetchs the first row and column value from the next resultset.
|
* Fetchs the first row and column value from the next resultset.
|
||||||
*
|
*
|
||||||
* @return {Object} the value if success, %null otherwise
|
* @return {Object} the value if success, %null otherwise
|
||||||
**/
|
**/
|
||||||
,fetchValue: function ()
|
,fetchValue: function() {
|
||||||
{
|
var row = this.fetchRow();
|
||||||
var row = this.fetchRow ();
|
|
||||||
|
|
||||||
if (row instanceof Array && row.length > 0)
|
if (row instanceof Array && row.length > 0)
|
||||||
return row[0];
|
return row[0];
|
||||||
|
|
|
@ -54,7 +54,7 @@ module.exports = new Class({
|
||||||
this.unref();
|
this.unref();
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onWindowError: function(message, file, line, col, err) {
|
,_onWindowError: function(message, file, line) {
|
||||||
var error = new Error(message);
|
var error = new Error(message);
|
||||||
error.fileName = file;
|
error.fileName = file;
|
||||||
error.lineNumber = line;
|
error.lineNumber = line;
|
||||||
|
@ -68,12 +68,15 @@ module.exports = new Class({
|
||||||
Htk.Toast.showError(_('Invalid login'));
|
Htk.Toast.showError(_('Invalid login'));
|
||||||
this._logout();
|
this._logout();
|
||||||
break;
|
break;
|
||||||
|
case 'Forbidden':
|
||||||
|
Htk.Toast.showError(_('You don\'t have enough privileges'));
|
||||||
|
break;
|
||||||
case 'UserDisabled':
|
case 'UserDisabled':
|
||||||
Htk.Toast.showError(_('User disabled'));
|
Htk.Toast.showError(_('User disabled'));
|
||||||
this._logout();
|
this._logout();
|
||||||
break;
|
break;
|
||||||
case 'SessionExpired':
|
case 'SessionExpired':
|
||||||
Htk.Toast.showError(_('You\'ve been too idle'));
|
Htk.Toast.showError(_('Session expired'));
|
||||||
this._logout();
|
this._logout();
|
||||||
break;
|
break;
|
||||||
case 'OutdatedVersion':
|
case 'OutdatedVersion':
|
||||||
|
@ -81,6 +84,14 @@ module.exports = new Class({
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Htk.Toast.showError(error.message);
|
Htk.Toast.showError(error.message);
|
||||||
|
} else if (error.statusCode)
|
||||||
|
switch (error.statusCode) {
|
||||||
|
case 401:
|
||||||
|
Htk.Toast.showError(_('Invalid login'));
|
||||||
|
this._logout();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Htk.Toast.showError(error.message);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
|
@ -48,7 +48,7 @@ module.exports = new Class({
|
||||||
|
|
||||||
this.$('social-bar').conn = this._conn;
|
this.$('social-bar').conn = this._conn;
|
||||||
|
|
||||||
var sql = 'SELECT nickname FROM account.myUser;'
|
var sql = 'SELECT id, name, nickname FROM account.myUser;'
|
||||||
+'SELECT defaultForm FROM config;'
|
+'SELECT defaultForm FROM config;'
|
||||||
+'SELECT url FROM imageConfig;'
|
+'SELECT url FROM imageConfig;'
|
||||||
+'SELECT dbproduccion FROM vn2008.tblContadores;'
|
+'SELECT dbproduccion FROM vn2008.tblContadores;'
|
||||||
|
@ -121,8 +121,8 @@ module.exports = new Class({
|
||||||
,onMainQueryDone: function(resultSet) {
|
,onMainQueryDone: function(resultSet) {
|
||||||
// Retrieving the user name
|
// Retrieving the user name
|
||||||
|
|
||||||
var userName = resultSet.fetchValue();
|
this.user = resultSet.fetchObject();
|
||||||
Vn.Node.setText(this.$('user-name'), userName);
|
Vn.Node.setText(this.$('user-name'), this.user.nickname);
|
||||||
|
|
||||||
// Retrieving configuration parameters
|
// Retrieving configuration parameters
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ Login phone: +34 607 562 391
|
||||||
Password forgotten? Push here: ¿Has oblidat la teva contrasenya?
|
Password forgotten? Push here: ¿Has oblidat la teva contrasenya?
|
||||||
Yet you are not a customer?: Encara no ets client?
|
Yet you are not a customer?: Encara no ets client?
|
||||||
Sign up: Registrarme
|
Sign up: Registrarme
|
||||||
You've been too idle: Has estat massa temps inactiu i la sessió ha expirat
|
You don't have enough privileges: No tens prou privilegis
|
||||||
|
Session expired: La sessió ha expirat
|
||||||
Invalid login: >-
|
Invalid login: >-
|
||||||
Usuari o contrasenya incorrectes, recorda que s'hi distingeix entre majúscula
|
Usuari o contrasenya incorrectes, recorda que s'hi distingeix entre majúscula
|
||||||
i minúscula
|
i minúscula
|
||||||
|
|
|
@ -10,7 +10,8 @@ Password forgotten? Push here: Password forgotten? Push here
|
||||||
Yet you are not a customer?: Yet you are not a customer?
|
Yet you are not a customer?: Yet you are not a customer?
|
||||||
Sign up: Sign up
|
Sign up: Sign up
|
||||||
Sign up link: http://bit.ly/2wLntMl
|
Sign up link: http://bit.ly/2wLntMl
|
||||||
You've been too idle: You have been idle too long and your session has expired
|
You don't have enough privileges: You don't have enough privileges
|
||||||
|
Session expired: Your session has expired
|
||||||
Invalid login: 'Username or password incorrect, remember that it is case-sensitive'
|
Invalid login: 'Username or password incorrect, remember that it is case-sensitive'
|
||||||
User disabled: >-
|
User disabled: >-
|
||||||
Authentication is correct but the user account has been disabled, please
|
Authentication is correct but the user account has been disabled, please
|
||||||
|
|
|
@ -10,7 +10,8 @@ Password forgotten? Push here: ¿Has olvidado tu contraseña?
|
||||||
Yet you are not a customer?: ¿Todavía no eres cliente?
|
Yet you are not a customer?: ¿Todavía no eres cliente?
|
||||||
Sign up: Registrarme
|
Sign up: Registrarme
|
||||||
Sign up link: http://bit.ly/2wLntMl
|
Sign up link: http://bit.ly/2wLntMl
|
||||||
You've been too idle: Has estado demasiado tiempo inactivo y la sesión ha expirado
|
You don't have enough privileges: No tienes suficientes privilegios
|
||||||
|
Session expired: La sesión ha expirado
|
||||||
Invalid login: >-
|
Invalid login: >-
|
||||||
Usuario o contraseña incorrectos, recuerda que se hace distinción entre
|
Usuario o contraseña incorrectos, recuerda que se hace distinción entre
|
||||||
mayúsculas y minúsculas
|
mayúsculas y minúsculas
|
||||||
|
|
|
@ -10,7 +10,8 @@ Password forgotten? Push here: as tu oublié ton mot de passe?
|
||||||
Yet you are not a customer?: Êtes-vous Pas encore client?
|
Yet you are not a customer?: Êtes-vous Pas encore client?
|
||||||
Sign up: Inscription
|
Sign up: Inscription
|
||||||
Sign up link: http://bit.ly/2msCil1
|
Sign up link: http://bit.ly/2msCil1
|
||||||
You've been too idle: Il a eu le temps de trop paresseux et votre session a expiré
|
You don't have enough privileges: Vous n'avez pas assez de privilèges
|
||||||
|
Session expired: Et votre session a expiré
|
||||||
Invalid login: >-
|
Invalid login: >-
|
||||||
Utilisateur ou mot de passe incorrect, n'oubliez pas de distinction entre
|
Utilisateur ou mot de passe incorrect, n'oubliez pas de distinction entre
|
||||||
majuscules et minuscules
|
majuscules et minuscules
|
||||||
|
|
|
@ -9,7 +9,6 @@ Login phone: +34 607 562 391
|
||||||
Password forgotten? Push here: Нууц үг мартсан? энд түлхэх
|
Password forgotten? Push here: Нууц үг мартсан? энд түлхэх
|
||||||
Yet you are not a customer?: Гэсэн хэдий ч та хэрэглэгчийн биш гэж үү?
|
Yet you are not a customer?: Гэсэн хэдий ч та хэрэглэгчийн биш гэж үү?
|
||||||
Sign up: бүртгүүлэх
|
Sign up: бүртгүүлэх
|
||||||
You've been too idle: 'Та нар ч бас зогссон байсан, чуулган хугацаа дууссан байна'
|
|
||||||
Invalid login: 'Хэрэглэгчийн нэр эсвэл нууц үг буруу, Тэр хэргийг мэдрэмтгий гэдгийг санаарай'
|
Invalid login: 'Хэрэглэгчийн нэр эсвэл нууц үг буруу, Тэр хэргийг мэдрэмтгий гэдгийг санаарай'
|
||||||
Please write your user name: Хэрэглэгчийн нэрээ бичнэ үү
|
Please write your user name: Хэрэглэгчийн нэрээ бичнэ үү
|
||||||
A mail has been sent wich you can recover your password: Мэйл та нууц үгээ сэргээх боломжтой А байна илгээсэн
|
A mail has been sent wich you can recover your password: Мэйл та нууц үгээ сэргээх боломжтой А байна илгээсэн
|
||||||
|
|
|
@ -9,7 +9,8 @@ Login phone: +34 963 242 100
|
||||||
Password forgotten? Push here: Não lembro minha palavra-passe
|
Password forgotten? Push here: Não lembro minha palavra-passe
|
||||||
Yet you are not a customer?: Ainda não és cliente?
|
Yet you are not a customer?: Ainda não és cliente?
|
||||||
Sign up: Cadastrar-se
|
Sign up: Cadastrar-se
|
||||||
You've been too idle: 'Muito tempo de inatividade, a sessão foi finalizada'
|
You don't have enough privileges: Você não tem privilégios suficientes
|
||||||
|
Session expired: 'A sessão foi finalizada'
|
||||||
Invalid login: >-
|
Invalid login: >-
|
||||||
Usuário ou Palavra-Passe incorreto, lembre-se de diferenciar maiusculas e
|
Usuário ou Palavra-Passe incorreto, lembre-se de diferenciar maiusculas e
|
||||||
minusculas
|
minusculas
|
||||||
|
|
|
@ -1,129 +1,112 @@
|
||||||
|
|
||||||
var Css = require ('./login.css');
|
require('./login.css');
|
||||||
var Tpl = require ('./login.xml');
|
var Tpl = require('./login.xml');
|
||||||
|
|
||||||
module.exports = new Class
|
module.exports = new Class({
|
||||||
({
|
|
||||||
Extends: Htk.Component,
|
Extends: Htk.Component,
|
||||||
Properties:
|
Properties:
|
||||||
{
|
{
|
||||||
conn:
|
conn:
|
||||||
{
|
{
|
||||||
type: Db.Connection
|
type: Db.Connection
|
||||||
,set: function (x)
|
,set: function(x) {
|
||||||
{
|
this.link({_conn: x}, {'loading-changed': this._onConnLoadChange});
|
||||||
this.link ({_conn: x}, {'loading-changed': this._onConnLoadChange});
|
|
||||||
}
|
}
|
||||||
,get: function ()
|
,get: function() {
|
||||||
{
|
|
||||||
return this._conn;
|
return this._conn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
,initialize: function (props)
|
,initialize: function(props) {
|
||||||
{
|
this.parent(props);
|
||||||
this.parent (props);
|
this.builderInitString(Tpl);
|
||||||
this.builderInitString (Tpl);
|
|
||||||
|
|
||||||
this.$('social-bar').conn = this._conn;
|
this.$('social-bar').conn = this._conn;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this.$('form').onsubmit = function ()
|
this.$('form').onsubmit = function() {
|
||||||
{
|
self._onSubmit();
|
||||||
self._onSubmit ();
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onConnLoadChange: function (conn, isLoading)
|
,_onConnLoadChange: function(conn, isLoading) {
|
||||||
{
|
|
||||||
if (isLoading)
|
if (isLoading)
|
||||||
this.$('spinner').start ();
|
this.$('spinner').start();
|
||||||
else
|
else
|
||||||
this.$('spinner').stop ();
|
this.$('spinner').stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
,show: function ()
|
,show: function() {
|
||||||
{
|
document.body.appendChild(this.node);
|
||||||
document.body.appendChild (this.node);
|
|
||||||
|
|
||||||
var lastUser = localStorage.getItem ('hederaLastUser');
|
var lastUser = localStorage.getItem('hederaLastUser');
|
||||||
|
|
||||||
if (lastUser)
|
if (lastUser)
|
||||||
this.$('user').value = lastUser;
|
this.$('user').value = lastUser;
|
||||||
|
|
||||||
this._focusUserInput ();
|
this._focusUserInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onSubmit: function ()
|
,_onSubmit: function() {
|
||||||
{
|
this._conn.open(
|
||||||
this._conn.open (
|
|
||||||
this.$('user').value,
|
this.$('user').value,
|
||||||
this.$('pass').value,
|
this.$('pass').value,
|
||||||
this.$('remember').checked,
|
this.$('remember').checked,
|
||||||
this._onConnOpen.bind (this)
|
this._onConnOpen.bind(this)
|
||||||
);
|
);
|
||||||
this._disableUi (true);
|
this._disableUi(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onConnOpen: function (conn, success, error)
|
,_onConnOpen: function(conn, success, error) {
|
||||||
{
|
|
||||||
this.$('pass').value = '';
|
this.$('pass').value = '';
|
||||||
this._disableUi (false);
|
this._disableUi(false);
|
||||||
|
|
||||||
if (success)
|
if (success) {
|
||||||
{
|
|
||||||
var user = this.$('user').value;
|
var user = this.$('user').value;
|
||||||
|
|
||||||
if (user)
|
if (user)
|
||||||
localStorage.setItem ('hederaLastUser', user);
|
localStorage.setItem('hederaLastUser', user);
|
||||||
|
|
||||||
this.signalEmit ('login');
|
this.signalEmit('login');
|
||||||
}
|
} else {
|
||||||
else
|
this._focusUserInput();
|
||||||
{
|
|
||||||
this._focusUserInput ();
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
,hide: function ()
|
,hide: function() {
|
||||||
{
|
Vn.Node.remove(this.node);
|
||||||
Vn.Node.remove (this.node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,_focusUserInput: function ()
|
,_focusUserInput: function() {
|
||||||
{
|
|
||||||
var userEntry = this.$('user');
|
var userEntry = this.$('user');
|
||||||
userEntry.focus ();
|
userEntry.focus();
|
||||||
userEntry.select ();
|
userEntry.select();
|
||||||
}
|
}
|
||||||
|
|
||||||
,_disableUi: function (disabled)
|
,_disableUi: function(disabled) {
|
||||||
{
|
|
||||||
this.$('user').disabled = disabled;
|
this.$('user').disabled = disabled;
|
||||||
this.$('pass').disabled = disabled;
|
this.$('pass').disabled = disabled;
|
||||||
this.$('submit').disabled = disabled;
|
this.$('submit').disabled = disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
,onPasswordLost: function ()
|
,onPasswordLost: function() {
|
||||||
{
|
|
||||||
var user = this.$('user').value;
|
var user = this.$('user').value;
|
||||||
|
|
||||||
if (!user)
|
if (!user)
|
||||||
Htk.Toast.showError (_('Please write your user name'));
|
Htk.Toast.showError(_('Please write your user name'));
|
||||||
else
|
else
|
||||||
this._conn.send ('core/recover-password', {recoverUser: user},
|
this._conn.send('core/recover-password', {recoverUser: user},
|
||||||
this._onPasswordRecovered.bind (this));
|
this._onPasswordRecovered.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onPasswordRecovered: function (json, error)
|
,_onPasswordRecovered: function(json, error) {
|
||||||
{
|
|
||||||
if (error)
|
if (error)
|
||||||
throw error;
|
throw error;
|
||||||
|
|
||||||
Htk.Toast.showMessage (_('A mail has been sent wich you can recover your password'));
|
Htk.Toast.showMessage(_('A mail has been sent wich you can recover your password'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
|
|
||||||
var Object = require ('./object');
|
var Object = require('./object');
|
||||||
var JsonException = require ('./json-exception');
|
var JsonException = require('./json-exception');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for JSON rest connections.
|
* Handler for JSON rest connections.
|
||||||
**/
|
**/
|
||||||
module.exports = new Class
|
module.exports = new Class({
|
||||||
({
|
|
||||||
Extends: Object
|
Extends: Object
|
||||||
|
|
||||||
,_connected: false
|
,_connected: false
|
||||||
|
@ -16,29 +15,26 @@ module.exports = new Class
|
||||||
/**
|
/**
|
||||||
* Initilizes the connection object.
|
* Initilizes the connection object.
|
||||||
**/
|
**/
|
||||||
,initialize: function ()
|
,initialize: function() {
|
||||||
{
|
this.parent();
|
||||||
this.parent ();
|
this.fetchToken();
|
||||||
this.fetchToken ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,fetchToken: function ()
|
,fetchToken: function() {
|
||||||
{
|
|
||||||
var token = null;
|
var token = null;
|
||||||
|
|
||||||
if (sessionStorage.getItem ('vnToken'))
|
if (sessionStorage.getItem('vnToken'))
|
||||||
token = sessionStorage.getItem ('vnToken');
|
token = sessionStorage.getItem('vnToken');
|
||||||
if (localStorage.getItem ('vnToken'))
|
if (localStorage.getItem('vnToken'))
|
||||||
token = localStorage.getItem ('vnToken');
|
token = localStorage.getItem('vnToken');
|
||||||
|
|
||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
,clearToken: function ()
|
,clearToken: function() {
|
||||||
{
|
|
||||||
this.token = null;
|
this.token = null;
|
||||||
localStorage.removeItem ('vnToken');
|
localStorage.removeItem('vnToken');
|
||||||
sessionStorage.removeItem ('vnToken');
|
sessionStorage.removeItem('vnToken');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,43 +45,37 @@ module.exports = new Class
|
||||||
* @param {Boolean} remember Specifies if the user should be remembered
|
* @param {Boolean} remember Specifies if the user should be remembered
|
||||||
* @param {Function} openCallback The function to call when operation is done
|
* @param {Function} openCallback The function to call when operation is done
|
||||||
**/
|
**/
|
||||||
,open: function (user, pass, remember, callback)
|
,open: function(user, pass, remember, callback) {
|
||||||
{
|
if (user !== null && user !== undefined) {
|
||||||
if (user !== null && user !== undefined)
|
|
||||||
{
|
|
||||||
var params = {
|
var params = {
|
||||||
user: user
|
user: user
|
||||||
,password: pass
|
,password: pass
|
||||||
,remember: remember
|
,remember: remember
|
||||||
};
|
};
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
var params = null;
|
var params = null;
|
||||||
|
|
||||||
this.send ('core/login', params,
|
this.lbSend('POST', 'Accounts/login', params,
|
||||||
this._onOpen.bind (this, callback, remember));
|
this._onOpen.bind(this, callback, remember));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when open operation is done.
|
* Called when open operation is done.
|
||||||
*/
|
*/
|
||||||
,_onOpen: function (callback, remember, json, error)
|
,_onOpen: function(callback, remember, json, error) {
|
||||||
{
|
if (json) {
|
||||||
if (json && json.login)
|
|
||||||
{
|
|
||||||
this._connected = true;
|
this._connected = true;
|
||||||
this.token = json.token;
|
this.token = json.token;
|
||||||
|
|
||||||
var storage = remember ? localStorage : sessionStorage;
|
var storage = remember ? localStorage : sessionStorage;
|
||||||
storage.setItem ('vnToken', this.token);
|
storage.setItem('vnToken', this.token);
|
||||||
|
|
||||||
this.signalEmit ('openned');
|
this.signalEmit('openned');
|
||||||
}
|
} else
|
||||||
else
|
this._closeClient();
|
||||||
this._closeClient ();
|
|
||||||
|
|
||||||
if (callback)
|
if (callback)
|
||||||
callback (this, this._connected, error);
|
callback(this, this._connected, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,58 +83,53 @@ module.exports = new Class
|
||||||
*
|
*
|
||||||
* @param {Function} callback The function to call when operation is done
|
* @param {Function} callback The function to call when operation is done
|
||||||
**/
|
**/
|
||||||
,close: function (callback)
|
,close: function(callback) {
|
||||||
{
|
this.lbSend('POST', 'Accounts/logout', null,
|
||||||
this._closeClient ();
|
this._onClose.bind(this, callback));
|
||||||
this.send ('core/logout', null,
|
this._closeClient();
|
||||||
this._onClose.bind (this, callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when close operation is done.
|
* Called when close operation is done.
|
||||||
*/
|
*/
|
||||||
,_onClose: function (callback, json, error)
|
,_onClose: function(callback, json, error) {
|
||||||
{
|
this.signalEmit('closed');
|
||||||
this.signalEmit ('closed');
|
|
||||||
|
|
||||||
if (callback)
|
if (callback)
|
||||||
callback (this, json === true, error);
|
callback(this, null, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
,_closeClient: function ()
|
,_closeClient: function() {
|
||||||
{
|
|
||||||
this._connected = false;
|
this._connected = false;
|
||||||
this.clearToken ();
|
this.clearToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suppants another user.
|
* Supplants another user.
|
||||||
*
|
*
|
||||||
* @param {String} user The user name
|
* @param {String} user The user name
|
||||||
* @param {Function} callback The callback function
|
* @param {Function} callback The callback function
|
||||||
**/
|
**/
|
||||||
,supplantUser: function (user, callback)
|
,supplantUser: function(user, callback) {
|
||||||
{
|
|
||||||
var params = {supplantUser: user};
|
var params = {supplantUser: user};
|
||||||
this.send ('core/supplant', params,
|
this.send('client/supplant', params,
|
||||||
this._onUserSupplant.bind (this, callback));
|
this._onUserSupplant.bind(this, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onUserSupplant: function (callback, json, error)
|
,_onUserSupplant: function(callback, json) {
|
||||||
{
|
|
||||||
if (json)
|
if (json)
|
||||||
this.token = json;
|
this.token = json;
|
||||||
|
|
||||||
if (callback)
|
if (callback)
|
||||||
callback (json != null);
|
callback(json != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ends the user supplanting and restores the last login.
|
* Ends the user supplanting and restores the last login.
|
||||||
**/
|
**/
|
||||||
,supplantEnd: function ()
|
,supplantEnd: function() {
|
||||||
{
|
this.lbSend('POST', 'Accounts/logout');
|
||||||
this.fetchToken ();
|
this.fetchToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,18 +140,16 @@ module.exports = new Class
|
||||||
* @param {Map} params The params to pass to the service
|
* @param {Map} params The params to pass to the service
|
||||||
* @param {Function} callback The response callback
|
* @param {Function} callback The response callback
|
||||||
**/
|
**/
|
||||||
,send: function (restService, params, callback)
|
,send: function(restService, params, callback) {
|
||||||
{
|
|
||||||
if (!params)
|
if (!params)
|
||||||
params = {};
|
params = {};
|
||||||
|
|
||||||
params.srv = 'json:'+ restService;
|
params.srv = 'json:'+ restService;
|
||||||
|
|
||||||
this.sendWithUrl (params, callback, 'POST', '.');
|
this.sendWithUrl(params, callback, 'POST', '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
,sendForm: function (form, callback)
|
,sendForm: function(form, callback) {
|
||||||
{
|
|
||||||
var params = {};
|
var params = {};
|
||||||
var elements = form.elements;
|
var elements = form.elements;
|
||||||
|
|
||||||
|
@ -174,83 +157,88 @@ module.exports = new Class
|
||||||
if (elements[i].name)
|
if (elements[i].name)
|
||||||
params[elements[i].name] = elements[i].value;
|
params[elements[i].name] = elements[i].value;
|
||||||
|
|
||||||
this.sendWithUrl (params, callback, 'POST', form.action);
|
this.sendWithUrl(params, callback, 'POST', form.action);
|
||||||
}
|
}
|
||||||
|
|
||||||
,sendFormMultipart: function (form, callback)
|
,sendFormMultipart: function(form, callback) {
|
||||||
{
|
var formData = new FormData(form);
|
||||||
var formData = new FormData (form);
|
|
||||||
|
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
request.open('POST', form.action, true);
|
||||||
if (this.token)
|
if (this.token)
|
||||||
formData.append ('token', this.token);
|
request.setRequestHeader('Authorization', this.token);
|
||||||
|
|
||||||
var request = new XMLHttpRequest ();
|
|
||||||
request.open ('POST', form.action, true);
|
|
||||||
request.onreadystatechange =
|
request.onreadystatechange =
|
||||||
this._onStateChange.bind (this, request, callback);
|
this._onStateChange.bind(this, request, callback);
|
||||||
request.send (formData);
|
request.send(formData);
|
||||||
|
|
||||||
this._addRequest ();
|
this._addRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
,sendFormData: function (formData, callback)
|
,sendFormData: function(formData, callback) {
|
||||||
{
|
var request = new XMLHttpRequest();
|
||||||
|
request.open('POST', '', true);
|
||||||
if (this.token)
|
if (this.token)
|
||||||
formData.append ('token', this.token);
|
request.setRequestHeader('Authorization', this.token);
|
||||||
|
|
||||||
var request = new XMLHttpRequest ();
|
|
||||||
request.open ('POST', '', true);
|
|
||||||
request.onreadystatechange =
|
request.onreadystatechange =
|
||||||
this._onStateChange.bind (this, request, callback);
|
this._onStateChange.bind(this, request, callback);
|
||||||
request.send (formData);
|
request.send(formData);
|
||||||
|
|
||||||
this._addRequest ();
|
this._addRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when REST response is received.
|
* Called when REST response is received.
|
||||||
*/
|
*/
|
||||||
,sendWithUrl: function (params, callback, method, url)
|
,sendWithUrl: function(params, callback, method, url) {
|
||||||
{
|
var request = new XMLHttpRequest();
|
||||||
if (this.token)
|
request.open(method, url, true);
|
||||||
params['token'] = this.token;
|
request.setRequestHeader('Content-Type',
|
||||||
|
|
||||||
var request = new XMLHttpRequest ();
|
|
||||||
request.open (method, url, true);
|
|
||||||
request.setRequestHeader ('Content-Type',
|
|
||||||
'application/x-www-form-urlencoded');
|
'application/x-www-form-urlencoded');
|
||||||
|
if (this.token)
|
||||||
|
request.setRequestHeader('Authorization', this.token);
|
||||||
request.onreadystatechange =
|
request.onreadystatechange =
|
||||||
this._onStateChange.bind (this, request, callback);
|
this._onStateChange.bind(this, request, callback);
|
||||||
request.send (Vn.Url.makeUri (params));
|
request.send(Vn.Url.makeUri(params));
|
||||||
|
|
||||||
this._addRequest ();
|
this._addRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
,_addRequest: function ()
|
,lbSend: function(method, url, params, callback) {
|
||||||
{
|
var request = new XMLHttpRequest();
|
||||||
|
request.open(method, `api/${url}`, true);
|
||||||
|
request.setRequestHeader('Content-Type',
|
||||||
|
'application/json;charset=utf-8');
|
||||||
|
if (this.token)
|
||||||
|
request.setRequestHeader('Authorization', this.token);
|
||||||
|
request.onreadystatechange =
|
||||||
|
this._onStateChange.bind(this, request, callback);
|
||||||
|
request.send(params && JSON.stringify(params));
|
||||||
|
|
||||||
|
this._addRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
,_addRequest: function() {
|
||||||
this._requestsCount++;
|
this._requestsCount++;
|
||||||
|
|
||||||
if (this._requestsCount === 1)
|
if (this._requestsCount === 1)
|
||||||
this.signalEmit ('loading-changed', true);
|
this.signalEmit('loading-changed', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onStateChange: function (request, callback)
|
,_onStateChange: function(request, callback) {
|
||||||
{
|
|
||||||
if (request.readyState !== 4)
|
if (request.readyState !== 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._requestsCount--;
|
this._requestsCount--;
|
||||||
|
|
||||||
if (this._requestsCount === 0)
|
if (this._requestsCount === 0)
|
||||||
this.signalEmit ('loading-changed', false);
|
this.signalEmit('loading-changed', false);
|
||||||
|
|
||||||
var data = null;
|
var data = null;
|
||||||
var error = null;
|
var error = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (request.status == 0)
|
if (request.status == 0) {
|
||||||
{
|
var ex = new JsonException();
|
||||||
var ex = new JsonException ();
|
|
||||||
ex.message = _('The server does not respond, please check your Internet connection');
|
ex.message = _('The server does not respond, please check your Internet connection');
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
@ -259,70 +247,75 @@ module.exports = new Class
|
||||||
|
|
||||||
try {
|
try {
|
||||||
contentType = request
|
contentType = request
|
||||||
.getResponseHeader ('Content-Type')
|
.getResponseHeader('Content-Type')
|
||||||
.split (';')[0]
|
.split(';')[0]
|
||||||
.trim ();
|
.trim();
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(err);
|
||||||
}
|
}
|
||||||
catch (e) {}
|
|
||||||
|
|
||||||
if (contentType != 'application/json')
|
if (contentType != 'application/json') {
|
||||||
{
|
var ex = new JsonException();
|
||||||
var ex = new JsonException ();
|
|
||||||
ex.message = request.statusText;
|
ex.message = request.statusText;
|
||||||
ex.code = request.status;
|
ex.code = request.status;
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
var json = JSON.parse (request.responseText);
|
|
||||||
var jsData = json.data;
|
|
||||||
//var jsWarns = json.warnings;
|
|
||||||
|
|
||||||
if (request.status == 200)
|
|
||||||
{
|
|
||||||
data = jsData;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var exception = jsData.exception;
|
|
||||||
|
|
||||||
if (exception)
|
|
||||||
exception = exception
|
|
||||||
.replace (/\\/g, '.')
|
|
||||||
.replace (/Exception$/, '')
|
|
||||||
.replace (/^Vn\.Web\./, '');
|
|
||||||
|
|
||||||
var ex = new JsonException ();
|
var json;
|
||||||
ex.exception = exception;
|
var jsData;
|
||||||
ex.message = jsData.message;
|
|
||||||
ex.code = jsData.code;
|
if (request.responseText)
|
||||||
ex.file = jsData.file;
|
json = JSON.parse(request.responseText);
|
||||||
ex.line = jsData.line;
|
if (json)
|
||||||
ex.trace = jsData.trace;
|
jsData = json.data || json;
|
||||||
|
|
||||||
|
if (request.status >= 200 && request.status < 300) {
|
||||||
|
data = jsData;
|
||||||
|
} else {
|
||||||
|
var exception = jsData.exception;
|
||||||
|
var error = jsData.error;
|
||||||
|
|
||||||
|
if (exception) {
|
||||||
|
exception = exception
|
||||||
|
.replace(/\\/g, '.')
|
||||||
|
.replace(/Exception$/, '')
|
||||||
|
.replace(/^Vn\.Web\./, '');
|
||||||
|
|
||||||
|
var ex = new JsonException();
|
||||||
|
ex.exception = exception;
|
||||||
|
ex.message = jsData.message;
|
||||||
|
ex.code = jsData.code;
|
||||||
|
ex.file = jsData.file;
|
||||||
|
ex.line = jsData.line;
|
||||||
|
ex.trace = jsData.trace;
|
||||||
|
} else if (error) {
|
||||||
|
var ex = new Error();
|
||||||
|
ex.name = error.name;
|
||||||
|
ex.message = error.message;
|
||||||
|
ex.code = error.code;
|
||||||
|
ex.statusCode = request.status;
|
||||||
|
}
|
||||||
|
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
} catch (e) {
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
data = null;
|
data = null;
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callback)
|
if (callback)
|
||||||
try {
|
try {
|
||||||
callback (data, error);
|
callback(data, error);
|
||||||
error = null;
|
error = null;
|
||||||
}
|
} catch (e) {
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
if (error) {
|
||||||
{
|
|
||||||
if (error.exception == 'SessionExpired')
|
if (error.exception == 'SessionExpired')
|
||||||
this.clearToken ();
|
this.clearToken();
|
||||||
|
|
||||||
this.signalEmit ('error', error);
|
this.signalEmit('error', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "hedera-web",
|
"name": "hedera-web",
|
||||||
"version": "1.407.66",
|
"version": "1.407.68",
|
||||||
"description": "Verdnatura web page",
|
"description": "Verdnatura web page",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</vn-group>
|
</vn-group>
|
||||||
<div id="report" class="sheet">
|
<div id="report" class="sheet">
|
||||||
<h2>
|
<h2>
|
||||||
@<htk-text column="id" form="ticket"/>
|
#<htk-text column="id" form="ticket"/>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Vn\Web;
|
||||||
|
|
||||||
|
class Supplant extends Vn\Web\JsonRequest {
|
||||||
|
const PARAMS = ['supplantUser'];
|
||||||
|
|
||||||
|
function run($db) {
|
||||||
|
$userId = $db->getValue(
|
||||||
|
'SELECT id FROM account.user WHERE `name` = #',
|
||||||
|
[$_REQUEST['supplantUser']]
|
||||||
|
);
|
||||||
|
|
||||||
|
$isClient = $db->getValue(
|
||||||
|
'SELECT COUNT(*) > 0 FROM vn.client WHERE id = #',
|
||||||
|
[$userId]
|
||||||
|
);
|
||||||
|
if (!$isClient)
|
||||||
|
throw new Web\ForbiddenException(s('The user is not a client'));
|
||||||
|
|
||||||
|
$isWorker = $db->getValue(
|
||||||
|
'SELECT COUNT(*) > 0 FROM vn.worker WHERE id = #',
|
||||||
|
[$userId]
|
||||||
|
);
|
||||||
|
if ($isWorker)
|
||||||
|
throw new Web\ForbiddenException(s('Workers cannot be supplanted'));
|
||||||
|
|
||||||
|
return $this->service->createToken($_REQUEST['supplantUser']);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
include __DIR__.'/account.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the user password.
|
|
||||||
**/
|
|
||||||
class ChangePassword extends Vn\Web\JsonRequest {
|
|
||||||
const PARAMS = ['oldPassword', 'newPassword'];
|
|
||||||
|
|
||||||
function run($db) {
|
|
||||||
$oldPassword = $_REQUEST['oldPassword'];
|
|
||||||
$newPassword = $_REQUEST['newPassword'];
|
|
||||||
|
|
||||||
$db->query('CALL account.myUser_changePassword(#, #)',
|
|
||||||
[$oldPassword, $newPassword]);
|
|
||||||
Account::sync($db, $_SESSION['user'], $newPassword);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
include __DIR__.'/account.php';
|
|
||||||
|
|
||||||
class Login extends Vn\Web\JsonRequest {
|
|
||||||
function run($db) {
|
|
||||||
if (!$_POST['user'] || !$_POST['password'])
|
|
||||||
throw new Vn\Web\BadLoginException();
|
|
||||||
|
|
||||||
try {
|
|
||||||
Account::trySync($db
|
|
||||||
,strtolower($_POST['user'])
|
|
||||||
,$_POST['password']
|
|
||||||
);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
error_log($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
$token = $this->service->createToken(
|
|
||||||
$_SESSION['user'],
|
|
||||||
!empty($_POST['remember'])
|
|
||||||
);
|
|
||||||
|
|
||||||
return [
|
|
||||||
'login' => TRUE,
|
|
||||||
'token' => $token
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
class Logout extends Vn\Web\JsonRequest {
|
|
||||||
function run($db) {
|
|
||||||
$this->service->logout();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,4 +7,3 @@ class Supplant extends Vn\Web\JsonRequest {
|
||||||
return $this->service->createToken($_REQUEST['supplantUser']);
|
return $this->service->createToken($_REQUEST['supplantUser']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
include __DIR__.'/account.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the user credentials on external systems like Samba, create
|
|
||||||
* home directory, create mailbox, etc.
|
|
||||||
**/
|
|
||||||
class SyncUser extends Vn\Web\JsonRequest {
|
|
||||||
const PARAMS = ['syncUser'];
|
|
||||||
|
|
||||||
function run($db) {
|
|
||||||
Account::sync($db, $_REQUEST['syncUser'], NULL);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
105
rest/dms/add.php
105
rest/dms/add.php
|
@ -1,105 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Vn\Lib;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a document to the Document Management System.
|
|
||||||
**/
|
|
||||||
class Add extends Vn\Web\JsonRequest {
|
|
||||||
function run($db) {
|
|
||||||
// XXX: Uncomment only to test the script
|
|
||||||
//$_REQUEST['description'] = 'description';
|
|
||||||
|
|
||||||
$description = empty($_REQUEST['description']) ?
|
|
||||||
NULL : $_REQUEST['description'];
|
|
||||||
|
|
||||||
$baseDir = _DATA_DIR .'/'. $this->app->getName();
|
|
||||||
$docsDir = "$baseDir/dms";
|
|
||||||
$tempDir = "$baseDir/.dms";
|
|
||||||
|
|
||||||
$digXDir = 3;
|
|
||||||
$zerosDir = '';
|
|
||||||
|
|
||||||
for ($i = 0; $i < $digXDir; $i++)
|
|
||||||
$zerosDir .= '0';
|
|
||||||
|
|
||||||
// Checks document restrictions
|
|
||||||
|
|
||||||
if (empty($_FILES['doc']['name']))
|
|
||||||
throw new Lib\UserException('File not choosed');
|
|
||||||
|
|
||||||
$maxSize = $db->getValue('SELECT max_size FROM dms_config');
|
|
||||||
|
|
||||||
if ($_FILES['doc']['size'] > $maxSize * 1048576)
|
|
||||||
throw new Lib\UserException(sprintf('File size exceeds size: %d MB', $maxSize));
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Registers the document in the database
|
|
||||||
|
|
||||||
$db->query('START TRANSACTION');
|
|
||||||
|
|
||||||
$db->query('INSERT INTO dms_document SET description = #', [$description]);
|
|
||||||
$docId =(string) $db->getValue('SELECT LAST_INSERT_ID()');
|
|
||||||
|
|
||||||
$len = strlen($docId);
|
|
||||||
$neededLevels = ceil($len / $digXDir) - 1;
|
|
||||||
|
|
||||||
$dirLevels = $db->getValue(
|
|
||||||
'SELECT dir_levels FROM dms_config LOCK IN SHARE MODE');
|
|
||||||
|
|
||||||
if ($dirLevels > $neededLevels)
|
|
||||||
$neededLevels = $dirLevels;
|
|
||||||
|
|
||||||
// Reorganizes the file repository if necessary
|
|
||||||
|
|
||||||
if ($dirLevels < $neededLevels)
|
|
||||||
$dirLevels = $db->getValue(
|
|
||||||
'SELECT dir_levels FROM dms_config FOR UPDATE');
|
|
||||||
|
|
||||||
if ($dirLevels < $neededLevels) {
|
|
||||||
if (is_dir($docsDir)) {
|
|
||||||
$dif =($neededLevels - $dirLevels) - 1;
|
|
||||||
$newDir = $docsDir;
|
|
||||||
|
|
||||||
for ($i = 0; $i < $dif; $i++)
|
|
||||||
$newDir .= "/$zerosDir";
|
|
||||||
|
|
||||||
$success = rename($docsDir, $tempDir)
|
|
||||||
&& mkdir($newDir, 0770, TRUE)
|
|
||||||
&& rename($tempDir, "$newDir/$zerosDir");
|
|
||||||
|
|
||||||
if (!$success)
|
|
||||||
throw new Exception('Error while reorganizing directory tree');
|
|
||||||
}
|
|
||||||
|
|
||||||
$curLevels = $db->query('UPDATE dms_config SET dir_levels = #',
|
|
||||||
[$neededLevels]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Saves the document to the repository
|
|
||||||
|
|
||||||
$padLen =($neededLevels + 1) * $digXDir;
|
|
||||||
$paddedId = str_pad($docId, $padLen, '0', STR_PAD_LEFT);
|
|
||||||
|
|
||||||
$saveDir = $docsDir;
|
|
||||||
|
|
||||||
for ($i = 0; $i < $neededLevels; $i++)
|
|
||||||
$saveDir .= '/'. substr($paddedId, $i * $digXDir, $digXDir);
|
|
||||||
|
|
||||||
if (!file_exists($saveDir))
|
|
||||||
mkdir($saveDir, 0770, TRUE);
|
|
||||||
|
|
||||||
$savePath = "$saveDir/". substr($paddedId, -$digXDir);
|
|
||||||
|
|
||||||
move_uploaded_file($_FILES['doc']['tmp_name'], $savePath);
|
|
||||||
|
|
||||||
$db->query('COMMIT');
|
|
||||||
|
|
||||||
return $docId;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$db->query('ROLLBACK');
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Vn\Lib;
|
|
||||||
|
|
||||||
class Sms extends Vn\Web\JsonRequest {
|
|
||||||
const PARAMS = [
|
|
||||||
'destination'
|
|
||||||
,'message'
|
|
||||||
];
|
|
||||||
|
|
||||||
const OK_STATES = [
|
|
||||||
0, // Ok
|
|
||||||
200 // Processing
|
|
||||||
];
|
|
||||||
|
|
||||||
function run($db) {
|
|
||||||
$smsConfig = $db->getObject('SELECT uri, user, password, title FROM vn.smsConfig');
|
|
||||||
|
|
||||||
$sClient = new SoapClient($smsConfig->uri);
|
|
||||||
$xmlString = $sClient->sendSMS(
|
|
||||||
$smsConfig->user
|
|
||||||
,$smsConfig->password
|
|
||||||
,$smsConfig->title
|
|
||||||
,$_REQUEST['destination']
|
|
||||||
,$_REQUEST['message']
|
|
||||||
);
|
|
||||||
$xmlResponse = new SimpleXMLElement($xmlString);
|
|
||||||
$res = $xmlResponse->sms;
|
|
||||||
|
|
||||||
$db->query(
|
|
||||||
'INSERT INTO vn.sms SET
|
|
||||||
`senderFk` = account.myUser_getId(),
|
|
||||||
`destinationFk` = #,
|
|
||||||
`destination` = #,
|
|
||||||
`message` = #,
|
|
||||||
`statusCode` = #,
|
|
||||||
`status` = #',
|
|
||||||
[
|
|
||||||
empty($_REQUEST['destinationId']) ? NULL : $_REQUEST['destinationId']
|
|
||||||
,$_REQUEST['destination']
|
|
||||||
,$_REQUEST['message']
|
|
||||||
,$res->codigo
|
|
||||||
,$res->descripcion
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!in_array((int) $res->codigo, self::OK_STATES))
|
|
||||||
throw new Lib\UserException($res->descripcion);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -31,13 +31,12 @@ class RestService extends Service {
|
||||||
$_REQUEST['method'], $class, './rest');
|
$_REQUEST['method'], $class, './rest');
|
||||||
$method->service = $this;
|
$method->service = $this;
|
||||||
|
|
||||||
|
$isAuthorized = $db->getValue('SELECT myUser_checkRestPriv(#)',
|
||||||
|
[$_REQUEST['method']]);
|
||||||
|
if (!$isAuthorized)
|
||||||
|
throw new ForbiddenException(s('You don\'t have enough privileges'));
|
||||||
|
|
||||||
if ($method::SECURITY == Security::DEFINER) {
|
if ($method::SECURITY == Security::DEFINER) {
|
||||||
$isAuthorized = $db->getValue('SELECT myUser_checkRestPriv(#)',
|
|
||||||
[$_REQUEST['method']]);
|
|
||||||
|
|
||||||
if (!$isAuthorized)
|
|
||||||
throw new UserException(s('You don\'t have enough privileges'));
|
|
||||||
|
|
||||||
$methodDb = $db;
|
$methodDb = $db;
|
||||||
} else
|
} else
|
||||||
$methodDb = $this->getUserDb($_SESSION['user']);
|
$methodDb = $this->getUserDb($_SESSION['user']);
|
||||||
|
@ -71,6 +70,8 @@ class RestService extends Service {
|
||||||
$status = 401;
|
$status = 401;
|
||||||
} catch (BadLoginException $e) {
|
} catch (BadLoginException $e) {
|
||||||
$status = 401;
|
$status = 401;
|
||||||
|
} catch (ForbiddenException $e) {
|
||||||
|
$status = 403;
|
||||||
} catch (Lib\UserException $e) {
|
} catch (Lib\UserException $e) {
|
||||||
$status = 400;
|
$status = 400;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|
117
web/service.php
117
web/service.php
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Vn\Web;
|
namespace Vn\Web;
|
||||||
|
|
||||||
|
include __DIR__.'/uid.php';
|
||||||
|
|
||||||
use Vn\Db;
|
use Vn\Db;
|
||||||
use Vn\Lib\Locale;
|
use Vn\Lib\Locale;
|
||||||
use Vn\Lib\UserException;
|
use Vn\Lib\UserException;
|
||||||
|
@ -21,6 +23,11 @@ class SessionExpiredException extends UserException {}
|
||||||
*/
|
*/
|
||||||
class BadLoginException extends UserException {}
|
class BadLoginException extends UserException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when user credentials are invalid.
|
||||||
|
*/
|
||||||
|
class ForbiddenException extends UserException {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when user credentials are invalid.
|
* Thrown when user credentials are invalid.
|
||||||
*/
|
*/
|
||||||
|
@ -130,62 +137,26 @@ abstract class Service {
|
||||||
*/
|
*/
|
||||||
function login() {
|
function login() {
|
||||||
$db = $this->db;
|
$db = $this->db;
|
||||||
$anonymousUser = FALSE;
|
$anonymousUser = TRUE;
|
||||||
|
|
||||||
if (isset($_POST['user']) && !empty($_POST['password'])) {
|
|
||||||
$user = strtolower($_POST['user']);
|
|
||||||
|
|
||||||
$passwordHash = $db->getValue(
|
if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||||
'SELECT bcryptPassword FROM account.user WHERE `name` = #',
|
$userId = $db->getValue(
|
||||||
[$user]
|
'SELECT userId FROM salix.AccessToken
|
||||||
|
WHERE id = #
|
||||||
|
AND NOW() <= TIMESTAMPADD(SECOND, ttl, created)',
|
||||||
|
[$_SERVER['HTTP_AUTHORIZATION']]
|
||||||
);
|
);
|
||||||
|
|
||||||
$passwordOk = !empty($passwordHash)
|
if (!$userId)
|
||||||
&& password_verify($_POST['password'], $passwordHash);
|
throw new SessionExpiredException();
|
||||||
|
|
||||||
// XXX: Compatibility with old MD5 passwords
|
$anonymousUser = FALSE;
|
||||||
if (empty($passwordHash)) {
|
$user = $db->getValue(
|
||||||
$md5Password = $db->getValue(
|
'SELECT `name` FROM account.user WHERE id = #',
|
||||||
'SELECT `password` FROM account.user
|
[$userId]
|
||||||
WHERE active AND `name` = #',
|
);
|
||||||
[$user]
|
} else
|
||||||
);
|
$user = $db->getValue('SELECT guestUser FROM config');
|
||||||
|
|
||||||
$passwordOk = !empty($md5Password)
|
|
||||||
&& $md5Password == md5($_POST['password']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$passwordOk) {
|
|
||||||
sleep(3);
|
|
||||||
throw new BadLoginException();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isset($_POST['token']) || isset($_GET['token'])) {
|
|
||||||
if (isset($_POST['token']))
|
|
||||||
$token = $_POST['token'];
|
|
||||||
if (isset($_GET['token']))
|
|
||||||
$token = $_GET['token'];
|
|
||||||
|
|
||||||
$key = $db->getValue('SELECT jwtKey FROM config');
|
|
||||||
|
|
||||||
try {
|
|
||||||
$jwtPayload = Jwt::decode($token, $key);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
throw new BadLoginException($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
$expiration = $jwtPayload['exp'];
|
|
||||||
|
|
||||||
if (empty($expiration) || $expiration <= time())
|
|
||||||
throw new SessionExpiredException();
|
|
||||||
|
|
||||||
$user = $jwtPayload['sub'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$user = $db->getValue('SELECT guestUser FROM config');
|
|
||||||
$anonymousUser = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$anonymousUser) {
|
if (!$anonymousUser) {
|
||||||
$isActive = $db->getValue(
|
$isActive = $db->getValue(
|
||||||
|
@ -217,9 +188,15 @@ abstract class Service {
|
||||||
* Logouts the current user. Cleans the last saved used credentials.
|
* Logouts the current user. Cleans the last saved used credentials.
|
||||||
*/
|
*/
|
||||||
function logout() {
|
function logout() {
|
||||||
|
if (!empty($_SERVER['HTTP_AUTHORIZATION']))
|
||||||
|
$db->query(
|
||||||
|
'DELETE FROM salix.AccessToken WHERE id = #',
|
||||||
|
[$_SERVER['HTTP_AUTHORIZATION']]
|
||||||
|
);
|
||||||
|
|
||||||
unset($_SESSION['user']);
|
unset($_SESSION['user']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates or returns a database connection where the authenticated user
|
* Creates or returns a database connection where the authenticated user
|
||||||
* is the role of the current logged user.
|
* is the role of the current logged user.
|
||||||
|
@ -248,15 +225,45 @@ abstract class Service {
|
||||||
return $userDb;
|
return $userDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a authentication token for the specified $user.
|
||||||
|
*
|
||||||
|
* @param {string} $user The user name
|
||||||
|
* @param {boolean} $remember Wether to create long live token
|
||||||
|
* @return {string} The generated token
|
||||||
|
*/
|
||||||
|
function createToken($user, $remember = FALSE) {
|
||||||
|
if ($remember)
|
||||||
|
$tokenLife = 2 * WEEK;
|
||||||
|
else
|
||||||
|
$tokenLife = 30 * MIN;
|
||||||
|
|
||||||
|
$token = uid(DEFAULT_TOKEN_LEN);
|
||||||
|
$userId = $this->db->getValue(
|
||||||
|
'SELECT id FROM account.user WHERE `name` = #',
|
||||||
|
[$user]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->db->query(
|
||||||
|
'INSERT INTO salix.AccessToken
|
||||||
|
SET id = #,
|
||||||
|
ttl = #,
|
||||||
|
created = NOW(),
|
||||||
|
userId = #',
|
||||||
|
[$token, $tokenLife, $userId]
|
||||||
|
);
|
||||||
|
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a JWT authentication token for the specified $user.
|
* Generates a JWT authentication token for the specified $user.
|
||||||
*
|
*
|
||||||
* @param {string} $user The user name
|
* @param {string} $user The user name
|
||||||
* @param {boolean} $remember Wether to create long live token
|
* @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
|
* @return {string} The JWT generated token
|
||||||
*/
|
*/
|
||||||
function createToken($user, $remember = FALSE) {
|
function createJwtToken($user, $remember = FALSE) {
|
||||||
if ($remember)
|
if ($remember)
|
||||||
$tokenLife = WEEK;
|
$tokenLife = WEEK;
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Vn\Web;
|
||||||
|
|
||||||
|
const DEFAULT_TOKEN_LEN = 64;
|
||||||
|
const UIDCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
||||||
|
|
||||||
|
function uid($length) {
|
||||||
|
$bytes = bin2hex(random_bytes($length));
|
||||||
|
$r = '';
|
||||||
|
for ($i = 0; $i < $length; $i++)
|
||||||
|
$r .= UIDCHARS[hexdec(substr($bytes, $i * 2, 2)) % 64];
|
||||||
|
return $r;
|
||||||
|
}
|
|
@ -42,15 +42,15 @@ var baseConfig = {
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
_DEV_MODE: devMode,
|
_DEV_MODE: devMode,
|
||||||
_DEV_SERVER_PORT: wpConfig.devServerPort,
|
_DEV_SERVER_PORT: wpConfig.devServerPort,
|
||||||
_PUBLIC_PATH: JSON.stringify (publicPath)
|
_PUBLIC_PATH: JSON.stringify(publicPath)
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
optimization: {
|
optimization: {
|
||||||
runtimeChunk: true,
|
runtimeChunk: true,
|
||||||
splitChunks: {
|
splitChunks: {
|
||||||
chunks: 'all',
|
chunks: 'all',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watchOptions: {
|
watchOptions: {
|
||||||
ignored: /node_modules/
|
ignored: /node_modules/
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,15 @@ var devConfig = {
|
||||||
devServer: {
|
devServer: {
|
||||||
host: '0.0.0.0',
|
host: '0.0.0.0',
|
||||||
port: wpConfig.devServerPort,
|
port: wpConfig.devServerPort,
|
||||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
headers: {'Access-Control-Allow-Origin': '*'},
|
||||||
stats: { chunks: false }
|
stats: { chunks: false },
|
||||||
|
proxy: {
|
||||||
|
'/api': 'http://localhost:3000',
|
||||||
|
'/': {
|
||||||
|
target: 'http://localhost/projects/hedera-web',
|
||||||
|
bypass: (req) => req.path !== '/' ? req.path : null
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
devtool: 'eval'
|
devtool: 'eval'
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue