UNPKG

@egalteam/framework-react-native

Version:

Egal

220 lines (211 loc) 8.52 kB
import axios, {Method} from 'axios'; import {ActionResult} from '../ActionResponses/ActionResult'; import {ActionError} from '../ActionResponses/ActionError'; import {ActionParameters} from '../Interfaces/ActionParameters'; import {getCookie, GlobalVariables, deleteCookie, setCookie} from '../../GlobalVariables'; import storage from '../../MMKVStorage'; let isRefreshing = false; let refreshSubscribers: any[] = []; let initialRequest: any = undefined; export class HttpRequest { actionResult: ActionResult; actionError: ActionError; constructor() { this.actionResult = {} as ActionResult; this.actionError = {} as ActionError; } subscribeTokenRefresh(cb: any): void { refreshSubscribers.push(cb); } onRefreshed(token: any): void { refreshSubscribers.map((cb) => cb(token)); } async refreshAccessToken(serviceName: string) { axios.interceptors.response.use( (response) => { return response; }, async (error) => { const {config} = error; if (error.response.data.action_error.internal_code === 'umt_expired') { this.refreshMasterToken().then(() => { this.refreshAccessToken(serviceName).then(() => { initialRequest.headers['Authorization'] = getCookie(serviceName); axios(initialRequest); refreshSubscribers = []; }) }).catch((error) => { return error }) } else { return error; } } ); if (storage.getString('umt') && storage.getString('umrt')) { let domain = GlobalVariables.httpBaseUrl ? GlobalVariables.httpBaseUrl : GlobalVariables.authBaseUrl; delete axios.defaults.headers.Authorization; deleteCookie(serviceName); await axios({ url: `${domain}/auth/User/loginToService`, method: 'POST', data: { service_name: serviceName, token: storage.getString('umt') } }) .then((response) => { deleteCookie(serviceName); setCookie(serviceName, response.data.action_result.data) this.onRefreshed(response.data.action_result.data) return response.data.action_result.data; }) .catch((error) => { return error; }); } } async refreshMasterToken() { if (storage.getString('umrt')) { let domain = GlobalVariables.httpBaseUrl ? GlobalVariables.httpBaseUrl : GlobalVariables.authBaseUrl; delete axios.defaults.headers.Authorization; await axios({ url: `${domain}/auth/User/refreshUserMasterToken`, method: 'POST', data: { token: storage.getString('umrt') } }) .then((response: any) => { storage.set( 'umrt', response.data.action_result.data.user_master_refresh_token ); storage.set('umt', response.data.action_result.data.user_master_token); }) .catch((error) => { storage.delete('umrt') return error; }); } else { return new ActionError('Session expired!', 401).getMessage() } } axiosConnect( serviceName: string, modelName: string, actionName: string, httpMethod: Method, actionParameters: ActionParameters | undefined, customActionParameters?: any, tokenName?: string ): Promise<any> { let domain = GlobalVariables.httpBaseUrl ? GlobalVariables.httpBaseUrl : GlobalVariables.authBaseUrl; let userTokenName = tokenName ? tokenName : GlobalVariables.tokenUST; let instance = axios.create(); if ( actionName !== 'register' && actionName !== 'login' && actionName !== 'loginToService' && actionName !== 'loginAndGetRefreshToken' ) { instance.defaults.headers.common['Authorization'] = getCookie(userTokenName); } instance.interceptors.response.use( (response) => { return response; }, async (error) => { const {config} = error; const originalRequest = config; initialRequest = originalRequest; if ('data' in error.response) { if ('action_error' in error.response.data) { if ( error.response.data.action_error.code === 401 && error.response.data.action_error.internal_code === 'ust_expired' ) { if (!isRefreshing) { isRefreshing = true; this.refreshAccessToken(serviceName).then(() => { isRefreshing = false; }) } return new Promise((resolve, reject) => { this.subscribeTokenRefresh((token: any) => { originalRequest.headers['Authorization'] = token; deleteCookie(serviceName); setCookie(serviceName, token) .then(() => { resolve(instance(originalRequest)); refreshSubscribers = []; }) .catch((error) => { reject(error); }); }); }); } else { return Promise.reject(error); } } else { return Promise.reject(error); } } } ); return new Promise((resolve, reject) => { let data; switch (actionName) { case 'register': case 'login': case 'loginToService': case 'loginAndGetRefreshToken': case 'getItems': case 'getItem': case 'delete': case 'getCount': case 'updateManyRaw': case 'deleteManyRaw': case 'deleteMany': data = actionParameters; break; case 'createMany': case 'updateMany': const actionManyParams = {objects: {}}; // @ts-ignore actionManyParams.objects = actionParameters; data = actionManyParams; break; default: data = {attributes: actionParameters, ...customActionParameters}; } if (GlobalVariables.httpBaseUrl || GlobalVariables.authBaseUrl) { instance({ url: `${domain}/${serviceName}/${modelName}/${actionName}`, method: httpMethod, data: data }) .then((response) => { resolve(response); }) .catch((error) => { if ('response' in error) { reject(error.response); } else { reject(error) } }); } else { this.actionError = new ActionError('Укажите URL!'); reject(this.actionError.getMessage()); } }); } }