• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geosolutions-it / MapStore2 / 14217089396

02 Apr 2025 10:11AM UTC coverage: 92.673% (+15.7%) from 76.984%
14217089396

push

github

web-flow
Fix #10819 Manager menu is merged into Login/user menu and Manager menu is now deprecated  (#10963)

245 of 385 branches covered (63.64%)

66 of 77 new or added lines in 3 files covered. (85.71%)

18 existing lines in 5 files now uncovered.

2011 of 2170 relevant lines covered (92.67%)

825.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.33
/web/client/plugins/Login.jsx
1
/*
2
 * Copyright 2016, GeoSolutions Sas.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under the BSD-style license found in the
6
 * LICENSE file in the root directory of this source tree.
7
 */
8

9
import React from 'react';
10
import PropTypes from 'prop-types';
11

12
import epics from '../epics/login';
13
import { comparePendingChanges } from '../epics/pendingChanges';
14
import security from '../reducers/security';
15
import { UserMenu, UserDetailsMenuItem, PasswordResetMenuItem, LoginMenuItem, LogoutMenuItem, Login } from './login/index';
16
import {createPlugin} from "../utils/PluginsUtils";
17
import {burgerMenuSelector} from "../selectors/controls";
18
import {userSelector, isAdminUserSelector} from "../selectors/security";
19
import  usePluginItems  from '../hooks/usePluginItems';
20
import { connect } from 'react-redux';
21
import { itemSelected } from '../actions/manager';
22
import { isPageConfigured } from '../selectors/plugins';
23

24
const IMPORTER_ID = 'importer';
1✔
25
const RULE_MANAGER_ID = 'rulesmanager';
1✔
26

27
/**
28
  * Login Plugin. Allow to login/logout or show user info and reset password tools. If the user role is admin it will also show the manager tools. (manage accounts, manage tags and rules manager)
29
  * It renders a menu in {@link #plugins.OmniBar|OmniBar} plugin.
30
  * If `localConfig.json` `authenticationProviders` property in the root contains only one value, the login will use that provider by default.
31
  * `authenticationProviders` members are object with
32
  * - `type` (`<openID|basic>`): indicates the type of authentication to use.
33
  * - `provider` (`<geostore|google|...>`). In case of `type=openID`, the provider indicates the path to query in GeoStore.
34
  * - `url` optional URL to redirect in case of `openID`. By default it will use the standard convention to `rest/geostore/{provider}/login`.
35
  * - `imageURL` optional URL for the image to use in the link of the login form. (certain pre-defined services like `google` may have their own default logo)
36
  * - `title` a text to show in the link to the login page of the provider, if logo is present, this text is used as `alt` text in for the image.
37
  * Example of configuration.
38
  * ```json
39
  * {
40
  *  "authenticationProviders": [{"type": "openID", "provider": "google"}, {"type": "basic", "provider": "geostore"}]
41
  * }
42
  * ```
43
  * By default, if not set, it will use classic `{"type": "basic", "provider": "geostore"}` setup for GeoStore.
44
 *
45
 * If you want to show this plugin with BurgerMenu (so without Sidebar), apply the following configuration:
46
 *
47
 * ```javascript
48
 * {
49
 *     "cfg": {},
50
 *     "override": {
51
 *         "OmniBar": {
52
 *             "priority": 5
53
 *         }
54
 *     }
55
 * }
56
 * ```
57
 *
58
  * @class
59
  * @memberof plugins
60
  * @static
61
  * @name Login
62
  *
63
  * @prop {string} cfg.id identifier of the Plugin, by default `"mapstore-login-menu"`
64
  * @prop {boolean} cfg.isUsingLDAP flag refers to if the user with type LDAP or not to manage show/hide change psasword, by default: false
65
  * @prop {object[]} items this property contains the items injected from the other plugins
66
  *  * using the `containers` option in the plugin that want to inject the new menu items.
67
  * ```javascript
68
  * const MyMenuItemComponent = connect(selector, { onActivateTool })(({
69
  *  itemComponent, // default component that provides a consistent UI (see ManagerMenuItem in ManagerMenu plugin for props)
70
  *  onItemSelected, // callback to trigger the menu manager action on click, an id should be passed as argument
71
  *  onActivateTool, // example of a custom connected action
72
  * }) => {
73
  *  const ItemComponent = itemComponent;
74
  *  return (
75
  *      <ItemComponent
76
  *          glyph="heart"
77
  *          msgId="myMessageId"
78
  *          href="myMessageId"
79
  *          onClick={() => onActivateTool()}
80
  *      />
81
  *  );
82
  * });
83
  * createPlugin(
84
  *  'MyPlugin',
85
  *  {
86
  *      containers: {
87
  *          Login: {
88
  *              target: 'manager-menu', // or also "user-menu" if you want item for user(role is not admin) for admin role use "manager-menu",
89
  *              name: "TOOLNAME", // a name for the current tool.
90
  *              Component: MyMenuItemComponent
91
  *          },
92
  * // ...
93
  */
94

