Skip to content

Commit

Permalink
Feature/8raven (#705)
Browse files Browse the repository at this point in the history
* Title not editable in standalone mode

* standalone load v1 (working)

* load from database refinements with new conf var

* config.json reset to defaults

* first implementation - needs few refinements

* index on feature/log: ceda481 first implementation - needs few refinements

* added Tooltip for Save button in standalone mode

* polished

* fix on error notification

* minor refinement in documentation

* hide logout button in standalone mode

* man merge d137081

* man chg 0484e44

* added configuration to allow multiple data DBs

* fix on config-entrypoint and reorder parameters

* bugfix on config-entrypoint.sh

* fix to update standaloneDB for standaloneMultiDB

* added useffect in card.tsx to save DB

* query modified in saveDashboardThunks

* updated config-entrypoint

* added config parameter to set cusom Header

* documentation

* fix dirt in style.config

* fix dirt in config.json

* Update ApplicationConfig.ts fix dirt

* moving logging logic to its own reducer

* fixing new selector and small refactorings

* cleaning code and testing standalone

* adding database list check

* changing version to 3.18 to address address Cve-2023-4863 and cve-2023-38039

* removing unused imports

* working on final release

* fixed dashboards sidebar error when the db doesn't contain any dashboard and tested standalone

* removing useless import

* removing change in runCypherQuery and reusing the status of the queryResult correctly to trigger db change

* removing change in runCypherQuery and reusing the status of the queryResult correctly to trigger db change

---------

Co-authored-by: BlackRaven <p.baldinixx@gmail.com>
Co-authored-by: BlackRaven <35220904+8Rav3n@users.noreply.github.com>
Co-authored-by: Alfred Rubin <alfredo.rubin@neo4j.com>
  • Loading branch information
4 people authored Dec 6, 2023
1 parent 9753f70 commit b56215e
Show file tree
Hide file tree
Showing 21 changed files with 773 additions and 172 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# build stage
FROM node:lts-alpine AS build-stage
FROM node:lts-alpine3.18 AS build-stage

RUN yarn global add typescript jest
WORKDIR /usr/local/src/neodash
Expand All @@ -16,7 +16,7 @@ COPY ./ /usr/local/src/neodash
RUN yarn run build-minimal

# production stage
FROM nginx:alpine AS neodash
FROM nginx:alpine3.18 AS neodash
RUN apk upgrade

ENV NGINX_PORT=5005
Expand Down
69 changes: 67 additions & 2 deletions docs/modules/ROOT/pages/developer-guide/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ will look like this:
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
"standaloneDashboardURL": ""
"standaloneDashboardURL": "",
"standaloneAllowLoad": false,
"standaloneLoadFromOtherDatabases": false,
"standaloneMultiDatabase": false,
"standaloneDatabaseList": "neo4j"
"loggingMode": "0",
"loggingDatabase": "logs",
"customHeader": "",
}
....

Expand Down Expand Up @@ -87,6 +94,52 @@ use multiple databases.
inside Neo4j and would like to run a standalone mode deployment with a
dashboard from a URL, set this parameter to the complete URL pointing to
the dashboard JSON.

|standaloneAllowLoad |boolean |false |If set to yes the "Load Dashboard"
button will be enabled in standalone mode, allowing users to load
additional dashboards from Neo4J. This parameter is false by default
_unless you are using Neo4j Enterprise Edition_, which lets you use multiple
databases.
*NOTE*: when Load is enabled in standalone mode, only Database is available
as a source, not file.

|standaloneLoadFromOtherDatabases |boolean |false |If _standaloneAllowLoad_ is
set to true, this parmeter enables or not users to load dashboards from
other databases than the one deifned in _standaloneDashboardDatabase_. If
_standaloneAllowLoad_ is set to false this parameters has no effect.

|standaloneMultiDatabase |boolean |false |If this parameter set to true, the
standalone configuration will ignore the _standaloneDatabase_ parameter and
allow users to choose which database to connect to in the login screen, among
the ones provided in _standaloneDatabaseList_, with a dropdown list. This
parameter is false by default _unless you are using Neo4j Enterprise Edition_,
which lets you use multiple databases.

