From 9ba3100fe69cc798f7d379505210bb4c5e4cf5ec Mon Sep 17 00:00:00 2001
From: Patrizio Bekerle <patrizio@bekerle.com>
Date: Thu, 18 Jun 2020 17:00:00 +0200
Subject: [PATCH] Integrate basic Nextcloud login (#26)

---
 assets/.htaccess.ejs                      |   2 +-
 rollup.config.js                          |   7 +-
 src/vpu-file-picker.js                    | 101 ++++++++++++++++++++++
 src/vpu-qualified-signature-pdf-upload.js |   5 ++
 4 files changed, 113 insertions(+), 2 deletions(-)
 create mode 100644 src/vpu-file-picker.js

diff --git a/assets/.htaccess.ejs b/assets/.htaccess.ejs
index b61fde8..f2512ee 100644
--- a/assets/.htaccess.ejs
+++ b/assets/.htaccess.ejs
@@ -4,7 +4,7 @@ DirectoryIndex <%= 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 www.handy-signatur.at <%= pdfAsQualifiedlySigningServer %>; img-src * blob: data:"
+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:"
 
 # 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/rollup.config.js b/rollup.config.js
index 379e185..59ecc85 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -33,6 +33,7 @@ const watchFull = process.env.WATCH_FULL !== undefined;
 console.log("build: " + build);
 let basePath = '';
 let entryPointURL = '';
+let nextcloudBaseURL = 'https://cloud.tugraz.at';
 let keyCloakServer = '';
 let keyCloakBaseURL = '';
 let keyCloakClientId = '';
@@ -46,6 +47,7 @@ switch (build) {
   case 'local':
     basePath = '/dist/';
     entryPointURL = 'http://127.0.0.1:8000';
+    nextcloudBaseURL = 'http://localhost:8081/index.php';
     keyCloakServer = 'auth-dev.tugraz.at';
     keyCloakBaseURL = 'https://' + keyCloakServer + '/auth';
     keyCloakClientId = 'auth-dev-mw-frontend-local';
@@ -79,6 +81,7 @@ switch (build) {
   case 'test':
     basePath = '/apps/signature/';
     entryPointURL = '';
+    nextcloudBaseURL = '';
     keyCloakServer = '';
     keyCloakBaseURL = '';
     keyCloakClientId = '';
@@ -175,6 +178,7 @@ export default {
         consts({
           environment: build,
           buildinfo: getBuildInfo(),
+          nextcloudBaseURL: nextcloudBaseURL,
         }),
         emitEJS({
           src: 'assets',
@@ -188,6 +192,7 @@ export default {
             },
             name: pkg.name,
             entryPointURL: entryPointURL,
+            nextcloudBaseURL: nextcloudBaseURL,
             keyCloakServer: keyCloakServer,
             keyCloakBaseURL: keyCloakBaseURL,
             keyCloakClientId: keyCloakClientId,
@@ -295,7 +300,7 @@ Dependencies:
           historyApiFallback: basePath + pkg.name + '.html',
           https: USE_HTTPS ? generateTLSConfig() : false,
           headers: {
-              'Content-Security-Policy': `default-src 'self' 'unsafe-eval' 'unsafe-inline' analytics.tugraz.at ${keyCloakServer} ${entryPointURL} httpbin.org www.handy-signatur.at ${pdfAsQualifiedlySigningServer} ; img-src * blob: data:`
+              '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:`
           },
         }) : false
     ]
diff --git a/src/vpu-file-picker.js b/src/vpu-file-picker.js
new file mode 100644
index 0000000..185fd50
--- /dev/null
+++ b/src/vpu-file-picker.js
@@ -0,0 +1,101 @@
+import {createI18nInstance} from './i18n.js';
+import {css, html} from 'lit-element';
+import {classMap} from 'lit-html/directives/class-map.js';
+import {live} from 'lit-html/directives/live.js';
+import {ScopedElementsMixin} from '@open-wc/scoped-elements';
+import VPULitElement from 'vpu-common/vpu-lit-element';
+import {MiniSpinner} from 'vpu-common';
+import * as commonUtils from "vpu-common/utils";
+import * as commonStyles from 'vpu-common/styles';
+import pdfjs from 'pdfjs-dist';
+
+const i18n = createI18nInstance();
+
+/**
+ * FilePicker web component
+ */
+export class FilePicker extends ScopedElementsMixin(VPULitElement) {
+    constructor() {
+        super();
+        this.lang = 'de';
+        this.baseUrl = '';
+        this.loginWindow = null;
+
+        this._onReceiveWindowMessage = this.onReceiveWindowMessage.bind(this);
+    }
+
+    static get scopedElements() {
+        return {
+            'vpu-mini-spinner': MiniSpinner,
+        };
+    }
+
+    /**
+     * See: https://lit-element.polymer-project.org/guide/properties#initialize
+     */
+    static get properties() {
+        return {
+            lang: { type: String },
+            baseUrl: { type: String, attribute: "base-url" },
+        };
+    }
+
+    update(changedProperties) {
+        changedProperties.forEach((oldValue, propName) => {
+            switch (propName) {
+                case "lang":
+                    i18n.changeLanguage(this.lang);
+                    break;
+            }
+        });
+
+        super.update(changedProperties);
+    }
+
+    disconnectedCallback() {
+        window.removeEventListener('message', this._onReceiveWindowMessage);
+        super.disconnectedCallback();
+      }
+
+    connectedCallback() {
+        super.connectedCallback();
+
+        this.updateComplete.then(()=>{
+            // see: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
+            window.addEventListener('message', this._onReceiveWindowMessage);
+        });
+    }
+
+    openFilePicker() {
+        this.loginWindow = window.open(this.baseUrl + "/apps/webapppassword/#", "Nextcloud Login",
+            "width=400,height=400,menubar=no,scrollbars=no,status=no,titlebar=no,toolbar=no");
+    }
+
+    onReceiveWindowMessage(event) {
+        const data = event.data;
+        console.log("data", data);
+
+        if (data.type === "webapppassword") {
+            this.loginWindow.close();
+            alert("Login name: " + data.loginName + "\nApp password: " + data.token);
+        }
+    }
+
+    static get styles() {
+        // language=css
+        return css`
+            ${commonStyles.getGeneralCSS()}
+            ${commonStyles.getButtonCSS()}
+        `;
+    }
+
+    render() {
+        return html`
+            <div>
+                <button class="button"
+                        title="${i18n.t('file-picker.open-file-picker')}"
+                        @click="${async () => { this.openFilePicker(); } }">${i18n.t('file-picker.open')}</button>
+            </div>
+        `;
+    }
+}
diff --git a/src/vpu-qualified-signature-pdf-upload.js b/src/vpu-qualified-signature-pdf-upload.js
index 997feca..709b3fc 100644
--- a/src/vpu-qualified-signature-pdf-upload.js
+++ b/src/vpu-qualified-signature-pdf-upload.js
@@ -13,6 +13,8 @@ import {classMap} from 'lit-html/directives/class-map.js';
 import {FileUpload} from 'vpu-file-upload';
 import JSONLD from "vpu-common/jsonld";
 import {TextSwitch} from './textswitch.js';
+import {FilePicker} from "./vpu-file-picker";
+import nextcloudBaseURL from 'consts:nextcloudBaseURL';
 
 const i18n = createI18nInstance();
 
@@ -61,6 +63,7 @@ class QualifiedSignaturePdfUpload extends ScopedElementsMixin(VPUSignatureLitEle
           'vpu-mini-spinner': MiniSpinner,
           'vpu-button': Button,
           'vpu-textswitch': TextSwitch,
+          'vpu-file-picker': FilePicker,
         };
     }
 
@@ -1101,6 +1104,8 @@ class QualifiedSignaturePdfUpload extends ScopedElementsMixin(VPUSignatureLitEle
             <div class="${classMap({hidden: !this.isLoading()})}">
                 <vpu-mini-spinner></vpu-mini-spinner>
             </div>
+            <!-- File picker test --> 
+<!--            <vpu-file-picker base-url="${nextcloudBaseURL}"></vpu-file-picker>-->
         `;
     }
 }
-- 
GitLab