diff --git a/app/soapbox/actions/auth.js b/app/soapbox/actions/auth.js index efcaf830e..49e02725b 100644 --- a/app/soapbox/actions/auth.js +++ b/app/soapbox/actions/auth.js @@ -4,7 +4,7 @@ import { importFetchedAccount } from './importer'; import snackbar from 'soapbox/actions/snackbar'; import { createAccount } from 'soapbox/actions/accounts'; import { fetchMeSuccess, fetchMeFail } from 'soapbox/actions/me'; -import { getLoggedInAccount } from 'soapbox/utils/auth'; +import { getLoggedInAccount, parseBaseURL } from 'soapbox/utils/auth'; import { createApp } from 'soapbox/actions/apps'; import { obtainOAuthToken, revokeOAuthToken } from 'soapbox/actions/oauth'; @@ -144,11 +144,13 @@ export function otpVerify(code, mfa_token) { }; } -export function verifyCredentials(token) { +export function verifyCredentials(token, accountUrl) { + const baseURL = parseBaseURL(accountUrl); + return (dispatch, getState) => { dispatch({ type: VERIFY_CREDENTIALS_REQUEST }); - return baseClient(token).get('/api/v1/accounts/verify_credentials').then(({ data: account }) => { + return baseClient(token, baseURL).get('/api/v1/accounts/verify_credentials').then(({ data: account }) => { dispatch(importFetchedAccount(account)); dispatch({ type: VERIFY_CREDENTIALS_SUCCESS, token, account }); if (account.id === getState().get('me')) dispatch(fetchMeSuccess(account)); @@ -208,7 +210,7 @@ export function fetchOwnAccounts() { state.getIn(['auth', 'users']).forEach(user => { const account = state.getIn(['accounts', user.get('id')]); if (!account) { - dispatch(verifyCredentials(user.get('access_token'))); + dispatch(verifyCredentials(user.get('access_token'), user.get('url'))); } }); }; diff --git a/app/soapbox/actions/me.js b/app/soapbox/actions/me.js index 13a6f86ce..f487043db 100644 --- a/app/soapbox/actions/me.js +++ b/app/soapbox/actions/me.js @@ -29,14 +29,16 @@ const getMeToken = state => { export function fetchMe() { return (dispatch, getState) => { - const token = getMeToken(getState()); + const state = getState(); + const token = getMeToken(state); + const accountUrl = getMeUrl(state); if (!token) { dispatch({ type: ME_FETCH_SKIP }); return noOp(); } dispatch(fetchMeRequest()); - return dispatch(verifyCredentials(token)).catch(error => { + return dispatch(verifyCredentials(token, accountUrl)).catch(error => { dispatch(fetchMeFail(error)); }); }; diff --git a/app/soapbox/api.js b/app/soapbox/api.js index 664a5a071..945ffbd25 100644 --- a/app/soapbox/api.js +++ b/app/soapbox/api.js @@ -2,7 +2,8 @@ import axios from 'axios'; import LinkHeader from 'http-link-header'; -import { getAccessToken, getAppToken } from 'soapbox/utils/auth'; +import { getAccessToken, getAppToken, parseBaseURL } from 'soapbox/utils/auth'; +import { createSelector } from 'reselect'; export const getLinks = response => { const value = response.headers.link; @@ -10,8 +11,7 @@ export const getLinks = response => { return LinkHeader.parse(value); }; -const getToken = (getState, authType) => { - const state = getState(); +const getToken = (state, authType) => { return authType === 'app' ? getAppToken(state) : getAccessToken(state); }; @@ -23,8 +23,17 @@ const maybeParseJSON = data => { } }; -export const baseClient = accessToken => { +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 : ''; +}); + +export const baseClient = (accessToken, baseURL = '') => { return axios.create({ + baseURL, headers: Object.assign(accessToken ? { 'Authorization': `Bearer ${accessToken}`, } : {}), @@ -34,6 +43,10 @@ export const baseClient = accessToken => { }; export default (getState, authType = 'user') => { - const accessToken = getToken(getState, authType); - return baseClient(accessToken); + const state = getState(); + const accessToken = getToken(state, authType); + const me = state.get('me'); + const baseURL = getAuthBaseURL(state, me); + + return baseClient(accessToken, baseURL); }; diff --git a/app/soapbox/utils/auth.js b/app/soapbox/utils/auth.js index b4af627c0..c697578a1 100644 --- a/app/soapbox/utils/auth.js +++ b/app/soapbox/utils/auth.js @@ -11,6 +11,14 @@ export const isURL = url => { } }; +export const parseBaseURL = url => { + try { + return new URL(url).origin; + } catch { + return ''; + } +}; + export const getLoggedInAccount = state => { const me = state.get('me'); return state.getIn(['accounts', me]);