diff --git a/Docs/ServerConfig/hetzner/Caddyfile b/Docs/ServerConfig/hetzner/Caddyfile index ed205e98c5..38960417ea 100644 --- a/Docs/ServerConfig/hetzner/Caddyfile +++ b/Docs/ServerConfig/hetzner/Caddyfile @@ -3,6 +3,7 @@ builds.mapcomplete.org { file_server browse header { +Permissions-Policy "interest-cohort=()" + Report-To "{\"group\":\"csp-endpoint\", \"max_age\":86400, \"endpoints\":[{\"url\":\"https://report.mapcomplete.org/csp\"}], \"include_subdomains\":true}" } } @@ -12,6 +13,7 @@ mapcomplete.org, www.mapcomplete.org { file_server header { +Permissions-Policy "interest-cohort=()" + Report-To "{\"group\":\"csp-endpoint\", \"max_age\":86400, \"endpoints\":[{\"url\":\"https://report.mapcomplete.org/csp\"}], \"include_subdomains\":true}" } handle_errors { @404 { @@ -28,6 +30,7 @@ dev.mapcomplete.org { file_server header { +Permissions-Policy "interest-cohort=()" + Report-To "{\"group\":\"csp-endpoint\", \"max_age\":86400, \"endpoints\":[{\"url\":\"https://report.mapcomplete.org/csp\"}], \"include_subdomains\":true}" } handle_errors { @404 { @@ -43,6 +46,7 @@ single.mapcomplete.org { file_server browse header { +Permissions-Policy "interest-cohort=()" + Report-To "{\"group\":\"csp-endpoint\", \"max_age\":86400, \"endpoints\":[{\"url\":\"https://report.mapcomplete.org/csp\"}], \"include_subdomains\":true}" } } @@ -59,6 +63,7 @@ velopark.mapcomplete.org { file_server header { +Permissions-Policy "interest-cohort=()" + Report-To "{\"group\":\"csp-endpoint\", \"max_age\":86400, \"endpoints\":[{\"url\":\"https://report.mapcomplete.org/csp\"}], \"include_subdomains\":true}" } } @@ -86,6 +91,9 @@ report.mapcomplete.org { studio.mapcomplete.org { reverse_proxy http://127.0.0.1:1235 + header { + Report-To "{\"group\":\"csp-endpoint\", \"max_age\":86400, \"endpoints\":[{\"url\":\"https://report.mapcomplete.org/csp\"}], \"include_subdomains\":true}" + } } lod.mapcomplete.org { diff --git a/assets/layers/kerbs/kerbs.json b/assets/layers/kerbs/kerbs.json index 23c267b69a..95dc4d7bb9 100644 --- a/assets/layers/kerbs/kerbs.json +++ b/assets/layers/kerbs/kerbs.json @@ -334,8 +334,8 @@ }, "condition": { "and": [ - "_geometry:type=Point", - "tactile_paving=yes" + "tactile_paving!=no", + "_geometry:type=Point" ] } }, diff --git a/scripts/generateLayouts.ts b/scripts/generateLayouts.ts index 02033237b1..b6aa9c0979 100644 --- a/scripts/generateLayouts.ts +++ b/scripts/generateLayouts.ts @@ -107,9 +107,9 @@ class GenerateLayouts extends Script { if (!layout.icon.endsWith(".svg")) { console.warn( "Not creating a social image for " + - layout.id + - " as it is _not_ a .svg: " + - layout.icon + layout.id + + " as it is _not_ a .svg: " + + layout.icon ) return undefined } @@ -142,9 +142,9 @@ class GenerateLayouts extends Script { id: "icon", transform: `translate(${cx - r},${cy - r}) scale(${ (r * 2) / Number(width) - }) `, + }) ` }, - g: [svg], + g: [svg] } }, (mightBeTokenToReplace) => { @@ -205,19 +205,19 @@ class GenerateLayouts extends Script { icons.push({ src: name, sizes: size + "x" + size, - type: "image/png", + type: "image/png" }) } icons.push({ src: path, sizes: "513x513", - type: "image/svg", + type: "image/svg" }) } else if (icon.endsWith(".png")) { icons.push({ src: icon, sizes: "513x513", - type: "image/png", + type: "image/png" }) } else { console.log(icon) @@ -236,11 +236,11 @@ class GenerateLayouts extends Script { description: ogDescr, orientation: "portrait-primary, landscape-primary", icons: icons, - categories: ["map", "navigation"], + categories: ["map", "navigation"] } return { manifest, - whiteIcons, + whiteIcons } } @@ -251,7 +251,7 @@ class GenerateLayouts extends Script { if (lang === "_context") { continue } - let display = ' style="display: none"' + let display = " style=\"display: none\"" if (!defaultSet) { display = "" defaultSet = true @@ -272,7 +272,7 @@ class GenerateLayouts extends Script { ...eli.features, bing, ...eli_global.map((properties) => ({ properties })), - ...layers_global.layers.map((properties) => ({ properties })), + ...layers_global.layers.map((properties) => ({ properties })) ] for (const feature of rasterLayers) { const f = feature @@ -293,7 +293,7 @@ class GenerateLayouts extends Script { url = url.substring("pmtiles://".length) } const styleSpec = await Utils.downloadJsonCached(url, 1000 * 120, { - Origin: "https://mapcomplete.org", + Origin: "https://mapcomplete.org" }) urls.push(...(f.properties["connect-src"] ?? [])) for (const key of Object.keys(styleSpec?.["sources"] ?? {})) { @@ -309,7 +309,7 @@ class GenerateLayouts extends Script { urls.push(url) if (urlClipped.endsWith(".json")) { const tileInfo = await Utils.downloadJsonCached(url, 1000 * 120, { - Origin: "https://mapcomplete.org", + Origin: "https://mapcomplete.org" }) urls.push(tileInfo["tiles"] ?? []) } @@ -338,7 +338,7 @@ class GenerateLayouts extends Script { "https://api.panoramax.xyz", "https://panoramax.mapcomplete.org", "https://data.velopark.be", - "https://data.mapcomplete.org", + "https://data.mapcomplete.org" ].concat(...(await this.eliUrls())) SpecialVisualizations.specialVisualizations.forEach((sv) => { @@ -427,23 +427,22 @@ class GenerateLayouts extends Script { "default-src": "'self'", "child-src": "'self' blob: ", "img-src": "* data:", // maplibre depends on 'data:' to load - "connect-src": "'self' " + connectSrc.join(" "), "report-to": "https://report.mapcomplete.org/csp", "worker-src": "'self' blob:", // Vite somehow loads the worker via a 'blob' "style-src": "'self' 'unsafe-inline'", // unsafe-inline is needed to change the default background pin colours "script-src": [ "'self'", "https://gc.zgo.at/count.js", - ...(options?.scriptSrcs?.map((s) => "'" + s + "'") ?? []), + ...(options?.scriptSrcs?.map((s) => "'" + s + "'") ?? []) ].join(" "), + "connect-src": "'self' " + connectSrc.join(" ") } const content = Object.keys(csp) .map((k) => k + " " + csp[k]) .join(" ; ") return [ - ``, - ``, + `` ].join("\n") } @@ -455,12 +454,12 @@ class GenerateLayouts extends Script { ) { Locale.language.setData(layout.language[0]) const targetLanguage = layout.language[0] - const ogTitle = Translations.T(layout.title).textFor(targetLanguage).replace(/"/g, '\\"') + const ogTitle = Translations.T(layout.title).textFor(targetLanguage).replace(/"/g, "\\\"") const ogDescr = Translations.T( layout.shortDescription ?? "Easily add and edit geodata with OpenStreetMap" ) .textFor(targetLanguage) - .replace(/"/g, '\\"') + .replace(/"/g, "\\\"") let ogImage = layout.socialImage let twitterImage = ogImage if (ogImage === ThemeConfig.defaultSocialImage && layout.official) { @@ -531,7 +530,7 @@ class GenerateLayouts extends Script { og, customCss, ``, - ...apple_icons, + ...apple_icons ].join("\n") let branchname = await this.getBranchName() @@ -554,7 +553,7 @@ class GenerateLayouts extends Script { .replace( //, await this.generateCsp(layout, layoutJson, { - scriptSrcs: [this.removeOtherLanguagesHash], + scriptSrcs: [this.removeOtherLanguagesHash] }) ) .replace( @@ -585,7 +584,7 @@ class GenerateLayouts extends Script { const imports = [ `import theme from "./public/assets/generated/themes/${theme.id}.json"`, - `import { ThemeMetaTagging } from "./src/assets/generated/metatagging/${theme.id}"`, + `import { ThemeMetaTagging } from "./src/assets/generated/metatagging/${theme.id}"` ] for (const layerName of Constants.added_by_default) { imports.push( @@ -632,7 +631,7 @@ class GenerateLayouts extends Script { "account", "openstreetmap", "custom", - "theme", + "theme" ] const args = process.argv const theme = args[2] @@ -683,7 +682,7 @@ class GenerateLayouts extends Script { startLon: 0, startZoom: 0, title: { en: "MapComplete" }, - description: { en: "A thematic map viewer and editor based on OpenStreetMap" }, + description: { en: "A thematic map viewer and editor based on OpenStreetMap" } }), alreadyWritten ) diff --git a/scripts/generateReviewsAnalysis.ts b/scripts/generateReviewsAnalysis.ts index 811cf902c6..94663c4505 100644 --- a/scripts/generateReviewsAnalysis.ts +++ b/scripts/generateReviewsAnalysis.ts @@ -60,7 +60,7 @@ export default class GenerateReviewsAnalysis extends Script { geojsonFeatures.push({ geometry: { type: "Point", - coordinates: [lon, lat], + coordinates: [lon, lat] }, type: "Feature", properties: { @@ -69,20 +69,28 @@ export default class GenerateReviewsAnalysis extends Script { opinion: review.opinion, client: review.metadata.client_id, nickname: review.metadata.nickname, - affiliated: "" + review.metadata.is_affiliated, - }, + affiliated: "" + review.metadata.is_affiliated + } }) } catch (e) { console.error(e) } } console.log("Total number of reviews", reviews.length) + + + const aliases = ["mapcomplete.osm.be", "pietervdvn.github.io", "dev.mapcomplete.org", "127.0.0.1:1234", "localhost:1234"] + for (const alias of aliases) { + clientWebsites["mapcomplete.org"] += clientWebsites[alias] + delete clientWebsites[alias] + } this.print("Website", clientWebsites) + this.print("Theme", themeHist) this.print("language", languageHist) const fc: FeatureCollection = { type: "FeatureCollection", - features: geojsonFeatures, + features: geojsonFeatures } const fcmc: FeatureCollection = { @@ -91,20 +99,24 @@ export default class GenerateReviewsAnalysis extends Script { (f) => f.properties.client.indexOf("mapcomplete") >= 0 || f.properties.client.indexOf("pietervdvn.github.io") >= 0 - ), + ) + } + if (!fs.existsSync("./reviews-analysis")) { + fs.mkdirSync("./reviews-analysis") } fs.writeFileSync( - "../MapComplete-data/reviews.geojson", + "./reviews-analysis/reviews.geojson", JSON.stringify(fc), { encoding: "utf-8" } ) fs.writeFileSync( - "../MapComplete-data/reviewsmc.geojson", + "./reviews-analysis/reviewsmc.geojson", JSON.stringify(fcmc), { encoding: "utf-8" } ) + console.log("See ./reviews-analysis for the output") } async main(args: string[]): Promise { @@ -151,10 +163,10 @@ export default class GenerateReviewsAnalysis extends Script { "rating", "opinion", "images", - "metadata", + "metadata" ] return new Promise((resolve) => { - const parser = parse({ delimiter: "," }, function (err, data) { + const parser = parse({ delimiter: "," }, function(err, data) { const asJson: Review[] = [] for (let i = 1; i < data.length; i++) { const line = data[i]