From aa4d1edd32006096791ffa9e8a78cc7c7be7dc34 Mon Sep 17 00:00:00 2001
From: Juan Ferrer Toribio
Date: Thu, 5 May 2022 15:56:17 +0200
Subject: [PATCH 1/4] #3806 Salix backend
---
app.js | 75 +++----
forms/account/conf/conf.js | 13 +-
forms/admin/connections/connections.js | 44 ++--
forms/admin/users/users.js | 25 +--
forms/ecomerce/ticket/ticket.js | 12 +-
js/db/result-set.js | 52 +++--
js/hedera/app.js | 15 +-
js/hedera/gui.js | 6 +-
js/hedera/locale/ca.yml | 3 +-
js/hedera/locale/en.yml | 3 +-
js/hedera/locale/es.yml | 3 +-
js/hedera/locale/fr.yml | 3 +-
js/hedera/locale/mn.yml | 1 -
js/hedera/locale/pt.yml | 3 +-
js/hedera/login.js | 99 ++++-----
js/vn/json-connection.js | 286 ++++++++++++-------------
rest/client/supplant.php | 30 +++
rest/core/change-password.php | 21 --
rest/core/login.php | 30 ---
rest/core/logout.php | 9 -
rest/core/supplant.php | 1 -
rest/core/sync-user.php | 17 --
rest/dms/add.php | 105 ---------
rest/misc/sms.php | 52 -----
web/rest-service.php | 13 +-
web/service.php | 81 +++----
webpack.config.js | 22 +-
27 files changed, 389 insertions(+), 635 deletions(-)
create mode 100644 rest/client/supplant.php
delete mode 100644 rest/core/change-password.php
delete mode 100644 rest/core/login.php
delete mode 100644 rest/core/logout.php
delete mode 100644 rest/core/sync-user.php
delete mode 100644 rest/dms/add.php
delete mode 100644 rest/misc/sms.php
diff --git a/app.js b/app.js
index 0481dfe5..aa8a23f4 100644
--- a/app.js
+++ b/app.js
@@ -1,71 +1,60 @@
+__webpack_public_path__ = _PUBLIC_PATH;
-var assetsPath;
+require('hedera/hedera');
-if (_DEV_MODE)
-{
- 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);
+window.onload = function() {
+ loadLocale(main);
}
-function main (req)
-{
+function main(req) {
if (req)
- onLocaleLoad (req);
+ onLocaleLoad(req);
- hederaWeb = new Hedera.App ();
- hederaWeb.run ();
+ hederaWeb = new Hedera.App();
+ hederaWeb.run();
}
-function loadLocale (cb)
-{
- Vn.Locale.init ();
+function loadLocale(cb) {
+ Vn.Locale.init();
var lang = Vn.Locale.language;
- var req = require.context ('js', true, /locale\/en.yml$/);
- onLocaleLoad (req);
+ var req = require.context('js', true, /locale\/en.yml$/);
+ onLocaleLoad(req);
- switch (lang)
- {
+ switch (lang) {
case 'ca':
- require ([], function () {
- cb (require.context ('js', true, /locale\/ca.yml$/)); });
+ require([], function() {
+ cb(require.context('js', true, /locale\/ca.yml$/));
+ });
break;
case 'es':
- require ([], function () {
- cb (require.context ('js', true, /locale\/es.yml$/)); });
+ require([], function() {
+ cb(require.context('js', true, /locale\/es.yml$/));
+ });
break;
case 'fr':
- require ([], function () {
- cb (require.context ('js', true, /locale\/fr.yml$/)); });
+ require([], function() {
+ cb(require.context('js', true, /locale\/fr.yml$/));
+ });
break;
case 'mn':
- require ([], function () {
- cb (require.context ('js', true, /locale\/mn.yml$/)); });
+ require([], function() {
+ cb(require.context('js', true, /locale\/mn.yml$/));
+ });
break;
case 'pt':
- require ([], function () {
- cb (require.context ('js', true, /locale\/pt.yml$/)); });
+ require([], function() {
+ cb(require.context('js', true, /locale\/pt.yml$/));
+ });
break;
default:
- cb ();
+ cb();
}
}
-function onLocaleLoad (req)
-{
- var keys = req.keys ();
+function onLocaleLoad(req) {
+ var keys = req.keys();
for (var i = 0; i < keys.length; i++)
- Vn.Locale.add (req (keys[i]));
+ Vn.Locale.add(req(keys[i]));
}
diff --git a/forms/account/conf/conf.js b/forms/account/conf/conf.js
index 68188877..4e82f0d4 100644
--- a/forms/account/conf/conf.js
+++ b/forms/account/conf/conf.js
@@ -5,8 +5,6 @@ Hedera.Conf = new Class({
,activate: function() {
this.$('user-model').setInfo('c', 'myClient', 'hedera');
- console.log(this.hash.get('verificationToken'));
-
if (this.hash.get('verificationToken'))
this.onPassChangeClick();
}
@@ -45,17 +43,20 @@ Hedera.Conf = new Class({
this.conn.send('core/restore-password', params,
this._onPassChange.bind(this));
} else {
+ let userId = this.gui.user.id;
params.oldPassword = oldPassword;
- this.conn.send('core/change-password', params,
- this._onPassChange.bind(this));
+ this.conn.lbSend('PATCH',
+ `Accounts/${userId}/changePassword`, params,
+ this._onPassChange.bind(this)
+ );
}
} catch (e) {
Htk.Toast.showError(e.message);
}
}
-
+
,_onPassChange: function(json, error) {
- if (json) {
+ if (!error) {
this.$('change-password').hide();
this.hash.unset('verificationToken');
Htk.Toast.showMessage(_('Password changed!'));
diff --git a/forms/admin/connections/connections.js b/forms/admin/connections/connections.js
index bb5c2993..ff058c12 100644
--- a/forms/admin/connections/connections.js
+++ b/forms/admin/connections/connections.js
@@ -1,52 +1,44 @@
-Hedera.Connections = new Class
-({
+Hedera.Connections = new Class({
Extends: Hedera.Form
,_timeoutId: null
- ,onModelStatusChange: function (model, status)
- {
+ ,onModelStatusChange: function(model) {
if (!model.ready)
return;
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 ()
- {
- clearTimeout (this._timeoutId);
+ ,deactivate: function() {
+ clearTimeout(this._timeoutId);
}
- ,onRefreshClick: function ()
- {
- this.$('sessions').refresh ();
+ ,onRefreshClick: function() {
+ this.$('sessions').refresh();
}
- ,onAccessLogClick: function (button, form)
- {
- this.hash.set ({
- 'form': 'admin/access-log'
- ,'user': form.get ('userId')
+ ,onAccessLogClick: function(button, form) {
+ this.hash.set({
+ form: 'admin/access-log'
+ ,user: form.get('userId')
});
}
- ,onChangeUserClick: function (button, form)
- {
- this.gui.supplantUser (form.get ('user'),
- this._onUserSupplant.bind (this));
+ ,onChangeUserClick: function(button, form) {
+ this.gui.supplantUser(form.get('user'),
+ this._onUserSupplant.bind(this));
}
- ,_onUserSupplant: function (userName)
- {
- this.hash.set ({'form': 'ecomerce/orders'});
+ ,_onUserSupplant: function() {
+ this.hash.set({form: 'ecomerce/orders'});
}
- ,sessionsFunc: function ()
- {
+ ,sessionsFunc: function() {
return 1;
}
});
diff --git a/forms/admin/users/users.js b/forms/admin/users/users.js
index 52a1de8b..ccca530c 100644
--- a/forms/admin/users/users.js
+++ b/forms/admin/users/users.js
@@ -1,18 +1,15 @@
-Hedera.Users = new Class
-({
+Hedera.Users = new Class({
Extends: Hedera.Form
- ,onAccessLogClick: function (button, form)
- {
- this.hash.set ({
+ ,onAccessLogClick: function(button, form) {
+ this.hash.set({
'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')
scope.$('disabled').style.display = isEnabled ?
'none' : 'block';
@@ -20,15 +17,13 @@ Hedera.Users = new Class
'block' : 'none';
}
- ,onChangeUserClick: function (button, form)
- {
- this.gui.supplantUser (form.get ('name'),
- this.onUserSupplant.bind (this));
+ ,onChangeUserClick: function(button, form) {
+ this.gui.supplantUser(form.get('name'),
+ this.onUserSupplant.bind(this));
}
- ,onUserSupplant: function ()
- {
- this.hash.set ({form: 'ecomerce/orders'});
+ ,onUserSupplant: function() {
+ this.hash.set({form: 'ecomerce/orders'});
}
});
diff --git a/forms/ecomerce/ticket/ticket.js b/forms/ecomerce/ticket/ticket.js
index 59a6f408..2204818d 100644
--- a/forms/ecomerce/ticket/ticket.js
+++ b/forms/ecomerce/ticket/ticket.js
@@ -19,11 +19,15 @@ Hedera.Ticket = new Class({
},
onPrintClick: function() {
- var batch = new Sql.Batch();
- batch.addValue('ticket', this.$('ticket-id').value);
- this.gui.openReport('delivery-note', batch);
+ let params = Vn.Url.makeUri({
+ authorization: this.conn.token,
+ ticketId: this.$('ticket-id').value,
+ recipientId: this.gui.user.id,
+ type: 'deliveryNote'
+ });
+ window.open(`/api/report/delivery-note?${params}`);
},
-
+
repeaterFunc: function(res, form) {
var discount = res.$('discount');
discount.style.display = form.get('discount') ? 'inline' : 'none';
diff --git a/js/db/result-set.js b/js/db/result-set.js
index 23d528d5..241a219b 100644
--- a/js/db/result-set.js
+++ b/js/db/result-set.js
@@ -1,19 +1,17 @@
-var Result = require ('./result');
+var Result = require('./result');
/**
* This class stores the database results.
**/
-module.exports = new Class
-({
+module.exports = new Class({
results: null
,error: null
/**
* Initilizes the resultset object.
**/
- ,initialize: function (results, error)
- {
+ ,initialize: function(results, error) {
this.results = results;
this.error = error;
}
@@ -23,19 +21,17 @@ module.exports = new Class
*
* @return {Db.Err} the error or null if no errors hapened
**/
- ,getError: function ()
- {
+ ,getError: function() {
return this.error;
}
- ,fetch: function ()
- {
+ ,fetch: function() {
if (this.error)
throw this.error;
if (this.results !== null
&& this.results.length > 0)
- return this.results.shift ();
+ return this.results.shift();
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
**/
- ,fetchResult: function ()
- {
- var result = this.fetch ();
+ ,fetchResult: function() {
+ var result = this.fetch();
- if (result !== null)
- {
+ if (result !== null) {
if (result.data instanceof Array)
- return new Result (result);
+ return new Result(result);
else
return true;
}
@@ -65,9 +59,8 @@ module.exports = new Class
*
* @return {Array} the row if success, %null otherwise
**/
- ,fetchRow: function ()
- {
- var result = this.fetch ();
+ ,fetchRow: function() {
+ var result = this.fetch();
if (result !== null
&& result.data instanceof Array
@@ -77,14 +70,29 @@ module.exports = new Class
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.
*
* @return {Object} the value if success, %null otherwise
**/
- ,fetchValue: function ()
- {
- var row = this.fetchRow ();
+ ,fetchValue: function() {
+ var row = this.fetchRow();
if (row instanceof Array && row.length > 0)
return row[0];
diff --git a/js/hedera/app.js b/js/hedera/app.js
index 8a3bc433..a27fa926 100644
--- a/js/hedera/app.js
+++ b/js/hedera/app.js
@@ -54,7 +54,7 @@ module.exports = new Class({
this.unref();
}
- ,_onWindowError: function(message, file, line, col, err) {
+ ,_onWindowError: function(message, file, line) {
var error = new Error(message);
error.fileName = file;
error.lineNumber = line;
@@ -68,12 +68,15 @@ module.exports = new Class({
Htk.Toast.showError(_('Invalid login'));
this._logout();
break;
+ case 'Forbidden':
+ Htk.Toast.showError(_('You don\'t have enough privileges'));
+ break;
case 'UserDisabled':
Htk.Toast.showError(_('User disabled'));
this._logout();
break;
case 'SessionExpired':
- Htk.Toast.showError(_('You\'ve been too idle'));
+ Htk.Toast.showError(_('Session expired'));
this._logout();
break;
case 'OutdatedVersion':
@@ -81,6 +84,14 @@ module.exports = new Class({
break;
default:
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 {
console.error(error);
diff --git a/js/hedera/gui.js b/js/hedera/gui.js
index 04177602..1409d1f2 100644
--- a/js/hedera/gui.js
+++ b/js/hedera/gui.js
@@ -48,7 +48,7 @@ module.exports = new Class({
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 url FROM imageConfig;'
+'SELECT dbproduccion FROM vn2008.tblContadores;'
@@ -121,8 +121,8 @@ module.exports = new Class({
,onMainQueryDone: function(resultSet) {
// Retrieving the user name
- var userName = resultSet.fetchValue();
- Vn.Node.setText(this.$('user-name'), userName);
+ this.user = resultSet.fetchObject();
+ Vn.Node.setText(this.$('user-name'), this.user.nickname);
// Retrieving configuration parameters
diff --git a/js/hedera/locale/ca.yml b/js/hedera/locale/ca.yml
index e26b24f7..7ad360ee 100644
--- a/js/hedera/locale/ca.yml
+++ b/js/hedera/locale/ca.yml
@@ -9,7 +9,8 @@ Login phone: +34 607 562 391
Password forgotten? Push here: ¿Has oblidat la teva contrasenya?
Yet you are not a customer?: Encara no ets client?
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: >-
Usuari o contrasenya incorrectes, recorda que s'hi distingeix entre majúscula
i minúscula
diff --git a/js/hedera/locale/en.yml b/js/hedera/locale/en.yml
index ff22a8f9..efe920dd 100644
--- a/js/hedera/locale/en.yml
+++ b/js/hedera/locale/en.yml
@@ -10,7 +10,8 @@ Password forgotten? Push here: Password forgotten? Push here
Yet you are not a customer?: Yet you are not a customer?
Sign up: Sign up
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'
User disabled: >-
Authentication is correct but the user account has been disabled, please
diff --git a/js/hedera/locale/es.yml b/js/hedera/locale/es.yml
index 1c994999..e769c5c5 100644
--- a/js/hedera/locale/es.yml
+++ b/js/hedera/locale/es.yml
@@ -10,7 +10,8 @@ Password forgotten? Push here: ¿Has olvidado tu contraseña?
Yet you are not a customer?: ¿Todavía no eres cliente?
Sign up: Registrarme
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: >-
Usuario o contraseña incorrectos, recuerda que se hace distinción entre
mayúsculas y minúsculas
diff --git a/js/hedera/locale/fr.yml b/js/hedera/locale/fr.yml
index 45d4fa56..db5d4fcc 100644
--- a/js/hedera/locale/fr.yml
+++ b/js/hedera/locale/fr.yml
@@ -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?
Sign up: Inscription
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: >-
Utilisateur ou mot de passe incorrect, n'oubliez pas de distinction entre
majuscules et minuscules
diff --git a/js/hedera/locale/mn.yml b/js/hedera/locale/mn.yml
index 06ee6aac..87c8f0e1 100644
--- a/js/hedera/locale/mn.yml
+++ b/js/hedera/locale/mn.yml
@@ -9,7 +9,6 @@ Login phone: +34 607 562 391
Password forgotten? Push here: Нууц үг мартсан? энд түлхэх
Yet you are not a customer?: Гэсэн хэдий ч та хэрэглэгчийн биш гэж үү?
Sign up: бүртгүүлэх
-You've been too idle: 'Та нар ч бас зогссон байсан, чуулган хугацаа дууссан байна'
Invalid login: 'Хэрэглэгчийн нэр эсвэл нууц үг буруу, Тэр хэргийг мэдрэмтгий гэдгийг санаарай'
Please write your user name: Хэрэглэгчийн нэрээ бичнэ үү
A mail has been sent wich you can recover your password: Мэйл та нууц үгээ сэргээх боломжтой А байна илгээсэн
diff --git a/js/hedera/locale/pt.yml b/js/hedera/locale/pt.yml
index 326d88be..05f68099 100644
--- a/js/hedera/locale/pt.yml
+++ b/js/hedera/locale/pt.yml
@@ -9,7 +9,8 @@ Login phone: +34 963 242 100
Password forgotten? Push here: Não lembro minha palavra-passe
Yet you are not a customer?: Ainda não és cliente?
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: >-
Usuário ou Palavra-Passe incorreto, lembre-se de diferenciar maiusculas e
minusculas
diff --git a/js/hedera/login.js b/js/hedera/login.js
index 3bfc4368..71dbef8f 100644
--- a/js/hedera/login.js
+++ b/js/hedera/login.js
@@ -1,129 +1,112 @@
-var Css = require ('./login.css');
-var Tpl = require ('./login.xml');
+require('./login.css');
+var Tpl = require('./login.xml');
-module.exports = new Class
-({
+module.exports = new Class({
Extends: Htk.Component,
Properties:
{
conn:
{
type: Db.Connection
- ,set: function (x)
- {
- this.link ({_conn: x}, {'loading-changed': this._onConnLoadChange});
+ ,set: function(x) {
+ this.link({_conn: x}, {'loading-changed': this._onConnLoadChange});
}
- ,get: function ()
- {
+ ,get: function() {
return this._conn;
}
}
}
- ,initialize: function (props)
- {
- this.parent (props);
- this.builderInitString (Tpl);
+ ,initialize: function(props) {
+ this.parent(props);
+ this.builderInitString(Tpl);
this.$('social-bar').conn = this._conn;
var self = this;
- this.$('form').onsubmit = function ()
- {
- self._onSubmit ();
+ this.$('form').onsubmit = function() {
+ self._onSubmit();
return false;
};
}
- ,_onConnLoadChange: function (conn, isLoading)
- {
+ ,_onConnLoadChange: function(conn, isLoading) {
if (isLoading)
- this.$('spinner').start ();
+ this.$('spinner').start();
else
- this.$('spinner').stop ();
+ this.$('spinner').stop();
}
- ,show: function ()
- {
- document.body.appendChild (this.node);
+ ,show: function() {
+ document.body.appendChild(this.node);
- var lastUser = localStorage.getItem ('hederaLastUser');
+ var lastUser = localStorage.getItem('hederaLastUser');
if (lastUser)
this.$('user').value = lastUser;
- this._focusUserInput ();
+ this._focusUserInput();
}
- ,_onSubmit: function ()
- {
- this._conn.open (
+ ,_onSubmit: function() {
+ this._conn.open(
this.$('user').value,
this.$('pass').value,
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._disableUi (false);
+ this._disableUi(false);
- if (success)
- {
+ if (success) {
var user = this.$('user').value;
if (user)
- localStorage.setItem ('hederaLastUser', user);
+ localStorage.setItem('hederaLastUser', user);
- this.signalEmit ('login');
- }
- else
- {
- this._focusUserInput ();
+ this.signalEmit('login');
+ } else {
+ this._focusUserInput();
throw error;
}
}
- ,hide: function ()
- {
- Vn.Node.remove (this.node);
+ ,hide: function() {
+ Vn.Node.remove(this.node);
}
- ,_focusUserInput: function ()
- {
+ ,_focusUserInput: function() {
var userEntry = this.$('user');
- userEntry.focus ();
- userEntry.select ();
+ userEntry.focus();
+ userEntry.select();
}
- ,_disableUi: function (disabled)
- {
+ ,_disableUi: function(disabled) {
this.$('user').disabled = disabled;
this.$('pass').disabled = disabled;
this.$('submit').disabled = disabled;
}
- ,onPasswordLost: function ()
- {
+ ,onPasswordLost: function() {
var user = this.$('user').value;
if (!user)
- Htk.Toast.showError (_('Please write your user name'));
+ Htk.Toast.showError(_('Please write your user name'));
else
- this._conn.send ('core/recover-password', {recoverUser: user},
- this._onPasswordRecovered.bind (this));
+ this._conn.send('core/recover-password', {recoverUser: user},
+ this._onPasswordRecovered.bind(this));
}
- ,_onPasswordRecovered: function (json, error)
- {
+ ,_onPasswordRecovered: function(json, error) {
if (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'));
}
});
diff --git a/js/vn/json-connection.js b/js/vn/json-connection.js
index ffd4912a..40939699 100644
--- a/js/vn/json-connection.js
+++ b/js/vn/json-connection.js
@@ -1,12 +1,11 @@
-var Object = require ('./object');
-var JsonException = require ('./json-exception');
+var Object = require('./object');
+var JsonException = require('./json-exception');
/**
* Handler for JSON rest connections.
**/
-module.exports = new Class
-({
+module.exports = new Class({
Extends: Object
,_connected: false
@@ -16,29 +15,26 @@ module.exports = new Class
/**
* Initilizes the connection object.
**/
- ,initialize: function ()
- {
- this.parent ();
- this.fetchToken ();
+ ,initialize: function() {
+ this.parent();
+ this.fetchToken();
}
- ,fetchToken: function ()
- {
+ ,fetchToken: function() {
var token = null;
- if (sessionStorage.getItem ('vnToken'))
- token = sessionStorage.getItem ('vnToken');
- if (localStorage.getItem ('vnToken'))
- token = localStorage.getItem ('vnToken');
+ if (sessionStorage.getItem('vnToken'))
+ token = sessionStorage.getItem('vnToken');
+ if (localStorage.getItem('vnToken'))
+ token = localStorage.getItem('vnToken');
this.token = token;
}
- ,clearToken: function ()
- {
+ ,clearToken: function() {
this.token = null;
- localStorage.removeItem ('vnToken');
- sessionStorage.removeItem ('vnToken');
+ localStorage.removeItem('vnToken');
+ sessionStorage.removeItem('vnToken');
}
/**
@@ -49,43 +45,37 @@ module.exports = new Class
* @param {Boolean} remember Specifies if the user should be remembered
* @param {Function} openCallback The function to call when operation is done
**/
- ,open: function (user, pass, remember, callback)
- {
- if (user !== null && user !== undefined)
- {
+ ,open: function(user, pass, remember, callback) {
+ if (user !== null && user !== undefined) {
var params = {
user: user
,password: pass
,remember: remember
};
- }
- else
+ } else
var params = null;
- this.send ('core/login', params,
- this._onOpen.bind (this, callback, remember));
+ this.lbSend('POST', 'Accounts/login', params,
+ this._onOpen.bind(this, callback, remember));
}
/*
* Called when open operation is done.
*/
- ,_onOpen: function (callback, remember, json, error)
- {
- if (json && json.login)
- {
+ ,_onOpen: function(callback, remember, json, error) {
+ if (json) {
this._connected = true;
this.token = json.token;
var storage = remember ? localStorage : sessionStorage;
- storage.setItem ('vnToken', this.token);
+ storage.setItem('vnToken', this.token);
- this.signalEmit ('openned');
- }
- else
- this._closeClient ();
+ this.signalEmit('openned');
+ } else
+ this._closeClient();
if (callback)
- callback (this, this._connected, error);
+ callback(this, this._connected, error);
}
/**
@@ -93,58 +83,52 @@ module.exports = new Class
*
* @param {Function} callback The function to call when operation is done
**/
- ,close: function (callback)
- {
- this._closeClient ();
- this.send ('core/logout', null,
- this._onClose.bind (this, callback));
+ ,close: function(callback) {
+ this.lbSend('POST', 'Accounts/logout', null,
+ this._onClose.bind(this, callback));
+ this._closeClient();
}
/*
* Called when close operation is done.
*/
- ,_onClose: function (callback, json, error)
- {
- this.signalEmit ('closed');
+ ,_onClose: function(callback, json, error) {
+ this.signalEmit('closed');
if (callback)
- callback (this, json === true, error);
+ callback(this, null, error);
}
- ,_closeClient: function ()
- {
+ ,_closeClient: function() {
this._connected = false;
- this.clearToken ();
+ this.clearToken();
}
/**
- * Suppants another user.
+ * Supplants another user.
*
* @param {String} user The user name
* @param {Function} callback The callback function
**/
- ,supplantUser: function (user, callback)
- {
+ ,supplantUser: function(user, callback) {
var params = {supplantUser: user};
- this.send ('core/supplant', params,
- this._onUserSupplant.bind (this, callback));
+ this.send('client/supplant', params,
+ this._onUserSupplant.bind(this, callback));
}
- ,_onUserSupplant: function (callback, json, error)
- {
+ ,_onUserSupplant: function(callback, json) {
if (json)
this.token = json;
if (callback)
- callback (json != null);
+ callback(json != null);
}
/**
* Ends the user supplanting and restores the last login.
**/
- ,supplantEnd: function ()
- {
- this.fetchToken ();
+ ,supplantEnd: function() {
+ this.fetchToken();
}
/**
@@ -155,18 +139,16 @@ module.exports = new Class
* @param {Map} params The params to pass to the service
* @param {Function} callback The response callback
**/
- ,send: function (restService, params, callback)
- {
+ ,send: function(restService, params, callback) {
if (!params)
params = {};
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 elements = form.elements;
@@ -174,83 +156,88 @@ module.exports = new Class
if (elements[i].name)
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)
- {
- var formData = new FormData (form);
+ ,sendFormMultipart: function(form, callback) {
+ var formData = new FormData(form);
+ var request = new XMLHttpRequest();
+ request.open('POST', form.action, true);
if (this.token)
- formData.append ('token', this.token);
-
- var request = new XMLHttpRequest ();
- request.open ('POST', form.action, true);
+ request.setRequestHeader('Authorization', this.token);
request.onreadystatechange =
- this._onStateChange.bind (this, request, callback);
- request.send (formData);
+ this._onStateChange.bind(this, request, callback);
+ 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)
- formData.append ('token', this.token);
-
- var request = new XMLHttpRequest ();
- request.open ('POST', '', true);
+ request.setRequestHeader('Authorization', this.token);
request.onreadystatechange =
- this._onStateChange.bind (this, request, callback);
- request.send (formData);
+ this._onStateChange.bind(this, request, callback);
+ request.send(formData);
- this._addRequest ();
+ this._addRequest();
}
/*
* Called when REST response is received.
*/
- ,sendWithUrl: function (params, callback, method, url)
- {
- if (this.token)
- params['token'] = this.token;
-
- var request = new XMLHttpRequest ();
- request.open (method, url, true);
- request.setRequestHeader ('Content-Type',
+ ,sendWithUrl: function(params, callback, method, url) {
+ var request = new XMLHttpRequest();
+ request.open(method, url, true);
+ request.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
+ if (this.token)
+ request.setRequestHeader('Authorization', this.token);
request.onreadystatechange =
- this._onStateChange.bind (this, request, callback);
- request.send (Vn.Url.makeUri (params));
+ this._onStateChange.bind(this, request, callback);
+ 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++;
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)
return;
this._requestsCount--;
if (this._requestsCount === 0)
- this.signalEmit ('loading-changed', false);
+ this.signalEmit('loading-changed', false);
var data = null;
var error = null;
try {
- if (request.status == 0)
- {
- var ex = new JsonException ();
+ if (request.status == 0) {
+ var ex = new JsonException();
ex.message = _('The server does not respond, please check your Internet connection');
throw ex;
}
@@ -259,70 +246,75 @@ module.exports = new Class
try {
contentType = request
- .getResponseHeader ('Content-Type')
- .split (';')[0]
- .trim ();
+ .getResponseHeader('Content-Type')
+ .split(';')[0]
+ .trim();
+ } catch (err) {
+ console.warn(err);
}
- catch (e) {}
- if (contentType != 'application/json')
- {
- var ex = new JsonException ();
+ if (contentType != 'application/json') {
+ var ex = new JsonException();
ex.message = request.statusText;
ex.code = request.status;
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 ();
- ex.exception = exception;
- ex.message = jsData.message;
- ex.code = jsData.code;
- ex.file = jsData.file;
- ex.line = jsData.line;
- ex.trace = jsData.trace;
+ var json;
+ var jsData;
+
+ if (request.responseText)
+ json = JSON.parse(request.responseText);
+ if (json)
+ 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;
}
- }
- catch (e)
- {
+ } catch (e) {
data = null;
error = e;
}
if (callback)
try {
- callback (data, error);
+ callback(data, error);
error = null;
- }
- catch (e)
- {
+ } catch (e) {
error = e;
}
- if (error)
- {
+ if (error) {
if (error.exception == 'SessionExpired')
- this.clearToken ();
+ this.clearToken();
- this.signalEmit ('error', error);
+ this.signalEmit('error', error);
}
}
});
diff --git a/rest/client/supplant.php b/rest/client/supplant.php
new file mode 100644
index 00000000..4b2dbf49
--- /dev/null
+++ b/rest/client/supplant.php
@@ -0,0 +1,30 @@
+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']);
+ }
+}
diff --git a/rest/core/change-password.php b/rest/core/change-password.php
deleted file mode 100644
index 4897d4f5..00000000
--- a/rest/core/change-password.php
+++ /dev/null
@@ -1,21 +0,0 @@
-query('CALL account.myUser_changePassword(#, #)',
- [$oldPassword, $newPassword]);
- Account::sync($db, $_SESSION['user'], $newPassword);
- return TRUE;
- }
-}
-
diff --git a/rest/core/login.php b/rest/core/login.php
deleted file mode 100644
index b9c58dd2..00000000
--- a/rest/core/login.php
+++ /dev/null
@@ -1,30 +0,0 @@
-getMessage());
- }
-
- $token = $this->service->createToken(
- $_SESSION['user'],
- !empty($_POST['remember'])
- );
-
- return [
- 'login' => TRUE,
- 'token' => $token
- ];
- }
-}
-
diff --git a/rest/core/logout.php b/rest/core/logout.php
deleted file mode 100644
index 632c5461..00000000
--- a/rest/core/logout.php
+++ /dev/null
@@ -1,9 +0,0 @@
-service->logout();
- return TRUE;
- }
-}
-
diff --git a/rest/core/supplant.php b/rest/core/supplant.php
index 885f6d66..8b471567 100644
--- a/rest/core/supplant.php
+++ b/rest/core/supplant.php
@@ -7,4 +7,3 @@ class Supplant extends Vn\Web\JsonRequest {
return $this->service->createToken($_REQUEST['supplantUser']);
}
}
-
diff --git a/rest/core/sync-user.php b/rest/core/sync-user.php
deleted file mode 100644
index b85639dc..00000000
--- a/rest/core/sync-user.php
+++ /dev/null
@@ -1,17 +0,0 @@
-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;
- }
- }
-}
-
diff --git a/rest/misc/sms.php b/rest/misc/sms.php
deleted file mode 100644
index 7be046a7..00000000
--- a/rest/misc/sms.php
+++ /dev/null
@@ -1,52 +0,0 @@
-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;
- }
-}
diff --git a/web/rest-service.php b/web/rest-service.php
index 3677cf52..5c0ed716 100644
--- a/web/rest-service.php
+++ b/web/rest-service.php
@@ -31,13 +31,12 @@ class RestService extends Service {
$_REQUEST['method'], $class, './rest');
$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) {
- $isAuthorized = $db->getValue('SELECT myUser_checkRestPriv(#)',
- [$_REQUEST['method']]);
-
- if (!$isAuthorized)
- throw new UserException(s('You don\'t have enough privileges'));
-
$methodDb = $db;
} else
$methodDb = $this->getUserDb($_SESSION['user']);
@@ -71,6 +70,8 @@ class RestService extends Service {
$status = 401;
} catch (BadLoginException $e) {
$status = 401;
+ } catch (ForbiddenException $e) {
+ $status = 403;
} catch (Lib\UserException $e) {
$status = 400;
} catch (\Exception $e) {
diff --git a/web/service.php b/web/service.php
index 5df829f1..abaa439b 100644
--- a/web/service.php
+++ b/web/service.php
@@ -21,6 +21,11 @@ class SessionExpiredException extends UserException {}
*/
class BadLoginException extends UserException {}
+/**
+ * Thrown when user credentials are invalid.
+ */
+class ForbiddenException extends UserException {}
+
/**
* Thrown when user credentials are invalid.
*/
@@ -130,62 +135,26 @@ abstract class Service {
*/
function login() {
$db = $this->db;
- $anonymousUser = FALSE;
-
- if (isset($_POST['user']) && !empty($_POST['password'])) {
- $user = strtolower($_POST['user']);
+ $anonymousUser = TRUE;
- $passwordHash = $db->getValue(
- 'SELECT bcryptPassword FROM account.user WHERE `name` = #',
- [$user]
+ if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
+ $userId = $db->getValue(
+ 'SELECT userId FROM salix.AccessToken
+ WHERE id = #
+ AND NOW() <= TIMESTAMPADD(SECOND, ttl, created)',
+ [$_SERVER['HTTP_AUTHORIZATION']]
);
- $passwordOk = !empty($passwordHash)
- && password_verify($_POST['password'], $passwordHash);
+ if (!$userId)
+ throw new SessionExpiredException();
- // XXX: Compatibility with old MD5 passwords
- if (empty($passwordHash)) {
- $md5Password = $db->getValue(
- 'SELECT `password` FROM account.user
- WHERE active AND `name` = #',
- [$user]
- );
-
- $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;
- }
- }
+ $anonymousUser = FALSE;
+ $user = $db->getValue(
+ 'SELECT `name` FROM account.user WHERE id = #',
+ [$userId]
+ );
+ } else
+ $user = $db->getValue('SELECT guestUser FROM config');
if (!$anonymousUser) {
$isActive = $db->getValue(
@@ -217,9 +186,15 @@ abstract class Service {
* Logouts the current user. Cleans the last saved used credentials.
*/
function logout() {
+ if (!empty($_SERVER['HTTP_AUTHORIZATION']))
+ $db->query(
+ 'DELETE FROM salix.AccessToken WHERE id = #',
+ [$_SERVER['HTTP_AUTHORIZATION']]
+ );
+
unset($_SESSION['user']);
}
-
+
/**
* Creates or returns a database connection where the authenticated user
* is the role of the current logged user.
diff --git a/webpack.config.js b/webpack.config.js
index f64116ba..9d7845b9 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -42,15 +42,15 @@ var baseConfig = {
new webpack.DefinePlugin({
_DEV_MODE: devMode,
_DEV_SERVER_PORT: wpConfig.devServerPort,
- _PUBLIC_PATH: JSON.stringify (publicPath)
+ _PUBLIC_PATH: JSON.stringify(publicPath)
})
],
- optimization: {
- runtimeChunk: true,
- splitChunks: {
- chunks: 'all',
- }
- },
+ optimization: {
+ runtimeChunk: true,
+ splitChunks: {
+ chunks: 'all',
+ }
+ },
watchOptions: {
ignored: /node_modules/
}
@@ -78,8 +78,12 @@ var devConfig = {
devServer: {
host: '0.0.0.0',
port: wpConfig.devServerPort,
- headers: { 'Access-Control-Allow-Origin': '*' },
- stats: { chunks: false }
+ headers: {'Access-Control-Allow-Origin': '*'},
+ stats: { chunks: false },
+ proxy: {
+ '/api': 'http://localhost:3000',
+ '/': 'http://localhost/projects/hedera-web'
+ }
},
devtool: 'eval'
};
From 4bb31e9dd3fba3bca3498022c599c14b0e1882ab Mon Sep 17 00:00:00 2001
From: Juan Ferrer Toribio
Date: Mon, 9 May 2022 15:52:29 +0200
Subject: [PATCH 2/4] #3806 Supplant fixes
---
forms/admin/items/ui.xml | 2 +-
forms/admin/users/ui.xml | 2 +-
forms/ecomerce/catalog/ui.xml | 2 +-
forms/ecomerce/orders/ui.xml | 2 +-
forms/ecomerce/ticket/ui.xml | 4 ++--
js/vn/json-connection.js | 1 +
reports/delivery-note/ui.xml | 2 +-
web/service.php | 36 +++++++++++++++++++++++++++++++++--
web/uid.php | 14 ++++++++++++++
webpack.config.js | 5 ++++-
10 files changed, 60 insertions(+), 10 deletions(-)
create mode 100644 web/uid.php
diff --git a/forms/admin/items/ui.xml b/forms/admin/items/ui.xml
index acd3aba4..41fbf780 100644
--- a/forms/admin/items/ui.xml
+++ b/forms/admin/items/ui.xml
@@ -50,7 +50,7 @@
- @
+ #
diff --git a/forms/admin/users/ui.xml b/forms/admin/users/ui.xml
index 088cac9d..0b41e395 100644
--- a/forms/admin/users/ui.xml
+++ b/forms/admin/users/ui.xml
@@ -50,7 +50,7 @@
- @ -
+ # -
diff --git a/forms/ecomerce/catalog/ui.xml b/forms/ecomerce/catalog/ui.xml
index f6780139..d7ea6de6 100644
--- a/forms/ecomerce/catalog/ui.xml
+++ b/forms/ecomerce/catalog/ui.xml
@@ -406,7 +406,7 @@
- @
+ #
diff --git a/forms/ecomerce/orders/ui.xml b/forms/ecomerce/orders/ui.xml
index b035a2fd..e64c70e0 100644
--- a/forms/ecomerce/orders/ui.xml
+++ b/forms/ecomerce/orders/ui.xml
@@ -56,7 +56,7 @@
- @
+ #
diff --git a/forms/ecomerce/ticket/ui.xml b/forms/ecomerce/ticket/ui.xml
index 0901920f..c14ff6fa 100644
--- a/forms/ecomerce/ticket/ui.xml
+++ b/forms/ecomerce/ticket/ui.xml
@@ -27,7 +27,7 @@
- @
+ #
Preparation
@@ -151,7 +151,7 @@
- @
+ #
diff --git a/js/vn/json-connection.js b/js/vn/json-connection.js
index 40939699..7e981ad7 100644
--- a/js/vn/json-connection.js
+++ b/js/vn/json-connection.js
@@ -128,6 +128,7 @@ module.exports = new Class({
* Ends the user supplanting and restores the last login.
**/
,supplantEnd: function() {
+ this.lbSend('POST', 'Accounts/logout');
this.fetchToken();
}
diff --git a/reports/delivery-note/ui.xml b/reports/delivery-note/ui.xml
index 452bb5e4..23f95654 100644
--- a/reports/delivery-note/ui.xml
+++ b/reports/delivery-note/ui.xml
@@ -8,7 +8,7 @@
- @
+ #