import type { CoreSetup , Logger } from 'src/core/server' ; import type { Space } from '../../../common' ; import { addSpaceIdToPath } from '../../../common' ; import { DEFAULT_SPACE_ID , ENTER_SPACE_PATH } from '../../../common/constants' ; import type { PluginsSetup } from '../../plugin' ; import type { SpacesServiceStart } from '../../spaces_service/spaces_service' ; import { wrapError } from '../errors' ; import { getSpaceSelectorUrl } from '../get_space_selector_url' ; export interface OnPostAuthInterceptorDeps { http : CoreSetup [ 'http' ] ; features : PluginsSetup [ 'features' ] ; getSpacesService : ( ) => SpacesServiceStart ; log : Logger ; } export function initSpacesOnPostAuthRequestInterceptor ( { features , getSpacesService , log , http , } ) { http . registerOnPostAuth ( async ( request , response , toolkit ) => { const serverBasePath = http . basePath . serverBasePath ; const path = request . url . pathname ; const spacesService = getSpacesService ( ) ; const spaceId = spacesService . getSpaceId ( request ) ; const isRequestingKibanaRoot = path === '/' && spaceId === DEFAULT_SPACE_ID ; const isRequestingSpaceRoot = path === '/' && spaceId !== DEFAULT_SPACE_ID ; const isRequestingApplication = path . startsWith ( '/app' ) ; if ( isRequestingKibanaRoot ) { try { const spacesClient = spacesService . createSpacesClient ( request ) ; const spaces = await spacesClient . getAll ( ) ; if ( spaces . length === 1 ) { const space = spaces [ 0 ] ; const destination = addSpaceIdToPath ( serverBasePath , space . id , ENTER_SPACE_PATH ) ; return response . redirected ( { headers : { location : destination } } ) ; } if ( spaces . length > 0 ) { return response . redirected ( { headers : { location : getSpaceSelectorUrl ( serverBasePath ) } , } ) ; } } catch ( error ) { return response . customError ( wrapError ( error ) ) ; } } else if ( isRequestingSpaceRoot ) { const destination = addSpaceIdToPath ( serverBasePath , spaceId , ENTER_SPACE_PATH ) ; return response . redirected ( { headers : { location : destination } } ) ; } if ( isRequestingApplication ) { let space ; try { log . debug ( `Verifying access to space "${ spaceId }"` ) ; const spacesClient = spacesService . createSpacesClient ( request ) ; space = await spacesClient . get ( spaceId ) ; } catch ( error ) { const wrappedError = wrapError ( error ) ; const statusCode = wrappedError . statusCode ; switch ( statusCode ) { case 403 : log . debug ( `User unauthorized for space "${ spaceId }". ${ error }` ) ; return response . forbidden ( ) ; case 404 : log . debug ( `Unable to navigate to space "${ spaceId }", redirecting to Space Selector. ${ error }` ) ; return response . redirected ( { headers : { location : getSpaceSelectorUrl ( serverBasePath ) } , } ) ; default : log . error ( `Unable to navigate to space "${ spaceId }". ${ error }` ) ; return response . customError ( wrappedError ) ; } } const appId = path . split ( '/' , 3 ) [ 2 ] ; if ( appId !== 'kibana' && space && space . disabledFeatures . length > 0 ) { log . debug ( `Verifying application is available: "${ appId }"` ) ; const allFeatures = features . getKibanaFeatures ( ) ; const isRegisteredApp = allFeatures . some ( ( feature ) => feature . app . includes ( appId ) ) ; if ( isRegisteredApp ) { const enabledFeatures = allFeatures . filter ( ( feature ) => ! space . disabledFeatures . includes ( feature . id ) ) ; const isAvailableInSpace = enabledFeatures . some ( ( feature ) => feature . app . includes ( appId ) ) ; if ( ! isAvailableInSpace ) { log . debug ( `App ${ appId } is not enabled within space "${ spaceId }".` ) ; return response . notFound ( ) ; } } } } return toolkit . next ( ) ; } ) ; }