|standaloneDatabaseList |string |neo4j |If _standaloneMultiDatabase_ is
set to true, this parmeter must contain a comma separated list of database
names that will be displayed as options in the Database dropdown at user
login (e.g. 'neo4j,database1,database2' will populate the database dropdown
with the values 'neo4j','database1' and 'database2' in the connection screen).
If _standaloneMultiDatabase_ is set to false this parameters has no effect.

|loggingMode |string |none |Determines whether neodash should create any
user activity logs. possible values include: `0` (no log is created),
`1` (user login are tracked), `2` (tracks when a specific dashboard is
accessed/loaded or saved by a user*).

⚠️ Logs are created in Neo4J DB using the current user credentials
(or standaloneUsername if configured); write access to the log database
must be granted to enble any user to create logs.

⚠️ * Load/Save from/to file are not logged (only from/to Database)

|loggingDatabase |string |neo4j |When loggingMode is set to anything
else than '0', the database to use for logging. Log records (nodes)
will be created in this database.

|customHeader |string |none |When set the dashboard header will display
the prameter value as a fixed string, otherwise it will display the host
and port of current connection.
|===

== Configuring SSO
Expand Down Expand Up @@ -129,11 +182,23 @@ be enabled by changing the `standalone` config parameter:
* If standalone mode is `false`, all other configuration parameters are
ignored. NeoDash will run in Editor mode, and require a manual sign-in.
* If standalone mode is `true`, NeoDash will read all configuration
parameters. A *fixed dashboard* will be auto-loaded, and no changes to
parameters. A *predefined dashboard* will be auto-loaded, and no changes to
the dashboard can be made. There are two types of valid standalone
deployments:
** A standalone deployment that *reads the fixed dashboard from Neo4j*.
The `standaloneDashboardName` and `standaloneDashboardDatabase` config
parameters are used to define these.
** A standalone deployment that *reads the fixed dashboard from a URL*.
The `standaloneDashboardURL` config parameter is used to define this.

* Standalone mode can also be configured to allow users load a different
dashboard after the predefined one is loaded (a `Load Dashboard` button
will be displayed on the right side of dashboard title).
The `standaloneAllowLoad` and `standaloneLoadFromOtherDatabases` are used
to define this.
* When allowing users to load dashboards dyamically in standalone mode,
they may also need to connect to different databases, depending on the
specific dashboard bing loaded. this can be enabled setting
`standaloneMultiDatabase` to true and providing a comma separated list
of the allowed database names in the`standaloneDatabaseList` parameter.

5 changes: 5 additions & 0 deletions docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ docker run -it --rm -p 5005:5005 \
-e standaloneDatabase="neo4j" \
-e standaloneDashboardName="My Dashboard" \
-e standaloneDashboardDatabase="dashboards" \
-e standaloneDashboardURL="dashboards" \
-e standaloneAllowLoad=false \
-e standaloneLoadFromOtherDatabases=false \
-e standaloneMultiDatabase=false \
-e standaloneDatabaseList="neo4j" \
neo4jlabs/neodash
....

