@egalteam/framework
Version:
Egal
220 lines (209 loc) • 8.57 kB
text/typescript
import {Method} from 'axios';
import {ActionResult} from '../ActionResponses/ActionResult';
import {ActionError} from '../ActionResponses/ActionError';
import {ActionParameters} from '../Interfaces/ActionParameters';
import {getCookie, GlobalVariables, deleteCookie, setCookie, decipherJWT} from '../../GlobalVariables';
import globalAxios from "../../AxiosInstance";
let isRefreshing = false;
let refreshSubscribers: any[] = [];
let initialRequest: any = undefined;
let targetServiceName: string = ''
let newToken: string = ''
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|undefined, requestServiceName?: string) {
globalAxios.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const {config} = error;
if (error.response.data.action_error.internal_code === 'umt_expired') {
this.refreshMasterToken(serviceName).then(() => {
this.refreshAccessToken(serviceName, requestServiceName).then(() => {
// @ts-ignore
initialRequest.headers['Authorization'] = getCookie(requestServiceName);
globalAxios(initialRequest);
refreshSubscribers = [];
})
}).catch((error) => {
return Promise.reject(error);
})
} else {
return Promise.reject(error);
}
}
);
if (localStorage.getItem('umt') && localStorage.getItem('umrt')) {
let domain = GlobalVariables.httpBaseUrl
? GlobalVariables.httpBaseUrl
: GlobalVariables.authBaseUrl;
delete globalAxios.defaults.headers.common.Authorization;
await globalAxios({
url: `${domain}/${serviceName}/User/loginToService`,
method: 'POST',
data: {
service_name: requestServiceName,
token: localStorage.getItem('umt')
}
})
.then((response) => {
// @ts-ignore
deleteCookie(requestServiceName);
this.setTargetMicroserviceName(response.data.action_result.data)
this.onRefreshed(response.data.action_result.data)
newToken = response.data.action_result.data
return response.data.action_result.data;
})
.catch((error) => {
return error;
});
}
}
async refreshMasterToken(serviceName:string|undefined) {
if (localStorage.getItem('umrt')) {
let domain = GlobalVariables.httpBaseUrl
? GlobalVariables.httpBaseUrl
: GlobalVariables.authBaseUrl;
delete globalAxios.defaults.headers.common.Authorization;
await globalAxios({
url: `${domain}/${serviceName}/User/refreshUserMasterToken`,
method: 'POST',
data: {
token: localStorage.getItem('umrt')
}
})
.then((response: any) => {
localStorage.setItem(
'umrt',
response.data.action_result.data.user_master_refresh_token
);
localStorage.setItem('umt', response.data.action_result.data.user_master_token);
})
.catch((error) => {
localStorage.removeItem('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,
refreshTokenName?: string
): Promise<any> {
let domain = GlobalVariables.httpBaseUrl
? GlobalVariables.httpBaseUrl
: GlobalVariables.authBaseUrl;
let userTokenName = GlobalVariables.tokenUST;
// let instance = axios.create();
if (
actionName !== 'register' &&
actionName !== 'login' &&
actionName !== 'loginToService' &&
actionName !== 'loginAndGetRefreshToken'
) {
globalAxios.defaults.headers.common['Authorization'] = getCookie(userTokenName);
}
globalAxios.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const {config} = error;
const originalRequest = config;
initialRequest = originalRequest;
if (
error.response.data.action_error.code === 401 &&
error.response.data.action_error.internal_code === 'ust_expired'
) {
const requestServiceName = this.setTargetMicroserviceName(initialRequest.headers.Authorization)
if (!isRefreshing) {
isRefreshing = true;
this.refreshAccessToken(refreshTokenName, requestServiceName).then(() => {
isRefreshing = false;
})
}
return new Promise((resolve, reject) => {
this.subscribeTokenRefresh((newToken: any) => {
originalRequest.headers['Authorization'] = getCookie(requestServiceName);
resolve(globalAxios(originalRequest));
refreshSubscribers = [];
});
});
} 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) {
globalAxios({
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());
}
});
}
setTargetMicroserviceName(token:string) {
let decipheredToken = decipherJWT(token)
targetServiceName = decipheredToken.target_service_name
setCookie(targetServiceName, token)
return targetServiceName
}
}