mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-07 15:27:43 +08:00
e01e484259
This allows us to use jquery.slim (and cash-dom in the future)
258 lines
6.7 KiB
JavaScript
258 lines
6.7 KiB
JavaScript
import window from 'window';
|
|
|
|
import { TOKEN_ERROR_LIMIT, AJAX_ERROR_LIMIT, DEFAULT_AJAX_TIMEOUT } from 'Common/Consts';
|
|
import { StorageResultType, Notification } from 'Common/Enums';
|
|
import { pInt, pString, isUnd } from 'Common/Utils';
|
|
import { data as GlobalsData } from 'Common/Globals';
|
|
import { ajax } from 'Common/Links';
|
|
import { runHook } from 'Common/Plugins';
|
|
|
|
import * as Settings from 'Storage/Settings';
|
|
|
|
class AbstractAjaxRemote {
|
|
constructor() {
|
|
this.oRequests = {};
|
|
}
|
|
|
|
abort(sAction, bClearOnly) {
|
|
if (this.oRequests[sAction]) {
|
|
if (!bClearOnly && this.oRequests[sAction].abort) {
|
|
// this.oRequests[sAction].__aborted = true;
|
|
this.oRequests[sAction].abort();
|
|
}
|
|
|
|
this.oRequests[sAction] = null;
|
|
delete this.oRequests[sAction];
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* @param {?Function} fCallback
|
|
* @param {string} sRequestAction
|
|
* @param {string} sType
|
|
* @param {?AjaxJsonDefaultResponse} oData
|
|
* @param {boolean} bCached
|
|
* @param {*=} oRequestParameters
|
|
*/
|
|
defaultResponse(fCallback, sRequestAction, sType, oData, bCached, oRequestParameters) {
|
|
const fCall = () => {
|
|
if (StorageResultType.Success !== sType && GlobalsData.bUnload) {
|
|
sType = StorageResultType.Unload;
|
|
}
|
|
|
|
if (StorageResultType.Success === sType && oData && !oData.Result) {
|
|
const err = oData ? oData.ErrorCode : null;
|
|
if (err) {
|
|
window.console.log('AbstractAjaxRemote ' + sRequestAction + ' request failed:', err, Notification.getKeyByValue(err));
|
|
}
|
|
if (
|
|
oData && [
|
|
Notification.AuthError,
|
|
Notification.AccessError,
|
|
Notification.ConnectionError,
|
|
Notification.DomainNotAllowed,
|
|
Notification.AccountNotAllowed,
|
|
Notification.MailServerError,
|
|
Notification.UnknownNotification,
|
|
Notification.UnknownError
|
|
].includes(err)
|
|
) {
|
|
++GlobalsData.iAjaxErrorCount;
|
|
}
|
|
|
|
if (oData && Notification.InvalidToken === err) {
|
|
++GlobalsData.iTokenErrorCount;
|
|
}
|
|
|
|
if (TOKEN_ERROR_LIMIT < GlobalsData.iTokenErrorCount) {
|
|
if (GlobalsData.__APP__ && GlobalsData.__APP__.loginAndLogoutReload) {
|
|
GlobalsData.__APP__.loginAndLogoutReload(false, true);
|
|
}
|
|
}
|
|
|
|
if (oData.ClearAuth || oData.Logout || AJAX_ERROR_LIMIT < GlobalsData.iAjaxErrorCount) {
|
|
if (GlobalsData.__APP__ && GlobalsData.__APP__.clearClientSideToken) {
|
|
GlobalsData.__APP__.clearClientSideToken();
|
|
|
|
if (!oData.ClearAuth && GlobalsData.__APP__.loginAndLogoutReload) {
|
|
GlobalsData.__APP__.loginAndLogoutReload(false, true);
|
|
}
|
|
}
|
|
}
|
|
} else if (StorageResultType.Success === sType && oData && oData.Result) {
|
|
GlobalsData.iAjaxErrorCount = 0;
|
|
GlobalsData.iTokenErrorCount = 0;
|
|
}
|
|
|
|
runHook('ajax-default-response', [
|
|
sRequestAction,
|
|
StorageResultType.Success === sType ? oData : null,
|
|
sType,
|
|
bCached,
|
|
oRequestParameters
|
|
]);
|
|
|
|
if (fCallback) {
|
|
fCallback(
|
|
sType,
|
|
StorageResultType.Success === sType ? oData : null,
|
|
bCached,
|
|
sRequestAction,
|
|
oRequestParameters
|
|
);
|
|
}
|
|
};
|
|
|
|
switch (sType) {
|
|
case 'success':
|
|
sType = StorageResultType.Success;
|
|
break;
|
|
case 'abort':
|
|
sType = StorageResultType.Abort;
|
|
break;
|
|
default:
|
|
sType = StorageResultType.Error;
|
|
break;
|
|
}
|
|
|
|
if (StorageResultType.Error === sType) {
|
|
setTimeout(fCall, 300);
|
|
} else {
|
|
fCall();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {?Function} fResultCallback
|
|
* @param {Object} oParameters
|
|
* @param {?number=} iTimeOut = 20000
|
|
* @param {string=} sGetAdd = ''
|
|
* @param {Array=} aAbortActions = []
|
|
* @returns {jQuery.jqXHR}
|
|
*/
|
|
ajaxRequest(fResultCallback, params, iTimeOut = 20000, sGetAdd = '', abortActions = []) {
|
|
params = params || {};
|
|
const isPost = '' === sGetAdd,
|
|
start = new window.Date().getTime(),
|
|
action = params.Action || '';
|
|
|
|
if (action && abortActions) {
|
|
abortActions.forEach(actionToAbort => this.abort(actionToAbort));
|
|
}
|
|
|
|
let init = {
|
|
mode: 'same-origin',
|
|
cache: 'no-cache',
|
|
redirect: 'error',
|
|
referrerPolicy: 'no-referrer',
|
|
credentials: 'same-origin'
|
|
};
|
|
if (isPost) {
|
|
init.method = 'POST';
|
|
init.headers = {
|
|
// 'Content-Type': 'application/json'
|
|
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
|
};
|
|
params.XToken = Settings.appSettingsGet('token');
|
|
// init.body = JSON.stringify(params);
|
|
const formData = new window.FormData();
|
|
Object.keys(params).forEach(key => {
|
|
formData.append(key, params[key])
|
|
});
|
|
init.body = (new URLSearchParams(formData)).toString();
|
|
}
|
|
|
|
if (window.AbortController) {
|
|
this.abort(action);
|
|
const controller = new window.AbortController();
|
|
setTimeout(() => controller.abort(), iTimeOut);
|
|
init.signal = controller.signal;
|
|
this.oRequests[action] = controller;
|
|
}
|
|
|
|
window.fetch(ajax(sGetAdd), init)
|
|
.then(response => response.json())
|
|
.then(oData => {
|
|
let cached = false;
|
|
if (oData && oData.Time) {
|
|
cached = pInt(oData.Time) > new window.Date().getTime() - start;
|
|
}
|
|
|
|
if (oData && oData.UpdateToken) {
|
|
if (GlobalsData.__APP__ && GlobalsData.__APP__.setClientSideToken) {
|
|
GlobalsData.__APP__.setClientSideToken(oData.UpdateToken);
|
|
}
|
|
}
|
|
|
|
let sType = 'success';
|
|
if (action && this.oRequests[action]) {
|
|
if (this.oRequests[action].__aborted) {
|
|
sType = 'abort';
|
|
}
|
|
|
|
this.oRequests[action] = null;
|
|
}
|
|
|
|
this.defaultResponse(fResultCallback, action, sType, oData, cached, params);
|
|
}).catch(err => {
|
|
window.console.log('AbstractAjaxRemote ' + action + ' request failed:', err, Notification.getKeyByValue(err));
|
|
if (err.name == 'AbortError') { // handle abort()
|
|
return Promise.reject(Notification.AjaxAbort);
|
|
}
|
|
return Promise.reject(err);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param {?Function} fCallback
|
|
* @param {string} sAction
|
|
* @param {Object=} oParameters
|
|
* @param {?number=} iTimeout
|
|
* @param {string=} sGetAdd = ''
|
|
* @param {Array=} aAbortActions = []
|
|
*/
|
|
defaultRequest(fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions) {
|
|
oParameters = oParameters || {};
|
|
oParameters.Action = sAction;
|
|
|
|
sGetAdd = pString(sGetAdd);
|
|
|
|
runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);
|
|
|
|
return this.ajaxRequest(
|
|
fCallback,
|
|
oParameters,
|
|
isUnd(iTimeout) ? DEFAULT_AJAX_TIMEOUT : pInt(iTimeout),
|
|
sGetAdd,
|
|
aAbortActions
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param {?Function} fCallback
|
|
*/
|
|
noop(fCallback) {
|
|
this.defaultRequest(fCallback, 'Noop');
|
|
}
|
|
|
|
/**
|
|
* @param {?Function} fCallback
|
|
*/
|
|
getPublicKey(fCallback) {
|
|
this.defaultRequest(fCallback, 'GetPublicKey');
|
|
}
|
|
|
|
/**
|
|
* @param {?Function} fCallback
|
|
* @param {string} sVersion
|
|
*/
|
|
jsVersion(fCallback, sVersion) {
|
|
this.defaultRequest(fCallback, 'Version', {
|
|
'Version': sVersion
|
|
});
|
|
}
|
|
}
|
|
|
|
export { AbstractAjaxRemote, AbstractAjaxRemote as default };
|