This commit is contained in:
Yuri Kuznetsov
2021-01-28 16:02:47 +02:00
parent f487479b1d
commit 5189f6b392
2 changed files with 95 additions and 29 deletions
+94 -28
View File
@@ -90,7 +90,7 @@ define(
this.id = options.id || 'espocrm-application-id'; this.id = options.id || 'espocrm-application-id';
this.useCache = options.useCache || this.useCache; this.useCache = options.useCache || this.useCache;
this.url = options.url || this.url; this.apiUrl = options.apiUrl || this.apiUrl;
this.basePath = options.basePath || ''; this.basePath = options.basePath || '';
this.ajaxTimeout = options.ajaxTimeout || 0; this.ajaxTimeout = options.ajaxTimeout || 0;
@@ -98,6 +98,7 @@ define(
this.appParams = {}; this.appParams = {};
this.loader = Espo.loader; this.loader = Espo.loader;
this.loader.basePath = this.basePath; this.loader.basePath = this.basePath;
this.controllers = {}; this.controllers = {};
@@ -188,7 +189,7 @@ define(
loader: null, loader: null,
url: 'api/v1', apiUrl: 'api/v1',
auth: null, auth: null,
@@ -357,31 +358,47 @@ define(
getController: function (name, callback) { getController: function (name, callback) {
if (!(name || false)) { if (!(name || false)) {
callback(this.baseController); callback(this.baseController);
return; return;
} }
if (!(name in this.controllers)) {
try { if (name in this.controllers) {
var className = this.metadata.get('clientDefs.' + name + '.controller'); callback(this.controllers[name]);
if (!className) { }
var module = this.metadata.get('scopes.' + name + '.module');
className = Espo.Utils.composeClassName(module, name, 'controllers'); try {
} var className = this.metadata.get('clientDefs.' + name + '.controller');
Espo.require(className, function (controllerClass) {
if (!className) {
var module = this.metadata.get('scopes.' + name + '.module');
className = Espo.Utils.composeClassName(module, name, 'controllers');
}
Espo.require(
className,
function (controllerClass) {
var injections = this.getControllerInjection(); var injections = this.getControllerInjection();
injections.baseController = this.baseController; injections.baseController = this.baseController;
this.controllers[name] = new controllerClass(this.baseController.params, injections); this.controllers[name] = new controllerClass(this.baseController.params, injections);
this.controllers[name].name = name; this.controllers[name].name = name;
this.controllers[name].masterView = this.masterView; this.controllers[name].masterView = this.masterView;
callback(this.controllers[name]); callback(this.controllers[name]);
}, this, function () { },
this,
function () {
this.baseController.error404(); this.baseController.error404();
}.bind(this)); }.bind(this)
return; );
} catch (e) {
this.baseController.error404(); return;
} }
catch (e) {
this.baseController.error404();
} }
callback(this.controllers[name]);
}, },
preLoad: function (callback) { preLoad: function (callback) {
@@ -439,13 +456,19 @@ define(
if (~name.indexOf('.')) { if (~name.indexOf('.')) {
console.warn(name + ': template name should use slashes for a directory separator.'); console.warn(name + ': template name should use slashes for a directory separator.');
} }
path = 'res/templates/' + name.split('.').join('/') + '.tpl'; path = 'res/templates/' + name.split('.').join('/') + '.tpl';
break; break;
case 'layoutTemplate': case 'layoutTemplate':
path = 'res/layout-types/' + name + '.tpl'; path = 'res/layout-types/' + name + '.tpl';
break; break;
case 'layout': case 'layout':
path = 'res/layouts/' + name + '.json'; path = 'res/layouts/' + name + '.json';
break; break;
} }
return path; return path;
@@ -453,10 +476,14 @@ define(
var getResourcePath = function (type, name) { var getResourcePath = function (type, name) {
var path; var path;
if (name.indexOf(':') != -1) { if (name.indexOf(':') != -1) {
var arr = name.split(':'); var arr = name.split(':');
name = arr[1]; name = arr[1];
var mod = arr[0]; var mod = arr[0];
if (mod == 'custom') { if (mod == 'custom') {
path = 'client/custom/' + getResourceInnerPath(type, name); path = 'client/custom/' + getResourceInnerPath(type, name);
} else { } else {
@@ -465,6 +492,7 @@ define(
} else { } else {
path = 'client/' + getResourceInnerPath(type, name); path = 'client/' + getResourceInnerPath(type, name);
} }
return path; return path;
}.bind(this); }.bind(this);
@@ -493,6 +521,7 @@ define(
this.baseController.on('login', function (data) { this.baseController.on('login', function (data) {
this.auth = Base64.encode(data.auth.userName + ':' + data.auth.token); this.auth = Base64.encode(data.auth.userName + ':' + data.auth.token);
this.storage.set('user', 'auth', this.auth); this.storage.set('user', 'auth', this.auth);
this.setCookieAuth(data.auth.userName, data.auth.token); this.setCookieAuth(data.auth.userName, data.auth.token);
@@ -511,6 +540,7 @@ define(
logout: function () { logout: function () {
if (this.auth) { if (this.auth) {
var arr = Base64.decode(this.auth).split(':'); var arr = Base64.decode(this.auth).split(':');
if (arr.length > 1) { if (arr.length > 1) {
Espo.Ajax.postRequest('App/action/destroyAuthToken', { Espo.Ajax.postRequest('App/action/destroyAuthToken', {
token: arr[1] token: arr[1]
@@ -523,19 +553,26 @@ define(
} }
this.auth = null; this.auth = null;
this.user.clear(); this.user.clear();
this.preferences.clear(); this.preferences.clear();
this.acl.clear(); this.acl.clear();
this.storage.clear('user', 'auth'); this.storage.clear('user', 'auth');
this.doAction({action: 'login'}); this.doAction({action: 'login'});
this.unsetCookieAuth(); this.unsetCookieAuth();
xhr = new XMLHttpRequest; xhr = new XMLHttpRequest;
xhr.open('GET', this.basePath + this.url + '/'); xhr.open('GET', this.basePath + this.apiUrl + '/');
xhr.setRequestHeader('Authorization', 'Basic ' + Base64.encode('**logout:logout')); xhr.setRequestHeader('Authorization', 'Basic ' + Base64.encode('**logout:logout'));
xhr.send(''); xhr.send('');
xhr.abort(); xhr.abort();
this.loadStylesheet(); this.loadStylesheet();
@@ -550,7 +587,9 @@ define(
setCookieAuth: function (username, token) { setCookieAuth: function (username, token) {
var date = new Date(); var date = new Date();
date.setTime(date.getTime() + (1000 * 24*60*60*1000)); date.setTime(date.getTime() + (1000 * 24*60*60*1000));
document.cookie = 'auth-username='+username+'; SameSite=Lax; expires='+date.toGMTString()+'; path=/'; document.cookie = 'auth-username='+username+'; SameSite=Lax; expires='+date.toGMTString()+'; path=/';
document.cookie = 'auth-token='+token+'; SameSite=Lax; expires='+date.toGMTString()+'; path=/'; document.cookie = 'auth-token='+token+'; SameSite=Lax; expires='+date.toGMTString()+'; path=/';
}, },
@@ -571,6 +610,7 @@ define(
resolve(); resolve();
return; return;
}; };
this.requestUserData(function (data) { this.requestUserData(function (data) {
options = data; options = data;
resolve(); resolve();
@@ -579,6 +619,7 @@ define(
]).then(function () { ]).then(function () {
(new Promise(function (resolve) { (new Promise(function (resolve) {
this.language.name = options.language; this.language.name = options.language;
this.language.load(function () { this.language.load(function () {
resolve(); resolve();
}.bind(this)); }.bind(this));
@@ -607,7 +648,7 @@ define(
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open('GET', this.basePath + this.url + '/'); xhr.open('GET', this.basePath + this.apiUrl + '/');
xhr.setRequestHeader('Authorization', 'Basic ' + this.auth); xhr.setRequestHeader('Authorization', 'Basic ' + this.auth);
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
@@ -615,6 +656,7 @@ define(
var arr = Base64.decode(this.auth).split(':'); var arr = Base64.decode(this.auth).split(':');
this.setCookieAuth(arr[0], arr[1]); this.setCookieAuth(arr[0], arr[1]);
callback(); callback();
} }
}.bind(this); }.bind(this);
@@ -630,30 +672,32 @@ define(
setupAjax: function () { setupAjax: function () {
var self = this; var self = this;
$.ajaxSetup({ $.ajaxSetup({
beforeSend: function (xhr, options) { beforeSend: function (xhr, options) {
if (!options.local && self.url) { if (!options.local && this.apiUrl) {
options.url = Espo.Utils.trimSlash(self.url) + '/' + options.url; options.url = Espo.Utils.trimSlash(this.apiUrl) + '/' + options.url;
} }
if (!options.local && self.basePath !== '') { if (!options.local && this.basePath !== '') {
options.url = self.basePath + options.url; options.url = this.basePath + options.url;
} }
if (self.auth !== null) { if (this.auth !== null) {
xhr.setRequestHeader('Authorization', 'Basic ' + self.auth); xhr.setRequestHeader('Authorization', 'Basic ' + this.auth);
xhr.setRequestHeader('Espo-Authorization', self.auth); xhr.setRequestHeader('Espo-Authorization', this.auth);
xhr.setRequestHeader('Espo-Authorization-By-Token', true); xhr.setRequestHeader('Espo-Authorization-By-Token', true);
} }
}, }.bind(this),
dataType: 'json', dataType: 'json',
timeout: this.ajaxTimeout, timeout: this.ajaxTimeout,
contentType: 'application/json' contentType: 'application/json',
}); });
$(document).ajaxError(function (event, xhr, options) { $(document).ajaxError(function (event, xhr, options) {
if (xhr.errorIsHandled) { if (xhr.errorIsHandled) {
return; return;
} }
var statusReason = xhr.getResponseHeader('X-Status-Reason'); var statusReason = xhr.getResponseHeader('X-Status-Reason');
switch (xhr.status) { switch (xhr.status) {
@@ -661,11 +705,15 @@ define(
if (xhr.statusText == 'timeout') { if (xhr.statusText == 'timeout') {
Espo.Ui.error(self.language.translate('Timeout')); Espo.Ui.error(self.language.translate('Timeout'));
} }
break; break;
case 200: case 200:
Espo.Ui.error(self.language.translate('Bad server response')); Espo.Ui.error(self.language.translate('Bad server response'));
console.error('Bad server response: ' + xhr.responseText); console.error('Bad server response: ' + xhr.responseText);
break; break;
case 401: case 401:
if (!options.login) { if (!options.login) {
if (self.auth) { if (self.auth) {
@@ -674,41 +722,59 @@ define(
console.error('Error 401: Unauthorized.'); console.error('Error 401: Unauthorized.');
} }
} }
break; break;
case 403: case 403:
if (options.main) { if (options.main) {
self.baseController.error403(); self.baseController.error403();
} else { } else {
var msg = self.language.translate('Error') + ' ' + xhr.status; var msg = self.language.translate('Error') + ' ' + xhr.status;
msg += ': ' + self.language.translate('Access denied'); msg += ': ' + self.language.translate('Access denied');
if (statusReason) { if (statusReason) {
msg += ': ' + statusReason; msg += ': ' + statusReason;
} }
Espo.Ui.error(msg); Espo.Ui.error(msg);
} }
break; break;
case 400: case 400:
var msg = self.language.translate('Error') + ' ' + xhr.status; var msg = self.language.translate('Error') + ' ' + xhr.status;
msg += ': ' + self.language.translate('Bad request'); msg += ': ' + self.language.translate('Bad request');
if (statusReason) { if (statusReason) {
msg += ': ' + statusReason; msg += ': ' + statusReason;
} }
Espo.Ui.error(msg); Espo.Ui.error(msg);
break; break;
case 404: case 404:
if (options.main) { if (options.main) {
self.baseController.error404(); self.baseController.error404();
} else { } else {
var msg = self.language.translate('Error') + ' ' + xhr.status; var msg = self.language.translate('Error') + ' ' + xhr.status;
msg += ': ' + self.language.translate('Not found'); msg += ': ' + self.language.translate('Not found');
Espo.Ui.error(msg); Espo.Ui.error(msg);
} }
break; break;
default: default:
var msg = self.language.translate('Error') + ' ' + xhr.status; var msg = self.language.translate('Error') + ' ' + xhr.status;
if (statusReason) { if (statusReason) {
msg += ': ' + statusReason; msg += ': ' + statusReason;
} }
Espo.Ui.error(msg); Espo.Ui.error(msg);
} }
+1 -1
View File
@@ -21,7 +21,7 @@
useCache: {{useCache}}, useCache: {{useCache}},
cacheTimestamp: {{cacheTimestamp}}, cacheTimestamp: {{cacheTimestamp}},
basePath: '{{basePath}}', basePath: '{{basePath}}',
url: '{{apiUrl}}', apiUrl: '{{apiUrl}}',
ajaxTimeout: {{ajaxTimeout}}, ajaxTimeout: {{ajaxTimeout}},
}, function (app) { }, function (app) {
{{runScript}} {{runScript}}