Design Hub is a NodeJS based application for molecule design and idea management. It includes an HTTP and WebSocket server to serve multiple clients running the embedded web application.
All configuration is performed on the server, this document describes the available options.
This application requires a configuration file to be passed as a command line argument. The configuration file holds all the key settings regarding database connection, networking, security, persistence, plugins and more.
The minimum configuration requires database details, JChem Microservices details, a license and a port to be specified, but a more general sample of typical options is below. Note that some values point to files or other services. These should be changed to match your environment - of course you can store your ChemAxon license files or Design Hub plugins anywhere. See below in the spreadsheet for your full list of options:
{
"jchemMicroServices": "http://jms-gateway:8080/",
"mjsService": "http://mjs-service:8080/",
"databaseHost": "db",
"databasePort": 5432,
"databaseName": "designhub",
"databaseUser": "designhubuser",
"databasePassword": "CHANGETHIS",
"secretKey": "CHANGETHIS",
"authentication": {
"internal": {
"type": "local",
"label": "Testing domain",
"accounts": [{
"username": "demo",
"password": "demo"
}]
}
}
}
Below you can find a detailed description for each option:
{info} Note: All relative paths are resolved against the location of
config.json
.
Parameter name (environment variable) | Type | Required | Description |
---|---|---|---|
databaseHost ML_DATABASE_HOST |
string | yes | Hostname of the PostgreSQL database to connect to. |
databasePort ML_DATABASE_PORT |
string | no | Port of the PostgreSQL database to connect to. Default: 5432 |
databaseName ML_DATABASE_NAME |
string | yes | Name of the database to connect to. |
databaseUser ML_DATABASE_USER |
string | no | Username to authenticate with the database. |
databasePassword ML_DATABASE_PASSWORD |
string | no | Password to authenticate with the database. |
databaseRootCert ML_DATABASE_ROOT_CERT |
string | no | Path to database root SSL certificate file. If this is set the database connections use SSL. |
databaseVersion ML_DATABASE_VERSION |
string | no | PostgreSQL dialect version to use in the Design Hub SQL client. Use this when connect to different flavors of PSQL, e.g. Enterprise DB. |
jchemMicroServices ML_JCHEM_MICRO_SERVICES |
string | see description | URL to JChem Microservices gateway module without the rest-v1/ ending.Required: either jchemMicroservices or all of jmsIo , jmsDb , jmsStructureManipulation are required |
jmsIo ML_JMS_IO |
string | see description | URL to the JChem Microservices IO module without the rest-v1/ ending. Use this if JMS IO is deployed without a gateway service, for example as a standalone service.Required: either jchemMicroservices or all of jmsIo , jmsDb , jmsStructureManipulation are required |
jmsDb ML_JMS_DB |
string | see description | URL to the JChem Microservices DB module without the rest-v1/ ending. Use this if JMS DB is deployed without a gateway service, for example as a standalone service.Required: either jchemMicroservices or all of jmsIo , jmsDb , jmsStructureManipulation are required |
jmsStructureManipulation ML_JMS_STRUCURE_MANIPULATION |
string | see description | URL to the JChem Microservices Structure Manipulation module without the rest-v1/ ending. Use this if JMS Structure Manipulation is deployed without a gateway service, for example as a standalone service.Required: either jchemMicroservices or all of jmsIo , jmsDb , jmsStructureManipulation are required |
jmsMarkush ML_JMS_MARKUSH |
string | see description | URL to the JChem Microservices Markush Enumeration module without the rest-v1/ ending. Use this if JMS Markush Enumeration is deployed without a gateway service, for example as a standalone service. This module is needed for the contentAnalyzers features to work.Required: yes if contentAnalyzers are enabled. |
jchemMicroServicesTypeName |
string | no | Configures the molecule type used to standardize chemical structures for the purposes of searches and virtual registration in the JChem Microservices DB module. Must be one of the available types already configured. For details, please see DB Web Services documentation. Default: sample |
mjsService ML_MJS_SERVICE |
string | yes | URL to the Marvin JS web service module without the rest-v1/ ending. For details, please see Marvin JS Web Service documentation. |
servicesDirectory ML_SERVICES_DIRECTORY |
string | no | Path to the folder where realtime, resolver, exporter and storage plugins are stored. The /services folder is declared as a docker volume, so it expected a deployment will mount a folder to this volume. Changing this folder is not recommended. For further details and examples, check the developer guide.Default: /services |
remoteServices |
array of strings | no | List of URLs to load realtime, slow, storage, exporter, resolvers plugins implementing the Design Hub HTTP API specification. For further details and examples, check the relevant developer guides. |
license ML_LICENSE CHEMAXON_LICENSE_URL |
string or array of strings | yes | Path to the license file(s) provided by ChemAxon for this application, accepting wildcards like *.cxl . |
tls |
object | no | HTTPS server options in key-value pair form. All options of the NodeJS TLS module are supported, but the most typical 4 options are highlighted below: key , cert , ca , pfx . For more configuration options and details see the official module description . |
tls.key |
string | no | Path to the private key of the server in PEM format. |
tls.cert |
string | no | Path to the certificate key of the server in PEM format. |
tls.ca |
string | no | Path to the trusted certificates in PEM format. If this is omitted, several well known "root" CAs will be used, like VeriSign. These are used to authorize connections. |
tls.pfx |
string | no | Path to the bundle of private key, certificate and CA certs of the server in PFX or PKCS12 format. Mutually exclusive with tls 's key , cert and ca options. |
hostname ML_HOSTNAME |
string | see description | Hostname of the server. Needed only for single sign-on authentication, where a service callback needs to registered. Required: if SAML authentication is configured |
port ML_PORT |
number | yes | The HTTP port you want the application to bind to. In Docker environments this is configured to an exposed port, therefore modifying this shouldn't necessary under normal circumstances. |
secretKey ML_SECRET_KEY |
string | yes | Key to sign the session cookie with to prevent tampering. This string should be known only to the administrator of the server. The following command will generate a random string you can consider using:node -p "require('crypto').randomBytes(20).toString('base64');" |
authentication |
object | yes | The available identity providers users can authenticate with, in key-value pair form. Key: identifier or name of the domain, containing only lowercase letters, numbers and -, i.e: [a-z0-9-]+ Value: object containing the settings for the domain and protocol specific settings. Each option must have the following 2 attributes, but may specify further options: label and type . The default user object attribute mapping can be overridden by setting userNameAttribute and displayNameAttribute .Provider specific options are described below in separate sections: LDAP, SAML, local, OpenID Connect, Synergy. |
authentication.<domain>.label |
string | yes | Human readable name of the domain. |
authentication.<domain>.type |
string | see description | "ldap" , "saml" , "openId" , "synergy" , "local" . Further, provider specific options are described below in separate sections` |
adminUsername ML_ADMIN_USERNAME |
string | no | Username used to authenticate in the admin area. For details on access see the admin guide. |
adminPassword ML_ADMIN_PASSWORD |
string | no | Password used to authenticate in the admin area. Consider loading this password from a file with limited read permissions to prevent other users of the operating system from seeing the value of this sensitive setting. |
hideDomainsOnLoginScreen |
boolean | no | Hides the domain picklist from the login page. When set to true , generated login URLs are printed on STDOUT , one for each authentication domain.Default: false |
themeOverrides ML_THEME_OVERRIDES |
string | no | Path to a CSS file that adds or changes styles used in the Design Hub theme. Default: no custom CSS file |
allowCrossOriginUploads ML_ALLOW_CROSS_ORIGIN_UPLOADS |
boolean | no | Enable CORS on the /upload/api endpoint (URL integration guide).Default: false |
marvinjs |
object | no | Configure Marvin JS’s display options and services (API reference). This option is available in authenticated domains as well to control different domains individually. For details, find the Marvin JS configuration section below. Example: "marvinjs": { |
ML_LOG_LEVEL |
string | no | Configures which application module is started at elevated or reduced log levels. For each module, ERROR , WARN , INFO or DEBUG log levels are available. The default log level is info for all modules.Syntax: global_log_level [log_level=module_name] [log_level=module_name] ... i.e. a space separated list of definitions, starting with a global level, followed by = separation between a log level and a module name. For a list of module names, it is recommended to always consult with ChemAxon technical support as module names refer to application modules subject to constant changes as the application is developed. This configuration option is only available as an environment variable.Default: info |
ML_LOG_TRANSPORT |
string | no | Configures which additional transports to send logged messages. Use this to enable logging to a graylog-compatible server. This configuration option is only available as an environment variable. Available options: gelf |
ML_LOG_GELF_HOST |
string | no | Hostname of the graylog server. |
ML_LOG_GELF_PORT |
number | no | Port of the graylog stream to send messages. This configuration option is only available as an environment variable. Default: 12201 |
ML_LOG_GELF_PROTOCOL |
string | no | Protocol of the graylog stream to send messages. This configuration option is only available as an environment variable. Default: udp |
fileStore ML_FILE_STORE |
string | yes | Path to the folder where files uploaded by users can be saved. The folder needs to be writable to the main NodeJS process running under uid=2584, gid=1597 .Default: /filestore which corresponds to a volume declared by default in the Design Hub docker image. |
filestoreImplementation ML_FILESTORE_IMPLEMENTATION |
string | no | Controls what backend to use when users upload files. The default solution uses a filesystem backend, using generated filenames. If file system access is a burden, then Design Hub's database can be used. For a cloud solution, an AWS S3 bucket can be configured to persist files. To use the latter option, the filestoreS3BucketName option must be set. Maximum file size is 100 MB for database and 1000 MB for disk and S3.Default: disk Values: disk , database or S3 |
filestoreS3BucketName ML_FILESTORE_S3_BUCKET_NAME |
string | see description | Defines the name of an AWS S3 bucket to save files to when users initiate uploads. The Design Hub process must have permissions to execute the getBucketAcl , upload , getObject , deleteObject methods, and credentials must be supplied using a method natively supported by the AWS SDK. For more details read its documentation.Required: yes when filestoreImplementation is set to S3 |
registry |
object | no | Configures how Design Hub should generate unique virtual IDs to compounds when they are shared (i.e. transitioned from private to public visibility). |
registry.externalCheckStop |
string | no | Configures how long after sharing a compound should be checked on a daily basis in a real compound registry. All compounds in a workflow status of shared are checked every day.Syntax: <number><period> where period can be one of: d (day), w (week), m (month), y (year).Default: 3m |
registry.idPrefix |
string | no | Configures what string to prefix numeric ids with. For example with a value of VXN . the id of compound 123456 will be VXN123456 .Default: CPD |
registry.idSeparator |
string | no | Configures what string to use - if any - as a separator between the idPrefix and the numeric id portion. For example with a value of - the id of compound 123456 will be CPD-123456 .Default: (empty string) |
registry.idStart |
number | no | Configures what number to add to sequential ids generated during compound sharing. For example with a value of 500000 and the id of compound 123456 will be CPD623456 .Default: 0 |
registry.idPadding |
number | no | Configures how many decimal places to pad on the left with 0 characters. For example with a value of 9 , the id of compound 123456 will be CPD000123456 .Default: 0 |
systemHelp |
array of objects | no | Adds additional links to the help menu available to users. Use this to provide more options to get technical support for on-premises deployments or related to custom plugin backends |
systemHelp[*].label |
string | no | Human-friendly label of an additional help item |
systemHelp[*].url |
string | no | Absolute URL (starting with https:// ) to the help item |
uploadCache |
number | no | Configures the expiry interval of chemical structure files uploaded using the REST API. Configuration value is given in milliseconds. Default: 720000 (2 hours) |
commentFinalMinutes ML_COMMENT_FINAL_MINUTES |
number | no | Configures the interval while comments can be modified or deleted by their owner. Configuration value is given in minutes. Default: 10 (10 minutes) |
limitPublicCompoundsListSize |
number | no | Configures the maximum size of list provided via API /api/compounds/public Default: 1000 |
compoundFields |
array of objects | no | Configures additional editable fields for compounds |
compoundFields[*].name |
string | yes | Unique internal identifier of this field |
compoundFields[*].label |
string | yes | Human-friendly label of this field |
compoundFields[*].values |
array of strings | no | When defined, the field will be displayed as a combobox/dropdown with these values as choices. When missing, the field is displayed as a text input field. |
compoundFields[*].required |
boolean | no | Turns the field into mandatory field, with an asterisk and red underline if left empty. |
compoundFields[*].pattern |
Regexp | no | A regular expression that is used to validate the input, e.g. \d+ can be used to allow only numbers. |
Design Hub requires JChem Microservices (DB, IO, Structure Manipulation and optionally Markush Enumeration modules) to function. Using can forward HTTP requests made by Marvin JS to a converter web service. Your license includes the use of JChem Web Services as that converter, so please follow the JChem Web Services installation guide to set it up - to make things simpler, you may skip all database related installation steps. Once done, you can point Design Hub to it in the configuration’s converterService option.
Design Hub supports a very simple local authentication intended for personal testing or evaluation purposes. This enables all features depending on tracking users and storing profiles, without having to setup identity provider connections. Accounts are read from a list specified in config.json
. Below you can find a sample:
{
"port": 443,
"hostname": "example.com",
"tls": {
"key": "/config/certs/example-com-key.pem",
"cert": "/config/certs/example-com-cert.pem"
},
"secretKey": "lalilulelo",
"authentication": {
"test": {
"type": "local",
"label": "Test Ltd",
"accounts": [
{"username": "demo", "password": "demo"},
{"username": "demo2", "password": "demo2"}
]
}
}
}
The application supports LDAP and LDAPS authentication, which works with Active Directory as well. The most common configuration options are supported. Below you can find a sample configuration and a full list of options:
{
"port": 443,
"hostname": "example.com",
"tls": {
"key": "/config/certs/example-com-key.pem",
"cert": "/config/certs/example-com-cert.pem"
},
"secretKey": "lalilulelo",
"authentication": {
"corporate": {
"type": "ldap",
"label": "ACME Inc",
"url": "ldaps://ipa.acme.com:636",
"bindDn": "uid=serviceaccount,cn=accounts,dc=acme",
"bindCredentials": "BF95KPnVD9FxyGPh",
"searchBase": "cn=accounts,dc=acme",
"searchFilter": "(uid={{username}})"
}
}
}
Name | Type | Description |
---|---|---|
url |
string | full URL of LDAP server, including protocol and port, e.g: ldaps://ldap.company.tld:636/ |
bindDn |
string | DN of user permitted to search the LDAP server within the defined search base |
bindCredentials |
string | password for bindDn |
searchBase |
string | part of the directory to search in for the user, e.g: cn=users,dc=company |
searchFilter |
string | search filter that should match the user with either 1 or 0 entries. Use literal {{username}} to add the given username to the search, e.g: (uid={{username}}) |
firstName |
string | LDAP attribute that holds the display name of the user |
searchAttributes |
array of strings | Optional. Names of attributes to fetch from the LDAP server, e.g: ['displayName', 'mail'] . 'mail' is a required element for functionality relying on users' email addresses (such as notifications about new comments). |
This application uses HTTP Redirect Binding for its AuthnRequests
, and expects to receive the messages back via the HTTP POST binding.
First, you’ll need to configure the application with a host. You can do this by setting port
, and hostname
. Next, it’s strongly recommended to setup HTTPS with the tls
settings, to make sure any login details are only transmitted over a secure channel.
config.json:
{
"port": 443,
"hostname": "example.com",
"tls": {
"key": "/config/certs/example-com-key.pem",
"cert": "/config/certs/example-com-cert.pem"
}
}
Next, add a secretKey
and configure your identity provider in authentication
:
config.json:
{
"port": 443,
"hostname": "example.com",
"tls": {
"key": "/config/certs/example-com-key.pem",
"cert": "/config/certs/example-com-cert.pem"
},
"secretKey": "lalilulelo",
"authentication": {
"internal": {
"type": "saml",
"label": "Example",
"entryPoint": "http://idp.example.com/oam/SSORedirect/metaAlias/apps/idp"
}
}
}
Using the domain chosen in the authentication settings, in the above example internal
, the Design Hub service can be registered in the SAML provider. To help this, a service metadata descriptor is available at the following address:
https://example.com/domains/internal/metadata
The service’s issuer / entity ID is marvin-live-app
and the callback URL is generated from the tls
, hostname
, port
and domain
name options.
<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="marvin-live-app">
<SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor/>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
<AssertionConsumerService index="1" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://example.com/domains/internal/callback"/>
</SPSSODescriptor>
</EntityDescriptor>
Name | Type | Description |
---|---|---|
entryPoint |
string | URL for the identity provider. Required: yes |
cert |
string | Path to the identity provider’s certificate used to validate any SAML authorization responses. |
privateCert |
string | Path to the certificate used to sign any SAML authentication requests. |
decryptionPvk |
string | Path to the private key of the identity provider, used to decrypt any encrypted assertions that are received |
decryptionCert |
string | Path to the certificate used to attach to the service metadata. |
identifierFormat |
string | Name ID format to request from the identity provider. The use of unspecified and transient are not recomennded to enable private room usage. Default: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress |
callbackUrlBase |
string | Alternative Design Hub server URL to use when generating metadata, and in SAML requests. Used when the application is behind a reverse proxy. |
emailAttribute |
string | The name of the attribute in the IdP assertion carrying the email of the user. In the absence of this setting the mail or email attribute are used if present or the NameID in case it is of the urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress format. |
Further options are available, please see this third-party module’s options.
The application supports OpenID Connect authentication. Below you can find a sample configuration and a full list of options:
{
"port": 443,
"hostname": "example.com",
"tls": {
"key": "/config/certs/example-com-key.pem",
"cert": "/config/certs/example-com-cert.pem"
},
"secretKey": "lalilulelo",
"authentication": {
"corporate": {
"type": "openId",
"label": "ACME Inc",
"issuer": "https://myissuer.com",
"clientID": "dh-client",
"clientSecret": "password",
"callbackUrlBase": "https://example.com"
}
}
}
Name | Type | Description |
---|---|---|
issuer |
string | provide either URL of the issuer if the issuer supports standard discovery or URL of the OpenID Connect metadata document (e.g. https://myissuer.com/.well-known/openid-configuration) |
clientID |
string | client ID setup by issuer for the application |
clientSecret |
string | client secret setup by issuer for the application. Optional. If clientSecret is not specified, PKCE is forced. |
pkce |
string | Code challenge method for PKCE. Valid values: plain , S256 . In case of missing clientSecret S256 is the default. Optional. |
callbackUrlBase |
string | URL of the Design Hub reachable from IDP |
scope |
string | Provided if needed for getting enough user information. Example: openid profile email |
The application supports authentication with ChemAxon Synergy. Below you can find a sample configuration and a full list of options:
{
"port": 443,
"hostname": "example.com",
"tls": {
"key": "/config/certs/example-com-key.pem",
"cert": "/config/certs/example-com-cert.pem"
},
"secretKey": "lalilulelo",
"authentication": {
"corporate": {
"type": "synergy",
"label": "ACME Inc",
"issuer": "https://acme.synergy.cxn.io",
"clientID": "dh-client",
"clientSecret": "password",
"callbackUrlBase": "https://example.com"
}
}
}
Name | Type | Description |
---|---|---|
issuer |
string | provide URL of Synergy including team (e.g. https://acme.synergy.cxn.io) |
clientID |
string | client ID setup in Synergy |
clientSecret |
string | client secret setup in Synergy |
callbackUrlBase |
string | URL of the Design Hub reachable from Synergy |
This option configures Marvin JS’s display options and services (API reference). This option is available in authenticated domains as well to control different domains individually. An object is passed as configuration with the following attributes:
key | value |
---|---|
templates |
Path to an MRV formatted template file |
webservices |
Map of webservice names and URLs matching MarvinJS's setServices() method.Default:{ "clean2dws": "/rest-v1/util/convert/clean", "molconvertws": "/rest-v1/util/calculate/molExport", "reactionconvertws": "/rest-v1/util/calculate/reactionExport", "stereoinfows": "/rest-v1/util/calculate/cipStereoInfo" } |
displaySettings |
Map of display settings and values. Default: { "toolbars": "search" } |
Reference: https://marvinjs-demo.chemaxon.com/latest/jsdoc.html
Example:
"marvinjs": {
"templates": "./templates.mrv",
"webservices": {
"clean2dws": "/rest-v1/util/convert/clean",
"molconvertws": "/rest-v1/util/calculate/molExport",
"reactionconvertws": "/rest-v1/util/calculate/reactionExport",
"stereoinfows": "/rest-v1/util/calculate/cipStereoInfo"
},
"displaySettings": {
"toolbars": "reporting"
}
}
From v20.13.0, the role based access control system can be used to assign authorized users of the system to groups and roles/permissions can be assigned to groups.
By adding a groups
section to the domain configuration, individual groups can be added with a name (e.g. READERS
or WRITERS)
and a list of permissions. With ldap
/saml
/openId
/synergy
authentication, group membership of individual users is provided by the identity provider. With local
authentication, individual accounts can be assigned to a group by referencing the assigned group name on each account record.
{
...
"authentication":
"access-readonly": {
"type": "local",
"label": "Read-only authorization scheme",
"groups": {
"READERS": [
"ACCESS_HYPOTHESES",
"READ_NONASSIGNED_CONTENT",
"READ_NONJOINED_PROJECTS",
"JOIN_PROJECTS"
],
"WRITERS": [
"ACCESS_HYPOTHESES",
"ADD_PROJECTS",
"CREATE_CONTENT",
"WRITE_NONASSIGNED_CONTENT",
"WRITE_NONJOINED_PROJECTS"
"JOIN_PROJECTS"
]
},
"accounts": [
{"username": "vip", "password": "vip", "group": "VIP"},
{"username": "reader", "password": "reader", "group": "READERS"},
{"username": "writer", "password": "writer", "group": "WRITERS"}
]
}
}
...
}
By logging in to the admin interface and selecting the appropriate domain, the list of users and groups are displayed in small tables. These can be used to manage the list of groups available in the system, permissions assigned to each group, and the group membership of users. Using the buttons in the top-right corner of the groups table, new groups can be added, and using the actions for each group, further modifications can be made.
Name | Description |
---|---|
READ_JOINED_PROJECTS |
Allows viewing any content in projects where the user is member |
WRITE_JOINED_PROJECTS |
Allows viewing, modifying or deleting any content in projects where the user is member |
READ_NONJOINED_PROJECTS |
Allows viewing any content in projects where the user is not a member |
WRITE_NONJOINED_PROJECTS |
Allows viewing, adding, modifying or deleting content in projects where the user is not a member |
READ_ASSIGNED_CONTENT |
Allows viewing content where the user is assigned |
WRITE_ASSIGNED_CONTENT |
Allows viewing, modifying or deleting content the where user is assigned |
READ_NONASSIGNED_CONTENT |
Allows viewing content where the user is not assigned |
WRITE_NONASSIGNED_CONTENT |
Allows viewing, modifying or deleting content where the user is not assigned |
ACCESS_COMPOUNDS |
Allows viewing compounds |
ACCESS_DESIGNSETS |
Allows viewing design sets and compounds |
ACCESS_HYPOTHESES |
Allows viewing hypotheses, design sets, and compounds |
ACCESS_PROJECTS_META |
Allows viewing the list of projects and use the information in it for queries |
ADD_PROJECTS |
Allows adding projects to the system, if a company support plugin implements the necessary capability, or none are used |
JOIN_PROJECTS |
Allows adding to or deleting from the project membership of the user |
CREATE_CONTENT |
Allows creating new hypotheses, design sets and compounds |
ACCESS_REST_API |
Allows creating, revoking and viewing API tokens |
ACCESS_TAGS |
Allows viewing, adding and removing tags |
ACCESS_PROPERTY |
Allows viewing, adding and removing realtime, datacollector or slow plugin |
ACCESS_VOTING |
Allows viewing and casting votes on compounds |
ACCESS_SUBSTANCE_ID |
Allows viewing, searching and exporting substance IDs of compounds. For users without this permission, the original virtual identifiers are used. |