Expand Down
7 changes: 7 additions & 0 deletions docs/modules/ROOT/pages/developer-guide/state-management.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ standalone mode.
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
"standaloneDashboardURL": "dashboards",
"loggingMode": "0",
"loggingDatabase": "logging",
"standaloneAllowLoad": false,
"standaloneLoadFromOtherDatabases ": false,
"standaloneMultiDatabase": false,
"standaloneDatabaseList": "neo4j",
"notificationIsDismissable": null
}
....
9 changes: 8 additions & 1 deletion public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,12 @@
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
"standaloneDashboardURL": ""
"standaloneDashboardURL": "",
"standaloneAllowLoad": false,
"standaloneLoadFromOtherDatabases": false,
"standaloneMultiDatabase": false,
"standaloneDatabaseList": "neo4j",
"loggingMode": "0",
"loggingDatabase": "logs",
"customHeader": ""
}
15 changes: 12 additions & 3 deletions scripts/config-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ echo " \
\"ssoEnabled\": ${ssoEnabled:=false}, \
\"ssoProviders\": ${ssoProviders:=[]}, \
\"ssoDiscoveryUrl\": \"${ssoDiscoveryUrl:='https://example.com'}\", \
\"standalone\": "${standalone:=false}", \
\"standalone\": ${standalone:=false}, \
\"standaloneProtocol\": \"${standaloneProtocol:='neo4j+s'}\", \
\"standaloneHost\": \"${standaloneHost:='test.databases.neo4j.io'}\", \
\"standalonePort\": ${standalonePort:=7687}, \
Expand All @@ -16,5 +16,14 @@ echo " \
\"standalonePassword\": \"${standalonePassword:=}\", \
\"standaloneDashboardName\": \"${standaloneDashboardName:='My Dashboard'}\", \
\"standaloneDashboardDatabase\": \"${standaloneDashboardDatabase:='neo4j'}\", \
\"standaloneDashboardURL\": \"${standaloneDashboardURL:=}\" \
}" > /usr/share/nginx/html/config.json
\"standaloneDashboardURL\": \"${standaloneDashboardURL:=}\", \
\"standaloneAllowLoad\": ${standaloneAllowLoad:=false}, \
\"standaloneLoadFromOtherDatabases\": ${standaloneLoadFromOtherDatabases:=false}, \
\"standaloneMultiDatabase\": ${standaloneMultiDatabase:=false}, \
\"standaloneDatabaseList\": \"${standaloneDatabaseList:='neo4j'}\", \
\"loggingMode\": \"${loggingMode:='0'}\", \
\"loggingDatabase\": \"${loggingDatabase:='logs'}\", \
\"customHeader\": \"${customHeader:=}\" \
}" > /usr/share/nginx/html/config.json

