The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/app/utils/client/lib/RestApiClient.js

175 lines
4.4 KiB

import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { baseURI } from './baseuri';
import { process2faReturn } from '../../../2fa/client/callWithTwoFactorRequired';
export const mountArrayQueryParameters = (label, array) => array.reduce((acc, item) => {
acc += `${ label }[]=${ item }&`;
return acc;
}, '');
export const APIClient = {
delete(endpoint, params) {
return APIClient._jqueryCall('DELETE', endpoint, params);
},
get(endpoint, params) {
return APIClient._jqueryCall('GET', endpoint, params);
},
post(endpoint, params, body) {
if (!body) {
body = params;
params = {};
}
return APIClient._jqueryCall('POST', endpoint, params, body);
},
upload(endpoint, params, formData, xhrOptions) {
if (!formData) {
formData = params;
params = {};
}
return APIClient._jqueryFormDataCall(endpoint, params, formData, xhrOptions);
},
getCredentials() {
return {
'X-User-Id': Meteor._localStorage.getItem(Accounts.USER_ID_KEY),
'X-Auth-Token': Meteor._localStorage.getItem(Accounts.LOGIN_TOKEN_KEY),
};
},
_generateQueryFromParams(params) {
let query = '';
if (params && typeof params === 'object') {
Object.keys(params).forEach((key) => {
query += query === '' ? '?' : '&';
if (Array.isArray(params[key])) {
const joinedArray = params[key].join(`&${ key }[]=`);
query += `${ key }[]=${ joinedArray }`;
} else {
query += `${ key }=${ params[key] }`;
}
});
}
return query;
},
_jqueryCall(method, endpoint, params, body, headers = {}) {
const query = APIClient._generateQueryFromParams(params);
return new Promise(function _rlRestApiGet(resolve, reject) {
jQuery.ajax({
method,
url: `${ baseURI }api/${ endpoint }${ query }`,
headers: Object.assign({
'Content-Type': 'application/json',
...APIClient.getCredentials(),
}, headers),
data: JSON.stringify(body),
success: function _rlGetSuccess(result) {
resolve(result);
},
error: function _rlGetFailure(xhr, status, errorThrown) {
APIClient.processTwoFactorError({
xhr,
params: [method, endpoint, params, body, headers],
resolve,
reject,
originalCallback() {
const error = new Error(errorThrown);
error.xhr = xhr;
reject(error);
},
});
},
});
});
},
_jqueryFormDataCall(endpoint, params, formData, { progress = () => {}, error = () => {} } = {}) {
const ret = { };
const query = APIClient._generateQueryFromParams(params);
if (!(formData instanceof FormData)) {
throw new Error('The formData parameter MUST be an instance of the FormData class.');
}
ret.promise = new Promise(function _jqueryFormDataPromise(resolve, reject) {
ret.xhr = jQuery.ajax({
xhr() {
const xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener('progress', function(evt) {
if (evt.lengthComputable) {
const percentComplete = evt.loaded / evt.total;
progress(percentComplete * 100);
}
}, false);
xhr.upload.addEventListener('error', error, false);
return xhr;
},
url: `${ baseURI }api/${ endpoint }${ query }`,
headers: APIClient.getCredentials(),
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function _jqueryFormDataSuccess(result) {
resolve(result);
},
error: function _jqueryFormDataError(xhr, status, errorThrown) {
const error = new Error(errorThrown);
error.xhr = xhr;
reject(error);
},
});
});
return ret;
},
processTwoFactorError({ xhr, params, originalCallback, resolve, reject }) {
if (!xhr.responseJSON || !xhr.responseJSON.errorType) {
return originalCallback();
}
process2faReturn({
error: xhr.responseJSON,
originalCallback,
onCode(code, method) {
const headers = params[params.length - 1];
headers['x-2fa-code'] = code;
headers['x-2fa-method'] = method;
APIClient._jqueryCall(...params).then(resolve).catch(reject);
},
});
},
v1: {
delete(endpoint, params) {
return APIClient.delete(`v1/${ endpoint }`, params);
},
get(endpoint, params) {
return APIClient.get(`v1/${ endpoint }`, params);
},
post(endpoint, params, body) {
return APIClient.post(`v1/${ endpoint }`, params, body);
},
upload(endpoint, params, formData) {
return APIClient.upload(`v1/${ endpoint }`, params, formData);
},
},
};