From 46cc9fbf7c5e8fc334bfac53a1578b6424f49600 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 12 Apr 2024 13:24:17 +0200 Subject: [PATCH 01/10] 964: Add releaseVersion, releaseTimestamp and screenId searchParams when starting app --- CHANGELOG.md | 3 +++ src/app.js | 26 ++++++++++++++++++++++++++ src/id-from-path.js | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df0e420a..d93d9f25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +- [#121](https://github.com/os2display/display-client/pull/120) + - Add releaseVersion, releaseTimestamp and screenId searchParams when starting app. + ## [2.0.1] - 2024-04-10 - [#120](https://github.com/os2display/display-client/pull/120) diff --git a/src/app.js b/src/app.js index a7ae800f..dac235ee 100644 --- a/src/app.js +++ b/src/app.js @@ -8,6 +8,7 @@ import Logger from './logger/logger'; import './app.scss'; import localStorageKeys from './local-storage-keys'; import fallback from './assets/fallback.png'; +import idFromPath from './id-from-path'; /** * App component. @@ -302,6 +303,24 @@ function App() { }; useEffect(() => { + const currentUrl = new URL(window.location.href); + + // Make sure have releaseVersion and releaseTimestamp set in url parameters. + if ( + !currentUrl.searchParams.has('releaseVersion') || + !currentUrl.searchParams.has('releaseTimestamp') + ) { + ReleaseLoader.loadConfig().then((release) => { + currentUrl.searchParams.set( + 'releaseTimestamp', + release.releaseTimestamp + ); + currentUrl.searchParams.set('releaseVersion', release.releaseVersion); + + window.history.replaceState(null, '', currentUrl); + }); + } + document.addEventListener('screen', screenHandler); document.addEventListener('reauthenticate', reauthenticateHandler); document.addEventListener('contentEmpty', contentEmpty); @@ -341,6 +360,13 @@ function App() { }, []); useEffect(() => { + // Append screenId to current url for easier debugging. + if (screen && screen['@id']) { + const url = new URL(window.location.href); + url.searchParams.set('screenId', idFromPath(screen['@id'])); + window.history.replaceState(null, '', url); + } + ConfigLoader.loadConfig().then((config) => { const token = localStorage.getItem(localStorageKeys.API_TOKEN); const tenantKey = localStorage.getItem(localStorageKeys.TENANT_KEY); diff --git a/src/id-from-path.js b/src/id-from-path.js index e81ec63c..a00d6a25 100644 --- a/src/id-from-path.js +++ b/src/id-from-path.js @@ -1,6 +1,6 @@ /** * @param {object} string - The url to cut id from. - * @returns {boolean} The id or false. + * @returns {string|boolean} The id or false. */ function idFromPath(string) { if (typeof string === 'string') { From 46cd7fb35e4a457aa7db2c66e5a023f45e270ef7 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:55:01 +0200 Subject: [PATCH 02/10] Update src/app.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ture Gjørup --- src/app.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app.js b/src/app.js index dac235ee..e57295ca 100644 --- a/src/app.js +++ b/src/app.js @@ -360,7 +360,9 @@ function App() { }, []); useEffect(() => { - // Append screenId to current url for easier debugging. + // Append screenId to current url for easier debugging. If errors are logged in the API's standard http log this + // makes it easy to see what screen client has made the http call by putting the screen id in the referer http + // header. if (screen && screen['@id']) { const url = new URL(window.location.href); url.searchParams.set('screenId', idFromPath(screen['@id'])); From f4e602fdfb7a75ef2fe9c8ade1ede01bdda4f665 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Mon, 15 Apr 2024 14:35:42 +0200 Subject: [PATCH 03/10] 391: Added max-age and expires 1 hour to config.json and release.json --- .docker/vhost.conf | 8 ++++++++ CHANGELOG.md | 3 +++ .../itkdev/etc/confd/templates/default.conf.tmpl | 6 ++++++ .../os2display/etc/confd/templates/default.conf.tmpl | 6 ++++++ 4 files changed, 23 insertions(+) diff --git a/.docker/vhost.conf b/.docker/vhost.conf index e60c1a1f..0c45385e 100644 --- a/.docker/vhost.conf +++ b/.docker/vhost.conf @@ -8,4 +8,12 @@ server { proxy_set_header Host $http_host; proxy_pass http://node:3000; } + + location ~* ^/client/(config|release)\.json$ { + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $http_host; + proxy_pass http://node:3000; + add_header Cache-Control "public, max-age=3600"; + expires 1h; + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index df0e420a..5519abb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +- [#122](https://github.com/os2display/display-client/pull/122) + - Added max-age and expires 1 hour to config.json and release.json. + ## [2.0.1] - 2024-04-10 - [#120](https://github.com/os2display/display-client/pull/120) diff --git a/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl b/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl index 59defbd6..b8f1a9e3 100644 --- a/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl +++ b/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl @@ -16,6 +16,12 @@ server { return 200 "User-agent: *\nDisallow: /\n"; } + location ~* ^/{{ getenv "APP_SCREEN_CLIENT_PATH" "/" }}(config|release)\.json$ { + add_header Cache-Control "public, max-age=3600"; + expires 1h; + try_files $uri $uri/ =404; + } + error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; } diff --git a/infrastructure/os2display/etc/confd/templates/default.conf.tmpl b/infrastructure/os2display/etc/confd/templates/default.conf.tmpl index 59defbd6..b8f1a9e3 100644 --- a/infrastructure/os2display/etc/confd/templates/default.conf.tmpl +++ b/infrastructure/os2display/etc/confd/templates/default.conf.tmpl @@ -16,6 +16,12 @@ server { return 200 "User-agent: *\nDisallow: /\n"; } + location ~* ^/{{ getenv "APP_SCREEN_CLIENT_PATH" "/" }}(config|release)\.json$ { + add_header Cache-Control "public, max-age=3600"; + expires 1h; + try_files $uri $uri/ =404; + } + error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; } From fa0f0f2428b50e651841b0801713358a5ed1ea11 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Tue, 16 Apr 2024 11:31:21 +0200 Subject: [PATCH 04/10] 1186: Fixed tests. Changed location --- .../etc/confd/templates/default.conf.tmpl | 2 +- .../etc/confd/templates/default.conf.tmpl | 2 +- src/app.spec.js | 63 +++++-------------- 3 files changed, 16 insertions(+), 51 deletions(-) diff --git a/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl b/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl index b8f1a9e3..12be7820 100644 --- a/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl +++ b/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl @@ -16,7 +16,7 @@ server { return 200 "User-agent: *\nDisallow: /\n"; } - location ~* ^/{{ getenv "APP_SCREEN_CLIENT_PATH" "/" }}(config|release)\.json$ { + location ~* ^{{ getenv "APP_SCREEN_CLIENT_PATH" "" }}/(config|release)\.json$ { add_header Cache-Control "public, max-age=3600"; expires 1h; try_files $uri $uri/ =404; diff --git a/infrastructure/os2display/etc/confd/templates/default.conf.tmpl b/infrastructure/os2display/etc/confd/templates/default.conf.tmpl index b8f1a9e3..12be7820 100644 --- a/infrastructure/os2display/etc/confd/templates/default.conf.tmpl +++ b/infrastructure/os2display/etc/confd/templates/default.conf.tmpl @@ -16,7 +16,7 @@ server { return 200 "User-agent: *\nDisallow: /\n"; } - location ~* ^/{{ getenv "APP_SCREEN_CLIENT_PATH" "/" }}(config|release)\.json$ { + location ~* ^{{ getenv "APP_SCREEN_CLIENT_PATH" "" }}/(config|release)\.json$ { add_header Cache-Control "public, max-age=3600"; expires 1h; try_files $uri $uri/ =404; diff --git a/src/app.spec.js b/src/app.spec.js index 4005f2a6..4518919a 100644 --- a/src/app.spec.js +++ b/src/app.spec.js @@ -10,9 +10,16 @@ describe('Client tests', () => { fixture: 'awaiting-bind-key-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.visit('/'); - cy.wait('@bindKey'); + // After this point we assume the config file is served from the browser + // cache, since it the nginx setup has a 1h caching set for config.json. + cy.wait(['@bindKey', '@config']); cy.get('.bind-key').should('exist'); cy.get('.bind-key') @@ -26,11 +33,6 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); - cy.intercept('GET', '**/config.json', { - statusCode: 200, - fixture: 'config.json', - }).as('config'); - cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 200, fixture: 'screen-empty.json', @@ -55,7 +57,6 @@ describe('Client tests', () => { cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', @@ -71,11 +72,6 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); - cy.intercept('GET', '**/config.json', { - statusCode: 200, - fixture: 'config.json', - }).as('config'); - cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 200, fixture: 'screen.json', @@ -124,7 +120,7 @@ describe('Client tests', () => { cy.wait([ '@bindKey', - '@config', + // '@config', '@screen', '@groups', '@campaigns', @@ -147,11 +143,6 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); - cy.intercept('GET', '**/config.json', { - statusCode: 200, - fixture: 'config.json', - }).as('config'); - cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 200, fixture: 'screen.json', @@ -180,7 +171,6 @@ describe('Client tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', @@ -200,11 +190,6 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); - cy.intercept('GET', '**/config.json', { - statusCode: 201, - fixture: 'config.json', - }).as('config'); - cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen.json', @@ -247,7 +232,6 @@ describe('Client tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@screen-groups', '@screen-campaigns', @@ -272,11 +256,6 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); - cy.intercept('GET', '**/config.json', { - statusCode: 201, - fixture: 'config.json', - }).as('config'); - cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen.json', @@ -333,7 +312,6 @@ describe('Client tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', @@ -356,11 +334,6 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); - cy.intercept('GET', '**/config.json', { - statusCode: 201, - fixture: 'config.json', - }).as('config'); - cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen.json', @@ -417,7 +390,6 @@ describe('Client tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', @@ -440,11 +412,6 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); - cy.intercept('GET', '**/config.json', { - statusCode: 201, - fixture: 'config.json', - }).as('config'); - cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen-diff-layout.json', @@ -493,7 +460,11 @@ describe('Client tests', () => { }).as('layout'); cy.visit('/'); - cy.wait(['@bindKey', '@config', '@screen', '@layout']); + cy.wait([ + '@bindKey', + '@screen', + '@layout', + ]); cy.get('.region') .eq(0) @@ -511,11 +482,6 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); - cy.intercept('GET', '**/config.json', { - statusCode: 201, - fixture: 'config.json', - }).as('config'); - cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen.json', @@ -577,7 +543,6 @@ describe('Client tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', From f8db34649f1722471ca2554dc9f9036d318c055a Mon Sep 17 00:00:00 2001 From: Jesper Kristensen Date: Tue, 16 Apr 2024 12:44:20 +0200 Subject: [PATCH 05/10] 1185: Ensured real ip is logged in nginx --- infrastructure/itkdev/etc/confd/templates/nginx.conf.tmpl | 6 +++++- .../os2display/etc/confd/templates/nginx.conf.tmpl | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/infrastructure/itkdev/etc/confd/templates/nginx.conf.tmpl b/infrastructure/itkdev/etc/confd/templates/nginx.conf.tmpl index a3961034..7b978c7c 100644 --- a/infrastructure/itkdev/etc/confd/templates/nginx.conf.tmpl +++ b/infrastructure/itkdev/etc/confd/templates/nginx.conf.tmpl @@ -34,7 +34,11 @@ http { include /etc/nginx/mime.types; default_type application/octet-stream; - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + set_real_ip_from 172.16.0.0/8; + real_ip_recursive on; + real_ip_header X-Forwarded-For; + + log_format main '$http_x_real_ip - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; diff --git a/infrastructure/os2display/etc/confd/templates/nginx.conf.tmpl b/infrastructure/os2display/etc/confd/templates/nginx.conf.tmpl index a3961034..7b978c7c 100644 --- a/infrastructure/os2display/etc/confd/templates/nginx.conf.tmpl +++ b/infrastructure/os2display/etc/confd/templates/nginx.conf.tmpl @@ -34,7 +34,11 @@ http { include /etc/nginx/mime.types; default_type application/octet-stream; - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + set_real_ip_from 172.16.0.0/8; + real_ip_recursive on; + real_ip_header X-Forwarded-For; + + log_format main '$http_x_real_ip - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; From d2d802cfe3548e352c24bc8eff804633531a145a Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:26:55 +0200 Subject: [PATCH 06/10] 1186: Changed to apply max-age 7d to all files and added cache busting to config.json and release.json. Added "loginCheckTimeout", "configFetchInterval", "refreshTokenTimeout", "releaseTimestampIntervalTimeout" to config.json --- .docker/vhost.conf | 10 +--- CHANGELOG.md | 3 ++ README.md | 47 ++++++++++--------- .../itkdev/etc/confd/templates/config.tmpl | 4 ++ .../etc/confd/templates/default.conf.tmpl | 8 +--- infrastructure/os2display/Readme.md | 28 +++++++++++ .../etc/confd/templates/config.tmpl | 4 ++ .../etc/confd/templates/default.conf.tmpl | 8 +--- public/example_config.json | 4 ++ src/app.js | 38 ++++++++++----- src/app.spec.js | 42 ++++++++++++++++- src/config-loader.js | 16 +++++-- src/release-loader.js | 3 +- src/schedule.spec.js | 4 -- 14 files changed, 156 insertions(+), 63 deletions(-) diff --git a/.docker/vhost.conf b/.docker/vhost.conf index 0c45385e..e29516e9 100644 --- a/.docker/vhost.conf +++ b/.docker/vhost.conf @@ -7,13 +7,7 @@ server { proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $http_host; proxy_pass http://node:3000; - } - - location ~* ^/client/(config|release)\.json$ { - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $http_host; - proxy_pass http://node:3000; - add_header Cache-Control "public, max-age=3600"; - expires 1h; + add_header Cache-Control "public, max-age=604800"; + expires 7d; } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 0abacf07..8f152390 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +- [#123](https://github.com/os2display/display-client/pull/123) + - Changed to apply max-age 7d to all files and added cache busting to config.json and release.json. + - Added "loginCheckTimeout", "configFetchInterval", "refreshTokenTimeout", "releaseTimestampIntervalTimeout" to config.json. - [#122](https://github.com/os2display/display-client/pull/122) - Added max-age and expires 1 hour to config.json and release.json. - [#121](https://github.com/os2display/display-client/pull/120) diff --git a/README.md b/README.md index 294e818e..f783121b 100644 --- a/README.md +++ b/README.md @@ -7,27 +7,32 @@ See [https://github.com/os2display/display-docs/blob/main/client.md](https://git The client can be configured by creating `public/config.json` with relevant values. See `public/example_config.json` for values. -```json -{ - "apiEndpoint": "", - "authenticationEndpoint": "/v2/authentication/screen", - "authenticationRefreshTokenEndpoint": "/v2/authentication/token/refresh", - "dataStrategy": { - "type": "pull", - "config": { - "interval": 30000, - "endpoint": "" - } - }, - "colorScheme": { - "type": "library", - "lat": 56.0, - "lng": 10.0 - }, - "schedulingInterval": 60000, - "debug": false -} -``` +Values explained: + +* apiEndpoint - The endpoint where the API can be called. +* authenticationEndpoint - The endpoint where the screen should +authenticate. +* authenticationRefreshTokenEndpoint - The endpoint where the token can +be refreshed. +* loginCheckTimeout - How often (milliseconds) should the screen check for +status when it is not logged in, and waiting for being activated in the +administration. +* configFetchInterval - How often (milliseconds) should a fresh +config.json be fetched. +* refreshTokenTimeout - How often (milliseconds) should it be checked +whether the token needs to be refreshed? +* releaseTimestampIntervalTimeout - How often (milliseconds) should the +code check if a new release has been deployed, and reload if true? +* dataStrategy.config.interval - How often (milliseconds) should data be fetched +for the logged in screen? +* dataStrategy.config.endpoint - The endpoint where the data should be fetched. +* colorScheme.lat - Where is the screen located? Used for darkmode. +* colorScheme.lng - Where is the screen located? Used for darkmode. +* schedulingInterval - How often (milliseconds) should scheduling for the +screen be checked. +* debug - Should the screen be in debug mode? If true, the cursor will be +invisible. + All endpoint should be configured with out a trailing slash. The endpoints `apiEndpoint` and `dataStrategy.config.endpoint` can be left empty if the api is hosted from the root of the same domain as the client. E.g. if the api is at https://example.org and the client is at https://example.org/client diff --git a/infrastructure/itkdev/etc/confd/templates/config.tmpl b/infrastructure/itkdev/etc/confd/templates/config.tmpl index 5fc0eabd..6f5277dc 100644 --- a/infrastructure/itkdev/etc/confd/templates/config.tmpl +++ b/infrastructure/itkdev/etc/confd/templates/config.tmpl @@ -2,6 +2,10 @@ "apiEndpoint": "{{ getenv "APP_API_ENDPOINT" "" }}", "authenticationEndpoint": "{{ getenv "APP_API_AUTHENTICATION_ENDPOINT" "/v2/authentication/token" }}", "authenticationRefreshTokenEndpoint": "{{ getenv "APP_API_AUTHENTICATION_REFRESH_ENDPOINT" "/v2/authentication/token/refresh" }}", + "loginCheckTimeout": {{ getenv "APP_LOGIN_CHECK_TIMEOUT" "20000" }}, + "configFetchInterval": {{ getenv "APP_CONFIG_FETCH_INTERVAL" "900000" }}, + "refreshTokenTimeout": {{ getenv "APP_REFRESH_TOKEN_TIMEOUT" "900000" }}, + "releaseTimestampIntervalTimeout": {{ getenv "APP_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT" "600000" }}, "dataStrategy": { "type": "pull", "config": { diff --git a/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl b/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl index 12be7820..787669db 100644 --- a/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl +++ b/infrastructure/itkdev/etc/confd/templates/default.conf.tmpl @@ -7,6 +7,8 @@ server { rewrite ^{{ getenv "APP_SCREEN_CLIENT_PATH" "/" }}(.*) /$1 break; index index.html; autoindex off; + add_header Cache-Control "public, max-age=604800"; + expires 7d; try_files $uri $uri/ =404; } @@ -16,12 +18,6 @@ server { return 200 "User-agent: *\nDisallow: /\n"; } - location ~* ^{{ getenv "APP_SCREEN_CLIENT_PATH" "" }}/(config|release)\.json$ { - add_header Cache-Control "public, max-age=3600"; - expires 1h; - try_files $uri $uri/ =404; - } - error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; } diff --git a/infrastructure/os2display/Readme.md b/infrastructure/os2display/Readme.md index eff0fb47..a4b7c03c 100644 --- a/infrastructure/os2display/Readme.md +++ b/infrastructure/os2display/Readme.md @@ -1,3 +1,31 @@ # OS2display image build This folder contains the infrastructure files for building the `os2display/display-client` image. + +## Environment variables that can be set + +### config.json + +* APP_API_ENDPOINT - The endpoint where the API can be called. +* APP_API_AUTHENTICATION_ENDPOINT - The endpoint where the screen should +authenticate. +* APP_API_AUTHENTICATION_REFRESH_ENDPOINT - The endpoint where the token can +be refreshed. +* APP_LOGIN_CHECK_TIMEOUT - How often (milliseconds) should the screen check for +status when it is not logged in, and waiting for being activated in the +administration. +* APP_CONFIG_FETCH_INTERVAL - How often (milliseconds) should a fresh +config.json be fetched. +* APP_REFRESH_TOKEN_TIMEOUT - How often (milliseconds) should it be checked +whether the token needs to be refreshed? +* APP_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT - How often (milliseconds) should the +code check if a new release has been deployed, and reload if true? +* APP_DATA_PULL_INTERVAL - How often (milliseconds) should data be fetched for +the logged in screen? +* APP_API_PATH - The endpoint where the data should be fetched. +* APP_CLIENT_LATITUDE - Where is the screen located? Used for darkmode. +* APP_CLIENT_LONGITUDE - Where is the screen located? Used for darkmode. +* APP_SCHEDULING_INTERVAL - How often (milliseconds) should scheduling for the +screen be checked. +* APP_DEBUG - Should the screen be in debug mode? If true, the cursor will be +invisible. diff --git a/infrastructure/os2display/etc/confd/templates/config.tmpl b/infrastructure/os2display/etc/confd/templates/config.tmpl index 69747181..878392bf 100644 --- a/infrastructure/os2display/etc/confd/templates/config.tmpl +++ b/infrastructure/os2display/etc/confd/templates/config.tmpl @@ -2,6 +2,10 @@ "apiEndpoint": "{{ getenv "APP_API_ENDPOINT" "/" }}", "authenticationEndpoint": "{{ getenv "APP_API_AUTHENTICATION_ENDPOINT" "/v2/authentication/token" }}", "authenticationRefreshTokenEndpoint": "{{ getenv "APP_API_AUTHENTICATION_REFRESH_ENDPOINT" "/v2/authentication/token/refresh" }}", + "loginCheckTimeout": {{ getenv "APP_LOGIN_CHECK_TIMEOUT" "20000" }}, + "configFetchInterval": {{ getenv "APP_CONFIG_FETCH_INTERVAL" "900000" }}, + "refreshTokenTimeout": {{ getenv "APP_REFRESH_TOKEN_TIMEOUT" "900000" }}, + "releaseTimestampIntervalTimeout": {{ getenv "APP_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT" "600000" }}, "dataStrategy": { "type": "pull", "config": { diff --git a/infrastructure/os2display/etc/confd/templates/default.conf.tmpl b/infrastructure/os2display/etc/confd/templates/default.conf.tmpl index 12be7820..787669db 100644 --- a/infrastructure/os2display/etc/confd/templates/default.conf.tmpl +++ b/infrastructure/os2display/etc/confd/templates/default.conf.tmpl @@ -7,6 +7,8 @@ server { rewrite ^{{ getenv "APP_SCREEN_CLIENT_PATH" "/" }}(.*) /$1 break; index index.html; autoindex off; + add_header Cache-Control "public, max-age=604800"; + expires 7d; try_files $uri $uri/ =404; } @@ -16,12 +18,6 @@ server { return 200 "User-agent: *\nDisallow: /\n"; } - location ~* ^{{ getenv "APP_SCREEN_CLIENT_PATH" "" }}/(config|release)\.json$ { - add_header Cache-Control "public, max-age=3600"; - expires 1h; - try_files $uri $uri/ =404; - } - error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; } diff --git a/public/example_config.json b/public/example_config.json index 93041281..daccb7d1 100644 --- a/public/example_config.json +++ b/public/example_config.json @@ -2,6 +2,10 @@ "apiEndpoint": "", "authenticationEndpoint": "/v2/authentication/screen", "authenticationRefreshTokenEndpoint": "/v2/authentication/token/refresh", + "loginCheckTimeout": 20000, + "configFetchInterval": 90000, + "refreshTokenTimeout": 900000, + "releaseTimestampIntervalTimeout": 600000, "dataStrategy": { "type": "pull", "config": { diff --git a/src/app.js b/src/app.js index e57295ca..8b0aeb9c 100644 --- a/src/app.js +++ b/src/app.js @@ -21,9 +21,9 @@ function App() { localStorageKeys.FALLBACK_IMAGE ); - const loginCheckTimeout = 15 * 1000; - const refreshTimeout = 60 * 1000; - const releaseTimestampIntervalTimeout = 1000 * 60 * 5; + const loginCheckTimeoutDefault = 20 * 1000; + const refreshTokenTimeoutDefault = 60 * 1000 * 15; + const releaseTimestampIntervalTimeoutDefault = 1000 * 60 * 10; const [running, setRunning] = useState(false); const [screen, setScreen] = useState(''); @@ -168,8 +168,13 @@ function App() { }) ); - // Start refresh token interval. - refreshTokenIntervalRef.current = setInterval(checkToken, refreshTimeout); + ConfigLoader.loadConfig().then((config) => { + // Start refresh token interval. + refreshTokenIntervalRef.current = setInterval( + checkToken, + config.refreshTokenTimeout ?? refreshTokenTimeoutDefault + ); + }); }; const checkLogin = () => { @@ -225,7 +230,10 @@ function App() { clearTimeout(timeoutRef.current); } - timeoutRef.current = setTimeout(checkLogin, loginCheckTimeout); + timeoutRef.current = setTimeout( + checkLogin, + config.loginCheckTimeout ?? loginCheckTimeoutDefault + ); } }) .catch(() => { @@ -233,7 +241,10 @@ function App() { clearTimeout(timeoutRef.current); } - timeoutRef.current = setTimeout(checkLogin, loginCheckTimeout); + timeoutRef.current = setTimeout( + checkLogin, + config.loginCheckTimeout ?? loginCheckTimeoutDefault + ); }); }); } @@ -331,10 +342,13 @@ function App() { checkForUpdates(); - releaseTimestampIntervalRef.current = setInterval( - checkForUpdates, - releaseTimestampIntervalTimeout - ); + ConfigLoader.loadConfig().then((config) => { + releaseTimestampIntervalRef.current = setInterval( + checkForUpdates, + config.releaseTimestampIntervalTimeout ?? + releaseTimestampIntervalTimeoutDefault + ); + }); return function cleanup() { Logger.log('info', 'Unmounting App.'); @@ -361,7 +375,7 @@ function App() { useEffect(() => { // Append screenId to current url for easier debugging. If errors are logged in the API's standard http log this - // makes it easy to see what screen client has made the http call by putting the screen id in the referer http + // makes it easy to see what screen client has made the http call by putting the screen id in the referer http // header. if (screen && screen['@id']) { const url = new URL(window.location.href); diff --git a/src/app.spec.js b/src/app.spec.js index 4518919a..8ce11942 100644 --- a/src/app.spec.js +++ b/src/app.spec.js @@ -19,7 +19,7 @@ describe('Client tests', () => { // After this point we assume the config file is served from the browser // cache, since it the nginx setup has a 1h caching set for config.json. - cy.wait(['@bindKey', '@config']); + cy.wait(['@bindKey']); cy.get('.bind-key').should('exist'); cy.get('.bind-key') @@ -33,6 +33,11 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 200, fixture: 'screen-empty.json', @@ -72,6 +77,11 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 200, fixture: 'screen.json', @@ -143,6 +153,11 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 200, fixture: 'screen.json', @@ -190,6 +205,11 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen.json', @@ -256,6 +276,11 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen.json', @@ -334,6 +359,11 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen.json', @@ -412,6 +442,11 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen-diff-layout.json', @@ -482,6 +517,11 @@ describe('Client tests', () => { fixture: 'screen-response.json', }).as('bindKey'); + cy.intercept('GET', '**/config.json', { + statusCode: 200, + fixture: 'config.json', + }).as('config'); + cy.intercept('GET', '**/screens/01FYEDW1N133SG516JVJ3VG5FY', { statusCode: 201, fixture: 'screen.json', diff --git a/src/config-loader.js b/src/config-loader.js index 20bed5f3..0a7671bb 100644 --- a/src/config-loader.js +++ b/src/config-loader.js @@ -1,5 +1,5 @@ -// Only fetch new config if more than 5 minutes have passed. -const configFetchInterval = 5 * 60 * 1000; +// Only fetch new config if more than 15 minutes have passed. +const configFetchIntervalDefault = 15 * 60 * 1000; // Defaults. let configData = null; @@ -18,10 +18,14 @@ const ConfigLoader = { activePromise = new Promise((resolve) => { const nowTimestamp = new Date().getTime(); - if (latestFetchTimestamp + configFetchInterval >= nowTimestamp) { + if ( + latestFetchTimestamp + + (configData?.configFetchInterval ?? configFetchIntervalDefault) >= + nowTimestamp + ) { resolve(configData); } else { - fetch('/client/config.json') + fetch(`/client/config.json?ts=${nowTimestamp}`) .then((response) => response.json()) .then((data) => { latestFetchTimestamp = nowTimestamp; @@ -49,6 +53,10 @@ const ConfigLoader = { endpoint: '/api', }, }, + loginCheckTimeout: 20000, + configFetchInterval: 900000, + refreshTokenTimeout: 900000, + releaseTimestampIntervalTimeout: 600000, colorScheme: { type: 'library', lat: 56.0, diff --git a/src/release-loader.js b/src/release-loader.js index 6b49f81f..155499f9 100644 --- a/src/release-loader.js +++ b/src/release-loader.js @@ -3,7 +3,8 @@ */ export default class ReleaseLoader { static async loadConfig() { - return fetch('/client/release.json') + const nowTimestamp = new Date().getTime(); + return fetch(`/client/release.json?ts=${nowTimestamp}`) .then((response) => response.json()) .catch((err) => { /* eslint-disable-next-line no-console */ diff --git a/src/schedule.spec.js b/src/schedule.spec.js index d169e493..3206c0e2 100644 --- a/src/schedule.spec.js +++ b/src/schedule.spec.js @@ -76,7 +76,6 @@ describe('Schedule tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', @@ -161,7 +160,6 @@ describe('Schedule tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', @@ -246,7 +244,6 @@ describe('Schedule tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', @@ -331,7 +328,6 @@ describe('Schedule tests', () => { cy.visit('/'); cy.wait([ '@bindKey', - '@config', '@screen', '@groups', '@campaigns', From 97589e07c92afba802267086c32d030f9854d71a Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:10:07 +0200 Subject: [PATCH 07/10] 1186: Simplified config.json --- CHANGELOG.md | 1 + README.md | 5 ----- infrastructure/itkdev/etc/confd/templates/config.tmpl | 9 +++------ infrastructure/os2display/Readme.md | 5 ----- .../os2display/etc/confd/templates/config.tmpl | 9 +++------ public/example_config.json | 5 +---- src/app.js | 4 ++-- src/config-loader.js | 7 ++----- src/data-sync/data-sync.js | 2 +- src/service/contentService.js | 8 +++++--- 10 files changed, 18 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f152390..310b32cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. - [#123](https://github.com/os2display/display-client/pull/123) - Changed to apply max-age 7d to all files and added cache busting to config.json and release.json. - Added "loginCheckTimeout", "configFetchInterval", "refreshTokenTimeout", "releaseTimestampIntervalTimeout" to config.json. + - Simplified config.json. - [#122](https://github.com/os2display/display-client/pull/122) - Added max-age and expires 1 hour to config.json and release.json. - [#121](https://github.com/os2display/display-client/pull/120) diff --git a/README.md b/README.md index f783121b..e696c8ce 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,6 @@ See `public/example_config.json` for values. Values explained: * apiEndpoint - The endpoint where the API can be called. -* authenticationEndpoint - The endpoint where the screen should -authenticate. -* authenticationRefreshTokenEndpoint - The endpoint where the token can -be refreshed. * loginCheckTimeout - How often (milliseconds) should the screen check for status when it is not logged in, and waiting for being activated in the administration. @@ -25,7 +21,6 @@ whether the token needs to be refreshed? code check if a new release has been deployed, and reload if true? * dataStrategy.config.interval - How often (milliseconds) should data be fetched for the logged in screen? -* dataStrategy.config.endpoint - The endpoint where the data should be fetched. * colorScheme.lat - Where is the screen located? Used for darkmode. * colorScheme.lng - Where is the screen located? Used for darkmode. * schedulingInterval - How often (milliseconds) should scheduling for the diff --git a/infrastructure/itkdev/etc/confd/templates/config.tmpl b/infrastructure/itkdev/etc/confd/templates/config.tmpl index 6f5277dc..a0bf386d 100644 --- a/infrastructure/itkdev/etc/confd/templates/config.tmpl +++ b/infrastructure/itkdev/etc/confd/templates/config.tmpl @@ -1,16 +1,13 @@ { "apiEndpoint": "{{ getenv "APP_API_ENDPOINT" "" }}", - "authenticationEndpoint": "{{ getenv "APP_API_AUTHENTICATION_ENDPOINT" "/v2/authentication/token" }}", - "authenticationRefreshTokenEndpoint": "{{ getenv "APP_API_AUTHENTICATION_REFRESH_ENDPOINT" "/v2/authentication/token/refresh" }}", "loginCheckTimeout": {{ getenv "APP_LOGIN_CHECK_TIMEOUT" "20000" }}, - "configFetchInterval": {{ getenv "APP_CONFIG_FETCH_INTERVAL" "900000" }}, - "refreshTokenTimeout": {{ getenv "APP_REFRESH_TOKEN_TIMEOUT" "900000" }}, + "configFetchInterval": {{ getenv "APP_CONFIG_FETCH_INTERVAL" "600000" }}, + "refreshTokenTimeout": {{ getenv "APP_REFRESH_TOKEN_TIMEOUT" "60000" }}, "releaseTimestampIntervalTimeout": {{ getenv "APP_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT" "600000" }}, "dataStrategy": { "type": "pull", "config": { - "interval": {{ getenv "APP_DATA_PULL_INTERVAL" "30000" }}, - "endpoint": "{{ getenv "APP_API_PATH" "" }}" + "interval": {{ getenv "APP_DATA_PULL_INTERVAL" "30000" }} } }, "colorScheme": { diff --git a/infrastructure/os2display/Readme.md b/infrastructure/os2display/Readme.md index a4b7c03c..090ae9bb 100644 --- a/infrastructure/os2display/Readme.md +++ b/infrastructure/os2display/Readme.md @@ -7,10 +7,6 @@ This folder contains the infrastructure files for building the `os2display/displ ### config.json * APP_API_ENDPOINT - The endpoint where the API can be called. -* APP_API_AUTHENTICATION_ENDPOINT - The endpoint where the screen should -authenticate. -* APP_API_AUTHENTICATION_REFRESH_ENDPOINT - The endpoint where the token can -be refreshed. * APP_LOGIN_CHECK_TIMEOUT - How often (milliseconds) should the screen check for status when it is not logged in, and waiting for being activated in the administration. @@ -22,7 +18,6 @@ whether the token needs to be refreshed? code check if a new release has been deployed, and reload if true? * APP_DATA_PULL_INTERVAL - How often (milliseconds) should data be fetched for the logged in screen? -* APP_API_PATH - The endpoint where the data should be fetched. * APP_CLIENT_LATITUDE - Where is the screen located? Used for darkmode. * APP_CLIENT_LONGITUDE - Where is the screen located? Used for darkmode. * APP_SCHEDULING_INTERVAL - How often (milliseconds) should scheduling for the diff --git a/infrastructure/os2display/etc/confd/templates/config.tmpl b/infrastructure/os2display/etc/confd/templates/config.tmpl index 878392bf..5c11314f 100644 --- a/infrastructure/os2display/etc/confd/templates/config.tmpl +++ b/infrastructure/os2display/etc/confd/templates/config.tmpl @@ -1,16 +1,13 @@ { "apiEndpoint": "{{ getenv "APP_API_ENDPOINT" "/" }}", - "authenticationEndpoint": "{{ getenv "APP_API_AUTHENTICATION_ENDPOINT" "/v2/authentication/token" }}", - "authenticationRefreshTokenEndpoint": "{{ getenv "APP_API_AUTHENTICATION_REFRESH_ENDPOINT" "/v2/authentication/token/refresh" }}", "loginCheckTimeout": {{ getenv "APP_LOGIN_CHECK_TIMEOUT" "20000" }}, - "configFetchInterval": {{ getenv "APP_CONFIG_FETCH_INTERVAL" "900000" }}, - "refreshTokenTimeout": {{ getenv "APP_REFRESH_TOKEN_TIMEOUT" "900000" }}, + "configFetchInterval": {{ getenv "APP_CONFIG_FETCH_INTERVAL" "600000" }}, + "refreshTokenTimeout": {{ getenv "APP_REFRESH_TOKEN_TIMEOUT" "60000" }}, "releaseTimestampIntervalTimeout": {{ getenv "APP_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT" "600000" }}, "dataStrategy": { "type": "pull", "config": { - "interval": {{ getenv "APP_DATA_PULL_INTERVAL" "30000" }}, - "endpoint": "{{ getenv "APP_API_PATH" "/" }}" + "interval": {{ getenv "APP_DATA_PULL_INTERVAL" "30000" }} } }, "colorScheme": { diff --git a/public/example_config.json b/public/example_config.json index daccb7d1..9d638e96 100644 --- a/public/example_config.json +++ b/public/example_config.json @@ -1,7 +1,5 @@ { "apiEndpoint": "", - "authenticationEndpoint": "/v2/authentication/screen", - "authenticationRefreshTokenEndpoint": "/v2/authentication/token/refresh", "loginCheckTimeout": 20000, "configFetchInterval": 90000, "refreshTokenTimeout": 900000, @@ -9,8 +7,7 @@ "dataStrategy": { "type": "pull", "config": { - "interval": 30000, - "endpoint": "" + "interval": 30000 } }, "colorScheme": { diff --git a/src/app.js b/src/app.js index 8b0aeb9c..f978ec1f 100644 --- a/src/app.js +++ b/src/app.js @@ -97,7 +97,7 @@ function App() { Logger.log('info', 'Refreshing token.'); ConfigLoader.loadConfig().then((config) => { - fetch(config.authenticationRefreshTokenEndpoint, { + fetch(`${config.apiEndpoint}/v2/authentication/token/refresh`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -187,7 +187,7 @@ function App() { startContent(localScreenId); } else { ConfigLoader.loadConfig().then((config) => { - fetch(config.authenticationEndpoint, { + fetch(`${config.apiEndpoint}/v2/authentication/screen`, { method: 'POST', mode: 'cors', credentials: 'include', diff --git a/src/config-loader.js b/src/config-loader.js index 0a7671bb..33396df9 100644 --- a/src/config-loader.js +++ b/src/config-loader.js @@ -43,19 +43,16 @@ const ConfigLoader = { // Default config. resolve({ - authenticationEndpoint: '/api/authentication/screen', - authenticationRefreshTokenEndpoint: - '/api/authentication/token/refresh', + apiEndpoint: '/api', dataStrategy: { type: 'pull', config: { interval: 30000, - endpoint: '/api', }, }, loginCheckTimeout: 20000, configFetchInterval: 900000, - refreshTokenTimeout: 900000, + refreshTokenTimeout: 15000, releaseTimestampIntervalTimeout: 600000, colorScheme: { type: 'library', diff --git a/src/data-sync/data-sync.js b/src/data-sync/data-sync.js index 6a50fef0..f74d9e98 100644 --- a/src/data-sync/data-sync.js +++ b/src/data-sync/data-sync.js @@ -15,7 +15,7 @@ class DataSync { constructor(config) { this.start = this.start.bind(this); - this.config = config.config; + this.config = config; this.strategy = null; switch (config.type) { diff --git a/src/service/contentService.js b/src/service/contentService.js index 0d8ffb10..3e87227a 100644 --- a/src/service/contentService.js +++ b/src/service/contentService.js @@ -44,13 +44,15 @@ class ContentService { Logger.log('info', 'Starting data synchronization'); ConfigLoader.loadConfig().then((config) => { - const dataStrategy = { ...config.dataStrategy }; + const dataStrategyConfig = { ...config.dataStrategy.config }; if (screenPath) { - dataStrategy.config.entryPoint = screenPath; + dataStrategyConfig.entryPoint = screenPath; } - this.dataSync = new DataSync(dataStrategy); + dataStrategyConfig.endpoint = config.apiEndpoint; + + this.dataSync = new DataSync(dataStrategyConfig); this.dataSync.start(); }); } From 47aedaa9b49c8bb7f3b8edc4eef38c401a29bde0 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:30:13 +0200 Subject: [PATCH 08/10] 1186: Updated example_config.json value --- README.md | 6 +++--- public/example_config.json | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e696c8ce..6c31f978 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ See [https://github.com/os2display/display-docs/blob/main/client.md](https://git ## Config The client can be configured by creating `public/config.json` with relevant values. -See `public/example_config.json` for values. +See `public/example_config.json` for example values. Values explained: -* apiEndpoint - The endpoint where the API can be called. +* apiEndpoint - The endpoint where the API is located. * loginCheckTimeout - How often (milliseconds) should the screen check for status when it is not logged in, and waiting for being activated in the administration. @@ -28,7 +28,7 @@ screen be checked. * debug - Should the screen be in debug mode? If true, the cursor will be invisible. -All endpoint should be configured with out a trailing slash. The endpoints `apiEndpoint` and `dataStrategy.config.endpoint` can be +All endpoint should be configured without a trailing slash. The endpoints `apiEndpoint` can be left empty if the api is hosted from the root of the same domain as the client. E.g. if the api is at https://example.org and the client is at https://example.org/client diff --git a/public/example_config.json b/public/example_config.json index 9d638e96..c5bf1609 100644 --- a/public/example_config.json +++ b/public/example_config.json @@ -1,5 +1,5 @@ { - "apiEndpoint": "", + "apiEndpoint": "https://os2display.example.org", "loginCheckTimeout": 20000, "configFetchInterval": 90000, "refreshTokenTimeout": 900000, @@ -16,5 +16,11 @@ "lng": 10.0 }, "schedulingInterval": 60000, - "debug": false + "debug": false, + "logging": [ + { + "transport": "console", + "level": "info" + } + ] } From dee8f0af76d013404f4e93b1bb6eca376b7bfe12 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:37:45 +0200 Subject: [PATCH 09/10] 1185: Updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 310b32cd..8683bf16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. - [#123](https://github.com/os2display/display-client/pull/123) + - Ensured real ip is logged in nginx. +- [#124](https://github.com/os2display/display-client/pull/124) - Changed to apply max-age 7d to all files and added cache busting to config.json and release.json. - Added "loginCheckTimeout", "configFetchInterval", "refreshTokenTimeout", "releaseTimestampIntervalTimeout" to config.json. - Simplified config.json. From 96dd61930060fc8f57674a835fbf8c0303c70700 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Thu, 25 Apr 2024 09:41:18 +0200 Subject: [PATCH 10/10] Updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8683bf16..ca40573b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. +## [2.0.2] - 2024-04-25 + - [#123](https://github.com/os2display/display-client/pull/123) - Ensured real ip is logged in nginx. - [#124](https://github.com/os2display/display-client/pull/124)