bigbuffet-rw/app/soapbox/api.js

91 lines
2.5 KiB
JavaScript
Raw Normal View History

/**
* API: HTTP client and utilities.
* @see {@link https://github.com/axios/axios}
* @module soapbox/api
*/
2020-03-27 13:59:38 -07:00
'use strict';
import axios from 'axios';
import LinkHeader from 'http-link-header';
2021-08-21 18:41:29 -07:00
import { createSelector } from 'reselect';
2021-09-05 11:21:39 -07:00
import { BACKEND_URL, FE_SUBDIRECTORY } from 'soapbox/build_config';
import { getAccessToken, getAppToken, parseBaseURL } from 'soapbox/utils/auth';
import { isURL } from 'soapbox/utils/auth';
2020-03-27 13:59:38 -07:00
/**
Parse Link headers, mostly for pagination.
@see {@link https://www.npmjs.com/package/http-link-header}
@param {object} response - Axios response object
@returns {object} Link object
*/
2020-03-27 13:59:38 -07:00
export const getLinks = response => {
const value = response.headers.link;
if (!value) return { refs: [] };
2020-03-27 13:59:38 -07:00
return LinkHeader.parse(value);
};
2021-08-21 18:41:29 -07:00
const getToken = (state, authType) => {
2021-03-31 12:47:54 -07:00
return authType === 'app' ? getAppToken(state) : getAccessToken(state);
};
2020-04-29 12:06:26 -07:00
2021-03-31 12:47:54 -07:00
const maybeParseJSON = data => {
try {
return JSON.parse(data);
} catch(Exception) {
return data;
}
};
2020-04-29 12:06:26 -07:00
2021-08-21 18:41:29 -07:00
const getAuthBaseURL = createSelector([
(state, me) => state.getIn(['accounts', me, 'url']),
(state, me) => state.getIn(['auth', 'me']),
], (accountUrl, authUserUrl) => {
const baseURL = parseBaseURL(accountUrl) || parseBaseURL(authUserUrl);
return baseURL !== window.location.origin ? baseURL : '';
});
/**
* Base client for HTTP requests.
* @param {string} accessToken
* @param {string} baseURL
* @returns {object} Axios instance
*/
2021-08-21 18:41:29 -07:00
export const baseClient = (accessToken, baseURL = '') => {
2020-04-04 13:28:57 -07:00
return axios.create({
// When BACKEND_URL is set, always use it.
baseURL: isURL(BACKEND_URL) ? BACKEND_URL : baseURL,
2020-06-09 12:45:48 -07:00
headers: Object.assign(accessToken ? {
2020-04-29 12:06:26 -07:00
'Authorization': `Bearer ${accessToken}`,
2020-04-04 13:28:57 -07:00
} : {}),
2021-03-31 12:47:54 -07:00
transformResponse: [maybeParseJSON],
2020-04-04 13:28:57 -07:00
});
};
2021-03-31 12:47:54 -07:00
/**
* Dumb client for grabbing static files.
2021-09-05 11:21:39 -07:00
* It uses FE_SUBDIRECTORY and parses JSON if possible.
* No authorization is needed.
*/
export const staticClient = axios.create({
2021-09-05 11:21:39 -07:00
baseURL: FE_SUBDIRECTORY,
transformResponse: [maybeParseJSON],
});
/**
* Stateful API client.
* Uses credentials from the Redux store if available.
* @param {function} getState - Must return the Redux state
* @param {string} authType - Either 'user' or 'app'
* @returns {object} Axios instance
*/
2021-03-31 12:47:54 -07:00
export default (getState, authType = 'user') => {
2021-08-21 18:41:29 -07:00
const state = getState();
const accessToken = getToken(state, authType);
const me = state.get('me');
const baseURL = getAuthBaseURL(state, me);
return baseClient(accessToken, baseURL);
2021-03-31 12:47:54 -07:00
};