From 97c84d42ba9a07fce28435a3db94027e8e6650d7 Mon Sep 17 00:00:00 2001 From: Kai Vandivier <49666798+KaiVandivier@users.noreply.github.com> Date: Mon, 4 Oct 2021 13:12:11 +0200 Subject: [PATCH 1/2] fix(service-worker): change routing to allow redirect to login page (#669) * fix(inject-manifest): skip index.html in second manifest * refactor(pwa-app): reconfigure standalone option * fix(service-worker): allow redirect to login page * refactor: use String.prototype.endsWith --- cli/src/lib/pwa/injectPrecacheManifest.js | 5 +- examples/pwa-app/d2.config.js | 2 - examples/pwa-app/package.json | 2 +- pwa/src/service-worker/service-worker.js | 100 +++++++++++++++------- 4 files changed, 71 insertions(+), 38 deletions(-) diff --git a/cli/src/lib/pwa/injectPrecacheManifest.js b/cli/src/lib/pwa/injectPrecacheManifest.js index b7b42c42d..13e5e86e4 100644 --- a/cli/src/lib/pwa/injectPrecacheManifest.js +++ b/cli/src/lib/pwa/injectPrecacheManifest.js @@ -42,8 +42,9 @@ module.exports = function injectPrecacheManifest(paths, config) { swDest: paths.shellBuildServiceWorker, globDirectory: paths.shellBuildOutput, globPatterns: ['**/*'], - // Skip `static` directory; CRA's workbox-webpack-plugin handles it smartly - globIgnores: ['static/**/*'], + // Skip index.html and `static` directory; + // CRA's workbox-webpack-plugin handles it smartly + globIgnores: ['static/**/*', 'index.html'], additionalManifestEntries: config.pwa.caching.additionalManifestEntries, injectionPoint: 'self.__WB_BUILD_MANIFEST', // Skip revision hashing for files with hash or semver in name: diff --git a/examples/pwa-app/d2.config.js b/examples/pwa-app/d2.config.js index 731e4fd6a..d7f7c1bfa 100644 --- a/examples/pwa-app/d2.config.js +++ b/examples/pwa-app/d2.config.js @@ -1,8 +1,6 @@ const config = { type: 'app', - standalone: true, - pwa: { enabled: true, caching: { diff --git a/examples/pwa-app/package.json b/examples/pwa-app/package.json index b961a144d..ce2a1c5ea 100644 --- a/examples/pwa-app/package.json +++ b/examples/pwa-app/package.json @@ -10,7 +10,7 @@ "test": "d2-app-scripts test", "deploy": "d2-app-scripts deploy", "serve": "serve -l 5500 build/app", - "demo": "yarn build --force --debug && yarn serve" + "demo": "yarn build --force --standalone --debug && yarn serve" }, "peerDependencies": { "@dhis2/app-runtime": "*", diff --git a/pwa/src/service-worker/service-worker.js b/pwa/src/service-worker/service-worker.js index c84f5a64f..a69bf6697 100644 --- a/pwa/src/service-worker/service-worker.js +++ b/pwa/src/service-worker/service-worker.js @@ -1,5 +1,5 @@ import { clientsClaim } from 'workbox-core' -import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching' +import { precacheAndRoute, matchPrecache, precache } from 'workbox-precaching' import { registerRoute, setDefaultHandler } from 'workbox-routing' import { NetworkFirst, @@ -57,45 +57,79 @@ export function setUpServiceWorker() { // Precache all of the assets generated by your build process. // Their URLs are injected into the manifest variable below. // This variable must be present somewhere in your service worker file, - // even if you decide not to use precaching. See https://cra.link/PWA - precacheAndRoute(self.__WB_MANIFEST || []) + // even if you decide not to use precaching. See https://cra.link/PWA. + // Includes all built assets and index.html + const precacheManifest = self.__WB_MANIFEST || [] + + // Extract index.html from the manifest to precache, then route + // in a custom way + const indexHtmlManifestEntry = precacheManifest.find(({ url }) => + url.endsWith('index.html') + ) + precache([indexHtmlManifestEntry]) + + // Custom strategy for handling app navigation, specifically to allow + // navigations to redirect to the login page while online if the + // user is unauthenticated. Fixes showing the app shell login dialog + // in production if a user is online and unauthenticated. + // Uses app-shell style routing to route navigations to index.html. + const navigationRouteMatcher = ({ request, url }) => { + // If this isn't a navigation, skip. + if (request.mode !== 'navigate') { + return false + } + + // If this is a URL that starts with /_, skip. + if (url.pathname.startsWith('/_')) { + return false + } + + // If this looks like a URL for a resource, because it contains + // a file extension, skip (unless it's index.html) + if ( + fileExtensionRegexp.test(url.pathname) && + !url.pathname.endsWith('index.html') + ) { + return false + } + + // Return true to signal that we want to use the handler. + return true + } + const indexUrl = process.env.PUBLIC_URL + '/index.html' + const navigationRouteHandler = ({ request }) => { + return fetch(request) + .then(response => { + if (response.type === 'opaqueredirect') { + // It's sending a redirect to the login page. Return + // that to the client + return response + } + + // Otherwise return precached index.html + return matchPrecache(indexUrl) + }) + .catch(() => { + // Request failed (maybe offline). Return cached response + return matchPrecache(indexUrl) + }) + } + registerRoute(navigationRouteMatcher, navigationRouteHandler) + + // Handle the rest of files in the manifest + const restOfManifest = precacheManifest.filter( + e => e !== indexHtmlManifestEntry + ) + precacheAndRoute(restOfManifest) // Similar to above; manifest injection from `workbox-build` // Precaches all assets in the shell's build folder except in `static` // (which CRA's workbox-webpack-plugin handle smartly). // Additional files to precache can be added using the - // `additionalManifestEntries` option in d2.config.js; see the docs + // `additionalManifestEntries` option in d2.config.js; see the docs and + // 'injectPrecacheManifest.js' in the CLI package. // '[]' fallback prevents an error when switching pwa enabled to disabled precacheAndRoute(self.__WB_BUILD_MANIFEST || []) - - // From CRA Boilerplate: - // Set up App Shell-style routing, so that all navigation requests - // are fulfilled with your index.html shell. Learn more at - // https://developers.google.com/web/fundamentals/architecture/app-shell - registerRoute( - // Return false to exempt requests from being fulfilled by index.html. - ({ request, url }) => { - // If this isn't a navigation, skip. - if (request.mode !== 'navigate') { - return false - } - - // If this is a URL that starts with /_, skip. - if (url.pathname.startsWith('/_')) { - return false - } - - // If this looks like a URL for a resource, because it contains - // a file extension, skip. - if (url.pathname.match(fileExtensionRegexp)) { - return false - } - - // Return true to signal that we want to use the handler. - return true - }, - createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html') - ) } // Request handler during recording mode: ALL requests are cached From f0e57bb07578d24c5ae53a0319899a1380f1dbc3 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 4 Oct 2021 11:20:58 +0000 Subject: [PATCH 2/2] chore(release): cut 8.1.2 [skip ci] ## [8.1.2](https://github.com/dhis2/app-platform/compare/v8.1.1...v8.1.2) (2021-10-04) ### Bug Fixes * **service-worker:** change routing to allow redirect to login page ([#669](https://github.com/dhis2/app-platform/issues/669)) ([97c84d4](https://github.com/dhis2/app-platform/commit/97c84d42ba9a07fce28435a3db94027e8e6650d7)) --- CHANGELOG.md | 7 +++++++ adapter/package.json | 6 +++--- cli/package.json | 4 ++-- examples/pwa-app/package.json | 2 +- examples/simple-app/package.json | 2 +- package.json | 2 +- pwa/package.json | 4 ++-- shell/package.json | 6 +++--- 8 files changed, 20 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d687dd0d..d7f8de964 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [8.1.2](https://github.com/dhis2/app-platform/compare/v8.1.1...v8.1.2) (2021-10-04) + + +### Bug Fixes + +* **service-worker:** change routing to allow redirect to login page ([#669](https://github.com/dhis2/app-platform/issues/669)) ([97c84d4](https://github.com/dhis2/app-platform/commit/97c84d42ba9a07fce28435a3db94027e8e6650d7)) + ## [8.1.1](https://github.com/dhis2/app-platform/compare/v8.1.0...v8.1.1) (2021-09-28) diff --git a/adapter/package.json b/adapter/package.json index 47580538e..38f225f92 100644 --- a/adapter/package.json +++ b/adapter/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-adapter", - "version": "8.1.1", + "version": "8.1.2", "repository": { "type": "git", "url": "https://github.com/amcgee/dhis2-app-platform", @@ -21,11 +21,11 @@ "build" ], "dependencies": { - "@dhis2/pwa": "8.1.1", + "@dhis2/pwa": "8.1.2", "moment": "^2.24.0" }, "devDependencies": { - "@dhis2/cli-app-scripts": "8.1.1", + "@dhis2/cli-app-scripts": "8.1.2", "@testing-library/react": "^12.0.0", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/cli/package.json b/cli/package.json index 0eaa56a70..31d617263 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/cli-app-scripts", - "version": "8.1.1", + "version": "8.1.2", "engines": { "node": ">=12" }, @@ -28,7 +28,7 @@ "@babel/preset-env": "^7.14.7", "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.6.0", - "@dhis2/app-shell": "8.1.1", + "@dhis2/app-shell": "8.1.2", "@dhis2/cli-helpers-engine": "^3.0.0", "@jest/core": "^27.0.6", "archiver": "^3.1.1", diff --git a/examples/pwa-app/package.json b/examples/pwa-app/package.json index ce2a1c5ea..33b41fd72 100644 --- a/examples/pwa-app/package.json +++ b/examples/pwa-app/package.json @@ -1,6 +1,6 @@ { "name": "pwa-app", - "version": "8.1.1", + "version": "8.1.2", "description": "", "license": "BSD-3-Clause", "private": true, diff --git a/examples/simple-app/package.json b/examples/simple-app/package.json index 088281458..20e923b3d 100644 --- a/examples/simple-app/package.json +++ b/examples/simple-app/package.json @@ -1,6 +1,6 @@ { "name": "simple-app", - "version": "8.1.1", + "version": "8.1.2", "repository": "https://github.com/amcgee/dhis2-app-platform", "author": "Austin McGee ", "license": "BSD-3-Clause", diff --git a/package.json b/package.json index 2449a0f03..fe2b3162e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "8.1.1", + "version": "8.1.2", "private": true, "repository": { "type": "git", diff --git a/pwa/package.json b/pwa/package.json index f02af26dd..a9127adbc 100644 --- a/pwa/package.json +++ b/pwa/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/pwa", - "version": "8.1.1", + "version": "8.1.2", "description": "", "license": "BSD-3-Clause", "publishConfig": { @@ -13,7 +13,7 @@ "deploy": "d2-app-scripts deploy" }, "devDependencies": { - "@dhis2/cli-app-scripts": "8.1.1" + "@dhis2/cli-app-scripts": "8.1.2" }, "dependencies": { "idb": "^6.0.0", diff --git a/shell/package.json b/shell/package.json index 933cf60c3..bfd06fea2 100644 --- a/shell/package.json +++ b/shell/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-shell", - "version": "8.1.1", + "version": "8.1.2", "repository": { "type": "git", "url": "https://github.com/amcgee/dhis2-app-platform", @@ -12,10 +12,10 @@ "access": "public" }, "dependencies": { - "@dhis2/app-adapter": "8.1.1", + "@dhis2/app-adapter": "8.1.2", "@dhis2/app-runtime": "^3.2.2", "@dhis2/d2-i18n": "^1.1.0", - "@dhis2/pwa": "8.1.1", + "@dhis2/pwa": "8.1.2", "@dhis2/ui": "^7.2.0", "classnames": "^2.2.6", "moment": "^2.29.1",