mirror of
https://github.com/bckelley/cgm-remote-monitor.git
synced 2026-08-24 03:14:12 -05:00
Fix CSP handling (#4449)
* Change incompatible module and fix a memory leak in the process * Fix fonts, allow websocket * Oops fix a brainfart with using the hostname * Don't inlude null hostname * Update the shrinkwrap * Instantiate new cache if new instance of profile code is created. Calculate IOB with three digit precision to keep tests happy (and this is roughly the precision we're operating at anyway). * - implement @jweismann suggestions https://github.com/nightscout/cgm-remote-monitor/pull/4449#issuecomment-469868508 - add frameAncestors, baseUri and formAction protection * update README and run doctoc * fix reportOnly * add objectSrc * Use modern CSS loading * Change CSS to use the "official" async loading across the board (which hopefully plays nicer with CSP) * first release candiate for 0.11.2 with Minimed EU Server and Guardian Connect integration - integrates https://github.com/mddub/minimed-connect-to-nightscout/pull/11 into Nightscout * bump node 10 LTS version * increase logging, fix /swagger.yaml * fix typo * set version to rc2, update mongodb to 3.2.2 * add SECURE_CSP_REPORT_ONLY (default false). * npm update and revert to requiring Node versions without security issues.
This commit is contained in:
+2
-1
@@ -3,11 +3,12 @@
|
||||
**Table of Contents**
|
||||
|
||||
- [Contributing to cgm-remote-monitor](#contributing-to-cgm-remote-monitor)
|
||||
- [Design](#design)
|
||||
- [Design & new features](#design--new-features)
|
||||
- [Develop on `dev`](#develop-on-dev)
|
||||
- [Style Guide](#style-guide)
|
||||
- [Create a prototype](#create-a-prototype)
|
||||
- [Submit a pull request](#submit-a-pull-request)
|
||||
- [Bug fixing](#bug-fixing)
|
||||
- [Comments and issues](#comments-and-issues)
|
||||
- [Co-ordination](#co-ordination)
|
||||
- [Other Dev Tips](#other-dev-tips)
|
||||
|
||||
@@ -48,6 +48,11 @@ Community maintained fork of the
|
||||
**Table of Contents**
|
||||
|
||||
- [Install](#install)
|
||||
- [Supported configurations:](#supported-configurations)
|
||||
- [Minimum browser requirements for viewing the site:](#minimum-browser-requirements-for-viewing-the-site)
|
||||
- [Windows installation software requirements:](#windows-installation-software-requirements)
|
||||
- [Installation notes for users with nginx or Apache reverse proxy for SSL/TLS offloading:](#installation-notes-for-users-with-nginx-or-apache-reverse-proxy-for-ssltls-offloading)
|
||||
- [Installation notes for Microsoft Azure, Windows:](#installation-notes-for-microsoft-azure-windows)
|
||||
- [Usage](#usage)
|
||||
- [Updating my version?](#updating-my-version)
|
||||
- [What is my mongo string?](#what-is-my-mongo-string)
|
||||
@@ -60,7 +65,7 @@ Community maintained fork of the
|
||||
- [Alarms](#alarms)
|
||||
- [Core](#core)
|
||||
- [Predefined values for your browser settings (optional)](#predefined-values-for-your-browser-settings-optional)
|
||||
- [Views](#views)
|
||||
- [Predefined values for your server settings (optional)](#predefined-values-for-your-server-settings-optional)
|
||||
- [Plugins](#plugins)
|
||||
- [Default Plugins](#default-plugins)
|
||||
- [`delta` (BG Delta)](#delta-bg-delta)
|
||||
@@ -108,7 +113,7 @@ Community maintained fork of the
|
||||
|
||||
# Install
|
||||
|
||||
Supported configurations:
|
||||
## Supported configurations:
|
||||
|
||||
If you plan to use Nightscout, we recommend using [Heroku](http://www.nightscout.info/wiki/welcome/set-up-nightscout-using-heroku), as Nightscout can reach the usage limits of the free Azure plan and cause it to shut down for hours or days. If you end up needing a paid tier, the $7/mo Heroku plan is also much cheaper than the first paid tier of Azure. Currently, the only added benefit to choosing the $7/mo Heroku plan vs the free Heroku plan is a section showing site use metrics for performance (such as response time). This has limited benefit to the average Nightscout user. In short, Heroku is the free and best option for Nightscout hosting.
|
||||
|
||||
@@ -118,7 +123,7 @@ If you plan to use Nightscout, we recommend using [Heroku](http://www.nightscout
|
||||
- Linux based install (Debian, Ubuntu, Raspbian) install with own Node.JS and MongoDB install (see software requirements below)
|
||||
- Windows based install with own Node.JS and MongoDB install (see software requirements below)
|
||||
|
||||
Minimum browser requirements for viewing the site:
|
||||
## Minimum browser requirements for viewing the site:
|
||||
|
||||
- Android 4
|
||||
- Chrome 68
|
||||
@@ -129,9 +134,9 @@ Minimum browser requirements for viewing the site:
|
||||
- Safari 11
|
||||
- Opera: 54
|
||||
|
||||
Windows installation software requirements:
|
||||
## Windows installation software requirements:
|
||||
|
||||
- [Node.js](http://nodejs.org/) Latest Node 8 LTS (Node 8.15.1 or later) or Node 10 LTS (Node 10.15.3 or later; Node 10.14.1 works for Azure). Use [Install instructions for Node](https://nodejs.org/en/download/package-manager/) or use `setup.sh`)
|
||||
- [Node.js](http://nodejs.org/) Latest Node 8 LTS (Node 8.15.1 or later) or Node 10 LTS (Node 10.15.2 or later; Node 10.14.1 works for Azure). Node versions that do not have the latest security patches will not work. Use [Install instructions for Node](https://nodejs.org/en/download/package-manager/) or use `setup.sh`)
|
||||
- [MongoDB](https://www.mongodb.com/download-center?jmp=nav#community) 3.x or later. MongoDB 2.4 is only supported for Raspberry Pi.
|
||||
|
||||
As a non-root user clone this repo then install dependencies into the root of the project:
|
||||
@@ -140,7 +145,15 @@ As a non-root user clone this repo then install dependencies into the root of th
|
||||
$ npm install
|
||||
```
|
||||
|
||||
Installation notes for Microsoft Azure, Windows:
|
||||
## Installation notes for users with nginx or Apache reverse proxy for SSL/TLS offloading:
|
||||
|
||||
- Set `INSECURE_USE_HTTP` to `false`, to be able to use non secure HTTP connections to Nightscout server
|
||||
- Your site redirects insecure connections to `https` by default. If you don't want that and use a Nginx or Apache proxy, set `INSECURE_USE_HTTP` to `true`. This will allow (unsafe) http traffic.
|
||||
- In case you use a proxy. Do not use an external network interfaces for hosting Nightscout. Make sure the unsecure port is not available from a remote network connection
|
||||
- HTTP Strict Transport Security (HSTS) headers are enabled by default, use settings `SECURE_HSTS_HEADER` and `SECURE_HSTS_HEADER_*`
|
||||
- See [Predefined values for your server settings](#predefined-values-for-your-server-settings-optional) for more details
|
||||
|
||||
## Installation notes for Microsoft Azure, Windows:
|
||||
|
||||
- If deploying the software to Microsoft Azure, you must set ** in the app settings for *WEBSITE_NODE_DEFAULT_VERSION* and *SCM_COMMAND_IDLE_TIMEOUT* **before** you deploy the latest Nightscout or the site deployment will likely fail. Other hosting environments do not require this setting. Please use:
|
||||
```
|
||||
@@ -279,13 +292,14 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm
|
||||
* `EDIT_MODE` (`on`) - possible values `on` or `off`. Enable or disable icon allowing enter treatments edit mode
|
||||
|
||||
### Predefined values for your server settings (optional)
|
||||
* `INSECURE_USE_HTTP` (`false`) - Redirect http url's to https. Possible values `false`, or `true`.
|
||||
* `INSECURE_USE_HTTP` (`false`) - Redirect unsafe http traffic to https. Possible values `false`, or `true`. Your site redirects to `https` by default. If you don't want that from Nightscout, but want to implement that with a Nginx or Apache proxy, set `INSECURE_USE_HTTP` to `true`. Note: This will allow (unsafe) http traffic to your Nightscout instance and is not recommended.
|
||||
* `SECURE_HSTS_HEADER` (`true`) - Add HTTP Strict Transport Security (HSTS) header. Possible values `false`, or `true`.
|
||||
* `SECURE_HSTS_HEADER_INCLUDESUBDOMAINS` (`false`) - includeSubdomains options for HSTS. Possible values `false`, or `true`.
|
||||
* `SECURE_HSTS_HEADER_PRELOAD` (`false`) - ask for preload in browsers for HSTS. Possible values `false`, or `true`.
|
||||
* `SECURE_CSP` (`false`) - Add Content Security Policy headers. Possible values `false`, or `true`. Currently Nightscout is not yet compatible with CSP.
|
||||
|
||||
### Views
|
||||
* `SECURE_CSP` (`false`) - Add Content Security Policy headers. Possible values `false`, or `true`.
|
||||
* `SECURE_CSP_REPORT_ONLY` (`false`) - If set to `true` allows to experiment with policies by monitoring (but not enforcing) their effects. Possible values `false`, or `true`.
|
||||
|
||||
### Views
|
||||
|
||||
There are a few alternate web views available that display a simplified BG stream. Append any of these to your Nightscout URL:
|
||||
* `/clock.html` - Shows current BG. Grey text on a black background.
|
||||
|
||||
@@ -16,8 +16,8 @@ function create(env, ctx) {
|
||||
app.enable('trust proxy'); // Allows req.secure test on heroku https connections.
|
||||
var insecureUseHttp = env.insecureUseHttp;
|
||||
var secureHstsHeader = env.secureHstsHeader;
|
||||
console.info('Security settings: INSECURE_USE_HTTP=',insecureUseHttp,', SECURE_HSTS_HEADER=',secureHstsHeader);
|
||||
if (!insecureUseHttp) {
|
||||
console.info('Redirecting http traffic to https because INSECURE_USE_HTTP=', insecureUseHttp);
|
||||
app.use((req, res, next) => {
|
||||
if (req.header('x-forwarded-proto') == 'https' || req.secure) {
|
||||
next();
|
||||
@@ -26,6 +26,7 @@ function create(env, ctx) {
|
||||
}
|
||||
})
|
||||
if (secureHstsHeader) { // Add HSTS (HTTP Strict Transport Security) header
|
||||
console.info('Enabled SECURE_HSTS_HEADER (HTTP Strict Transport Security)');
|
||||
const helmet = require('helmet');
|
||||
var includeSubDomainsValue = env.secureHstsHeaderIncludeSubdomains;
|
||||
var preloadValue = env.secureHstsHeaderPreload;
|
||||
@@ -35,19 +36,46 @@ function create(env, ctx) {
|
||||
includeSubDomains: includeSubDomainsValue,
|
||||
preload: preloadValue
|
||||
}
|
||||
}))
|
||||
}));
|
||||
if (env.secureCsp) {
|
||||
var secureCspReportOnly= env.secureCspReportOnly;
|
||||
if (secureCspReportOnly) {
|
||||
console.info( 'Enabled SECURE_CSP (Content Security Policy header). Not enforcing. Report only.' );
|
||||
} else {
|
||||
console.info( 'Enabled SECURE_CSP (Content Security Policy header). Enforcing.' );
|
||||
}
|
||||
app.use(helmet.contentSecurityPolicy({ //TODO make NS work without 'unsafe-inline'
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
styleSrc: ["'self'", 'https://fonts.googleapis.com/',"'unsafe-inline'"],
|
||||
scriptSrc: ["'self'", "'unsafe-inline'"],
|
||||
fontSrc: [ "'self'", 'https://fonts.gstatic.com/']
|
||||
}
|
||||
fontSrc: [ "'self'", 'https://fonts.gstatic.com/', 'data:'],
|
||||
imgSrc: [ "'self'", 'data:'],
|
||||
objectSrc: ["'none'"], // Restricts <object>, <embed>, and <applet> elements
|
||||
reportUri: '/report-violation',
|
||||
frameAncestors: ["'none'"], // Clickjacking protection, using frame-ancestors
|
||||
baseUri: ["'none'"], // Restricts use of the <base> tag
|
||||
formAction: ["'self'"], // Restricts where <form> contents may be submitted
|
||||
},
|
||||
reportOnly: secureCspReportOnly
|
||||
}));
|
||||
app.use(helmet.referrerPolicy({ policy: 'no-referrer' }));
|
||||
app.use(helmet.featurePolicy({ features: { payment: ["'none'"], } }));
|
||||
app.use(bodyParser.json({type: ['json', 'application/csp-report'] }))
|
||||
app.post('/report-violation', (req, res) => {
|
||||
if (req.body) {
|
||||
console.log('CSP Violation: ', req.body) }
|
||||
else {
|
||||
console.log('CSP Violation: No data received!')
|
||||
}
|
||||
res.status(204).end()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.info('Security settings: INSECURE_USE_HTTP=',insecureUseHttp,', SECURE_HSTS_HEADER=',secureHstsHeader);
|
||||
}
|
||||
|
||||
app.set('view engine', 'ejs');
|
||||
// this allows you to render .html files as templates in addition to .ejs
|
||||
@@ -140,6 +168,12 @@ function create(env, ctx) {
|
||||
res.sendFile(__dirname + '/swagger.json');
|
||||
});
|
||||
|
||||
// expose swagger.yaml
|
||||
app.get('/swagger.yaml', function(req, res) {
|
||||
res.sendFile(__dirname + '/swagger.yaml');
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
if (env.settings.isEnabled('dumps')) {
|
||||
var heapdump = require('heapdump');
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
|
||||
|
||||
- [Nightscout/IFTTT Maker](#nightscoutifttt-maker)
|
||||
- [Overview](#overview)
|
||||
- [Note: There have been some recent reports of the IFTTT service delaying Nightscout alarms. Be sure to test your implementation before relying solely on its alerts. Pushover is an alternate push notification service that might be worth considering as well.](#note-there-have-been-some-recent-reports-of-the-ifttt-service-delaying-nightscout-alarms-be-sure-to-test-your-implementation-before-relying-solely-on-its-alerts-pushover-is-an-alternate-push-notification-service-that-might-be-worth-considering-as-well)
|
||||
- [Events](#events)
|
||||
- [Creating an Applet](#creating-an-applet)
|
||||
- [1. Choose a Service](#1-choose-a-service)
|
||||
- [2. Choose a Trigger](#2-choose-a-trigger)
|
||||
- [3. Complete the Trigger field](#3-complete-the-trigger-field)
|
||||
- [4. Create an Action](#4-create-an-action)
|
||||
- [5. Complete Action Fields](#5-complete-action-fields)
|
||||
- [6. Review and Finish](#6-review-and-finish)
|
||||
- [7. Get your Maker Key](#7-get-your-maker-key)
|
||||
- [8. Configure your Nightscout site](#8-configure-your-nightscout-site)
|
||||
- [9. Configure the IFTTT mobile app](#9-configure-the-ifttt-mobile-app)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
- [Nightscout/IFTTT Maker](#nightscoutifttt-maker)
|
||||
|
||||
@@ -61,7 +61,7 @@ function setSSL() {
|
||||
env.secureHstsHeaderIncludeSubdomains = readENVTruthy("SECURE_HSTS_HEADER_INCLUDESUBDOMAINS", false);
|
||||
env.secureHstsHeaderPreload= readENVTruthy("SECURE_HSTS_HEADER_PRELOAD", false);
|
||||
env.secureCsp = readENVTruthy("SECURE_CSP", false);
|
||||
|
||||
env.secureCspReportOnly = readENVTruthy("SECURE_CSP_REPORT_ONLY", false);
|
||||
}
|
||||
|
||||
// A little ugly, but we don't want to read the secret into a var
|
||||
|
||||
+3
-3
@@ -34,9 +34,9 @@ function init(ctx) {
|
||||
if (_.isEmpty(result)) {
|
||||
result = treatmentResult;
|
||||
} else if (treatmentResult.iob) {
|
||||
result.treatmentIob = treatmentResult.iob;
|
||||
result.treatmentIob = +(Math.round(treatmentResult.iob + "e+3") + "e-3");
|
||||
}
|
||||
|
||||
if (result.iob) result.iob = +(Math.round(result.iob + "e+3") + "e-3");
|
||||
return addDisplay(result);
|
||||
};
|
||||
|
||||
@@ -162,7 +162,7 @@ function init(ctx) {
|
||||
});
|
||||
|
||||
return {
|
||||
iob: totalIOB
|
||||
iob: +(Math.round(totalIOB + "e+3") + "e-3")
|
||||
, activity: totalActivity
|
||||
, lastBolus: lastBolus
|
||||
, source: translate('Care Portal')
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
|
||||
var _ = require('lodash');
|
||||
var moment = require('moment-timezone');
|
||||
var NodeCache = require('node-cache');
|
||||
var c = require('memory-cache');
|
||||
var times = require('./times');
|
||||
var crypto = require('crypto');
|
||||
|
||||
var cacheTTL = 600;
|
||||
|
||||
var prevBasalTreatment = null;
|
||||
|
||||
function init (profileData) {
|
||||
|
||||
var profile = { };
|
||||
var cache = new c.Cache();
|
||||
|
||||
profile.timeValueCache = new NodeCache({ stdTTL: 600, checkperiod: 600 });
|
||||
|
||||
profile.loadData = function loadData (profileData) {
|
||||
if (profileData && profileData.length) {
|
||||
profile.data = profile.convertToProfileStore(profileData);
|
||||
@@ -86,7 +87,7 @@ function init (profileData) {
|
||||
var minuteTime = Math.round(time / 60000) * 60000;
|
||||
|
||||
var cacheKey = (minuteTime + valueType + spec_profile + profile.profiletreatments_hash);
|
||||
var returnValue = profile.timeValueCache[cacheKey];
|
||||
var returnValue = cache.get(cacheKey);
|
||||
|
||||
if (returnValue) {
|
||||
return returnValue;
|
||||
@@ -132,7 +133,7 @@ function init (profileData) {
|
||||
}
|
||||
}
|
||||
|
||||
profile.timeValueCache[cacheKey] = returnValue;
|
||||
cache.put(cacheKey, returnValue, cacheTTL);
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
@@ -258,7 +259,7 @@ function init (profileData) {
|
||||
}
|
||||
|
||||
returnValue = treatment;
|
||||
profile.timeValueCache[cacheKey] = returnValue;
|
||||
cache.put(cacheKey, returnValue, cacheTTL);
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
@@ -309,7 +310,7 @@ function init (profileData) {
|
||||
profile.getTempBasal = function getTempBasal (time, spec_profile) {
|
||||
|
||||
var cacheKey = 'basal' + time + profile.tempbasaltreatments_hash + profile.combobolustreatments_hash + profile.profiletreatments_hash + spec_profile;
|
||||
var returnValue = profile.timeValueCache[cacheKey];
|
||||
var returnValue = cache.get(cacheKey);
|
||||
|
||||
if (returnValue) {
|
||||
return returnValue;
|
||||
@@ -338,7 +339,7 @@ function init (profileData) {
|
||||
, combobolusbasal: combobolusbasal
|
||||
, totalbasal: tempbasal + combobolusbasal
|
||||
};
|
||||
profile.timeValueCache[cacheKey] = returnValue;
|
||||
cache.put(cacheKey, returnValue, cacheTTL);
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,23 +10,24 @@ function boot (env, language) {
|
||||
// Check Node version.
|
||||
// Latest Node 8 LTS and Latest Node 10 LTS are recommended and supported.
|
||||
// Latest Node version on Azure is tolerated, but not recommended
|
||||
// Latest Node (non LTS) version works, but not recommended
|
||||
// Other versions will not start
|
||||
// Latest Node (non LTS) version works, but is not recommended
|
||||
// Older Node versions or Node versions with known security issues will not work.
|
||||
// More explicit:
|
||||
// < 8 does not work, not supported
|
||||
// >= 8.15.1 works, supported and recommended
|
||||
// == 9.x does not work, not supported
|
||||
// == 10.14.1 works, not fully supported and not recommended (Azure version)
|
||||
// == 10.14.2 does not work, not supported and not recommended,
|
||||
// >= 10.15.3 works, supported and recommended
|
||||
// >= 10.15.2 works, supported and recommended
|
||||
// >= 11.12.0 does work, not recommended, will not be supported. We only support Node LTS releases
|
||||
///////////////////////////////////////////////////
|
||||
function checkNodeVersion (ctx, next) {
|
||||
var semver = require('semver');
|
||||
var nodeVersion = process.version;
|
||||
|
||||
if ( semver.satisfies(nodeVersion, '^8.15.1') || semver.satisfies(nodeVersion, '^10.15.3')) {
|
||||
if ( semver.satisfies(nodeVersion, '^8.15.1') || semver.satisfies(nodeVersion, '^10.15.2')) {
|
||||
//Latest Node 8 LTS and Latest Node 10 LTS are recommended and supported.
|
||||
//Require at least Node 8 LTS and Node 10 LTS without known security issues
|
||||
console.debug('Node LTS version ' + nodeVersion + ' is supported');
|
||||
next();
|
||||
}
|
||||
@@ -42,7 +43,7 @@ function boot (env, language) {
|
||||
next();
|
||||
} else {
|
||||
// Other versions will not start
|
||||
console.log( 'ERROR: Node version ' + nodeVersion + ' is not supported. Please upgrade your Node');
|
||||
console.log( 'ERROR: Node version ' + nodeVersion + ' is not supported. Please use a secure LTS version or upgrade your Node');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+1909
-162
File diff suppressed because it is too large
Load Diff
+6
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nightscout",
|
||||
"version": "0.11.2-rc1-20190320",
|
||||
"version": "0.11.2-rc2-20190323",
|
||||
"description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.",
|
||||
"license": "AGPL-3.0",
|
||||
"author": "Nightscout Team",
|
||||
@@ -74,11 +74,12 @@
|
||||
"jsdom": "~11.11.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lodash": "^4.17.11",
|
||||
"memory-cache": "^0.2.0",
|
||||
"mime": "^2.4.0",
|
||||
"minimed-connect-to-nightscout": "^1.2.0",
|
||||
"minimed-connect-to-nightscout": "^1.2.2",
|
||||
"moment": "^2.24.0",
|
||||
"moment-timezone": "^0.5.23",
|
||||
"mongodb": "^3.1.13",
|
||||
"mongodb": "^3.2.2",
|
||||
"mongomock": "^0.1.2",
|
||||
"node-cache": "^4.2.0",
|
||||
"parse-duration": "^0.1.1",
|
||||
@@ -86,12 +87,12 @@
|
||||
"pushover-notifications": "^1.2.0",
|
||||
"random-token": "0.0.8",
|
||||
"request": "^2.88.0",
|
||||
"semver": "^5.6.0",
|
||||
"semver": "^6.0.0",
|
||||
"share2nightscout-bridge": "^0.2.1",
|
||||
"shiro-trie": "^0.4.8",
|
||||
"simple-statistics": "^0.7.0",
|
||||
"socket.io": "~2.1.1",
|
||||
"swagger-ui-dist": "^3.21.0",
|
||||
"swagger-ui-dist": "^3.22.0",
|
||||
"terser": "^3.17.0",
|
||||
"traverse": "^0.6.6"
|
||||
},
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
"info": {
|
||||
"title": "Nightscout API",
|
||||
"description": "Own your DData with the Nightscout API",
|
||||
"version": "0.11.2-rc1-20190320",
|
||||
"version": "0.11.2-rc2-20190323",
|
||||
"license": {
|
||||
"name": "AGPL 3",
|
||||
"url": "https://www.gnu.org/licenses/agpl.txt"
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ servers:
|
||||
info:
|
||||
title: Nightscout API
|
||||
description: Own your DData with the Nightscout API
|
||||
version: 0.11.2-rc1-20190320
|
||||
version: 0.11.2-rc2-20190323
|
||||
license:
|
||||
name: AGPL 3
|
||||
url: 'https://www.gnu.org/licenses/agpl.txt'
|
||||
|
||||
@@ -25,10 +25,12 @@
|
||||
<meta name="msapplication-config" content="/browserconfig.xml">
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/main.css?v=<%= locals.cachebuster %>" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/drawer.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/ui-darkness/jquery-ui.min.css">
|
||||
|
||||
<link rel="preload" href="/css/main.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/drawer.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/admin.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/ui-darkness/jquery-ui.min.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<% include preloadCSS %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="toolbar">
|
||||
|
||||
@@ -24,11 +24,13 @@
|
||||
<meta name="msapplication-config" content="/browserconfig.xml">
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/main.css?v=<%= locals.cachebuster %>" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/dropdown.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/drawer.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/food.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/ui-darkness/jquery-ui.min.css">
|
||||
<link rel="preload" href="/css/main.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/dropdown.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/drawer.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/food.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/ui-darkness/jquery-ui.min.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<% include preloadCSS %>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="toolbar">
|
||||
|
||||
+4
-4
@@ -27,9 +27,9 @@
|
||||
<meta name="msapplication-TileImage" content="/images/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="/browserconfig.xml">
|
||||
<meta name="theme-color" content="#333333">
|
||||
<link rel="stylesheet" type="text/css" href="css/ui-darkness/jquery-ui.min.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" type="text/css" href="css/jquery.tooltips.css" media="none" onload="if(media!='all')media='all'">
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css?v=<%= locals.cachebuster %>" media="none" onload="if(media!='all')media='all'" />
|
||||
<link rel="preload" href="css/ui-darkness/jquery-ui.min.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="css/jquery.tooltips.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="css/main.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
|
||||
<style media="screen" type="text/css">
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<% include preloadCSS %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="centerMessagePanel">
|
||||
|
||||
@@ -17,7 +17,8 @@ CACHE MANIFEST
|
||||
/manifest.json
|
||||
/images/favicon.ico
|
||||
/images/mstile-144x144.png
|
||||
/css/ui-darkness/jquery-ui.min.css
|
||||
/css/ui-darkness/jquery-ui.min.css?v=<%= locals.cachebuster %>
|
||||
/css/jquery.tooltips.css?v=<%= locals.cachebuster %>
|
||||
/audio/alarm.mp3
|
||||
/audio/alarm2.mp3
|
||||
/css/ui-darkness/images/ui-icons_ffffff_256x240.png
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
<script>
|
||||
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
|
||||
/* This file is meant as a standalone workflow for
|
||||
- testing support for link[rel=preload]
|
||||
- enabling async CSS loading in browsers that do not support rel=preload
|
||||
- applying rel preload css once loaded, whether supported or not.
|
||||
*/
|
||||
(function( w ){
|
||||
"use strict";
|
||||
// rel=preload support test
|
||||
if( !w.loadCSS ){
|
||||
w.loadCSS = function(){};
|
||||
}
|
||||
// define on the loadCSS obj
|
||||
var rp = loadCSS.relpreload = {};
|
||||
// rel=preload feature support test
|
||||
// runs once and returns a function for compat purposes
|
||||
rp.support = (function(){
|
||||
var ret;
|
||||
try {
|
||||
ret = w.document.createElement( "link" ).relList.supports( "preload" );
|
||||
} catch (e) {
|
||||
ret = false;
|
||||
}
|
||||
return function(){
|
||||
return ret;
|
||||
};
|
||||
})();
|
||||
|
||||
// if preload isn't supported, get an asynchronous load by using a non-matching media attribute
|
||||
// then change that media back to its intended value on load
|
||||
rp.bindMediaToggle = function( link ){
|
||||
// remember existing media attr for ultimate state, or default to 'all'
|
||||
var finalMedia = link.media || "all";
|
||||
|
||||
function enableStylesheet(){
|
||||
link.media = finalMedia;
|
||||
}
|
||||
|
||||
// bind load handlers to enable media
|
||||
if( link.addEventListener ){
|
||||
link.addEventListener( "load", enableStylesheet );
|
||||
} else if( link.attachEvent ){
|
||||
link.attachEvent( "onload", enableStylesheet );
|
||||
}
|
||||
|
||||
// Set rel and non-applicable media type to start an async request
|
||||
// note: timeout allows this to happen async to let rendering continue in IE
|
||||
setTimeout(function(){
|
||||
link.rel = "stylesheet";
|
||||
link.media = "only x";
|
||||
});
|
||||
// also enable media after 3 seconds,
|
||||
// which will catch very old browsers (android 2.x, old firefox) that don't support onload on link
|
||||
setTimeout( enableStylesheet, 3000 );
|
||||
};
|
||||
|
||||
// loop through link elements in DOM
|
||||
rp.poly = function(){
|
||||
// double check this to prevent external calls from running
|
||||
if( rp.support() ){
|
||||
return;
|
||||
}
|
||||
var links = w.document.getElementsByTagName( "link" );
|
||||
for( var i = 0; i < links.length; i++ ){
|
||||
var link = links[ i ];
|
||||
// qualify links to those with rel=preload and as=style attrs
|
||||
if( link.rel === "preload" && link.getAttribute( "as" ) === "style" && !link.getAttribute( "data-loadcss" ) ){
|
||||
// prevent rerunning on link
|
||||
link.setAttribute( "data-loadcss", true );
|
||||
// bind listeners to toggle media back
|
||||
rp.bindMediaToggle( link );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// if unsupported, run the polyfill
|
||||
if( !rp.support() ){
|
||||
// run once at least
|
||||
rp.poly();
|
||||
|
||||
// rerun poly on an interval until onload
|
||||
var run = w.setInterval( rp.poly, 500 );
|
||||
if( w.addEventListener ){
|
||||
w.addEventListener( "load", function(){
|
||||
rp.poly();
|
||||
w.clearInterval( run );
|
||||
} );
|
||||
} else if( w.attachEvent ){
|
||||
w.attachEvent( "onload", function(){
|
||||
rp.poly();
|
||||
w.clearInterval( run );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// commonjs
|
||||
if( typeof exports !== "undefined" ){
|
||||
exports.loadCSS = loadCSS;
|
||||
}
|
||||
else {
|
||||
w.loadCSS = loadCSS;
|
||||
}
|
||||
}( typeof global !== "undefined" ? global : this ) );
|
||||
</script>
|
||||
@@ -25,10 +25,12 @@
|
||||
<meta name="msapplication-config" content="/browserconfig.xml">
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/main.css?v=<%= locals.cachebuster %>" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/drawer.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/profile.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/ui-darkness/jquery-ui.min.css">
|
||||
<link rel="preload" href="/css/main.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/drawer.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/profile.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/ui-darkness/jquery-ui.min.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<% include preloadCSS %>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="toolbar">
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
<meta name="msapplication-config" content="/browserconfig.xml">
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/report.css?v=<%= locals.cachebuster %>" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/ui-lightness/jquery-ui.min.css">
|
||||
<link rel="preload" href="/css/report.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/ui-lightness/jquery-ui.min.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<% include preloadCSS %>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
<meta name="msapplication-config" content="/browserconfig.xml">
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/translations.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/ui-lightness/jquery-ui.min.css">
|
||||
<link rel="preload" href="/css/translations.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<link rel="preload" href="/css/ui-lightness/jquery-ui.min.css?v=<%= locals.cachebuster %>" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<% include preloadCSS %>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1><img src="/images/logo1.png"><span class="translate">Nightscout translations</span></h1>
|
||||
|
||||
Reference in New Issue
Block a user