Handle edge case for GitHub oAuth URL mismatch (#105302)
* Hangle edge case for github oauth mismatch * Fix grammar * Refactor test
This commit is contained in:
parent
9c2effc93e
commit
e5c3065adf
|
@ -20,8 +20,14 @@ jest.mock('../../../../app_logic', () => ({
|
|||
}));
|
||||
import { AppLogic } from '../../../../app_logic';
|
||||
|
||||
import { ADD_GITHUB_PATH, SOURCES_PATH, getSourcesPath } from '../../../../routes';
|
||||
import {
|
||||
ADD_GITHUB_PATH,
|
||||
SOURCES_PATH,
|
||||
PERSONAL_SOURCES_PATH,
|
||||
getSourcesPath,
|
||||
} from '../../../../routes';
|
||||
import { CustomSource } from '../../../../types';
|
||||
import { PERSONAL_DASHBOARD_SOURCE_ERROR } from '../../constants';
|
||||
import { SourcesLogic } from '../../sources_logic';
|
||||
|
||||
import {
|
||||
|
@ -36,7 +42,7 @@ describe('AddSourceLogic', () => {
|
|||
const { mount } = new LogicMounter(AddSourceLogic);
|
||||
const { http } = mockHttpValues;
|
||||
const { navigateToUrl } = mockKibanaValues;
|
||||
const { clearFlashMessages, flashAPIErrors } = mockFlashMessageHelpers;
|
||||
const { clearFlashMessages, flashAPIErrors, setErrorMessage } = mockFlashMessageHelpers;
|
||||
|
||||
const defaultValues = {
|
||||
addSourceCurrentStep: AddSourceSteps.ConfigIntroStep,
|
||||
|
@ -353,6 +359,33 @@ describe('AddSourceLogic', () => {
|
|||
expect(navigateToUrl).toHaveBeenCalledWith(`${ADD_GITHUB_PATH}/configure${queryString}`);
|
||||
});
|
||||
|
||||
describe('Github error edge case', () => {
|
||||
const getGithubQueryString = (context: 'organization' | 'account') =>
|
||||
`?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch&state=%7B%22action%22%3A%22create%22%2C%22context%22%3A%22${context}%22%2C%22service_type%22%3A%22github%22%2C%22csrf_token%22%3A%22TOKEN%3D%3D%22%2C%22index_permissions%22%3Afalse%7D`;
|
||||
|
||||
it('handles "organization" redirect and displays error', () => {
|
||||
const githubQueryString = getGithubQueryString('organization');
|
||||
AddSourceLogic.actions.saveSourceParams(githubQueryString);
|
||||
|
||||
expect(navigateToUrl).toHaveBeenCalledWith('/');
|
||||
expect(setErrorMessage).toHaveBeenCalledWith(
|
||||
'The redirect_uri MUST match the registered callback URL for this application.'
|
||||
);
|
||||
});
|
||||
|
||||
it('handles "account" redirect and displays error', () => {
|
||||
const githubQueryString = getGithubQueryString('account');
|
||||
AddSourceLogic.actions.saveSourceParams(githubQueryString);
|
||||
|
||||
expect(navigateToUrl).toHaveBeenCalledWith(PERSONAL_SOURCES_PATH);
|
||||
expect(setErrorMessage).toHaveBeenCalledWith(
|
||||
PERSONAL_DASHBOARD_SOURCE_ERROR(
|
||||
'The redirect_uri MUST match the registered callback URL for this application.'
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('handles error', async () => {
|
||||
http.get.mockReturnValue(Promise.reject('this is an error'));
|
||||
|
||||
|
|
|
@ -16,14 +16,21 @@ import {
|
|||
flashAPIErrors,
|
||||
setSuccessMessage,
|
||||
clearFlashMessages,
|
||||
setErrorMessage,
|
||||
} from '../../../../../shared/flash_messages';
|
||||
import { HttpLogic } from '../../../../../shared/http';
|
||||
import { KibanaLogic } from '../../../../../shared/kibana';
|
||||
import { parseQueryParams } from '../../../../../shared/query_params';
|
||||
import { AppLogic } from '../../../../app_logic';
|
||||
import { CUSTOM_SERVICE_TYPE, WORKPLACE_SEARCH_URL_PREFIX } from '../../../../constants';
|
||||
import { SOURCES_PATH, ADD_GITHUB_PATH, getSourcesPath } from '../../../../routes';
|
||||
import {
|
||||
SOURCES_PATH,
|
||||
ADD_GITHUB_PATH,
|
||||
PERSONAL_SOURCES_PATH,
|
||||
getSourcesPath,
|
||||
} from '../../../../routes';
|
||||
import { CustomSource } from '../../../../types';
|
||||
import { PERSONAL_DASHBOARD_SOURCE_ERROR } from '../../constants';
|
||||
import { staticSourceData } from '../../source_data';
|
||||
import { SourcesLogic } from '../../sources_logic';
|
||||
|
||||
|
@ -50,6 +57,8 @@ export interface OauthParams {
|
|||
state: string;
|
||||
session_state: string;
|
||||
oauth_verifier?: string;
|
||||
error?: string;
|
||||
error_description?: string;
|
||||
}
|
||||
|
||||
export interface AddSourceActions {
|
||||
|
@ -501,6 +510,22 @@ export const AddSourceLogic = kea<MakeLogicType<AddSourceValues, AddSourceAction
|
|||
const state = JSON.parse(params.state);
|
||||
const isOrganization = state.context !== 'account';
|
||||
|
||||
/**
|
||||
There is an extreme edge case where the user is trying to connect Github as source from ent-search,
|
||||
after configuring it in Kibana. When this happens, Github redirects the user from ent-search to Kibana
|
||||
with special error properties in the query params. In this case we need to redirect the user to the
|
||||
app home page and display the error message, and not persist the other query params to the server.
|
||||
*/
|
||||
if (params.error_description) {
|
||||
navigateToUrl(isOrganization ? '/' : PERSONAL_SOURCES_PATH);
|
||||
setErrorMessage(
|
||||
isOrganization
|
||||
? params.error_description
|
||||
: PERSONAL_DASHBOARD_SOURCE_ERROR(params.error_description)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await http.get(route, { query });
|
||||
const {
|
||||
|
|
|
@ -470,3 +470,10 @@ export const PRIVATE_DASHBOARD_READ_ONLY_MODE_WARNING = i18n.translate(
|
|||
'Workplace Search is currently available for search only, due to regular maintenance. Contact your system administrator for more information.',
|
||||
}
|
||||
);
|
||||
|
||||
export const PERSONAL_DASHBOARD_SOURCE_ERROR = (error: string) =>
|
||||
i18n.translate('xpack.enterpriseSearch.workplaceSearch.personalDashboardSourceError', {
|
||||
defaultMessage:
|
||||
'Could not connect the source, reach out to your admin for help. Error message: {error}',
|
||||
values: { error },
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue