UNPKG

@parcl-finance/product-sdk

Version:

TypeScript SDK for interacting with Parcl's product APIs

242 lines 9.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setItem = exports.removeItem = exports.getItem = exports.setAccessToken = exports.getAccessToken = exports.setRefreshToken = exports.getRefreshToken = exports.HttpClient = void 0; const tslib_1 = require("tslib"); const axios_1 = tslib_1.__importStar(require("axios")); const auth_1 = require("./constants/auth"); class HttpClient { baseUrl; headers; instance; constructor(baseUrl, headers) { this.baseUrl = baseUrl; this.headers = headers; this.instance = axios_1.default.create({ baseURL: baseUrl, headers, }); this.instance.defaults.headers["Content-Type"] = "application/json"; } handleResponse = (response) => { return response.data; }; setAuthorizationHeader = (token) => { if (token !== undefined) { this.instance.defaults.headers.Authorization = `Bearer ${token}`; } else if (typeof window !== "undefined") { const infoStr = localStorage.getItem(auth_1.LOCAL_STORAGE_KEY_USER_ACCESS_TOKEN_INFO); if (infoStr === null) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} failed to get user access token info from local storage`); } const info = JSON.parse(infoStr); const now = Math.floor(Date.now() / 1000); if (info.expiration < now) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} user access token is expired`); } this.instance.defaults.headers.Authorization = "Bearer " + info.token; } else { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} no access token provided AND environment is not compatible with browser APIs`); } }; get = async ({ path, params, accessToken }) => { if (accessToken) { this.setAuthorizationHeader(accessToken); } const response = await this.instance.get(path, { params }); return this.handleResponse(response); }; getWithAuth = async ({ path, params, authority, }) => { const accessToken = getAccessToken({ publicKey: authority }); if (accessToken === null) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} failed to get user access token info from local storage, please login to get an access token`); } try { const response = await this.instance.get(path, { params, headers: { Authorization: `Bearer ${accessToken}`, }, }); return this.handleResponse(response); } catch (error) { if ((0, axios_1.isAxiosError)(error)) { if (error.response?.status === 401) { // in case of expired token // data will be { message: string; expiredToken: boolean } // returned by the auth middleware const responseData = error.response?.data; if (responseData.expiredToken) { const refreshToken = getRefreshToken({ publicKey: authority }); if (!refreshToken) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} No refresh token available, please login to get a refresh token`); } const tokens = await this.refreshTokens(authority, refreshToken); console.log("refreshed access token, retrying request"); const res = await this.instance.get(path, { params, headers: { Authorization: `Bearer ${tokens.accessToken}`, }, }); return this.handleResponse(res); } } } throw error; } }; post = async ({ path, body, params, accessToken }) => { if (accessToken) { this.setAuthorizationHeader(accessToken); } const response = await this.instance.post(path, body, { params }); return this.handleResponse(response); }; postWithAuth = async ({ path, body, params, authority }) => { const accessToken = getAccessToken({ publicKey: authority }); if (accessToken === null) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} failed to get user access token info from local storage, please login to get an access token`); } try { console.log("postWithAuth"); const response = await this.instance.post(path, body, { params, headers: { Authorization: `Bearer ${accessToken}`, }, }); return this.handleResponse(response); } catch (error) { if ((0, axios_1.isAxiosError)(error)) { if (error.response?.status === 401) { // in case of expired token // data will be { message: string; expiredToken: boolean } // returned by the auth middleware const responseData = error.response?.data; if (responseData.expiredToken) { const refreshToken = getRefreshToken({ publicKey: authority }); if (!refreshToken) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} No refresh token available, please login to get a refresh token`); } const tokens = await this.refreshTokens(authority, refreshToken); console.log("refreshed access token, retrying request"); const res = await this.instance.post(path, body, { params, headers: { Authorization: `Bearer ${tokens.accessToken}`, }, }); return this.handleResponse(res); } } } throw error; } }; refreshTokens = async (publicKey, refreshToken) => { try { const response = await this.instance.post("/auth/refresh-token", { refreshToken }); if (response.status !== 200) { throw new Error("Failed to refresh token"); } setAccessToken({ publicKey, token: response.data.accessToken, }); setRefreshToken({ publicKey, token: response.data.refreshToken, }); return response.data; } catch (error) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} failed to refresh token, please login again`); } }; put = async ({ path, body, accessToken }) => { if (accessToken) { this.setAuthorizationHeader(accessToken); } const response = await this.instance.put(path, body); return this.handleResponse(response); }; delete = async ({ path, params, accessToken }) => { if (accessToken) { this.setAuthorizationHeader(accessToken); } const response = await this.instance.delete(path, { params }); return this.handleResponse(response); }; } exports.HttpClient = HttpClient; function getAccessTokenCompositeKey({ publicKey }) { const keyStr = publicKey.toBase58(); return `${auth_1.LOCAL_STORAGE_KEY_USER_ACCESS_TOKEN_INFO}_v2_${keyStr}`; } function getRefreshTokenCompositeKey({ publicKey }) { const keyStr = publicKey.toBase58(); return `${auth_1.LOCAL_STORAGE_KEY_USER_REFRESH_TOKEN_INFO}_v2_${keyStr}`; } function getRefreshToken({ publicKey }) { if (publicKey === null) return; const composite = getRefreshTokenCompositeKey({ publicKey }); const token = getItem(composite); if (token === undefined) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} failed to get user refresh token info from local storage`); } return token; } exports.getRefreshToken = getRefreshToken; function setRefreshToken({ publicKey, token, }) { if (publicKey === null) return; const composite = getRefreshTokenCompositeKey({ publicKey }); setItem(composite, token); } exports.setRefreshToken = setRefreshToken; function getAccessToken({ publicKey }) { if (publicKey === null) return; const composite = getAccessTokenCompositeKey({ publicKey }); const token = getItem(composite); if (token === undefined) { throw new Error(`${auth_1.AUTH_ERROR_PREFIX} failed to get user access token info from local storage`); } return token; } exports.getAccessToken = getAccessToken; function setAccessToken({ publicKey, token, }) { if (publicKey === null) return; const composite = getAccessTokenCompositeKey({ publicKey }); setItem(composite, token); } exports.setAccessToken = setAccessToken; function getItem(key) { if (typeof window !== "undefined") { const item = localStorage.getItem(key); if (!item) return; return JSON.parse(item); } return; } exports.getItem = getItem; function removeItem(key) { if (typeof window !== "undefined") { localStorage.removeItem(key); } } exports.removeItem = removeItem; function setItem(key, value) { if (typeof window !== "undefined") { localStorage.setItem(key, JSON.stringify(value)); } } exports.setItem = setItem; //# sourceMappingURL=httpClient.js.map