This reverts commit 8cdf56636a
.
This commit is contained in:
parent
d6200462c6
commit
e378555971
|
@ -3,7 +3,7 @@
|
|||
"version": "8.0.0",
|
||||
"kibanaVersion": "kibana",
|
||||
"configPath": ["xpack", "cloud"],
|
||||
"optionalPlugins": ["usageCollection", "home", "security"],
|
||||
"optionalPlugins": ["usageCollection", "home"],
|
||||
"server": true,
|
||||
"ui": true
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import { PluginInitializerContext } from '../../../../src/core/public';
|
||||
import { CloudPlugin } from './plugin';
|
||||
|
||||
export { CloudSetup, CloudConfigType } from './plugin';
|
||||
export { CloudSetup } from './plugin';
|
||||
export function plugin(initializerContext: PluginInitializerContext) {
|
||||
return new CloudPlugin(initializerContext);
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
function createSetupMock() {
|
||||
return {
|
||||
cloudId: 'mock-cloud-id',
|
||||
isCloudEnabled: true,
|
||||
resetPasswordUrl: 'reset-password-url',
|
||||
accountUrl: 'account-url',
|
||||
};
|
||||
}
|
||||
|
||||
export const cloudMock = {
|
||||
createSetup: createSetupMock,
|
||||
};
|
|
@ -6,51 +6,40 @@
|
|||
|
||||
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { SecurityPluginStart } from '../../security/public';
|
||||
import { getIsCloudEnabled } from '../common/is_cloud_enabled';
|
||||
import { ELASTIC_SUPPORT_LINK } from '../common/constants';
|
||||
import { HomePublicPluginSetup } from '../../../../src/plugins/home/public';
|
||||
import { createUserMenuLinks } from './user_menu_links';
|
||||
|
||||
export interface CloudConfigType {
|
||||
interface CloudConfigType {
|
||||
id?: string;
|
||||
resetPasswordUrl?: string;
|
||||
deploymentUrl?: string;
|
||||
accountUrl?: string;
|
||||
}
|
||||
|
||||
interface CloudSetupDependencies {
|
||||
home?: HomePublicPluginSetup;
|
||||
}
|
||||
|
||||
interface CloudStartDependencies {
|
||||
security?: SecurityPluginStart;
|
||||
}
|
||||
|
||||
export interface CloudSetup {
|
||||
cloudId?: string;
|
||||
cloudDeploymentUrl?: string;
|
||||
isCloudEnabled: boolean;
|
||||
resetPasswordUrl?: string;
|
||||
accountUrl?: string;
|
||||
}
|
||||
|
||||
export class CloudPlugin implements Plugin<CloudSetup> {
|
||||
private config!: CloudConfigType;
|
||||
private isCloudEnabled: boolean;
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext) {
|
||||
this.config = this.initializerContext.config.get<CloudConfigType>();
|
||||
this.isCloudEnabled = false;
|
||||
}
|
||||
|
||||
public async setup(core: CoreSetup, { home }: CloudSetupDependencies) {
|
||||
const { id, resetPasswordUrl, deploymentUrl } = this.config;
|
||||
this.isCloudEnabled = getIsCloudEnabled(id);
|
||||
const isCloudEnabled = getIsCloudEnabled(id);
|
||||
|
||||
if (home) {
|
||||
home.environment.update({ cloud: this.isCloudEnabled });
|
||||
if (this.isCloudEnabled) {
|
||||
home.environment.update({ cloud: isCloudEnabled });
|
||||
if (isCloudEnabled) {
|
||||
home.tutorials.setVariable('cloud', { id, resetPasswordUrl });
|
||||
}
|
||||
}
|
||||
|
@ -58,11 +47,11 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
return {
|
||||
cloudId: id,
|
||||
cloudDeploymentUrl: deploymentUrl,
|
||||
isCloudEnabled: this.isCloudEnabled,
|
||||
isCloudEnabled,
|
||||
};
|
||||
}
|
||||
|
||||
public start(coreStart: CoreStart, { security }: CloudStartDependencies) {
|
||||
public start(coreStart: CoreStart) {
|
||||
const { deploymentUrl } = this.config;
|
||||
coreStart.chrome.setHelpSupportUrl(ELASTIC_SUPPORT_LINK);
|
||||
if (deploymentUrl) {
|
||||
|
@ -74,10 +63,5 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
href: deploymentUrl,
|
||||
});
|
||||
}
|
||||
|
||||
if (security && this.isCloudEnabled) {
|
||||
const userMenuLinks = createUserMenuLinks(this.config);
|
||||
security.navControlService.addUserMenuLinks(userMenuLinks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { UserMenuLink } from '../../security/public';
|
||||
import { CloudConfigType } from '.';
|
||||
|
||||
export const createUserMenuLinks = (config: CloudConfigType): UserMenuLink[] => {
|
||||
const { resetPasswordUrl, accountUrl } = config;
|
||||
const userMenuLinks = [] as UserMenuLink[];
|
||||
|
||||
if (resetPasswordUrl) {
|
||||
userMenuLinks.push({
|
||||
label: i18n.translate('xpack.cloud.userMenuLinks.profileLinkText', {
|
||||
defaultMessage: 'Cloud profile',
|
||||
}),
|
||||
iconType: 'logoCloud',
|
||||
href: resetPasswordUrl,
|
||||
order: 100,
|
||||
});
|
||||
}
|
||||
|
||||
if (accountUrl) {
|
||||
userMenuLinks.push({
|
||||
label: i18n.translate('xpack.cloud.userMenuLinks.accountLinkText', {
|
||||
defaultMessage: 'Account & Billing',
|
||||
}),
|
||||
iconType: 'gear',
|
||||
href: accountUrl,
|
||||
order: 200,
|
||||
});
|
||||
}
|
||||
|
||||
return userMenuLinks;
|
||||
};
|
|
@ -23,7 +23,6 @@ const configSchema = schema.object({
|
|||
apm: schema.maybe(apmConfigSchema),
|
||||
resetPasswordUrl: schema.maybe(schema.string()),
|
||||
deploymentUrl: schema.maybe(schema.string()),
|
||||
accountUrl: schema.maybe(schema.string()),
|
||||
});
|
||||
|
||||
export type CloudConfigType = TypeOf<typeof configSchema>;
|
||||
|
@ -33,7 +32,6 @@ export const config: PluginConfigDescriptor<CloudConfigType> = {
|
|||
id: true,
|
||||
resetPasswordUrl: true,
|
||||
deploymentUrl: true,
|
||||
accountUrl: true,
|
||||
},
|
||||
schema: configSchema,
|
||||
};
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
export { SecurityPluginSetup, SecurityPluginStart };
|
||||
export { AuthenticatedUser } from '../common/model';
|
||||
export { SecurityLicense, SecurityLicenseFeatures } from '../common/licensing';
|
||||
export { UserMenuLink } from '../public/nav_control';
|
||||
|
||||
export const plugin: PluginInitializer<
|
||||
SecurityPluginSetup,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import { authenticationMock } from './authentication/index.mock';
|
||||
import { createSessionTimeoutMock } from './session/session_timeout.mock';
|
||||
import { licenseMock } from '../common/licensing/index.mock';
|
||||
import { navControlServiceMock } from './nav_control/index.mock';
|
||||
|
||||
function createSetupMock() {
|
||||
return {
|
||||
|
@ -16,13 +15,7 @@ function createSetupMock() {
|
|||
license: licenseMock.create(),
|
||||
};
|
||||
}
|
||||
function createStartMock() {
|
||||
return {
|
||||
navControlService: navControlServiceMock.createStart(),
|
||||
};
|
||||
}
|
||||
|
||||
export const securityMock = {
|
||||
createSetup: createSetupMock,
|
||||
createStart: createStartMock,
|
||||
};
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { SecurityNavControlServiceStart } from '.';
|
||||
|
||||
export const navControlServiceMock = {
|
||||
createStart: (): jest.Mocked<SecurityNavControlServiceStart> => ({
|
||||
getUserMenuLinks$: jest.fn(),
|
||||
addUserMenuLinks: jest.fn(),
|
||||
}),
|
||||
};
|
|
@ -4,5 +4,4 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { SecurityNavControlService, SecurityNavControlServiceStart } from './nav_control_service';
|
||||
export { UserMenuLink } from './nav_control_component';
|
||||
export { SecurityNavControlService } from './nav_control_service';
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
.chrNavControl__userMenu {
|
||||
.euiContextMenuPanelTitle {
|
||||
// Uppercased by default, override to match actual username
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.euiContextMenuItem {
|
||||
// Temp fix for EUI issue https://github.com/elastic/eui/issues/3092
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { shallowWithIntl, nextTick, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { SecurityNavControl } from './nav_control_component';
|
||||
import { AuthenticatedUser } from '../../common/model';
|
||||
|
@ -18,7 +17,6 @@ describe('SecurityNavControl', () => {
|
|||
user: new Promise(() => {}) as Promise<AuthenticatedUser>,
|
||||
editProfileUrl: '',
|
||||
logoutUrl: '',
|
||||
userMenuLinks$: new BehaviorSubject([]),
|
||||
};
|
||||
|
||||
const wrapper = shallowWithIntl(<SecurityNavControl {...props} />);
|
||||
|
@ -44,7 +42,6 @@ describe('SecurityNavControl', () => {
|
|||
user: Promise.resolve({ full_name: 'foo' }) as Promise<AuthenticatedUser>,
|
||||
editProfileUrl: '',
|
||||
logoutUrl: '',
|
||||
userMenuLinks$: new BehaviorSubject([]),
|
||||
};
|
||||
|
||||
const wrapper = shallowWithIntl(<SecurityNavControl {...props} />);
|
||||
|
@ -73,7 +70,6 @@ describe('SecurityNavControl', () => {
|
|||
user: Promise.resolve({ full_name: 'foo' }) as Promise<AuthenticatedUser>,
|
||||
editProfileUrl: '',
|
||||
logoutUrl: '',
|
||||
userMenuLinks$: new BehaviorSubject([]),
|
||||
};
|
||||
|
||||
const wrapper = mountWithIntl(<SecurityNavControl {...props} />);
|
||||
|
@ -95,7 +91,6 @@ describe('SecurityNavControl', () => {
|
|||
user: Promise.resolve({ full_name: 'foo' }) as Promise<AuthenticatedUser>,
|
||||
editProfileUrl: '',
|
||||
logoutUrl: '',
|
||||
userMenuLinks$: new BehaviorSubject([]),
|
||||
};
|
||||
|
||||
const wrapper = mountWithIntl(<SecurityNavControl {...props} />);
|
||||
|
@ -112,37 +107,4 @@ describe('SecurityNavControl', () => {
|
|||
expect(findTestSubject(wrapper, 'profileLink')).toHaveLength(1);
|
||||
expect(findTestSubject(wrapper, 'logoutLink')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders a popover with additional user menu links registered by other plugins', async () => {
|
||||
const props = {
|
||||
user: Promise.resolve({ full_name: 'foo' }) as Promise<AuthenticatedUser>,
|
||||
editProfileUrl: '',
|
||||
logoutUrl: '',
|
||||
userMenuLinks$: new BehaviorSubject([
|
||||
{ label: 'link1', href: 'path-to-link-1', iconType: 'empty', order: 1 },
|
||||
{ label: 'link2', href: 'path-to-link-2', iconType: 'empty', order: 2 },
|
||||
{ label: 'link3', href: 'path-to-link-3', iconType: 'empty', order: 3 },
|
||||
]),
|
||||
};
|
||||
|
||||
const wrapper = mountWithIntl(<SecurityNavControl {...props} />);
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
|
||||
expect(findTestSubject(wrapper, 'userMenu')).toHaveLength(0);
|
||||
expect(findTestSubject(wrapper, 'profileLink')).toHaveLength(0);
|
||||
expect(findTestSubject(wrapper, 'userMenuLink__link1')).toHaveLength(0);
|
||||
expect(findTestSubject(wrapper, 'userMenuLink__link2')).toHaveLength(0);
|
||||
expect(findTestSubject(wrapper, 'userMenuLink__link3')).toHaveLength(0);
|
||||
expect(findTestSubject(wrapper, 'logoutLink')).toHaveLength(0);
|
||||
|
||||
wrapper.find(EuiHeaderSectionItemButton).simulate('click');
|
||||
|
||||
expect(findTestSubject(wrapper, 'userMenu')).toHaveLength(1);
|
||||
expect(findTestSubject(wrapper, 'profileLink')).toHaveLength(1);
|
||||
expect(findTestSubject(wrapper, 'userMenuLink__link1')).toHaveLength(1);
|
||||
expect(findTestSubject(wrapper, 'userMenuLink__link2')).toHaveLength(1);
|
||||
expect(findTestSubject(wrapper, 'userMenuLink__link3')).toHaveLength(1);
|
||||
expect(findTestSubject(wrapper, 'logoutLink')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,52 +7,38 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { Component } from 'react';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import {
|
||||
EuiAvatar,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiHeaderSectionItemButton,
|
||||
EuiLink,
|
||||
EuiText,
|
||||
EuiSpacer,
|
||||
EuiPopover,
|
||||
EuiLoadingSpinner,
|
||||
EuiIcon,
|
||||
EuiContextMenu,
|
||||
EuiContextMenuPanelItemDescriptor,
|
||||
IconType,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { AuthenticatedUser } from '../../common/model';
|
||||
|
||||
import './nav_control_component.scss';
|
||||
|
||||
export interface UserMenuLink {
|
||||
label: string;
|
||||
iconType: IconType;
|
||||
href: string;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
user: Promise<AuthenticatedUser>;
|
||||
editProfileUrl: string;
|
||||
logoutUrl: string;
|
||||
userMenuLinks$: Observable<UserMenuLink[]>;
|
||||
}
|
||||
|
||||
interface State {
|
||||
isOpen: boolean;
|
||||
authenticatedUser: AuthenticatedUser | null;
|
||||
userMenuLinks: UserMenuLink[];
|
||||
}
|
||||
|
||||
export class SecurityNavControl extends Component<Props, State> {
|
||||
private subscription?: Subscription;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isOpen: false,
|
||||
authenticatedUser: null,
|
||||
userMenuLinks: [],
|
||||
};
|
||||
|
||||
props.user.then((authenticatedUser) => {
|
||||
|
@ -62,18 +48,6 @@ export class SecurityNavControl extends Component<Props, State> {
|
|||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.subscription = this.props.userMenuLinks$.subscribe(async (userMenuLinks) => {
|
||||
this.setState({ userMenuLinks });
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.subscription) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
onMenuButtonClick = () => {
|
||||
if (!this.state.authenticatedUser) {
|
||||
return;
|
||||
|
@ -92,13 +66,13 @@ export class SecurityNavControl extends Component<Props, State> {
|
|||
|
||||
render() {
|
||||
const { editProfileUrl, logoutUrl } = this.props;
|
||||
const { authenticatedUser, userMenuLinks } = this.state;
|
||||
const { authenticatedUser } = this.state;
|
||||
|
||||
const username =
|
||||
const name =
|
||||
(authenticatedUser && (authenticatedUser.full_name || authenticatedUser.username)) || '';
|
||||
|
||||
const buttonContents = authenticatedUser ? (
|
||||
<EuiAvatar name={username} size="s" />
|
||||
<EuiAvatar name={name} size="s" />
|
||||
) : (
|
||||
<EuiLoadingSpinner size="m" />
|
||||
);
|
||||
|
@ -118,60 +92,6 @@ export class SecurityNavControl extends Component<Props, State> {
|
|||
</EuiHeaderSectionItemButton>
|
||||
);
|
||||
|
||||
const profileMenuItem = {
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.security.navControlComponent.editProfileLinkText"
|
||||
defaultMessage="Profile"
|
||||
/>
|
||||
),
|
||||
icon: <EuiIcon type="user" size="m" />,
|
||||
href: editProfileUrl,
|
||||
'data-test-subj': 'profileLink',
|
||||
};
|
||||
|
||||
const logoutMenuItem = {
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id="xpack.security.navControlComponent.logoutLinkText"
|
||||
defaultMessage="Log out"
|
||||
/>
|
||||
),
|
||||
icon: <EuiIcon type="exit" size="m" />,
|
||||
href: logoutUrl,
|
||||
'data-test-subj': 'logoutLink',
|
||||
};
|
||||
|
||||
const items: EuiContextMenuPanelItemDescriptor[] = [];
|
||||
|
||||
items.push(profileMenuItem);
|
||||
|
||||
if (userMenuLinks.length) {
|
||||
const userMenuLinkMenuItems = userMenuLinks
|
||||
.sort(({ order: orderA = Infinity }, { order: orderB = Infinity }) => orderA - orderB)
|
||||
.map(({ label, iconType, href }: UserMenuLink) => ({
|
||||
name: <EuiText>{label}</EuiText>,
|
||||
icon: <EuiIcon type={iconType} size="m" />,
|
||||
href,
|
||||
'data-test-subj': `userMenuLink__${label}`,
|
||||
}));
|
||||
|
||||
items.push(...userMenuLinkMenuItems, {
|
||||
isSeparator: true,
|
||||
key: 'securityNavControlComponent__userMenuLinksSeparator',
|
||||
});
|
||||
}
|
||||
|
||||
items.push(logoutMenuItem);
|
||||
|
||||
const panels = [
|
||||
{
|
||||
id: 0,
|
||||
title: username,
|
||||
items,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<EuiPopover
|
||||
id="headerUserMenu"
|
||||
|
@ -182,10 +102,45 @@ export class SecurityNavControl extends Component<Props, State> {
|
|||
repositionOnScroll
|
||||
closePopover={this.closeMenu}
|
||||
panelPaddingSize="none"
|
||||
buffer={0}
|
||||
>
|
||||
<div data-test-subj="userMenu">
|
||||
<EuiContextMenu className="chrNavControl__userMenu" initialPanelId={0} panels={panels} />
|
||||
<div style={{ width: 320 }} data-test-subj="userMenu">
|
||||
<EuiFlexGroup gutterSize="m" className="euiHeaderProfile" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiAvatar name={name} size="xl" />
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem>
|
||||
<EuiText>
|
||||
<p className="eui-textBreakWord">{name}</p>
|
||||
</EuiText>
|
||||
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup justifyContent="spaceBetween">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiLink href={editProfileUrl} data-test-subj="profileLink">
|
||||
<FormattedMessage
|
||||
id="xpack.security.navControlComponent.editProfileLinkText"
|
||||
defaultMessage="Edit profile"
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiLink href={logoutUrl} data-test-subj="logoutLink">
|
||||
<FormattedMessage
|
||||
id="xpack.security.navControlComponent.logoutLinkText"
|
||||
defaultMessage="Log out"
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
</EuiPopover>
|
||||
);
|
||||
|
|
|
@ -4,16 +4,12 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { sortBy } from 'lodash';
|
||||
import { Observable, Subscription, BehaviorSubject, ReplaySubject } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { CoreStart } from 'src/core/public';
|
||||
|
||||
import ReactDOM from 'react-dom';
|
||||
import React from 'react';
|
||||
|
||||
import { SecurityLicense } from '../../common/licensing';
|
||||
import { SecurityNavControl, UserMenuLink } from './nav_control_component';
|
||||
import { SecurityNavControl } from './nav_control_component';
|
||||
import { AuthenticationServiceSetup } from '../authentication';
|
||||
|
||||
interface SetupDeps {
|
||||
|
@ -26,18 +22,6 @@ interface StartDeps {
|
|||
core: CoreStart;
|
||||
}
|
||||
|
||||
export interface SecurityNavControlServiceStart {
|
||||
/**
|
||||
* Returns an Observable of the array of user menu links registered by other plugins
|
||||
*/
|
||||
getUserMenuLinks$: () => Observable<UserMenuLink[]>;
|
||||
|
||||
/**
|
||||
* Registers the provided user menu links to be displayed in the user menu in the global nav
|
||||
*/
|
||||
addUserMenuLinks: (newUserMenuLink: UserMenuLink[]) => void;
|
||||
}
|
||||
|
||||
export class SecurityNavControlService {
|
||||
private securityLicense!: SecurityLicense;
|
||||
private authc!: AuthenticationServiceSetup;
|
||||
|
@ -47,16 +31,13 @@ export class SecurityNavControlService {
|
|||
|
||||
private securityFeaturesSubscription?: Subscription;
|
||||
|
||||
private readonly stop$ = new ReplaySubject(1);
|
||||
private userMenuLinks$ = new BehaviorSubject<UserMenuLink[]>([]);
|
||||
|
||||
public setup({ securityLicense, authc, logoutUrl }: SetupDeps) {
|
||||
this.securityLicense = securityLicense;
|
||||
this.authc = authc;
|
||||
this.logoutUrl = logoutUrl;
|
||||
}
|
||||
|
||||
public start({ core }: StartDeps): SecurityNavControlServiceStart {
|
||||
public start({ core }: StartDeps) {
|
||||
this.securityFeaturesSubscription = this.securityLicense.features$.subscribe(
|
||||
({ showLinks }) => {
|
||||
const isAnonymousPath = core.http.anonymousPaths.isAnonymous(window.location.pathname);
|
||||
|
@ -68,14 +49,6 @@ export class SecurityNavControlService {
|
|||
}
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
getUserMenuLinks$: () =>
|
||||
this.userMenuLinks$.pipe(map(this.sortUserMenuLinks), takeUntil(this.stop$)),
|
||||
addUserMenuLinks: (userMenuLink: UserMenuLink[]) => {
|
||||
this.userMenuLinks$.next(userMenuLink);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public stop() {
|
||||
|
@ -84,7 +57,6 @@ export class SecurityNavControlService {
|
|||
this.securityFeaturesSubscription = undefined;
|
||||
}
|
||||
this.navControlRegistered = false;
|
||||
this.stop$.next();
|
||||
}
|
||||
|
||||
private registerSecurityNavControl(
|
||||
|
@ -100,7 +72,6 @@ export class SecurityNavControlService {
|
|||
user: currentUserPromise,
|
||||
editProfileUrl: core.http.basePath.prepend('/security/account'),
|
||||
logoutUrl: this.logoutUrl,
|
||||
userMenuLinks$: this.userMenuLinks$,
|
||||
};
|
||||
ReactDOM.render(
|
||||
<I18nContext>
|
||||
|
@ -115,8 +86,4 @@ export class SecurityNavControlService {
|
|||
|
||||
this.navControlRegistered = true;
|
||||
}
|
||||
|
||||
private sortUserMenuLinks(userMenuLinks: UserMenuLink[]) {
|
||||
return sortBy(userMenuLinks, 'order');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,12 +97,7 @@ describe('Security Plugin', () => {
|
|||
data: {} as DataPublicPluginStart,
|
||||
features: {} as FeaturesPluginStart,
|
||||
})
|
||||
).toEqual({
|
||||
navControlService: {
|
||||
getUserMenuLinks$: expect.any(Function),
|
||||
addUserMenuLinks: expect.any(Function),
|
||||
},
|
||||
});
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it('starts Management Service if `management` plugin is available', () => {
|
||||
|
|
|
@ -146,13 +146,11 @@ export class SecurityPlugin
|
|||
|
||||
public start(core: CoreStart, { management, securityOss }: PluginStartDependencies) {
|
||||
this.sessionTimeout.start();
|
||||
this.navControlService.start({ core });
|
||||
this.securityCheckupService.start({ securityOssStart: securityOss, docLinks: core.docLinks });
|
||||
|
||||
if (management) {
|
||||
this.managementService.start({ capabilities: core.application.capabilities });
|
||||
}
|
||||
|
||||
return { navControlService: this.navControlService.start({ core }) };
|
||||
}
|
||||
|
||||
public stop() {
|
||||
|
|
Loading…
Reference in a new issue