diff --git a/changelogs/fragments/7600.yml b/changelogs/fragments/7600.yml new file mode 100644 index 000000000000..1a295f1963c9 --- /dev/null +++ b/changelogs/fragments/7600.yml @@ -0,0 +1,2 @@ +feat: +- Add a util function to generate the relative redirectUrl. ([#7600](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7600)) \ No newline at end of file diff --git a/src/core/server/http/http_tools.test.ts b/src/core/server/http/http_tools.test.ts index 0759e4f2430d..82339127ad39 100644 --- a/src/core/server/http/http_tools.test.ts +++ b/src/core/server/http/http_tools.test.ts @@ -50,12 +50,15 @@ import { HapiValidationError, getServerOptions, getRequestId, + getRedirectUrl, } from './http_tools'; import { HttpServer } from './http_server'; import { HttpConfig, config } from './http_config'; import { Router } from './router'; import { loggingSystemMock } from '../logging/logging_system.mock'; import { ByteSizeValue } from '@osd/config-schema'; +import { httpServerMock } from './http_server.mocks'; +import { updateWorkspaceState } from '../utils'; const emptyOutput = { statusCode: 400, @@ -269,3 +272,30 @@ describe('getRequestId', () => { }); }); }); + +describe('getRedirectUrl', () => { + it('should prepend with basePath when no requestWorkspaceId is present in request', () => { + const request = httpServerMock.createOpenSearchDashboardsRequest(); + expect( + getRedirectUrl({ + request, + nextUrl: '/app/next_url', + basePath: '/base', + }) + ).toEqual('/base/app/next_url'); + }); + + it('should prepend with basePath and workspace prefix when requestWorkspaceId is present in request', () => { + const request = httpServerMock.createOpenSearchDashboardsRequest(); + updateWorkspaceState(request, { + requestWorkspaceId: 'workspace_id', + }); + expect( + getRedirectUrl({ + request, + nextUrl: '/app/next_url', + basePath: '/base', + }) + ).toEqual('/base/w/workspace_id/app/next_url'); + }); +}); diff --git a/src/core/server/http/http_tools.ts b/src/core/server/http/http_tools.ts index d0136500c7b0..4524f44e5e09 100644 --- a/src/core/server/http/http_tools.ts +++ b/src/core/server/http/http_tools.ts @@ -35,6 +35,9 @@ import { ValidationError } from 'joi'; import uuid from 'uuid'; import { HttpConfig } from './http_config'; import { validateObject } from './prototype_pollution'; +import { getWorkspaceState } from '../utils'; +import { OpenSearchDashboardsRequest } from './router'; +import { WORKSPACE_PATH_PREFIX } from '../../../core/utils'; /** * Converts OpenSearch Dashboards `HttpConfig` into `ServerOptions` that are accepted by the Hapi server. @@ -194,3 +197,24 @@ export function getRequestId(request: Request, options: HttpConfig['requestId']) ? request.headers['x-opaque-id'] ?? uuid.v4() : uuid.v4(); } + +/** + * Return back the expected redirect url with basePath and conditional workspace id based on the request. + * This method should be used when the request is not authenticated and need a redirect url after login. + * And it should take care all the stuff on prepending required params into the path. + * @param request Hapi request object + * @returns the expected next url + */ +export function getRedirectUrl(props: { + request: OpenSearchDashboardsRequest; + nextUrl: string; // The url without basePath and workspace id prefix + basePath: string; +}) { + const { request, nextUrl, basePath } = props; + const workspaceState = getWorkspaceState(request); + if (workspaceState.requestWorkspaceId) { + return `${basePath}${WORKSPACE_PATH_PREFIX}/${workspaceState.requestWorkspaceId}${nextUrl}`; + } + + return `${basePath}${nextUrl}`; +} diff --git a/src/core/server/http/index.ts b/src/core/server/http/index.ts index 14397456afd6..1ac011747fc4 100644 --- a/src/core/server/http/index.ts +++ b/src/core/server/http/index.ts @@ -105,3 +105,4 @@ export { } from './cookie_session_storage'; export * from './types'; export { BasePath, IBasePath } from './base_path_service'; +export { getRedirectUrl } from './http_tools';