From d9d1490f678fddf3560f3b6fbf0a0f984d4735d2 Mon Sep 17 00:00:00 2001
From: Benedikt Heinrichs <heinrichs@itc.rwth-aachen.de>
Date: Wed, 24 Apr 2024 12:16:24 +0200
Subject: [PATCH] Fix: Clickable link on banner

---
 package.json                            |  1 +
 src/components/banner/Maintenance.vue   |  3 +-
 src/main.ts                             |  3 ++
 src/modules/resource/pages/Settings.vue |  6 +--
 src/plugins/vue-dompurify-html.ts       |  8 ++++
 src/store/index.ts                      |  4 +-
 yarn.lock                               | 56 ++++++++++++++++++++-----
 7 files changed, 65 insertions(+), 16 deletions(-)
 create mode 100644 src/plugins/vue-dompurify-html.ts

diff --git a/package.json b/package.json
index 1472af79..e1725b47 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
     "uuid": "^9.0.1",
     "vue": "^2.7.15",
     "vue-demi": "^0.14.6",
+    "vue-dompurify-html": "4.1.4",
     "vue-i18n": "^8.28.2",
     "vue-multiselect": "^2.1.8",
     "vue-observe-visibility": "^1.0.0",
diff --git a/src/components/banner/Maintenance.vue b/src/components/banner/Maintenance.vue
index 4e51ec6b..cedca43b 100644
--- a/src/components/banner/Maintenance.vue
+++ b/src/components/banner/Maintenance.vue
@@ -10,7 +10,7 @@
       <span class="font-weight-bold">
         {{ `${messageType}${$t("banner.separator")}` }}
       </span>
-      {{ messageBody }}
+      <span v-dompurify-html="messageBody"></span>
       <span v-if="maintenance.href">
         {{ $t("banner.maintenance.linkText") }}
         <a :href="maintenance.href" target="_blank"
@@ -23,6 +23,7 @@
 
 <script lang="ts">
 import { defineComponent } from "vue";
+
 // import the main store
 import useMainStore from "@/store/index";
 import type { MaintenanceDto } from "@coscine/api-client/dist/types/Coscine.Api";
diff --git a/src/main.ts b/src/main.ts
index 3c52f750..1c392abe 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -17,6 +17,9 @@ import "@/plugins/bootstrap-vue";
 /* Stream Polyfill */
 import "@/plugins/stream-poly";
 
+/* vue-dompurify-html */
+import "@/plugins/vue-dompurify-html";
+
 /* Corporate Design */
 import "@/assets/scss/_custom.scss";
 import "@/assets/css/_custom.css";
diff --git a/src/modules/resource/pages/Settings.vue b/src/modules/resource/pages/Settings.vue
index db75a4e6..e2e88299 100644
--- a/src/modules/resource/pages/Settings.vue
+++ b/src/modules/resource/pages/Settings.vue
@@ -305,9 +305,9 @@ export default defineComponent({
       if (this.project?.id && this.resource?.id) {
         // Load resource
         await this.resourceStore.retrieveResource(
-            this.project?.id,
-            this.resource?.id,
-          );
+          this.project?.id,
+          this.resource?.id,
+        );
       }
       // Load Project Visibilities if not present
       if (this.projectStore.visibilities === null) {
diff --git a/src/plugins/vue-dompurify-html.ts b/src/plugins/vue-dompurify-html.ts
new file mode 100644
index 00000000..b2b7e7d5
--- /dev/null
+++ b/src/plugins/vue-dompurify-html.ts
@@ -0,0 +1,8 @@
+/* vue-dompurify-html */
+import Vue from "vue";
+import VueDOMPurifyHTML from "vue-dompurify-html";
+Vue.use(VueDOMPurifyHTML, {
+  default: {
+    ADD_ATTR: ["target"],
+  },
+});
diff --git a/src/store/index.ts b/src/store/index.ts
index 6d016105..1c2dc25e 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -125,9 +125,9 @@ export const useMainStore = defineStore({
         const startsDate = new Date(2024, 3, 22, 0, 0, 0).toUTCString();
         const endsDate = new Date(2024, 4, 7, 0, 0, 0).toUTCString();
         const injectedBanner = {
-          body: `Your opinion matters! The survey on the use of Coscine will take place from April 22 to May 7, 2024. Take the opportunity and help us to optimize the platform. The survey takes approximately 15 minutes. https://s2survey.net/coscine_2024/
+          body: `Your opinion matters! The survey on the use of Coscine will take place from April 22 to May 6, 2024. Take the opportunity and help us to optimize the platform. The survey takes approximately 15 minutes. <a href="https://s2survey.net/coscine_2024/" target="_blank">https://s2survey.net/coscine_2024/</a>
           //
-          Ihre Meinung ist uns wichtig! Vom 22. April bis 7. Mai 2024 findet die Umfrage zur Nutzung von Coscine statt. Nutzen Sie die Chance und tragen Sie aktiv dazu bei, die Plattform zu optimieren. Die Umfrage dauert ca. 15 Minuten. https://s2survey.net/coscine_2024/`,
+          Ihre Meinung ist uns wichtig! Vom 22. April bis 6. Mai 2024 findet die Umfrage zur Nutzung von Coscine statt. Nutzen Sie die Chance und tragen Sie aktiv dazu bei, die Plattform zu optimieren. Die Umfrage dauert ca. 15 Minuten. <a href="https://s2survey.net/coscine_2024/" target="_blank">https://s2survey.net/coscine_2024/</a>`,
           displayName: "User Survey",
           startsDate: startsDate,
           endsDate: endsDate,
diff --git a/yarn.lock b/yarn.lock
index 5a2c22a7..d70becbd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -436,18 +436,18 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@coscine/api-client@npm:3.6.0-issue-2445-extractedmetadata.1":
-  version: 3.6.0-issue-2445-extractedmetadata.1
-  resolution: "@coscine/api-client@npm:3.6.0-issue-2445-extractedmetadata.1::__archiveUrl=https%3A%2F%2Fgit.rwth-aachen.de%2Fapi%2Fv4%2Fprojects%2F61847%2Fpackages%2Fnpm%2F%40coscine%2Fapi-client%2F-%2F%40coscine%2Fapi-client-3.6.0-issue-2445-extractedmetadata.1.tgz"
+"@coscine/api-client@npm:3.7.0":
+  version: 3.7.0
+  resolution: "@coscine/api-client@npm:3.7.0::__archiveUrl=https%3A%2F%2Fgit.rwth-aachen.de%2Fapi%2Fv4%2Fprojects%2F61847%2Fpackages%2Fnpm%2F%40coscine%2Fapi-client%2F-%2F%40coscine%2Fapi-client-3.7.0.tgz"
   dependencies:
     axios: "npm:^1.6.2"
-  checksum: 10/b7bacd8750b70b8988e4a2d691333476ef08558a0cf0e42b006d997791bfe353b42c6210525e36717b23f4f8906dbb8879f950172b2e3023c82a13e86b6b1924
+  checksum: 10/d19534138f738458ae29f8dce260eb87d43f001581d69e24d1377be4b74cb05070d40e04b1d28abc196aeca125deb9d5d84f21818e4b2a5e3b4a2ee7d70ec2bc
   languageName: node
   linkType: hard
 
-"@coscine/form-generator@npm:^3.6.2":
-  version: 3.6.2
-  resolution: "@coscine/form-generator@npm:3.6.2::__archiveUrl=https%3A%2F%2Fgit.rwth-aachen.de%2Fapi%2Fv4%2Fprojects%2F35944%2Fpackages%2Fnpm%2F%40coscine%2Fform-generator%2F-%2F%40coscine%2Fform-generator-3.6.2.tgz"
+"@coscine/form-generator@npm:3.6.3":
+  version: 3.6.3
+  resolution: "@coscine/form-generator@npm:3.6.3::__archiveUrl=https%3A%2F%2Fgit.rwth-aachen.de%2Fapi%2Fv4%2Fprojects%2F35944%2Fpackages%2Fnpm%2F%40coscine%2Fform-generator%2F-%2F%40coscine%2Fform-generator-3.6.3.tgz"
   dependencies:
     "@zazuko/prefixes": "npm:^2.1.0"
     bootstrap: "npm:4.6.1"
@@ -464,7 +464,7 @@ __metadata:
   peerDependencies:
     "@vue/composition-api": ^1.0.0-rc.1
     vue: ^2.0.0
-  checksum: 10/28487fee5fa850af79c54c0f1591c351836c47b96bf3633189ea24e6858a091878857b17b5b2329a55595a7231f4c5c9e07bc5d3baa419c3bd54474b36b351c8
+  checksum: 10/611adf6c0e7488d435d8cb1f2b77f6d8ccc869e0405356700480155ca1f9a7f06103d3a20309bb364d259a24bc7e88e66e9822d02c8ba7ccd2b16a89215a194f
   languageName: node
   linkType: hard
 
@@ -5534,6 +5534,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"dompurify@npm:^3.0.0":
+  version: 3.1.0
+  resolution: "dompurify@npm:3.1.0"
+  checksum: 10/a8788d3510b0a5e26ae8f1beb3f079be63f417be0f7259918c273bd53f9b9eab50a0708e065caff9904ae97895cc4a7d4c66a1076021a9be0685389ad8ae4d2d
+  languageName: node
+  linkType: hard
+
 "domutils@npm:^3.0.1, domutils@npm:^3.1.0":
   version: 3.1.0
   resolution: "domutils@npm:3.1.0"
@@ -13459,8 +13466,8 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "ui@workspace:."
   dependencies:
-    "@coscine/api-client": "npm:3.6.0-issue-2445-extractedmetadata.1"
-    "@coscine/form-generator": "npm:^3.6.2"
+    "@coscine/api-client": "npm:3.7.0"
+    "@coscine/form-generator": "npm:3.6.3"
     "@dynamic-mapper/mapper": "npm:^1.10.4"
     "@pinia/testing": "npm:^0.1.3"
     "@rdfjs-elements/formats-pretty": "npm:^0.6.4"
@@ -13533,6 +13540,7 @@ __metadata:
     vitest: "npm:^0.34.6"
     vue: "npm:^2.7.15"
     vue-demi: "npm:^0.14.6"
+    vue-dompurify-html: "npm:4.1.4"
     vue-i18n: "npm:^8.28.2"
     vue-multiselect: "npm:^2.1.8"
     vue-observe-visibility: "npm:^1.0.0"
@@ -14233,6 +14241,34 @@ __metadata:
   languageName: node
   linkType: hard
 
+"vue-demi@npm:^0.14.0":
+  version: 0.14.7
+  resolution: "vue-demi@npm:0.14.7"
+  peerDependencies:
+    "@vue/composition-api": ^1.0.0-rc.1
+    vue: ^3.0.0-0 || ^2.6.0
+  peerDependenciesMeta:
+    "@vue/composition-api":
+      optional: true
+  bin:
+    vue-demi-fix: bin/vue-demi-fix.js
+    vue-demi-switch: bin/vue-demi-switch.js
+  checksum: 10/04884677b8790320bcd3cbbf8dae1c4da9f4ab304659bf18d69b11255f7d16825d2135d2d0e565b1a1f1b7f601100eb26760254129c6bacec2c7e72ab0f61d52
+  languageName: node
+  linkType: hard
+
+"vue-dompurify-html@npm:4.1.4":
+  version: 4.1.4
+  resolution: "vue-dompurify-html@npm:4.1.4"
+  dependencies:
+    dompurify: "npm:^3.0.0"
+    vue-demi: "npm:^0.14.0"
+  peerDependencies:
+    vue: ^2.7.0 || ^3.0.0
+  checksum: 10/1e5ff02dfcfd898dfacd21d81a7a1e04a990f85e6d25cc4ceb7af5dc095ad58ebeb1b06ba192ec148254eb9a20e47968c408d770a89a92cb46954d6b2af77f5a
+  languageName: node
+  linkType: hard
+
 "vue-eslint-parser@npm:^9.3.1":
   version: 9.3.2
   resolution: "vue-eslint-parser@npm:9.3.2"
-- 
GitLab