From 05eda8d33465732ffd9286fcb2a6d4c27c4be7fc Mon Sep 17 00:00:00 2001
From: Christoph Reiter <reiter.christoph@gmail.com>
Date: Wed, 3 Feb 2021 11:38:48 +0100
Subject: [PATCH] showcase: port to app config

---
 toolkit-showcase/app.config.js        |  22 +++
 toolkit-showcase/assets/.htaccess.ejs |   6 +-
 toolkit-showcase/deploy.php           |  18 +-
 toolkit-showcase/package.json         |  13 +-
 toolkit-showcase/rollup.config.js     | 227 +++++++++-----------------
 5 files changed, 113 insertions(+), 173 deletions(-)
 create mode 100644 toolkit-showcase/app.config.js

diff --git a/toolkit-showcase/app.config.js b/toolkit-showcase/app.config.js
new file mode 100644
index 00000000..f9dfa2a8
--- /dev/null
+++ b/toolkit-showcase/app.config.js
@@ -0,0 +1,22 @@
+export default {
+    local: {
+        basePath: '/dist/',
+        entryPointURL: 'http://127.0.0.1:8000',
+        keyCloakBaseURL: 'https://auth-dev.tugraz.at/auth',
+        keyCloakClientId: 'auth-dev-mw-frontend-local',
+        matomoUrl: 'https://analytics.tugraz.at/',
+        matomoSiteId: 131,
+        nextcloudBaseURL: 'http://localhost:8081',
+        nextcloudName: 'TU Graz cloud',
+    },
+    development: {
+        basePath: '/apps/checkin/',
+        entryPointURL: 'https://mw-dev.tugraz.at',
+        keyCloakBaseURL: 'https://auth-dev.tugraz.at/auth',
+        keyCloakClientId: 'demo-dev_tugraz_at-DEMO',
+        matomoUrl: 'https://analytics.tugraz.at/',
+        matomoSiteId: 131,
+        nextcloudBaseURL: 'https://nc-dev.tugraz.at/pers',
+        nextcloudName: 'TU Graz cloud',
+    },
+};
\ No newline at end of file
diff --git a/toolkit-showcase/assets/.htaccess.ejs b/toolkit-showcase/assets/.htaccess.ejs
index f2512eea..968bcc63 100644
--- a/toolkit-showcase/assets/.htaccess.ejs
+++ b/toolkit-showcase/assets/.htaccess.ejs
@@ -1,10 +1,10 @@
-DirectoryIndex <%= getUrl(name + '.html') %>
+DirectoryIndex <%- getUrl(name + '.html') %>
 <FilesMatch "^(de|en|)$">
-    FallbackResource <%= getUrl(name + '.html') %>
+    FallbackResource <%- getUrl(name + '.html') %>
 </FilesMatch>
 
 Header set Cache-Control "must-revalidate, max-age=60"
-Header set Content-Security-Policy "default-src 'self' 'unsafe-eval' 'unsafe-inline' analytics.tugraz.at <%= keyCloakServer %> <%= entryPointURL %> httpbin.org <%= nextcloudBaseURL %> www.handy-signatur.at <%= pdfAsQualifiedlySigningServer %>; img-src * blob: data:"
+Header set Content-Security-Policy "<%- CSP %>"
 
 # Apache adds a "-gzip" suffix to the etag when it uses gzip but doesn't
 # take that into account when receiving requests.
diff --git a/toolkit-showcase/deploy.php b/toolkit-showcase/deploy.php
index ab2a3619..e5d2e8d3 100644
--- a/toolkit-showcase/deploy.php
+++ b/toolkit-showcase/deploy.php
@@ -37,24 +37,16 @@ host('development')
     ->hostname('mw@mw01-dev.tugraz.at')
     ->set('deploy_path', '/home/mw/dev/deploy/apps/demo');
 
