@datagouv/components-next 1.0.2-dev.202 → 1.0.2-dev.203

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { g as Ke } from "./main--ZN-jusz.js";
1
+ import { g as Ke } from "./main-CICNrWF8.js";
2
2
  import We from "vue";
3
3
  function Fe(I, K) {
4
4
  for (var V = 0; V < K.length; V++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datagouv/components-next",
3
- "version": "1.0.2-dev.202",
3
+ "version": "1.0.2-dev.203",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -67,7 +67,7 @@ import styleVector from '../../../assets/json/vector.json'
67
67
  import PreviewUnavailable from './PreviewUnavailable.vue'
68
68
  import { useTranslation } from '../../composables/useTranslation'
69
69
  import franceSvg from './france.svg?raw'
70
- import { getOwnerName, getOwnerPage } from '../../functions/owned'
70
+ import { getMapAttribution } from '../../functions/owned'
71
71
 
72
72
  const props = defineProps<{ resource: Resource, dataset: Dataset | DatasetV2 }>()
73
73
 
@@ -94,11 +94,7 @@ const lastUpdate = computed(() => {
94
94
 
95
95
  const container = useTemplateRef('containerRef')
96
96
 
97
- const attributions = computed(() => {
98
- if (!props.dataset.organization && !props.dataset.owner)
99
- return ''
100
- return `© <a href="${getOwnerPage(props.dataset)}" target="_blank">${getOwnerName(props.dataset)}</a>`
101
- })
97
+ const attributions = computed(() => getMapAttribution(props.dataset))
102
98
 
103
99
  async function displayMap() {
104
100
  await import('maplibre-gl/dist/maplibre-gl.css')
@@ -19,3 +19,24 @@ export function getOwnerPage(owned: Owned): string | null {
19
19
  }
20
20
  return null // Not supposed to exist but it does...
21
21
  }
22
+
23
+ function escapeHtml(value: string): string {
24
+ return value
25
+ .replace(/&/g, '&amp;')
26
+ .replace(/</g, '&lt;')
27
+ .replace(/>/g, '&gt;')
28
+ .replace(/"/g, '&quot;')
29
+ .replace(/'/g, '&#39;')
30
+ }
31
+
32
+ export function getMapAttribution(owned: Owned): string {
33
+ const name = getOwnerName(owned)
34
+ const page = getOwnerPage(owned)
35
+ if (!name && !page)
36
+ return ''
37
+ // The owner name is free text any user controls (organization name, or a
38
+ // profile's first/last name). maplibre-gl injects this attribution string
39
+ // into the DOM as HTML, and its own attribution sanitizer is bypassable via
40
+ // mutation XSS, so every interpolated value has to be escaped here.
41
+ return `© <a href="${escapeHtml(page ?? '')}" target="_blank">${escapeHtml(name)}</a>`
42
+ }