95
function LoginPlugin({
96
    id,
97
    user,
98
    entries,
99
    enableRulesManager,
100
    enableImporter,
101
    onItemSelected,
102
    hidden,
103
    items,
104
    isUsingLDAP,
105
    isAdmin,
106
    displayName,
107
    showAccountInfo,
108
    bsStyle,
109
    className
110
}, context) {
111

112
    const { loadedPlugins } = context;
16✔
113
    const configuredItems = usePluginItems({ items, loadedPlugins });
16✔
114
    const showPasswordChange = !(!isAdmin && isUsingLDAP);
16✔
115
    const authenticated = user?.[displayName];
16✔
116
    const userItems = authenticated ? [
16✔
117
        { name: 'UserDetails', Component: UserDetailsMenuItem, position: 1},
118
        { name: 'PasswordReset', Component: PasswordResetMenuItem, position: 2},
NEW
119
        ...configuredItems.filter(({ target }) => target === 'user-menu')
×
120
    ].sort((a, b) => a.position - b.position) : [];
11✔
121

122
    const managerItems = authenticated && isAdmin ? [
16✔
123
        ...entries
124
            .filter(e => enableRulesManager || e.path !== '/rules-manager')
3✔
125
            .filter(e => enableImporter || e.path !== '/importer')
2✔
126
            .map(e => ({...e, onClick: () => onItemSelected(e.id)})),
1✔
NEW
127
        ...configuredItems.filter(({ target }) => target === 'manager-menu')
×
NEW
128
    ].sort((a, b) => a.position - b.position) : [];
×
129

130
    const authItem = authenticated ? [{ name: 'Logout', Component: LogoutMenuItem }] : [{ name: 'Login', Component: LoginMenuItem}];
16✔
131

132
    const menuItems = [
16✔
133
        ...userItems,
134
        ...(userItems.length ? [{ type: 'divider' }] : []),
16✔
135
        ...managerItems,
136
        ...(managerItems.length ? [{ type: 'divider' }] : []),
16✔
137
        ...authItem
138
    ];
139

140
    return (
16✔
141
        <>
142
            <UserMenu
143
                key={authenticated ? 'authenticated' : '' }
16✔
144
                user={user}
145
                hidden={hidden}
146
                menuItems={menuItems}
147
                id={id}
148
                className={className}
149
                tooltipPosition={"bottom"}
150
                bsStyle={authenticated ? "success" : bsStyle}
16✔
151
                isAdmin={isAdmin}
152
                showPasswordChange={showPasswordChange}
153
                showAccountInfo={showAccountInfo}
154
                isUsingLDAP={isUsingLDAP}
155
            />
156
            <Login/>
157
        </>
158

159
    );
160
}
161

162

163
const ConnectedLoginPlugin = connect((state) => ({
18✔
164
    hidden: false,
165
    user: userSelector(state),
166
    enableRulesManager: isPageConfigured(RULE_MANAGER_ID)(state),
167
    enableImporter: isPageConfigured(IMPORTER_ID)(state),
168
    isAdmin: isAdminUserSelector(state)
169
}), {
170
    onItemSelected: itemSelected
171
})(LoginPlugin);
172

173
LoginPlugin.contextTypes = {
1✔
174
    loadedPlugins: PropTypes.object
175
};
176

177
LoginPlugin.propTypes = {
1✔
178
    id: PropTypes.string,
179
    entries: PropTypes.array,
180
    onItemSelected: PropTypes.func,
181
    enableRulesManager: PropTypes.bool,
182
    enableImporter: PropTypes.bool,
183
    items: PropTypes.array,
184
    user: PropTypes.object,
185
    hidden: PropTypes.bool,
186
    isAdmin: PropTypes.bool,
187
    isUsingLDAP: PropTypes.bool,
188
    displayName: PropTypes.string,
189
    className: PropTypes.string
190
};
191

192
LoginPlugin.defaultProps = {
1✔
193
    id: 'mapstore-login-menu',
194
    displayName: "name",
195
    user: {},
196
    entries: [
197
        {
198
            name: 'users.title',
199
            msgId: 'users.title',
200
            glyph: '1-group-mod',
201
            path: '/manager/usermanager',
202
            position: 1
203
        },
204
        {
205
            name: 'rulesmanager.menutitle',
206
            msgId: 'rulesmanager.menutitle',
207
            glyph: 'admin-geofence',
208
            path: '/rules-manager',
209
            position: 2
210
        },
211
        {
212
            name: 'importer.title',
213
            msgId: 'importer.title',
214
            glyph: 'upload',
215
            path: '/importer',
216
            position: 3
217
        }
218
    ],
219
    onItemSelected: () => {},
220
    items: [],
221
    enableRulesManager: false,
222
    enableImporter: false,
223
    hidden: false,
224
    isAdmin: false,
225
    isUsingLDAP: false,
226
    className: 'square-button'
227
};
228

229

230
export default createPlugin('Login', {
231
    component: ConnectedLoginPlugin,
232
    containers: {
233
        OmniBar: {
234
            name: "login",
235
            position: 3,
236
            tool: ConnectedLoginPlugin,
237
            priority: 1
238
        },
239
        BrandNavbar: {
240
            target: 'right-menu',
241
            position: 9,
242
            priority: 3,
243
            // TODO: remove square-button-md as soon all square button size are aligned
NEW
244
            Component: connect(() => ({ className: 'square-button-md' }))(ConnectedLoginPlugin)
×
245
        },
246
        SidebarMenu: {
247
            name: "login",
248
            position: 2,
249
            tool: ConnectedLoginPlugin,
250
            selector: (state) => ({
9✔
251
                style: { display: burgerMenuSelector(state) ? 'none' : null }
9!
252
            }),
253
            priority: 2
254
        }
255
    },
256
    reducers: {security},
257
    epics: {
258
        ...epics,
259
        comparePendingChanges
260
    }
261
});
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc