Marvin Live configuration guide

    Marvin Live 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.

    Configuration

    This application requires a configuration file to be passed as a command line argument. The configuration file holds all the key settings regarding networking, security, persistence, plugins and more. A sample file with defaults is provided within the application files: ~/app/node_modules/marvin-live/config-sample.json.

    Please copy this to your application directory, and rename it to your preference. Do not modify this file in place, and do not store your settings within the node_modulesdirectory, because it is automatically removed / replaced on upgrade !

    
    user:~/app$ cp node_modules/marvin-live/config-sample.json \
    ./config.json

    {info} Note: on Windows, make sure you save the json file with ANSI encoding when editing with a text editor such as Notepad.

    The minimum configuration requires port and license attributes to be specified, but a more general sample of the 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 Marvin Live plugins anywhere. See below in the spreadsheet for your full list of options:

    
    {
     "converterService": "http://localhost:8080/webservices/",
     "servicesDirectory": "../services/",
     "port": 8888,
     "license": ["./marvin4js-license.cxl", "./mlive-license.cxl"],
     "secretKey": "CHANGETHIS",
     "authentication": {
       "internal": {
         "type": "local",
         "label": "Testing domain",
         "accounts": [{
           "username": "demo",
           "password": "demo"
         }]
       }
      },
      "snapshotFields": [{
        "name": "task",
        "label": "Task"
      }, {
        "name": "status",
        "label": "Status",
        "values": ["Not ready for review", "Ready for review", "Approved", "On hold", "Synthesized", "Cancelled"]
      }]
    }

    Below you can find a detailed description for each option:

    {info} Note: All relative paths are resolved against the location of config.json.

    {info} Note 1: port 0 is treated as an ephemeral port, i.e: a random open port will be chosen.

    Note 2: On Linux/Unix servers non-root processes aren’t allowed to use port <1024, unless you change cap_net_bind_service in setcap. See below for the details of using setcap.

    Parameter name (environment variable) Type Description
    converterService ML_CONVERTER_SERVICE string URL to JChem Web Services without the rest-v0/ ending. Marvin Live will proxy requests by Marvin JS to this location for format converters and cleaners.Required: no
    servicesDirectory ML_SERVICES_DIRECTORY string Path to the folder where your real time, resolver, exporter and storage plugins are stored. For further details and examples, check the developer guide .Required: no
    license ML_LICENSE string or array of strings Path to the license file(s) provided by ChemAxon for this application. Accepts wildcards like *.cxl as of v16.12.5.Required: yes
    tls object 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 please see the official module description .
    tls.key string Path to the private key of the server in PEM format.Required: yes
    tls.cert string Path to the certificate key of the server in PEM format.Required: yes
    tls.ca string 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 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, certand caoptions.
    hostname ML_HOSTNAME string 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 The HTTP port you want the application to bind to. Naturally this port needs to be free.Default: 80Required: yes
    secretKey ML_SECRET_KEY string 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');"Required: yes
    authentication object 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.Provider specific options are document below in separate sections: LDAP , SAML , local .
    authentication.<domain>.label string Human readable name of the domain.Required: yes
    authentication.<domain>.type string "ldap", "saml" or "local"
    hideDomainsOnLoginScreen boolean 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
    databaseLocation ML_DATABASE_LOCATION string Path to the folder where databases can be created and kept.Default: in the folder of config.json
    deleteUnusedRooms ML_DELETE_UNUSED_ROOMS string Duration of inactivity in a room before it can be deleted in the following syntax: [0-9]+[m|h|d].This option is available in authenticated domains as well to control different domains individually.Examples:"90m" : delete after 90 minutes of inactivity"24h" : delete after 24 hours of inactivity"30d" : delete after 30 days of inactivityDefault: no deletion
    databaseCleanupInterval number Frequency of checking inactivity in rooms for cleanup, see deleteUnusedRooms. This option is available in authenticated domains as well to control different domains individually.Examples:When deleteUnusedRooms is "90m", databaseCleanupInterval could be lowered to 10 minutes by setting 600000.Default: 3600000 (1 hour in milliseconds)
    saveReportOnDelete ML_SAVE_REPORT_ON_DELETE string Path to the folder where an MRV formatted meeting report should be saved before a room is deleted with deleteUnusedRooms. This option is available in authenticated domains as well to control different domains individually.Default: no automatic saving
    themeOverrides ML_THEME_OVERRIDES string Path to a CSS file that adds or changes styles used in the Marvin Live theme.Default: no custom CSS file
    allowCrossOriginUploads ML_ALLOW_CROSS_ORIGIN_UPLOADS boolean Enable CORS on the /upload/apiendpoint (URL integration guide).Default: false
    enablePrivateRooms boolean Enable or disable the creation of private rooms from the lounge. Only available in authenticated domains, where a persistent user handle is available (username, DN, NameID).Default: true
    enablePublicRooms boolean Enable or disable the creation of public rooms from the lounge.Default: true
    marvinjs object 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, please find the Marvin JS configuration section below.Example: "marvinjs": { "templates": "./templates.mrv", "webservices": { "clean2dws": "/rest-v0/util/convert/clean", "molconvertws": "/rest-v0/util/calculate/molExport", "reactionconvertws": "/rest-v0/util/calculate/reactionExport", "stereoinfows": "/rest-v0/util/calculate/cipStereoInfo" },  "displaySettings": {     "toolbars": "reporting"  } }
    snapshotFields array of objects Configure what metadata fields should be prompted and tracked for each snapshot. This option is available in authenticated domains as well to control different domains individually. For details please find the Snapshot fields configuration section below.Default: "snapshotFields": [{ "name": "task", "label": "Task" }], Available from v17.30.0, replacing the previous deprecated additionalSnapshotFields configuration.

    Converter and cleaner web services

    Marvin Live 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 Marvin Live to it in the configuration’s converterService option.

    Setting up local authentication

    Marvin Live 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": "../certs/example-com-key.pem",
       "cert": "../certs/example-com-cert.pem"
     },
     "secretKey": "lalilulelo",
     "authentication": {
       "test": {
         "type": "local",
         "label": "Test Ltd",
         "accounts": [
           {"username": "demo", "password": "demo"},
           {"username": "demo2", "password": "demo2"}
         ]
       }
     }
    }

    Setting up LDAP authentication

    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": "../certs/example-com-key.pem",
       "cert": "../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}})"
       }
     }
    }

    LDAP specific configuration options

    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

    Setting up SAML authentication

    This application uses HTTP Redirect Binding for its AuthnRequests, and expects to receive the messages back via the HTTP POST binding.

    Configuration

    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": "../certs/example-com-key.pem",
       "cert": "../certs/example-com-cert.pem"
     }
    }

    Next, add a secretKeyand configure your identity provider in authentication: config.json:

    
    {
     "port": 443,
     "hostname": "example.com",
     "tls": {
       "key": "../certs/example-com-key.pem",
       "cert": "../certs/example-com-cert.pem"
     },
     "secretKey": "lalilulelo",
     "authentication": {
       "internal": {
         "type": "saml",
         "label": "Example",
         "entryPoint": "http://idp.example.com/oam/SSORedirect/metaAlias/apps/idp"
       }
     }
    }

    Registering as Service Provider

    Using the domain chosen in the authentication settings, in this example "internal", you can now register the Marvin Live service with your SAML provider. A service metadata descriptor is available if you open:

    https://example.com/login/internal/metadata

    The service’s issuer / entity ID is marvin-live-appand 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:8888/login/internal/callback"/>
      </SPSSODescriptor>
    </EntityDescriptor>

    SAML specific parameters

    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 Marvin Live server URL to use when generating metadata, and in SAML requests. Used when the application is behind a reverse proxy.

    Further options are available, please see this third-party module’s options.

    Marvin JS configuration

    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() methodDefault:{ "clean2dws": "/rest-v0/util/convert/clean", "molconvertws": "/rest-v0/util/calculate/molExport", "reactionconvertws": "/rest-v0/util/calculate/reactionExport", "stereoinfows": "/rest-v0/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-v0/util/convert/clean",
         "molconvertws": "/rest-v0/util/calculate/molExport",
         "reactionconvertws": "/rest-v0/util/calculate/reactionExport",
         "stereoinfows": "/rest-v0/util/calculate/cipStereoInfo"
      },
      "displaySettings": {
         "toolbars": "reporting"
      }
    }

    Snapshot field configuration

    Snapshot fields configure what metadata fields should be prompted and tracked for each snapshot. This option is available in authenticated domains as well to control different domains individually. An array of objects can be used as configuration, where each object has the following attributes:

    Name Type Description
    name string program name of the field
    label string human friendly name of the field
    placeholder string placeholder / example value. Optional.
    pattern string validation pattern for accepted values. Optional.
    values array of strings precise list of accepted values. Optional.
    ordered boolean in case of "values" option, this flag allows sorting snapshots based on the array index of the selected values. Optional
    colors array of strings in case of "values" option, colors assign a highlight color to selected value. Values are #RRGGBB formatted color codes. Intended primarily to highlight priority values (e.g. High -#EE2839, Medium - #FFD126, Low - #00C178. Optional

    Example:

    
    "snapshotFields": [{
      "name": "comment",
      "label": "Comment"
    }, {
      "name": "series",
      "label": "Series",
      "placeholder": "CXN123",
      "pattern": "^CXN\\d+$"
    }, {
      "name": "status"
      "label": "Status",
      "values": ["Not ready for review", "Ready for review", "Approved", "On hold", "Synthesized", "Cancelled"]
    }, {
      "label": "Priority",
      "name": "priority",
      "values": ["High", "Medium", "Low"],
      "ordered": true,
      "colors": ["/display/docs/marvin-live-configuration-guide.md#EE2839", "/display/docs/marvin-live-configuration-guide.md#FFD126", "/display/docs/marvin-live-configuration-guide.md#00C178"]
    }],

    Default:

    
    "snapshotFields": [{
      "name": "task",
      "label": "Task"
    }],

    Available from v17.30.0, replacing the previous deprecated additionalSnapshotFields configuration.

    Persistent storage

    Marvin Live includes an embedded database that keeps a history of all meeting rooms and their content - chemical structures drawn and comments. The purpose of this database is to prevent data loss during upgrades or configuration changes, but it’s used to store session information as well. To support typical data retention policies, Marvin Live can be configured to automatically delete unused meeting rooms with all included data, see deleteUnusedRooms.

    A separate database instance is created per authentication domain - stored in a folder named db-name. If no authentication domain is specified, all meeting content is stored in a db-appfolder. Session store is located in sessiondb. The location of these database folders can be changed with the databaseLocationsetting.

    Installing a plugin

    As described in the developer guides (see listing in the documentation index), Marvin Live comes with an ecosystem of plugins for a variety of uses. These plugins are static files stored in the servicesDirectory as defined in config.json and since the plugins are NodeJS modules, they can define their own dependencies, independent from what Marvin Live might provide and how that might change over time. For this reason, plugin dependencies need to be installed in the servicesDirectory. Installation goes exactly like with Marvin Live itself: npm install

    
    user:~/app/$ grep "servicesDirectory" config.json
        "servicesDirectory": "../services/",
    user:~/app/$ cd ../services/
    user:~/services/$ ls -al
    drwxr-xr-x  78 user group  2496 Nov 23 09:54 .
    drwxr-xr-x  75 user group  2400 Nov 16 12:39 ..
    -rw-rw-r--   1 user group    63 Nov 22 18:40 cc.credentials.json
    -rw-r--r--   1 user group  1574 Nov 23 09:53 compliancechecker.realtime.js
    -rw-r--r--   1 user group   587 Oct  6 13:00 compliancechecker.template.html
    -rw-r--r--   1 user group  2772 Aug 28 16:41 knimerest.realtime.js
    -rw-r--r--   1 user group   633 Mar 10  2017 knimerest.template.html
    -rw-r--r--   1 user group  2819 Oct  6 13:02 ml-utils.js
    -rw-r--r--   1 user group   575 Oct  6 12:54 package.json
    -rw-r--r--   1 user group   484 Nov 23 16:37 smiles.export.js
    user:~/services/$ less package.json #inspect dependencies
    user:~/services/$ npm install