echo "${styleConfigJson:={\}}" > /usr/share/nginx/html/style.config.json
16 changes: 15 additions & 1 deletion src/application/ApplicationActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ export const setStandaloneEnabled = (
standaloneDashboardDatabase: string,
standaloneDashboardURL: string,
standaloneUsername: string,
standalonePassword: string
standalonePassword: string,
standaloneAllowLoad: boolean,
standaloneLoadFromOtherDatabases: boolean,
standaloneMultiDatabase: boolean,
standaloneDatabaseList: string
) => ({
type: SET_STANDALONE_ENABLED,
payload: {
Expand All @@ -163,6 +167,10 @@ export const setStandaloneEnabled = (
standaloneDashboardURL,
standaloneUsername,
standalonePassword,
standaloneAllowLoad,
standaloneLoadFromOtherDatabases,
standaloneMultiDatabase,
standaloneDatabaseList,
},
});

Expand Down Expand Up @@ -219,3 +227,9 @@ export const setParametersToLoadAfterConnecting = (parameters: any) => ({
type: SET_PARAMETERS_TO_LOAD_AFTER_CONNECTING,
payload: { parameters },
});

export const SET_CUSTOM_HEADER = 'APPLICATION/SET_CUSTOM_HEADER';
export const setCustomHeader = (customHeader: any) => ({
type: SET_CUSTOM_HEADER,
payload: { customHeader },
});
42 changes: 42 additions & 0 deletions src/application/ApplicationReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ import {
SET_STANDALONE_MODE,
SET_WAIT_FOR_SSO,
SET_WELCOME_SCREEN_OPEN,
SET_CUSTOM_HEADER,
} from './ApplicationActions';
import {
SET_LOGGING_MODE,
SET_LOGGING_DATABASE,
SET_LOG_ERROR_NOTIFICATION,
LOGGING_PREFIX,
} from './logging/LoggingActions';
import { loggingReducer, LOGGING_INITIAL_STATE } from './logging/LoggingReducer';

const update = (state, mutations) => Object.assign({}, state, mutations);

Expand All @@ -56,6 +64,7 @@ const initialState = {
dashboardToLoadAfterConnecting: null,
waitForSSO: false,
standalone: false,
logging: LOGGING_INITIAL_STATE,
};
export const applicationReducer = (state = initialState, action: { type: any; payload: any }) => {
const { type, payload } = action;
Expand All @@ -82,6 +91,11 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
if (!action.type.startsWith('APPLICATION/')) {
return state;
}
if (action.type.startsWith(LOGGING_PREFIX)) {
const enrichedPayload = update(payload, { logging: state.logging });
const enrichedAction = { type, payload: enrichedPayload };
return { ...state, logging: loggingReducer(state.logging, enrichedAction) };
}

// Application state updates are handled here.
switch (type) {
Expand Down Expand Up @@ -134,6 +148,21 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
state = update(state, { standalone: standalone });
return state;
}
case SET_LOGGING_MODE: {
const { loggingMode } = payload;
state = update(state, { loggingMode: loggingMode });
return state;
}
case SET_LOGGING_DATABASE: {
const { loggingDatabase } = payload;
state = update(state, { loggingDatabase: loggingDatabase });
return state;
}
case SET_LOG_ERROR_NOTIFICATION: {
const { logErrorNotification } = payload;
state = update(state, { logErrorNotification: logErrorNotification });
return state;
}
case SET_SSO_ENABLED: {
const { enabled, discoveryUrl } = payload;
state = update(state, { ssoEnabled: enabled, ssoDiscoveryUrl: discoveryUrl });
Expand Down Expand Up @@ -166,6 +195,10 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
standaloneDashboardURL,
standaloneUsername,
standalonePassword,
standaloneAllowLoad,
standaloneLoadFromOtherDatabases,
standaloneMultiDatabase,
standaloneDatabaseList,
} = payload;
state = update(state, {
standalone: standalone,
Expand All @@ -178,6 +211,10 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
standaloneDashboardURL: standaloneDashboardURL,
standaloneUsername: standaloneUsername,
standalonePassword: standalonePassword,
standaloneAllowLoad: standaloneAllowLoad,
standaloneLoadFromOtherDatabases: standaloneLoadFromOtherDatabases,
standaloneMultiDatabase: standaloneMultiDatabase,
standaloneDatabaseList: standaloneDatabaseList,
});
return state;
}
Expand Down Expand Up @@ -268,6 +305,11 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
});
return state;
}
case SET_CUSTOM_HEADER: {
const { customHeader } = payload;
state = update(state, { customHeader: customHeader });
return state;
}
default: {
return state;
}
Expand Down
16 changes: 16 additions & 0 deletions src/application/ApplicationSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export const applicationGetConnectionDatabase = (state: any) => {
return state.application.connection.database;
};

export const applicationGetConnectionUser = (state: any) => {
return state.application.connection.username;
};

export const applicationGetShareDetails = (state: any) => {
return state.application.shareDetails;
};
Expand All @@ -45,6 +49,10 @@ export const applicationIsStandalone = (state: any) => {
return state.application.standalone;
};

export const applicationGetLoggingMode = (state: any) => {
return state.application.loggingMode;
};

export const applicationHasNeo4jDesktopConnection = (state: any) => {
return state.application.desktopConnection != null;
};
Expand Down Expand Up @@ -86,6 +94,10 @@ export const applicationGetStandaloneSettings = (state: any) => {
standaloneDashboardURL: state.application.standaloneDashboardURL,
standaloneUsername: state.application.standaloneUsername,
standalonePassword: state.application.standalonePassword,
standaloneAllowLoad: state.application.standaloneAllowLoad,
standaloneLoadFromOtherDatabases: state.application.standaloneLoadFromOtherDatabases,
standaloneMultiDatabase: state.application.standaloneMultiDatabase,
standaloneDatabaseList: state.application.standaloneDatabaseList,
};
};

Expand All @@ -112,3 +124,7 @@ export const applicationGetDebugState = (state: any) => {
}
return copy;
};

export const applicationGetCustomHeader = (state: any) => {
return state.application.customHeader;
};
Loading

0 comments on commit b56215e

Please sign in to comment.