UNPKG

signalk-server

Version:

An implementation of a [Signal K](http://signalk.org) server for boats.

136 lines (129 loc) 29.7 kB
<!DOCTYPE html><html class="default" lang="en" data-base="../../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>WebApps | Signal K</title><meta name="description" content="Documentation for Signal K"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../../assets/style.css?cache=1767726585343"/><link rel="stylesheet" href="../../assets/highlight.css?cache=1767726585343"/><script defer src="../../assets/main.js?cache=1767726585343"></script><script async src="../../assets/icons.js?cache=1767726585343" id="tsd-icons-script"></script><script async src="../../assets/search.js?cache=1767726585343" id="tsd-search-script"></script><script async src="../../assets/navigation.js?cache=1767726585343" id="tsd-nav-script"></script><script async src="../../assets/hierarchy.js?cache=1767726585343" id="tsd-hierarchy-script"></script><link rel="stylesheet" href="../../assets/theme.css"/></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../../index.html" class="title"><img src="../../assets/logo.svg" alt="Signal K"/></a><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../../assets/icons.svg#icon-search"></use></svg><span class="visible@s">Search</span></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><div id="tsd-toolbar-links"><a href="https://discord.gg/uuZrwz4dCS" target="_blank" rel="noopener" class="toolbar-icon visible@s" aria-label="Discord"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M524.5 69.8a1.5 1.5 0 0 0 -.8-.7A485.1 485.1 0 0 0 404.1 32a1.8 1.8 0 0 0 -1.9 .9 337.5 337.5 0 0 0 -14.9 30.6 447.8 447.8 0 0 0 -134.4 0 309.5 309.5 0 0 0 -15.1-30.6 1.9 1.9 0 0 0 -1.9-.9A483.7 483.7 0 0 0 116.1 69.1a1.7 1.7 0 0 0 -.8 .7C39.1 183.7 18.2 294.7 28.4 404.4a2 2 0 0 0 .8 1.4A487.7 487.7 0 0 0 176 479.9a1.9 1.9 0 0 0 2.1-.7A348.2 348.2 0 0 0 208.1 430.4a1.9 1.9 0 0 0 -1-2.6 321.2 321.2 0 0 1 -45.9-21.9 1.9 1.9 0 0 1 -.2-3.1c3.1-2.3 6.2-4.7 9.1-7.1a1.8 1.8 0 0 1 1.9-.3c96.2 43.9 200.4 43.9 295.5 0a1.8 1.8 0 0 1 1.9 .2c2.9 2.4 6 4.9 9.1 7.2a1.9 1.9 0 0 1 -.2 3.1 301.4 301.4 0 0 1 -45.9 21.8 1.9 1.9 0 0 0 -1 2.6 391.1 391.1 0 0 0 30 48.8 1.9 1.9 0 0 0 2.1 .7A486 486 0 0 0 610.7 405.7a1.9 1.9 0 0 0 .8-1.4C623.7 277.6 590.9 167.5 524.5 69.8zM222.5 337.6c-29 0-52.8-26.6-52.8-59.2S193.1 219.1 222.5 219.1c29.7 0 53.3 26.8 52.8 59.2C275.3 311 251.9 337.6 222.5 337.6zm195.4 0c-29 0-52.8-26.6-52.8-59.2S388.4 219.1 417.9 219.1c29.7 0 53.3 26.8 52.8 59.2C470.7 311 447.5 337.6 417.9 337.6z"></path></svg></a><a href="https://github.com/SignalK/signalk-server" target="_blank" rel="noopener" class="toolbar-icon visible@s" aria-label="Discord"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"></path></svg></a><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="../../Developing.html">Developing</a></li><li><a href="../Plugins.html">Plugins</a></li><li><a href="" aria-current="page">WebApps</a></li></ul></div><div class="tsd-panel tsd-typography"><h1 id="webapps-and-components" class="tsd-anchor-link">WebApps and Components<a href="#webapps-and-components" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>Signal K Server provides the following ways to add web-based user interfaces to enhance functionality and usability:</p> <ol> <li> <p><strong>Standalone WebApps</strong> are web applications that when launched, the server Admin UI disappears and the webapp controls the whole page (browser window / tab).</p> </li> <li> <p><strong>Embedded WebApps</strong> are web applications that when launched, are <strong>embedded in the server Admin UI</strong>, leaving the toolbar and menu available to the user. <img src="../../media/vesselpositions.png" alt="vesselpositions" title="Vesselpositions Embedded Webapp"></p> </li> <li> <p><strong>Embedded Plugin Configuration Forms</strong> are forms provided by a plugin that the server embeds within the <em>Plugin Config</em> screen to replace the generic form rendered using the plugin <em>configuration schema</em>. This allows a richer set of controls to be provided for the user to configure the plugin compared to the more generice server generated form provides. <img src="../../media/calibration.png" alt="calibration" title="Calibration plugin configuration form"></p> </li> <li> <p><strong>Embedded Components</strong> are individual UI components provided by a plugin or a webapp. They are listed in the <em>Addons</em> section at the bottom of the <em>Webapps</em> page of the Admin UI. More a concept than a fully implemented feature at this stage, the idea is to allow a plugin to add individual components to different parts of the server UI.</p> </li> </ol> <p>All Plugins, WebApps and Components can be installed via the <em>Appstore</em>.</p> <h2 id="webapp-structure" class="tsd-anchor-link">WebApp Structure<a href="#webapp-structure" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>All WebApps (like plugins) are installed with <code>npm</code>, either from the npm registry or from your own Github repository. Only WebApps that are relevant for all users should be published to <code>npm</code> to be made available in the <em>Appstore</em> of all Signal K Servers.</p> <p><em>Note: Private plugins need not be published to <code>npm</code> - see the documentation for <a href="https://docs.npmjs.com/cli/v6/commands/npm-install">npm install</a> for details.</em></p> <p>The basic structure of a webapp is:</p> <ul> <li>A folder named <code>public</code> that contains the html, JavaScript and resource files such as images, fonts and style sheets. This folder is automatically mounted by the server so that the webapp is available after installation and the server restarted.</li> <li><code>package.json</code> containing special keywords that classifies the webapp: <ul> <li><code>signalk-webapp</code> - standalone webapp</li> <li><code>signalk-embeddable-webapp</code> - embeddable webapp</li> <li><code>signalk-plugin-configurator</code> - plugin configuration form</li> </ul> </li> </ul> <p>This structure is all that is needed for a standalone webapp.</p> <p>You can also include the following section in <code>package.json</code> to control how your webapp appears in the <em>Webapps</em> list:</p> <pre><code class="JSON"><span class="hl-0"> </span><span class="hl-4">&quot;signalk&quot;</span><span class="hl-0">: {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;appIcon&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;./assets/icons/icon-72x72.png&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;displayName&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;Freeboard-SK&quot;</span><br/><span class="hl-0"> },</span> </code><button type="button">Copy</button></pre> <p>where:</p> <ul> <li><code>appIcon</code> is the path (relative to the <code>public</code> directory) to an image within the package to display in the webapp list. The image should be at least 72x72 pixels in size.</li> <li><code>displayName</code> is the text you want to appear as the name in the webapp list. <em>(By default the _name</em> attribute in the <code>package.json</code> is used.)_. Displayname is also used in an automatic redirect from the root of the server: if you have a webapp with displayName <code>foo</code> and you access it using for example the url <a href="http://foo.bar.org:3000">http://foo.bar.org:3000</a> the first part of the hostname matches the webapp's displayName and you will be redirected to it instead of the default landingPage, the Admin webapp. With this mechanism you can add easy to access DNS names to each webapp, including .local names.</li> </ul> <p>See also <a href="../../Developing.html#offline-use">Working Offline</a>.</p> <h2 id="application-data-storing-webapp-data-on-the-server" class="tsd-anchor-link">Application Data: Storing Webapp Data on the Server<a href="#application-data-storing-webapp-data-on-the-server" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Application Data is only supported if security is turned on. It supports two namespaces, one for <em>global data</em> and one for <em>user specific data</em>. For example, a client might want to store boat specific gauge configuration globally so that other users have access to it. Otherwise, it could use the user area to store user specific preferences.</p> <p>The data is structured and manipulated in JSON format.</p> <p>Global storage: <code>/signalk/v1/applicationData/global/:appid/:version</code> User storage: <code>/signalk/v1/applicationData/user/:appid/:version</code></p> <p>There are two ways to update or add stored data:</p> <ul> <li>You can POST any json data to any path:</li> </ul> <pre><code><span class="hl-2">POST</span><span class="hl-0"> </span><span class="hl-1">/</span><span class="hl-0">signalk</span><span class="hl-1">/</span><span class="hl-0">v1</span><span class="hl-1">/</span><span class="hl-0">applicationData</span><span class="hl-1">/</span><span class="hl-0">user</span><span class="hl-1">/</span><span class="hl-0">my</span><span class="hl-1">-</span><span class="hl-0">application</span><span class="hl-1">/</span><span class="hl-2">1.0</span><span class="hl-1">/</span><span class="hl-0">unitPreferences</span><br/><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-4">&quot;shortDistance&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;m&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-4">&quot;longDistance&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;km&quot;</span><br/><span class="hl-0">}</span> </code><button>Copy</button></pre> <ul> <li>You can also use json patch format (<a href="http://jsonpatch.com">http://jsonpatch.com</a>):</li> </ul> <pre><code><span class="hl-2">POST</span><span class="hl-0"> </span><span class="hl-1">/</span><span class="hl-0">signalk</span><span class="hl-1">/</span><span class="hl-0">v1</span><span class="hl-1">/</span><span class="hl-0">applicationData</span><span class="hl-1">/</span><span class="hl-0">user</span><span class="hl-1">/</span><span class="hl-0">my</span><span class="hl-1">-</span><span class="hl-0">application</span><span class="hl-1">/</span><span class="hl-2">1.0</span><br/><span class="hl-0">[</span><br/><span class="hl-0"> { </span><span class="hl-4">&quot;op&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;add&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;path&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;/unitPreferences&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;value&quot;</span><span class="hl-0">: { </span><span class="hl-4">&quot;shortDistace&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;m&quot;</span><span class="hl-0"> } },</span><br/><span class="hl-0"> { </span><span class="hl-4">&quot;op&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;add&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;path&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;/unitPreferences/longDistance&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;value&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;km&quot;</span><span class="hl-0">}</span><br/><span class="hl-0">]</span> </code><button>Copy</button></pre> <p>Use an HTTP GET request to retrieve data from the server:</p> <p><code>GET /signalk/v1/applicationData/user/my-application/1.0/unitPreferences/shortDistance</code></p> <p>You can just GET the list of keys:</p> <pre><code><span class="hl-2">GET</span><span class="hl-0"> </span><span class="hl-1">/</span><span class="hl-0">signalk</span><span class="hl-1">/</span><span class="hl-0">v1</span><span class="hl-1">/</span><span class="hl-0">applicationData</span><span class="hl-1">/</span><span class="hl-0">user</span><span class="hl-1">/</span><span class="hl-0">my</span><span class="hl-1">-</span><span class="hl-0">application</span><span class="hl-1">/</span><span class="hl-2">1.0</span><span class="hl-1">/</span><span class="hl-0">unitPreferences</span><span class="hl-1">?</span><span class="hl-0">keys</span><span class="hl-1">=</span><span class="hl-2">true</span><br/><span class="hl-0">[ </span><span class="hl-4">&quot;longDistance&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;shortDistance&quot;</span><span class="hl-0">]</span> </code><button>Copy</button></pre> <p>You get can a list of available versions:</p> <pre><code><span class="hl-2">GET</span><span class="hl-0"> </span><span class="hl-1">/</span><span class="hl-0">signalk</span><span class="hl-1">/</span><span class="hl-0">v1</span><span class="hl-1">/</span><span class="hl-0">applicationData</span><span class="hl-1">/</span><span class="hl-0">user</span><span class="hl-1">/</span><span class="hl-0">my</span><span class="hl-1">-</span><span class="hl-0">application</span><br/><span class="hl-0">[ </span><span class="hl-4">&quot;1.0&quot;</span><span class="hl-0">, </span><span class="hl-4">&quot;1.1&quot;</span><span class="hl-0">]</span> </code><button>Copy</button></pre> <h2 id="discovering-server-features" class="tsd-anchor-link">Discovering Server Features<a href="#discovering-server-features" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>To assist in tailoring a WebApps UI, it can &quot;discover&quot; the features supported by the server by sending a request to <code>/signalk/v2/features</code>.</p> <p>The response wil contain an object detailing the available APIs and Plugins.</p> <p>You can use the <code>enabled</code> parameter to specify to only return enabled or disabled features.</p> <p>To list only enabled features: <code>/signalk/v2/features?enable=1</code></p> <p>To list only disabled features: <code>/signalk/v2/features?enable=0</code></p> <p><em>Example response:</em></p> <pre><code class="JSON"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;apis&quot;</span><span class="hl-0">: [</span><br/><span class="hl-0"> </span><span class="hl-4">&quot;resources&quot;</span><span class="hl-0">,</span><span class="hl-4">&quot;course&quot;</span><br/><span class="hl-0"> ],</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;plugins&quot;</span><span class="hl-0">: [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;id&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;anchoralarm&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;name&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;Anchor Alarm&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;version&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;1.13.0&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;enabled&quot;</span><span class="hl-0">: </span><span class="hl-2">true</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;id&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;autopilot&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;name&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;Autopilot Control&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;version&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;1.4.0&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;enabled&quot;</span><span class="hl-0">: </span><span class="hl-2">false</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;id&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;sk-to-nmea2000&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;name&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;Signal K to NMEA 2000&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;version&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;2.17.0&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;enabled&quot;</span><span class="hl-0">: </span><span class="hl-2">false</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;id&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;udp-nmea-sender&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;name&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;UDP NMEA0183 Sender&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;version&quot;</span><span class="hl-0">: </span><span class="hl-4">&quot;2.0.0&quot;</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">&quot;enabled&quot;</span><span class="hl-0">: </span><span class="hl-2">false</span><br/><span class="hl-0"> }</span><br/><span class="hl-0"> ]</span><br/><span class="hl-0">}</span> </code><button type="button">Copy</button></pre> <h2 id="embedded-components-and-admin-ui--server-interfaces" class="tsd-anchor-link">Embedded Components and Admin UI / Server interfaces<a href="#embedded-components-and-admin-ui--server-interfaces" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Embedded components are implemented using <a href="https://webpack.js.org/concepts/module-federation/">Webpack Federated Modules</a> and <a href="https://reactjs.org/docs/code-splitting.html">React Code Splitting</a>.</p> <p><em>Note: There is no keyword for a module that provides only embedded components, use <code>signalk-webapp</code> instead.</em></p> <p>You need to configured Webpack to create the necessary code for federation using <em>ModuleFederationPlugin</em> and expose the component with fixed names:</p> <ul> <li>embeddable webapp: <code>./AppPanel</code></li> <li>plugin configuration form: <code>./PluginConfigurationPanel</code></li> <li>embedded component: <code>./AddonPanel</code></li> </ul> <p>The ModuleFederationPlugin library name must match the package name and be a &quot;safe&quot; name for a webpack module like in <code>library: { type: 'var', name: packageJson.name.replace(/[-@/]/g, '_') },</code></p> <p>The exposed modules need to <code>export default</code> a React component - both class based components and stateless functional components can be used. The server dependencies like <code>reactstrap</code> can and should be used. Add <code>@signalk/server-admin-ui-dependencies</code> as a dependency to the webapp, it defines the depedencies used by the server admin UI.</p> <p>See the vesselpositions embedded webapp/component and Calibration plugin for examples of each. It is probably easier to start with either one and modify them to suit your needs. Don't forget to change the module id and name in package.json!</p> <h2 id="webapp--component-and-admin-ui--server-interfaces" class="tsd-anchor-link">WebApp / Component and Admin UI / Server interfaces<a href="#webapp--component-and-admin-ui--server-interfaces" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Standalone WebApps can use the server's APIs <em>(Signal K http and WebSocket APIs as well as any server specific endpoints)</em> but they need to implement everything else themselves.</p> <p>Embedded WebApps, Components and Plugin Configuration Forms work inside the Admin UI, so they can interact with both the Admin UI and the server using APIs exposed by the Admin UI as component properties.</p> <p>Embedded webapp properties:</p> <ul> <li>access to the login status of the browser user</li> <li>ability to render Login form instead of the webapp content</li> <li>getting and setting application data</li> <li>opening an automatically reconnecting WebSocket connection to the server</li> <li>getting Signal K data via <code>get</code></li> <li><a href="https://github.com/SignalK/signalk-server/blob/master/packages/server-admin-ui/src/views/Webapps/Embedded.js">Embedded</a></li> </ul> <p>PluginConfigurationForm properties:</p> <ul> <li><code>configuration</code> : the configuration data of the plugin</li> <li><code>save</code>: function to save the configuration data</li> <li><a href="https://github.com/SignalK/signalk-server/blob/master/packages/server-admin-ui/src/views/Configuration/EmbeddedPluginConfigurationForm.js">EmbeddedPluginConfigurationForm</a></li> </ul> <p><strong><em>Note: The documentation regarding embedded WebApps and Components provided at this time is rudimentary and should be considered under development as the concept is evolving.</em></strong></p> <h2 id="authentication-and-session-management" class="tsd-anchor-link">Authentication and Session Management<a href="#authentication-and-session-management" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Per <a href="https://signalk.org/specification/1.7.0/doc/security.html#authentication-via-http">the specification</a> the server provides the endpoint <code>/signalk/v1/auth/login</code> for logging in. A successful request will</p> <ul> <li>set an authentication cookie</li> <li>return an authentication token</li> </ul> <p>For <strong>cookie based, shared sessions</strong> all a webapp needs to do is use <code>credentials: &quot;include&quot;</code> when making api calls with <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#sending_a_request_with_credentials_included">fetch</a>. Cookies are included automatically in the initial WebSocket opening HTTP request, so the same works automatically for WebSocket connections.</p> <p>The session cookie's value is the same as the token value: it is a JWT token that includes a validity period and is signed by the server. The server is stateless: JWT is verified for each request for a valid signature and time. Validity period is governed by server's security <code>expires</code> configuration value that can be changed in Admin UI's Security section.</p> <p>The login endpoint has an optional <code>rememberMe</code> request parameter. By default, without <code>rememberMe</code> set to true, the cookie is erased on browser restarts per standard browser behavior. When true the response's set cookie header includes MaxAge value based on the server's <code>expires</code> value. This makes the cookie persist over browser restarts.</p> <p>As the cookie is set to be <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#security"><code>HttpOnly</code></a> webapp JavaScript has no access to it. Including it in server requests and persisting its value is managed by the browser, governed by the <code>Set-Cookie</code> headers sent by the server.</p> <p>Additionally the server sets cookie <code>skLoginInfo</code> when the user logs in and removes it when the user logs out. A webapp can poll for changes of this cookie to be notified of the browser's cookie based login status.</p> <p>For <strong>token based sessions</strong> a webapp may manage the authentication token itself. It must include it explicitly in fetch call headers. As JavaScript has no access to headers but cookies are included automatically by browsers when opening WebSocket connections the server will use the server-set, HttpOnly cookie. Normally browsers do not allow shadowing the server-set cookie with a new value. The only option for WebSocket connections is using a query parameter to override the cookie with a token.</p> <p>The order that the server uses for finding the JWT token is</p> <ol> <li>query parameter <code>token</code></li> <li>request header <code>authorization</code></li> <li>authorization cookie (name managed by the server)</li> </ol> <p>Token-based session management is currently discouraged, because it may result in <strong>session confusion</strong>: all login calls set the shared session cookie for all webapps that are using cookie based, shared sessions.</p> <p>Each webapp acting separately, managing its authentication token independently, means that</p> <ul> <li>each application needs to implement token management separately so that closing and reopening the webapp during a browser session does not require the user to reauthenticate</li> <li>when navigating between the different webapps the user needs to authenticate to each one separately</li> </ul> <p>The server's Admin UI is a regular webapp using cookie based sessions, there is no separate authentication mechanism.</p> </div></div><div class="col-sidebar"><div class="page-menu"><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../../assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#webapp-structure"><span>Web<wbr/>App <wbr/>Structure</span></a><a href="#application-data-storing-webapp-data-on-the-server"><span>Application <wbr/>Data: <wbr/>Storing <wbr/>Webapp <wbr/>Data on the <wbr/>Server</span></a><a href="#discovering-server-features"><span>Discovering <wbr/>Server <wbr/>Features</span></a><a href="#embedded-components-and-admin-ui--server-interfaces"><span>Embedded <wbr/>Components and <wbr/>Admin <wbr/>UI / <wbr/>Server interfaces</span></a><a href="#webapp--component-and-admin-ui--server-interfaces"><span>Web<wbr/>App / <wbr/>Component and <wbr/>Admin <wbr/>UI / <wbr/>Server interfaces</span></a><a href="#authentication-and-session-management"><span>Authentication and <wbr/>Session <wbr/>Management</span></a></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../../modules.html">Signal K</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>