From 4a3ce9acba7d0919d8151e06ac6565988788cba4 Mon Sep 17 00:00:00 2001 From: joshinat0r Date: Fri, 21 Aug 2020 10:19:47 +0200 Subject: [PATCH 01/11] respect DNT --- public/umami.js | 2 +- tracker/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/umami.js b/public/umami.js index 64a68198..003d97bd 100644 --- a/public/umami.js +++ b/public/umami.js @@ -1 +1 @@ -!function(){"use strict";function e(e){var t=this.constructor;return this.then((function(n){return t.resolve(e()).then((function(){return n}))}),(function(n){return t.resolve(e()).then((function(){return t.reject(n)}))}))}var t=setTimeout;function n(e){return Boolean(e&&void 0!==e.length)}function r(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],f(e,this)}function i(e,t){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,o._immediateFn((function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null!==n){var r;try{r=n(e._value)}catch(e){return void a(t.promise,e)}u(t.promise,r)}else(1===e._state?u:a)(t.promise,e._value)}))):e._deferreds.push(t)}function u(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof o)return e._state=3,e._value=t,void c(e);if("function"==typeof n)return void f((r=n,i=t,function(){r.apply(i,arguments)}),e)}e._state=1,e._value=t,c(e)}catch(t){a(e,t)}var r,i}function a(e,t){e._state=2,e._value=t,c(e)}function c(e){2===e._state&&0===e._deferreds.length&&o._immediateFn((function(){e._handled||o._unhandledRejectionFn(e._value)}));for(var t=0,n=e._deferreds.length;t Date: Fri, 21 Aug 2020 11:51:42 +0200 Subject: [PATCH 02/11] proper cross browser dnt support --- lib/web.js | 12 ++++++++++++ tracker/index.js | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/web.js b/lib/web.js index b75a6ba7..4b703894 100644 --- a/lib/web.js +++ b/lib/web.js @@ -46,3 +46,15 @@ export const hook = (_this, method, callback) => { return orig.apply(_this, args); }; }; + +export const doNotTrack = () => { + if (window.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack || 'msTrackingProtectionEnabled' in window.external) { + if (window.doNotTrack == "1" || navigator.doNotTrack == "yes" || navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1" || window.external.msTrackingProtectionEnabled()) { + return true + } else { + return false + } + } else { + return false + } +} diff --git a/tracker/index.js b/tracker/index.js index 48dcc487..708a9b37 100644 --- a/tracker/index.js +++ b/tracker/index.js @@ -1,6 +1,6 @@ import 'promise-polyfill/src/polyfill'; import 'unfetch/polyfill'; -import { post, hook } from '../lib/web'; +import { post, hook, doNotTrack } from '../lib/web'; (window => { const { @@ -13,7 +13,7 @@ import { post, hook } from '../lib/web'; const script = document.querySelector('script[data-website-id]'); - if (!script || navigator.doNotTrack === "1") return; + if (!script || doNotTrack()) return; const website = script.getAttribute('data-website-id'); const hostUrl = new URL(script.src).origin; From 6445702610e3d6fbfdeca41a908203303491a1f5 Mon Sep 17 00:00:00 2001 From: joshinat0r Date: Fri, 21 Aug 2020 11:53:07 +0200 Subject: [PATCH 03/11] rebuild tracking script --- public/umami.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/umami.js b/public/umami.js index 003d97bd..3bf2dec5 100644 --- a/public/umami.js +++ b/public/umami.js @@ -1 +1 @@ -!function(){"use strict";function e(e){var t=this.constructor;return this.then((function(n){return t.resolve(e()).then((function(){return n}))}),(function(n){return t.resolve(e()).then((function(){return t.reject(n)}))}))}var t=setTimeout;function n(e){return Boolean(e&&void 0!==e.length)}function r(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],f(e,this)}function i(e,t){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,o._immediateFn((function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null!==n){var r;try{r=n(e._value)}catch(e){return void a(t.promise,e)}u(t.promise,r)}else(1===e._state?u:a)(t.promise,e._value)}))):e._deferreds.push(t)}function u(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof o)return e._state=3,e._value=t,void c(e);if("function"==typeof n)return void f((r=n,i=t,function(){r.apply(i,arguments)}),e)}e._state=1,e._value=t,c(e)}catch(t){a(e,t)}var r,i}function a(e,t){e._state=2,e._value=t,c(e)}function c(e){2===e._state&&0===e._deferreds.length&&o._immediateFn((function(){e._handled||o._unhandledRejectionFn(e._value)}));for(var t=0,n=e._deferreds.length;t Date: Sat, 22 Aug 2020 00:34:56 -0700 Subject: [PATCH 04/11] fix typo in active visitor count --- components/charts/ActiveUsers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/charts/ActiveUsers.js b/components/charts/ActiveUsers.js index 4d1118fa..10c10155 100644 --- a/components/charts/ActiveUsers.js +++ b/components/charts/ActiveUsers.js @@ -38,7 +38,7 @@ export default function ActiveUsers({ websiteId, className }) { {props.x.interpolate(x => x.toFixed(0))} -
{`current vistor${count !== 1 ? 's' : ''}`}
+
{`current visitor${count !== 1 ? 's' : ''}`}
); From 9ac97a329359f6b7332c867892617d9287442ec8 Mon Sep 17 00:00:00 2001 From: Snir David Date: Sat, 22 Aug 2020 12:22:29 +0300 Subject: [PATCH 05/11] Collect urls in pushstate the same way as in initial load --- public/umami.js | 2 +- tracker/index.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/public/umami.js b/public/umami.js index 3bf2dec5..781d1f10 100644 --- a/public/umami.js +++ b/public/umami.js @@ -1 +1 @@ -!function(){"use strict";function e(e){var t=this.constructor;return this.then((function(n){return t.resolve(e()).then((function(){return n}))}),(function(n){return t.resolve(e()).then((function(){return t.reject(n)}))}))}var t=setTimeout;function n(e){return Boolean(e&&void 0!==e.length)}function r(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],f(e,this)}function i(e,t){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,o._immediateFn((function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null!==n){var r;try{r=n(e._value)}catch(e){return void u(t.promise,e)}a(t.promise,r)}else(1===e._state?a:u)(t.promise,e._value)}))):e._deferreds.push(t)}function a(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof o)return e._state=3,e._value=t,void c(e);if("function"==typeof n)return void f((r=n,i=t,function(){r.apply(i,arguments)}),e)}e._state=1,e._value=t,c(e)}catch(t){u(e,t)}var r,i}function u(e,t){e._state=2,e._value=t,c(e)}function c(e){2===e._state&&0===e._deferreds.length&&o._immediateFn((function(){e._handled||o._unhandledRejectionFn(e._value)}));for(var t=0,n=e._deferreds.length;t { + const handlePush = (state, title, navaigatedUrl) => { removeEvents(); currentRef = currentUrl; - currentUrl = url; + const url = new URL(navaigatedUrl); + currentUrl = `${url.pathname}${url.search}`; pageView(); }; From d1c7f2162b5328b5bf0c2ee993d1177351a78b83 Mon Sep 17 00:00:00 2001 From: Cobin Bluth Date: Sat, 22 Aug 2020 12:00:35 +0200 Subject: [PATCH 06/11] fix docker-compose --- .dockerignore | 2 ++ Dockerfile | 2 ++ docker-compose.yml | 22 ++++++++++------------ 3 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..12fe6241 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +.git +docker-compose.yml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index a3e31e09..4625124c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ FROM node:12.18-alpine +ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami" + COPY . /app WORKDIR /app diff --git a/docker-compose.yml b/docker-compose.yml index b09b81eb..f9560dd9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,25 +1,23 @@ -version: '3.8' +--- +version: '3' services: umami: build: . ports: - "3000:3000" environment: - DATABASE_URL: postgresql://umami:umami@postgres:5432/umami + DATABASE_URL: postgresql://umami:umami@db:5432/umami HASH_SALT: replace-me-with-a-random-string - postgres: + depends_on: + - db + db: image: postgres:alpine - ports: - - "5432:5432" environment: + POSTGRES_DB: umami POSTGRES_USER: umami POSTGRES_PASSWORD: umami volumes: - - type: bind - source: ./sql/schema.postgresql.sql - target: /docker-entrypoint-initdb.d/schema.postgresql.sql - - type: volume - source: postgres-data - target: /var/lib/postgresql/data + - ./sql/schema.postgresql.sql:/docker-entrypoint-initdb.d/schema.postgresql.sql:ro + - umami-db-data:/var/lib/postgresql/data volumes: - postgres-data: + umami-db-data: From 51f19e36f61838646a2949828a69a31246500b8c Mon Sep 17 00:00:00 2001 From: Joshua Hahn Date: Sat, 22 Aug 2020 12:03:39 +0200 Subject: [PATCH 07/11] fix DNT check --- lib/web.js | 23 +++++++++++++++++------ public/umami.js | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/web.js b/lib/web.js index 4b703894..8f1e26d5 100644 --- a/lib/web.js +++ b/lib/web.js @@ -48,13 +48,24 @@ export const hook = (_this, method, callback) => { }; export const doNotTrack = () => { - if (window.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack || 'msTrackingProtectionEnabled' in window.external) { - if (window.doNotTrack == "1" || navigator.doNotTrack == "yes" || navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1" || window.external.msTrackingProtectionEnabled()) { - return true + if ( + window.doNotTrack || + navigator.doNotTrack || + navigator.msDoNotTrack || + 'msTrackingProtectionEnabled' in window.external + ) { + if ( + window.doNotTrack == '1' || + navigator.doNotTrack == 'yes' || + navigator.doNotTrack == '1' || + navigator.msDoNotTrack == '1' || + (window.external.msTrackingProtectionEnabled && window.external.msTrackingProtectionEnabled()) + ) { + return true; } else { - return false + return false; } } else { - return false + return false; } -} +}; diff --git a/public/umami.js b/public/umami.js index 3bf2dec5..ce6e7e5e 100644 --- a/public/umami.js +++ b/public/umami.js @@ -1 +1 @@ -!function(){"use strict";function e(e){var t=this.constructor;return this.then((function(n){return t.resolve(e()).then((function(){return n}))}),(function(n){return t.resolve(e()).then((function(){return t.reject(n)}))}))}var t=setTimeout;function n(e){return Boolean(e&&void 0!==e.length)}function r(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],f(e,this)}function i(e,t){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,o._immediateFn((function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null!==n){var r;try{r=n(e._value)}catch(e){return void u(t.promise,e)}a(t.promise,r)}else(1===e._state?a:u)(t.promise,e._value)}))):e._deferreds.push(t)}function a(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof o)return e._state=3,e._value=t,void c(e);if("function"==typeof n)return void f((r=n,i=t,function(){r.apply(i,arguments)}),e)}e._state=1,e._value=t,c(e)}catch(t){u(e,t)}var r,i}function u(e,t){e._state=2,e._value=t,c(e)}function c(e){2===e._state&&0===e._deferreds.length&&o._immediateFn((function(){e._handled||o._unhandledRejectionFn(e._value)}));for(var t=0,n=e._deferreds.length;t Date: Sat, 22 Aug 2020 18:26:29 +0200 Subject: [PATCH 08/11] aaand another DNT fix --- lib/web.js | 4 +++- public/umami.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/web.js b/lib/web.js index 8f1e26d5..3cf942ab 100644 --- a/lib/web.js +++ b/lib/web.js @@ -59,7 +59,9 @@ export const doNotTrack = () => { navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1' || - (window.external.msTrackingProtectionEnabled && window.external.msTrackingProtectionEnabled()) + (window.external && + window.external.msTrackingProtectionEnabled && + window.external.msTrackingProtectionEnabled()) ) { return true; } else { diff --git a/public/umami.js b/public/umami.js index ce6e7e5e..66d5766a 100644 --- a/public/umami.js +++ b/public/umami.js @@ -1 +1 @@ -!function(){"use strict";function e(e){var t=this.constructor;return this.then((function(n){return t.resolve(e()).then((function(){return n}))}),(function(n){return t.resolve(e()).then((function(){return t.reject(n)}))}))}var t=setTimeout;function n(e){return Boolean(e&&void 0!==e.length)}function r(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],f(e,this)}function i(e,t){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,o._immediateFn((function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null!==n){var r;try{r=n(e._value)}catch(e){return void u(t.promise,e)}a(t.promise,r)}else(1===e._state?a:u)(t.promise,e._value)}))):e._deferreds.push(t)}function a(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof o)return e._state=3,e._value=t,void c(e);if("function"==typeof n)return void f((r=n,i=t,function(){r.apply(i,arguments)}),e)}e._state=1,e._value=t,c(e)}catch(t){u(e,t)}var r,i}function u(e,t){e._state=2,e._value=t,c(e)}function c(e){2===e._state&&0===e._deferreds.length&&o._immediateFn((function(){e._handled||o._unhandledRejectionFn(e._value)}));for(var t=0,n=e._deferreds.length;t Date: Sat, 22 Aug 2020 17:28:23 -0400 Subject: [PATCH 09/11] share page loading since there isn't a spinner, just returning null, just like pages/dashboard.js --- pages/share/[...id].js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pages/share/[...id].js b/pages/share/[...id].js index 15b911d4..21005a53 100644 --- a/pages/share/[...id].js +++ b/pages/share/[...id].js @@ -6,6 +6,7 @@ import NotFound from 'pages/404'; import { get } from 'lib/web'; export default function SharePage() { + const [loading, setLoading] = useState(true); const [websiteId, setWebsiteId] = useState(); const [notFound, setNotFound] = useState(false); const router = useRouter(); @@ -23,10 +24,16 @@ export default function SharePage() { useEffect(() => { if (id) { - loadData(); + loadData().finally(() => { + setLoading(false); + }); + } else { + setLoading(false); } }, [id]); + if (loading) return null; + if (!id || notFound) { return ; } From 73ea516a7abc5e7018c9311f3c832ba6ee91c76e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20M=C3=BCller-Downing?= Date: Sat, 22 Aug 2020 22:39:01 +1000 Subject: [PATCH 10/11] Add DATABASE_TYPE environment variable Determines which Prisma schema to use --- Dockerfile | 5 ++++- docker-compose.yml | 1 + scripts/copy-db-schema.js | 10 +++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4625124c..871b8a87 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,9 @@ FROM node:12.18-alpine -ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami" +ARG DATABASE_TYPE + +ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami" \ + DATABASE_TYPE=$DATABASE_TYPE COPY . /app WORKDIR /app diff --git a/docker-compose.yml b/docker-compose.yml index f9560dd9..7f1b42ff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,7 @@ services: - "3000:3000" environment: DATABASE_URL: postgresql://umami:umami@db:5432/umami + DATABASE_TYPE: postgresql HASH_SALT: replace-me-with-a-random-string depends_on: - db diff --git a/scripts/copy-db-schema.js b/scripts/copy-db-schema.js index 60c39598..5dda2215 100644 --- a/scripts/copy-db-schema.js +++ b/scripts/copy-db-schema.js @@ -2,15 +2,15 @@ require('dotenv').config(); const fs = require('fs'); const path = require('path'); -const db = process.env.DATABASE_URL.split(':')[0]; +const databaseType = process.env.DATABASE_TYPE || process.env.DATABASE_URL.split(':')[0]; -if (!db) { - throw new Error('Database not specified'); +if (!databaseType) { + throw new Error('Database schema not specified'); } -console.log(`Database detected: ${db}`); +console.log(`Database schema detected: ${databaseType}`); -const src = path.resolve(__dirname, `../prisma/schema.${db}.prisma`); +const src = path.resolve(__dirname, `../prisma/schema.${databaseType}.prisma`); const dest = path.resolve(__dirname, '../prisma/schema.prisma'); fs.copyFileSync(src, dest); From 8c66af79d83e7ce94d169df2472bb7f746fefa37 Mon Sep 17 00:00:00 2001 From: tim-hub Date: Sun, 23 Aug 2020 14:07:01 +1200 Subject: [PATCH 11/11] for better local building performance - ignore node_modules for building performance - ignore some misc stuff, DS_Store, etc --- .dockerignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index 12fe6241..40d5f5bb 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,6 @@ .git -docker-compose.yml \ No newline at end of file +docker-compose.yml +Dockerfile +.gitignore +.DS_Store +node_modules