All files / lib/api/core index.ts

0% Statements 0/42
0% Branches 0/18
0% Functions 0/2
0% Lines 0/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89                                                                                                                                                                                 
import { CORE_SERVER_HOST, INTEGRATE_LOGIN_HOST } from '@lib/config';
import { getLocalStorage, setLocalStorage } from '@lib/utils/localStorage';
import {
  AuthApi,
  NoticeApi,
  Configuration,
  SharedApi,
  SearchApi,
  PointApi
} from '@uniquegood/realworld-core-interface';
import axios from 'axios';
import moize from 'moize';
import { decodeJwt } from 'jose';
import { authApi } from '../auth';
 
const memoizedRefreshRequest = moize(
  async ({ accessToken, refreshToken }: { accessToken: string; refreshToken: string }) => {
    const { data } = await coreAuthApi.refresh(undefined, {
      accessToken,
      refreshToken
    });
 
    return data;
  },
  {
    maxAge: 5000
  }
);
 
const configuration = new Configuration({ basePath: `https://${CORE_SERVER_HOST}` });
export const axiosInstanceWithToken = axios.create({ withCredentials: true });
export const axiosInstance = axios.create({ withCredentials: true });
 
axiosInstanceWithToken.interceptors.request.use(async (config) => {
  try {
    if (!config.headers) return config;
 
    const accessToken = getLocalStorage('accessToken');
    if (!accessToken) throw new Error('No accessToken');
 
    const { exp } = decodeJwt(accessToken);
    if (!exp) throw new Error('No exp');
 
    const now = Math.floor(Date.now() / 1000);
    if (exp < now) {
      const refreshToken = getLocalStorage('refreshToken');
      if (!refreshToken) throw new Error('No refreshToken');
 
      const refreshed = await memoizedRefreshRequest({
        accessToken,
        refreshToken
      });
 
      if (!refreshed.token || !refreshed.refreshToken) throw new Error('No refreshed token');
 
      setLocalStorage('accessToken', refreshed.token);
      setLocalStorage('refreshToken', refreshed.refreshToken);
      config.headers.Authorization = `Bearer ${refreshed.token}`;
    } else {
      config.headers.Authorization = `Bearer ${accessToken}`;
    }
  } catch (e) {
    try {
      const {
        data: { token: newAccessToken, refreshToken: newRefreshToken }
      } = await authApi.apiAuthReissueGet();
 
      if (newAccessToken && newRefreshToken) {
        setLocalStorage('accessToken', newAccessToken);
        setLocalStorage('refreshToken', newRefreshToken);
        config.headers.Authorization = `Bearer ${newAccessToken}`;
      }
    } catch (e) {
      window.location.href = `https://${INTEGRATE_LOGIN_HOST}/auth/signin?redirectUrl=${encodeURI(
        window.location.href
      )}`;
    }
  }
 
  return config;
});
 
export const coreAuthApiWithToken = new AuthApi(configuration, undefined, axiosInstanceWithToken);
export const coreAuthApi = new AuthApi(configuration, undefined, axiosInstance);
export const coreNoticeApi = new NoticeApi(configuration, undefined, axiosInstanceWithToken);
export const coreSharedApi = new SharedApi(configuration, undefined, axiosInstanceWithToken);
export const coreSearchApi = new SearchApi(configuration, undefined, axiosInstanceWithToken);
export const corePointApi = new PointApi(configuration, undefined, axiosInstanceWithToken);