-// Demo build task
-task('build-demo', function () {
+task('build', function () {
+    $stage = get('stage');
     runLocally("yarn install");
-    runLocally("yarn run build-demo");
-})->onStage('demo');
-
-// Demo dev task
-task('build-development', function () {
-    runLocally("yarn install");
-    runLocally("yarn run build-dev");
-})->onStage('development');
-
+    runLocally("APP_ENV=$stage yarn run build");
+});
 
 // Deploy task
 task('deploy', [
     'deploy:info',
-    'build-demo',
-    'build-development',
+    'build',
     'deploy:prepare',
     'deploy:lock',
     'deploy:release',
diff --git a/toolkit-showcase/package.json b/toolkit-showcase/package.json
index 30bbfeeb..73e58e57 100644
--- a/toolkit-showcase/package.json
+++ b/toolkit-showcase/package.json
@@ -5,7 +5,8 @@
   "license": "LGPL-2.1-or-later",
   "private": true,
   "workspaces": [
-    "../packages/*"
+    "../packages/*",
+    "."
   ],
   "devDependencies": {
     "@babel/core": "^7.10.3",
@@ -18,7 +19,6 @@
     "@rollup/plugin-commonjs": "^17.0.0",
     "@rollup/plugin-json": "^4.1.0",
     "@rollup/plugin-node-resolve": "^11.0.0",
-    "@rollup/plugin-replace": "^2.3.3",
     "@rollup/plugin-url": "^6.0.0",
     "babel-eslint": "^10.0.3",
     "chai": "^4.2.0",
@@ -67,15 +67,14 @@
     "webdav": "^3.3.0"
   },
   "scripts": {
-    "build-dev": "rollup -c --environment BUILD:development",
-    "build-prod": "rollup -c --environment BUILD:production",
-    "build-demo": "rollup -c --environment BUILD:demo",
+    "build": "rollup -c",
     "i18next": "i18next-scanner",
     "watch": "rollup -c --watch",
     "watch-local": "yarn run watch",
     "watch-full": "rollup -c --watch --environment FORCE_FULL",
-    "test": "rollup -c --environment BUILD:test && karma start --singleRun",
-    "test-full": "rollup -c --environment FORCE_FULL,BUILD:test && karma start --singleRun",
+    "watch-bs": "rollup -c --watch --environment APP_ENV:bs",
+    "test": "rollup -c --environment APP_ENV:test && karma start --singleRun",
+    "test-full": "rollup -c --environment FORCE_FULL,APP_ENV:test && karma start --singleRun",
     "lint": "eslint ."
   }
 }
diff --git a/toolkit-showcase/rollup.config.js b/toolkit-showcase/rollup.config.js
index 5004c26f..a232dcd3 100644
--- a/toolkit-showcase/rollup.config.js
+++ b/toolkit-showcase/rollup.config.js
@@ -6,7 +6,6 @@ import commonjs from '@rollup/plugin-commonjs';
 import copy from 'rollup-plugin-copy';
 import {terser} from "rollup-plugin-terser";
 import json from '@rollup/plugin-json';
-import replace from "@rollup/plugin-replace";
 import serve from 'rollup-plugin-serve';
 import urlPlugin from "@rollup/plugin-url";
 import license from 'rollup-plugin-license';
@@ -14,126 +13,65 @@ import del from 'rollup-plugin-delete';
 import md from 'rollup-plugin-md';
 import emitEJS from 'rollup-plugin-emit-ejs'
 import babel from '@rollup/plugin-babel'
-import {generateTLSConfig} from '../rollup.utils.js';
-
-// -------------------------------
-
-// Some new web APIs are only available when HTTPS is active.
-// Note that this only works with a Non-HTTPS API endpoint with Chrome,
-// Firefox will emit CORS errors, see https://bugzilla.mozilla.org/show_bug.cgi?id=1488740
-const USE_HTTPS = true;
-
-// -------------------------------
+import appConfig from './app.config.js';
+import {generateTLSConfig, getBuildInfo, getPackagePath, getDistPath} from '../rollup.utils.js';
 
 const pkg = require('./package.json');
-const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
+const appEnv = (typeof process.env.APP_ENV !== 'undefined') ? process.env.APP_ENV : 'local';
 const watch = process.env.ROLLUP_WATCH === 'true';
-const buildFull = (!watch && build !== 'test') || (process.env.FORCE_FULL !== undefined);
-
-console.log("build: " + build);
-let basePath = '';
-let entryPointURL = '';
-let nextcloudBaseURL = 'https://cloud.tugraz.at';
-let nextcloudWebAppPasswordURL = nextcloudBaseURL + '/apps/webapppassword';
-let nextcloudWebDavURL = nextcloudBaseURL + '/remote.php/dav/files';
-let nextcloudName = 'TU Graz cloud';
-let keyCloakServer = '';
-let keyCloakBaseURL = '';
-let keyCloakClientId = '';
-let pdfAsQualifiedlySigningServer = '';
-const matomoUrl = "https://analytics.tugraz.at/";
-const matomoSiteId = 131;
+const buildFull = (!watch && appEnv !== 'test') || (process.env.FORCE_FULL !== undefined);
 let useTerser = buildFull;
 let useBabel = buildFull;
 let checkLicenses = buildFull;
+let useHTTPS = true;
 
-switch (build) {
-  case 'local':
-    basePath = '/dist/';
-    entryPointURL = 'http://127.0.0.1:8000';
-    nextcloudBaseURL = 'http://localhost:8081';
-    nextcloudWebAppPasswordURL = nextcloudBaseURL + '/index.php/apps/webapppassword';
-    nextcloudWebDavURL = nextcloudBaseURL + '/remote.php/dav/files';
-    keyCloakServer = 'auth-dev.tugraz.at';
-    keyCloakBaseURL = 'https://' + keyCloakServer + '/auth';
-    keyCloakClientId = 'auth-dev-mw-frontend-local';
-    pdfAsQualifiedlySigningServer = 'sig-dev.tugraz.at';
-    break;
-  case 'development':
-    basePath = '/apps/demo/';
-    entryPointURL = 'https://mw-dev.tugraz.at';
-    // "/pers" can't go here because it's not allowed in the "Content-Security-Policy"
-    nextcloudBaseURL = 'https://nc-dev.tugraz.at';
-    // "/index.php" is needed to don't get a "This origin is not allowed!" because the "target-origin" get parameter can't be read
-    nextcloudWebAppPasswordURL = nextcloudBaseURL + '/pers/index.php/apps/webapppassword';
-    nextcloudWebDavURL = nextcloudBaseURL + '/pers/remote.php/dav/files';
-    keyCloakServer = 'auth-dev.tugraz.at';
-    keyCloakBaseURL = 'https://' + keyCloakServer + '/auth';
-    keyCloakClientId = 'demo-dev_tugraz_at-DEMO';
-    pdfAsQualifiedlySigningServer = 'sig-dev.tugraz.at';
-    break;
-  case 'demo':
-    basePath = '/apps/demo/';
-    entryPointURL = 'https://api-demo.tugraz.at';
-    // "/pers" can't go here because it's not allowed in the "Content-Security-Policy"
-    nextcloudBaseURL = 'https://nc-dev.tugraz.at';
-    // "/index.php" is needed to don't get a "This origin is not allowed!" because the "target-origin" get parameter can't be read
-    nextcloudWebAppPasswordURL = nextcloudBaseURL + '/pers/index.php/apps/webapppassword';
-    nextcloudWebDavURL = nextcloudBaseURL + '/pers/remote.php/dav/files';
-    keyCloakServer = 'auth-test.tugraz.at';
-    keyCloakBaseURL = 'https://' + keyCloakServer + '/auth';
-    keyCloakClientId = 'auth-dev-mw-frontend';
-    pdfAsQualifiedlySigningServer = 'sig-dev.tugraz.at';
-    break;
+console.log("APP_ENV: " + appEnv);
 
-  default:
-    console.error('Unknown build environment: ' + build);
+let config;
+if (appEnv in appConfig) {
+    config = appConfig[appEnv];
+} else if (appEnv === 'test') {
+    config = {
+        basePath: '/',
+        entryPointURL: 'https://test',
+        keyCloakBaseURL: 'https://test',
+        keyCloakClientId: '',
+        matomoUrl: '',
+        matomoSiteId: -1,
+        nextcloudBaseURL: 'https://test',
+        nextcloudName: '',
+    };
+} else {
+    console.error(`Unknown build environment: '${appEnv}', use one of '${Object.keys(appConfig)}'`);
     process.exit(1);
 }
 
-let nextcloudFileURL = nextcloudBaseURL + '/apps/files/?dir=';
+if (config.nextcloudBaseURL) {
+    config.nextcloudFileURL = config.nextcloudBaseURL + '/index.php/apps/files/?dir=';
+    config.nextcloudWebAppPasswordURL = config.nextcloudBaseURL + '/index.php/apps/webapppassword';
+    config.nextcloudWebDavURL = config.nextcloudBaseURL + '/remote.php/dav/files';
+} else {
+    config.nextcloudFileURL = '';
+    config.nextcloudWebAppPasswordURL = '';
+    config.nextcloudWebDavURL = '';
+}
 
-function getBuildInfo() {
-    const child_process = require('child_process');
-    const url = require('url');
+function getOrigin(url) {
+    if (url)
+        return new URL(url).origin;
+    return '';
+}
 
-    let remote = child_process.execSync('git config --get remote.origin.url').toString().trim();
-    let commit = child_process.execSync('git rev-parse --short HEAD').toString().trim();
+config.CSP = `default-src 'self' 'unsafe-eval' 'unsafe-inline' \
+${getOrigin(config.matomoUrl)} ${getOrigin(config.keyCloakBaseURL)} ${getOrigin(config.entryPointURL)} \
+httpbin.org ${getOrigin(config.nextcloudBaseURL)}; \
+img-src * blob: data:`;
 
-    let parsed = url.parse(remote);
-    // convert git urls
-    if (parsed.protocol === null) {
-        parsed = url.parse('git://' + remote.replace(":", "/"));
-        parsed.protocol = 'https:';
-    }
-    let newPath = parsed.path.slice(0, parsed.path.lastIndexOf('.'));
-    let newUrl = parsed.protocol + '//' + parsed.host + newPath + '/commit/' + commit;
 
+export default (async () => {
+    let privatePath = await getDistPath(pkg.name)
     return {
-        info: commit,
-        url: newUrl,
-        time: new Date().toISOString(),
-        env: build
-    }
-}
-
-export async function getPackagePath(packageName, assetPath) {
-    const r = resolve();
-    const resolved = await r.resolveId(packageName);
-    let packageRoot;
-    if (resolved !== null) {
-        const id = (await r.resolveId(packageName)).id;
-        const packageInfo = r.getPackageInfoForId(id);
-        packageRoot = packageInfo.root;
-    } else {
-        // Non JS packages
-        packageRoot = path.dirname(require.resolve(packageName + '/package.json'));
-    }
-    return path.relative(process.cwd(), path.join(packageRoot, assetPath));
-}
-
-export default (async () => {return {
-    input: (build != 'test') ? glob.sync('src/*.js') : glob.sync('test/**/*.js'),
+    input: (appEnv != 'test') ? glob.sync('src/dbp-*.js') : glob.sync('test/**/*.js'),
     output: {
       dir: 'dist',
       entryFileNames: '[name].js',
@@ -154,11 +92,6 @@ export default (async () => {return {
         }
         warn(warning);
     },
-    watch: {
-      chokidar: {
-        usePolling: true
-      }
-    },
     plugins: [
         del({
           targets: 'dist/*'
@@ -168,26 +101,24 @@ export default (async () => {return {
           include: ['**/*.ejs', '**/.*.ejs'],
           data: {
             getUrl: (p) => {
-              return url.resolve(basePath, p);
+              return url.resolve(config.basePath, p);
             },
             getPrivateUrl: (p) => {
-                return url.resolve(`${basePath}local/${pkg.name}/`, p);
+                return url.resolve(`${config.basePath}${privatePath}/`, p);
             },
             name: pkg.name,
-            entryPointURL: entryPointURL,
-            nextcloudBaseURL: nextcloudBaseURL,
-            nextcloudWebAppPasswordURL: nextcloudWebAppPasswordURL,
-            nextcloudWebDavURL: nextcloudWebDavURL,
-            nextcloudFileURL: nextcloudFileURL,
-            nextcloudName: nextcloudName,
-            keyCloakServer: keyCloakServer,
-            keyCloakBaseURL: keyCloakBaseURL,
-            keyCloakClientId: keyCloakClientId,
-            pdfAsQualifiedlySigningServer: pdfAsQualifiedlySigningServer,
-            environment: build,
-            matomoUrl: matomoUrl,
-            matomoSiteId: matomoSiteId,
-            buildInfo: getBuildInfo()
+            entryPointURL: config.entryPointURL,
+            nextcloudBaseURL: config.nextcloudBaseURL,
+            nextcloudWebAppPasswordURL: config.nextcloudWebAppPasswordURL,
+            nextcloudWebDavURL: config.nextcloudWebDavURL,
+            nextcloudFileURL: config.nextcloudFileURL,
+            nextcloudName: config.nextcloudName,
+            keyCloakBaseURL: config.keyCloakBaseURL,
+            keyCloakClientId: config.keyCloakClientId,
+            CSP: config.CSP,
+            matomoUrl: config.matomoUrl,
+            matomoSiteId: config.matomoSiteId,
+            buildInfo: getBuildInfo(appEnv)
           }
         }),
         resolve({
@@ -234,34 +165,30 @@ Dependencies:
           emitFiles: true,
           fileName: 'shared/[name].[hash][extname]'
         }),
-        replace({
-            "process.env.BUILD": '"' + build + '"',
-        }),
         useTerser ? terser() : false,
         copy({
             targets: [
-                {src: 'assets/silent-check-sso.html', dest:'dist'},
+                {src: 'assets/*.css', dest: 'dist/' + await getDistPath(pkg.name)},
+                {src: 'assets/*.ico', dest: 'dist/' + await getDistPath(pkg.name)},
+                {src: 'assets/*.metadata.json', dest: 'dist'},
+                {src: 'assets/*.svg', dest: 'dist/' + await getDistPath(pkg.name)},
                 {src: 'assets/htaccess-shared', dest: 'dist/shared/', rename: '.htaccess'},
-                {src: 'assets/*.css', dest: 'dist/local/' + pkg.name},
-                {src: 'assets/*.ico', dest: 'dist/local/' + pkg.name},
-                {src: 'assets/*.svg', dest: 'dist/local/' + pkg.name},
+                {src: 'assets/icon-*.png', dest: 'dist/' + await getDistPath(pkg.name)},
+                {src: 'assets/manifest.json', dest: 'dist', rename: pkg.name + '.manifest.json'},
+                {src: 'assets/silent-check-sso.html', dest:'dist'},
                 {
-                    src: 'node_modules/pdfjs-dist/build/pdf.worker.min.js',
-                    dest: 'dist/local/' + pkg.name + '/pdfjs',
+                    src: await getPackagePath('pdfjs-dist', 'es5/build/pdf.worker.js'),
+                    dest: 'dist/' + await getDistPath(pkg.name, 'pdfjs'),
                     // enable signatures in pdf preview
-                    transform: (contents) => contents.toString().replace('if("Sig"===a.fieldType){a.fieldValue=null;this.setFlags(r.AnnotationFlag.HIDDEN)}', '')
+                    transform: (contents) => contents.toString().replace('"Sig"', '"Sig-patched-show-anyway"')
                 },
-                {src: 'node_modules/pdfjs-dist/cmaps/*', dest: 'dist/local/' + pkg.name + '/pdfjs'}, // do we want all map files?
-                {src: await getPackagePath('@dbp-toolkit/font-source-sans-pro', 'files/*'), dest: 'dist/local/' + pkg.name + '/fonts/source-sans-pro'},
-                {src: 'node_modules/@dbp-toolkit/common/src/spinner.js', dest: 'dist/local/' + pkg.name, rename: 'spinner.js'},
-                {src: 'node_modules/@dbp-toolkit/common/misc/browser-check.js', dest: 'dist/local/' + pkg.name, rename: 'browser-check.js'},
-                {src: 'assets/icon-*.png', dest: 'dist/local/' + pkg.name},
-                {src: 'assets/*-placeholder.png', dest: 'dist/local/' + pkg.name},
-                {src: 'assets/manifest.json', dest: 'dist', rename: pkg.name + '.manifest.json'},
-                {src: 'assets/*.metadata.json', dest: 'dist'},
-                {src: 'node_modules/@dbp-toolkit/common/assets/icons/*.svg', dest: 'dist/local/@dbp-toolkit/common/icons'},
-                {src: 'node_modules/tabulator-tables/dist/css', dest: 'dist/local/@dbp-toolkit/file-handling/tabulator-tables'},
-                {src: 'node_modules/qr-scanner/qr-scanner-worker.*', dest: 'dist/local/qr-code-scanner'},
+                {src: await getPackagePath('pdfjs-dist', 'cmaps/*'), dest: 'dist/' + await getDistPath(pkg.name, 'pdfjs')}, // do we want all map files?
+                {src: await getPackagePath('@dbp-toolkit/font-source-sans-pro', 'files/*'), dest: 'dist/' + await getDistPath(pkg.name, 'fonts/source-sans-pro')},
+                {src: await getPackagePath('@dbp-toolkit/common', 'src/spinner.js'), dest: 'dist/' + await getDistPath(pkg.name)},
+                {src: await getPackagePath('@dbp-toolkit/common', 'misc/browser-check.js'), dest: 'dist/' + await getDistPath(pkg.name)},
+                {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')},
+                {src: await getPackagePath('tabulator-tables', 'dist/css'), dest: 'dist/' + await getDistPath('@dbp-toolkit/file-handling', 'tabulator-tables')},
+                {src: await getPackagePath('qr-scanner', 'qr-scanner-worker.*'), dest: 'dist/' + await getDistPath('@dbp-toolkit/qr-code-scanner')},
             ],
         }),
         useBabel && babel({
@@ -293,10 +220,10 @@ Dependencies:
           contentBase: '.',
           host: '127.0.0.1',
           port: 8001,
-          historyApiFallback: basePath + pkg.name + '.html',
-          https: USE_HTTPS ? await generateTLSConfig() : false,
+          historyApiFallback: config.basePath + pkg.name + '.html',
+          https: useHTTPS ? await generateTLSConfig() : false,
           headers: {
-              'Content-Security-Policy': `default-src 'self' 'unsafe-eval' 'unsafe-inline' analytics.tugraz.at ${keyCloakServer} ${entryPointURL} httpbin.org ${nextcloudBaseURL} www.handy-signatur.at ${pdfAsQualifiedlySigningServer} ; img-src * blob: data:`
+              'Content-Security-Policy': config.CSP
           },
         }) : false
     ]
-- 
GitLab