hedera-web/js/vn/json-connection.js

300 lines
6.3 KiB
JavaScript
Raw Normal View History

2016-09-26 09:28:47 +00:00
2022-11-28 08:51:31 +00:00
const VnObject = require('./object');
const JsonException = require('./json-exception');
2016-09-26 09:28:47 +00:00
2016-09-23 22:47:34 +00:00
/**
* Handler for JSON rest connections.
2022-05-26 06:08:31 +00:00
*/
2022-05-05 13:56:17 +00:00
module.exports = new Class({
2022-11-28 08:51:31 +00:00
Extends: VnObject,
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
_connected: false,
_requestsCount: 0,
token: null,
2016-09-23 22:47:34 +00:00
/**
* Initilizes the connection object.
2022-05-26 06:08:31 +00:00
*/
2022-11-28 08:51:31 +00:00
initialize() {
2022-06-06 16:02:17 +00:00
VnObject.prototype.initialize.call(this);
2022-05-05 13:56:17 +00:00
this.fetchToken();
2022-11-28 08:51:31 +00:00
},
2016-10-04 15:27:49 +00:00
2022-11-28 08:51:31 +00:00
fetchToken() {
let token = null;
2022-05-05 13:56:17 +00:00
if (sessionStorage.getItem('vnToken'))
token = sessionStorage.getItem('vnToken');
if (localStorage.getItem('vnToken'))
token = localStorage.getItem('vnToken');
this.token = token;
2022-11-28 08:51:31 +00:00
},
2022-11-28 08:51:31 +00:00
clearToken() {
this.token = null;
2022-05-05 13:56:17 +00:00
localStorage.removeItem('vnToken');
sessionStorage.removeItem('vnToken');
2022-11-28 08:51:31 +00:00
},
2016-09-23 22:47:34 +00:00
/**
* Opens the connection to the REST service.
*
2016-10-04 15:27:49 +00:00
* @param {String} user The user name
2016-09-23 22:47:34 +00:00
* @param {String} password The user password
* @param {Boolean} remember Specifies if the user should be remembered
* @return {Promise} Resolved when operation is done
2022-05-26 06:08:31 +00:00
*/
2022-11-28 08:51:31 +00:00
async open(user, pass, remember) {
let params;
2022-05-05 13:56:17 +00:00
if (user !== null && user !== undefined) {
params = {
2023-01-16 12:59:11 +00:00
user,
password: pass
2016-09-23 22:47:34 +00:00
};
2022-05-05 13:56:17 +00:00
} else
params = null;
2016-09-23 22:47:34 +00:00
try {
2022-11-28 08:51:31 +00:00
const json = await this.post('Accounts/login', params);
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
const storage = remember ? localStorage : sessionStorage;
storage.setItem('vnToken', json.token);
2016-09-23 22:47:34 +00:00
this.token = json.token;
this._connected = true;
2022-05-30 01:30:33 +00:00
this.emit('openned');
} catch(err) {
2022-05-05 13:56:17 +00:00
this._closeClient();
throw err;
}
2022-11-28 08:51:31 +00:00
},
2016-09-23 22:47:34 +00:00
/**
* Closes the connection to the REST service.
*
* @return {Promise} Resolved when operation is done
2022-05-26 06:08:31 +00:00
*/
2022-11-28 08:51:31 +00:00
async close() {
const token = this.token;
2022-05-05 13:56:17 +00:00
this._closeClient();
2022-05-30 01:30:33 +00:00
this.emit('closed');
2022-11-28 08:51:31 +00:00
if (token) {
const config = {
headers: {'Authorization': token}
};
await this.send('user/logout');
2023-07-28 08:16:28 +00:00
await this.post('Accounts/logout', null, config);
2022-11-28 08:51:31 +00:00
}
},
2016-09-24 14:32:31 +00:00
2022-11-28 08:51:31 +00:00
_closeClient() {
2016-09-24 14:32:31 +00:00
this._connected = false;
2022-05-05 13:56:17 +00:00
this.clearToken();
2022-11-28 08:51:31 +00:00
},
2016-09-23 22:47:34 +00:00
/**
* Executes the specified REST service with the given params and calls
* the callback when response is received.
*
2022-11-28 08:51:31 +00:00
* @param {String} url The service path
* @param {Object} params The params to pass to the service
* @return {Object} The parsed JSON response
2022-05-26 06:08:31 +00:00
*/
2022-11-28 08:51:31 +00:00
async send(url, params) {
if (!params) params = {};
params.srv = `json:${url}`;
2022-11-28 08:51:54 +00:00
return this.sendWithUrl('POST', '.', params);
2022-11-28 08:51:31 +00:00
},
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
async sendForm(form) {
const params = {};
const elements = form.elements;
2016-09-23 22:47:34 +00:00
for (var i = 0; i < elements.length; i++)
if (elements[i].name)
params[elements[i].name] = elements[i].value;
2022-11-28 08:51:54 +00:00
return this.sendWithUrl('POST', form.action, params);
2022-11-28 08:51:31 +00:00
},
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
async sendFormMultipart(form) {
2022-11-28 08:51:54 +00:00
return this.request({
2022-11-28 08:51:31 +00:00
method: 'POST',
url: form.action,
data: new FormData(form)
});
},
2017-05-08 15:54:35 +00:00
2022-11-28 08:51:31 +00:00
async sendFormData(formData) {
2022-11-28 08:51:54 +00:00
return this.request({
2022-11-28 08:51:31 +00:00
method: 'POST',
url: '',
data: formData
});
},
2017-05-08 15:54:35 +00:00
2016-09-23 22:47:34 +00:00
/*
* Called when REST response is received.
*/
2022-11-28 08:51:31 +00:00
async sendWithUrl(method, url, params) {
2022-11-28 08:51:54 +00:00
return this.request({
2022-11-28 08:51:31 +00:00
method,
url,
data: Vn.Url.makeUri(params),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
},
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
async get(url, config) {
config = Object.assign({}, config, {
method: 'GET',
url: `api/${url}`
});
2022-11-28 08:51:54 +00:00
return this.request(config);
2022-11-28 08:51:31 +00:00
},
async post(url, data, config) {
2022-11-28 08:51:54 +00:00
return this.requestData('POST', url, data, config);
2022-11-28 08:51:31 +00:00
},
async patch(url, data, config) {
2022-11-28 08:51:54 +00:00
return this.requestData('PATCH', url, data, config);
2022-11-28 08:51:31 +00:00
},
async requestData(method, url, data, config) {
config = Object.assign({}, config, {
method,
url: `api/${url}`,
data: data && JSON.stringify(data),
});
config.headers = Object.assign({}, config.headers, {
'Content-Type': 'application/json;charset=utf-8'
});
2022-11-28 08:51:54 +00:00
return this.request(config);
2022-11-28 08:51:31 +00:00
},
2022-05-05 13:56:17 +00:00
2022-11-28 08:51:31 +00:00
async request(config) {
const request = new XMLHttpRequest();
request.open(config.method, config.url, true);
2022-05-05 13:56:17 +00:00
if (this.token)
request.setRequestHeader('Authorization', this.token);
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
const headers = config.headers;
if (headers)
for (const header in headers)
request.setRequestHeader(header, headers[header]);
2022-11-28 08:51:31 +00:00
const promise = new Promise((resolve, reject) => {
request.onreadystatechange =
2022-11-28 08:51:31 +00:00
() => this._onStateChange(request, resolve, reject);
});
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
request.send(config.data);
2016-09-23 22:47:34 +00:00
this._requestsCount++;
if (this._requestsCount === 1)
2022-05-30 01:30:33 +00:00
this.emit('loading-changed', true);
2022-11-28 08:51:54 +00:00
return promise;
2022-11-28 08:51:31 +00:00
},
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
_onStateChange(request, resolve, reject) {
2016-09-23 22:47:34 +00:00
if (request.readyState !== 4)
return;
this._requestsCount--;
if (this._requestsCount === 0)
2022-05-30 01:30:33 +00:00
this.emit('loading-changed', false);
2016-09-23 22:47:34 +00:00
2022-11-28 08:51:31 +00:00
let data = null;
let error = null;
try {
2022-05-05 13:56:17 +00:00
if (request.status == 0) {
2022-11-28 08:51:31 +00:00
const err = new JsonException();
err.message = _('The server does not respond, please check your Internet connection');
err.statusCode = request.status;
throw err;
2016-09-23 22:47:34 +00:00
}
2022-11-28 08:51:31 +00:00
let contentType = null;
2016-09-23 22:47:34 +00:00
try {
contentType = request
2022-05-05 13:56:17 +00:00
.getResponseHeader('Content-Type')
.split(';')[0]
.trim();
} catch (err) {
console.warn(err);
2016-09-23 22:47:34 +00:00
}
2022-05-05 13:56:17 +00:00
if (contentType != 'application/json') {
2022-11-28 08:51:31 +00:00
const err = new JsonException();
err.message = request.statusText;
err.statusCode = request.status;
throw err;
2016-09-23 22:47:34 +00:00
}
2022-05-05 13:56:17 +00:00
2022-11-28 08:51:31 +00:00
let json;
let jsData;
2022-05-05 13:56:17 +00:00
if (request.responseText)
json = JSON.parse(request.responseText);
if (json)
jsData = json.data || json;
if (request.status >= 200 && request.status < 300) {
2016-09-23 22:47:34 +00:00
data = jsData;
2022-05-05 13:56:17 +00:00
} else {
2022-11-28 08:51:31 +00:00
let exception = jsData.exception;
let error = jsData.error;
let err = new JsonException();
2022-05-05 13:56:17 +00:00
if (exception) {
exception = exception
2022-05-05 13:56:17 +00:00
.replace(/\\/g, '.')
2023-01-16 12:59:11 +00:00
.replace(/Exception$/, 'Error')
2022-05-05 13:56:17 +00:00
.replace(/^Vn\.Web\./, '');
2022-11-28 08:51:31 +00:00
err.exception = exception;
err.message = jsData.message;
err.code = jsData.code;
err.file = jsData.file;
err.line = jsData.line;
err.trace = jsData.trace;
err.statusCode = request.status;
2022-05-05 13:56:17 +00:00
} else if (error) {
2022-11-28 08:51:31 +00:00
err.message = error.message;
err.code = error.code;
err.statusCode = request.status;
} else {
err.message = request.statusText;
err.statusCode = request.status;
2022-05-05 13:56:17 +00:00
}
2022-11-28 08:51:31 +00:00
throw err;
2016-09-23 22:47:34 +00:00
}
2022-05-05 13:56:17 +00:00
} catch (e) {
2016-09-23 22:47:34 +00:00
data = null;
error = e;
}
2022-11-28 08:51:31 +00:00
2022-05-05 13:56:17 +00:00
if (error) {
if (error.exception == 'SessionExpired')
2022-05-05 13:56:17 +00:00
this.clearToken();
2022-05-26 08:00:19 +00:00
2022-05-30 01:30:33 +00:00
this.emit('error', error);
2022-11-28 08:51:54 +00:00
reject(error);
2022-11-28 08:51:31 +00:00
} else
resolve(data);
2016-09-23 22:47:34 +00:00
}
});