@parcl-finance/product-sdk
Version:
TypeScript SDK for interacting with Parcl's product APIs
242 lines • 9.79 kB
JavaScript
;
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