From 41fb3dfdd8c9a1f988fc3be8b4b5607b848fd205 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 01:44:44 +0000 Subject: [PATCH 01/22] fix(deps): update rust-stable (#1719) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- server/Cargo.lock | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/server/Cargo.lock b/server/Cargo.lock index 34582726c..d69bc5589 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -676,7 +676,7 @@ dependencies = [ "hyperlocal", "log", "pin-project-lite", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-native-certs 0.7.3", "rustls-pemfile 2.2.0", "rustls-pki-types", @@ -2233,7 +2233,7 @@ dependencies = [ "hyper 1.5.0", "hyper-util", "log", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-native-certs 0.8.0", "rustls-pki-types", "tokio", @@ -2785,7 +2785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -3188,7 +3188,7 @@ dependencies = [ "rand", "regex", "reqwest 0.12.9", - "rustls 0.23.19", + "rustls 0.23.20", "sentry", "sentry-actix", "serde", @@ -4581,7 +4581,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.0.0", - "rustls 0.23.19", + "rustls 0.23.20", "socket2", "thiserror", "tokio", @@ -4598,7 +4598,7 @@ dependencies = [ "rand", "ring", "rustc-hash 2.0.0", - "rustls 0.23.19", + "rustls 0.23.20", "slab", "thiserror", "tinyvec", @@ -4953,7 +4953,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-native-certs 0.8.0", "rustls-pemfile 2.2.0", "rustls-pki-types", @@ -5119,9 +5119,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "aws-lc-rs", "log", @@ -5313,7 +5313,7 @@ dependencies = [ "httpdate", "native-tls", "reqwest 0.12.9", - "rustls 0.23.19", + "rustls 0.23.20", "sentry-backtrace", "sentry-contexts", "sentry-core", @@ -5429,18 +5429,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -5875,7 +5875,7 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pemfile 2.2.0", "serde", "serde_json", @@ -6466,7 +6466,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pki-types", "tokio", ] @@ -6826,7 +6826,7 @@ dependencies = [ "log", "native-tls", "once_cell", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pki-types", "url", "webpki-roots 0.26.6", From c754b1caa3970cb8324e86c46edaee4bd3166904 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Fri, 13 Dec 2024 20:43:48 +0100 Subject: [PATCH 02/22] fixed `icon-padding` in the style not working as expected --- map/styles/navigatum-basemap.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/map/styles/navigatum-basemap.json b/map/styles/navigatum-basemap.json index 494f767e2..b4a7c4a61 100644 --- a/map/styles/navigatum-basemap.json +++ b/map/styles/navigatum-basemap.json @@ -5446,7 +5446,7 @@ "icon-text-fit": "both", "icon-size": 1.4, "icon-anchor": "center", - "icon-padding": ["literal", [3]], + "icon-padding": 3, "icon-offset": [0, -0.5], "icon-image": "rounded_rectangle" }, @@ -6028,7 +6028,7 @@ "icon-text-fit": "both", "icon-size": 1.4, "icon-anchor": "center", - "icon-padding": ["literal", [3]], + "icon-padding": 3, "icon-offset": [0, -0.5] }, "paint": { From 90812c550cfbf60284f0cdfcaaf998ad3a31cd6f Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 14 Dec 2024 00:10:47 +0100 Subject: [PATCH 03/22] bumped rust dependencies --- server/Cargo.lock | 6 +++--- server/Cargo.toml | 38 +++++++++++++++++++------------------- server/src/main.rs | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/server/Cargo.lock b/server/Cargo.lock index d69bc5589..ddab8cb98 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -877,9 +877,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -2785,7 +2785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] diff --git a/server/Cargo.toml b/server/Cargo.toml index 8b824a7ff..d3ebb89b5 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -17,51 +17,51 @@ path = "src/main.rs" [dependencies] # logging/obeservability actix-web-prom = { version = "0.9.0", default-features = false, features = [] } -tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json", "fmt"] } -tracing = "0.1.40" +tracing-subscriber = { version = "0.3.19", features = ["env-filter", "json", "fmt"] } +tracing = "0.1.41" tracing-log = { version = "0.2.0", features = ["std", "log-tracer", "interest-cache"] } -tracing-actix-web = "0.7.11" +tracing-actix-web = "0.7.15" sentry = { version = "0.35.0", features = ["tracing", "metrics", "backtrace", "contexts", "debug-images", "panic", "reqwest", "rustls"] } sentry-actix = "0.35.0" # errors -anyhow = { version = "1.0.86", features = ["backtrace"] } +anyhow = { version = "1.0.94", features = ["backtrace"] } #serialisation -serde = { version = "1.0.208", features = ["derive"] } -serde_json = { version = "1.0.125", features = ["raw_value"] } +serde = { version = "1.0.216", features = ["derive"] } +serde_json = { version = "1.0.133", features = ["raw_value"] } serde_yaml = "0.9.34" # runtime + webserver -tokio = { version = "1.39", default-features = false, features = ["rt-multi-thread", "time", "sync", "process"] } +tokio = { version = "1.42.0", default-features = false, features = ["rt-multi-thread", "time", "sync", "process"] } actix-web = { version = "4.9.0", default-features = false, features = ["compress-brotli", "compress-gzip", "compress-zstd", "cookies", "http2", "macros"] } actix-cors = "0.7.0" -rustls = "0.23.14" +rustls = "0.23.20" cached = { version = "0.54.0", features = ["default", "async", "disk_store"] } -futures = "0.3.30" +futures = "0.3.31" unicode-truncate = "2.0.0" # database sqlx = { version = "0.8.0", features = ['chrono', 'json', 'macros', 'migrate', 'postgres', 'runtime-tokio', 'tls-rustls'], default-features = false } -chrono = { version = "0.4.38", default-features = false, features = ["serde"] } +chrono = { version = "0.4.39", default-features = false, features = ["serde"] } # search meilisearch-sdk = "0.27.1" logos = "0.15.0" -regex = "1.10.6" +regex = "1.11.1" # web access oauth2 = { version = "4.4.2", default-features = false, features = ["rustls-tls", "reqwest"] } -reqwest = { version = "0.12.7", default-features = false, features = ["gzip", "hickory-dns", "http2", "json", "rustls-tls"] } +reqwest = { version = "0.12.9", default-features = false, features = ["gzip", "hickory-dns", "http2", "json", "rustls-tls"] } # image production -image = { version = "0.25.2", default-features = false, features = ["jpeg", "png", "webp"] } +image = { version = "0.25.5", default-features = false, features = ["jpeg", "png", "webp"] } imageproc = "0.25.0" ab_glyph = { version = "0.2.28", default-features = false } rand = "0.8.5" -octocrab = { version = "0.42.0", default-features = false, features = ["default-client", "retry", "rustls", "rustls-webpki-tokio"] } +octocrab = { version = "0.42.1", default-features = false, features = ["default-client", "retry", "rustls", "rustls-webpki-tokio"] } # auth/security jsonwebtoken = { version = "9.3.0", default-features = false, features = [] } @@ -73,16 +73,16 @@ base64 = "0.22.1" polars = { version = "0.44.2", features = ["dtype-struct", "dtype-date", "dtype-datetime", "dtype-duration", "parquet"], default-features = false } # geodata -geo = { version = "0.29.0", features = ["use-serde"], default-features = false } +geo = { version = "0.29.3", features = ["use-serde"], default-features = false } geozero = { version = "0.14.0", features = ["with-postgis-sqlx", "with-geo"], default-features = false } geo-types = { version = "0.7.13", default-features = false } -actix-middleware-etag = "0.4.1" +actix-middleware-etag = "0.4.2" [dev-dependencies] insta = { version = "1.39.0", features = ["json", "redactions", "yaml"] } -pretty_assertions = "1.4.0" -testcontainers = { version = "0.23.0", features = ["watchdog"] } -testcontainers-modules = { version = "0.11.0", features = ["meilisearch", "postgres"] } +pretty_assertions = "1.4.1" +testcontainers = { version = "0.23.1", features = ["watchdog"] } +testcontainers-modules = { version = "0.11.4", features = ["meilisearch", "postgres"] } tracing-test = "0.2.5" diff --git a/server/src/main.rs b/server/src/main.rs index a28ab5c7a..8f32c8e3f 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -170,7 +170,7 @@ async fn run_maintenance_work( set.spawn(async move { maps::refresh::all_entries(&map_pool).await }); let cal_pool = pool.clone(); set.spawn(async move { calendar::refresh::all_entries(&cal_pool).await }); - while set.join_next().await.is_some() {} + set.join_all().await; } /// we split main and run because otherwise sentry could not be properly instrumented From 39c86d36a955c93eb6ec669a71fd0628720d9436 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 14 Dec 2024 22:06:02 +0100 Subject: [PATCH 04/22] marked `RUSTSEC-2024-0421` as non-exploitable --- .github/workflows/cargo-audit.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cargo-audit.yaml b/.github/workflows/cargo-audit.yaml index 8dac78d09..4fa019462 100644 --- a/.github/workflows/cargo-audit.yaml +++ b/.github/workflows/cargo-audit.yaml @@ -17,7 +17,8 @@ jobs: - uses: rustsec/audit-check@v2.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} - ignore: RUSTSEC-2023-0071,RUSTSEC-2024-0363,RUSTSEC-2024-0379,RUSTSEC-2024-0384 + ignore: RUSTSEC-2023-0071,RUSTSEC-2024-0363,RUSTSEC-2024-0379,RUSTSEC-2024-0384,RUSTSEC-2024-0421 + # RUSTSEC-2024-0421 = idna accepts Punycode labels that do not produce any non-ASCII when decoded => not used explitably # RUSTSEC-2024-0384 = instant (Used via instant v0.1.13 > parking_lot v0.11.2 > sled v0.34.7 > cached v0.54.0) is unmaintained => Since `parking_lot`, `sled` and `cached` are maintained and the open issues in `instant` are wasm-related, I am going to close this # RUSTSEC-2024-0379 = unsoundness in fast-float => only used in intialisation logic, fix in polars is in main and is awaiting release # RUSTSEC-2024-0363 = Binary Protocol Misinterpretation caused by Truncating or Overflowing Casts => caught by maximum request sizes From 0e7656d74d8c5742003fc11920d35870d7b2b7ca Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 14 Dec 2024 00:48:58 +0100 Subject: [PATCH 05/22] inlined `loadInteractiveMap` --- webclient/app/components/IndoorMap.vue | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/webclient/app/components/IndoorMap.vue b/webclient/app/components/IndoorMap.vue index 3db103eff..8aeb38238 100644 --- a/webclient/app/components/IndoorMap.vue +++ b/webclient/app/components/IndoorMap.vue @@ -15,10 +15,6 @@ const initialLoaded = ref(false); type DetailsResponse = components["schemas"]["DetailsResponse"]; onMounted(async () => { - await loadInteractiveMap(); -}); - -async function loadInteractiveMap() { if (!webglSupport) return; const doMapUpdate = async function () { @@ -57,7 +53,7 @@ async function loadInteractiveMap() { // The map element should be visible when initializing if (!document.querySelector("#interactive-map .maplibregl-canvas")) await nextTick(doMapUpdate); else await doMapUpdate(); -} +}); function createMarker(hueRotation = 0): HTMLDivElement { const markerDiv = document.createElement("div"); From 51a1f3946851ee80dd4a222f78d5a84ad28caab0 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 14 Dec 2024 01:36:44 +0100 Subject: [PATCH 06/22] simplified map intialisation to take less data --- .../app/components/DetailsInteractiveMap.vue | 41 +++++++++-------- webclient/app/components/IndoorMap.vue | 45 ++++++++----------- webclient/app/pages/[view]/[id].vue | 8 +++- webclient/app/pages/next.client.vue | 4 +- 4 files changed, 51 insertions(+), 47 deletions(-) diff --git a/webclient/app/components/DetailsInteractiveMap.vue b/webclient/app/components/DetailsInteractiveMap.vue index 293d0da4e..6e8ccad92 100644 --- a/webclient/app/components/DetailsInteractiveMap.vue +++ b/webclient/app/components/DetailsInteractiveMap.vue @@ -5,11 +5,22 @@ import { FloorControl } from "~/composables/FloorControl"; import { webglSupport } from "~/composables/webglSupport"; import type { components } from "~/api_types"; -const props = defineProps<{ data: DetailsResponse; debugMode: boolean }>(); +const props = defineProps<{ + coords: DetailsResponse["coords"]; + type: DetailsResponse["type"]; + maps: DetailsResponse["maps"]; + id: DetailsResponse["id"]; + debugMode: boolean; +}>(); const map = ref(undefined); const marker = ref(undefined); const floorControl = ref(new FloorControl()); const runtimeConfig = useRuntimeConfig(); +const zoom = computed(() => { + if (props.type === "building") return 17; + if (props.type === "room") return 18; + return 16; +}); const initialLoaded = ref(false); @@ -30,26 +41,21 @@ function loadInteractiveMap() { document.getElementById("interactive-map")?.classList.remove("loading"); } } - marker.value = new Marker({ element: createMarker() }); - const coords = props.data.coords; if (map.value !== undefined) { + const _marker = new Marker({ element: createMarker() }); + _marker.setLngLat([props.coords.lon, props.coords.lat]); // @ts-expect-error somehow this is too deep for typescript - marker.value.setLngLat([coords.lon, coords.lat]); - marker.value.addTo(map.value as Map); + _marker.addTo(map.value as Map); + marker.value = _marker; } - const overlays = props.data.maps?.overlays; + const overlays = props.maps?.overlays; if (overlays) floorControl.value.updateFloors(overlays); else floorControl.value.resetFloors(); - const defaultZooms: { [index: string]: number | undefined } = { - building: 17, - room: 18, - }; - map.value?.flyTo({ - center: [coords.lon, coords.lat], - zoom: defaultZooms[props.data.type || "undefined"] || 16, + center: [props.coords.lon, props.coords.lat], + zoom: zoom.value, speed: 1, maxDuration: 2000, }); @@ -99,13 +105,12 @@ function initMap(containerId: string): Map { attributionControl: false, }); if (props.debugMode) { - const coords = props.data.coords; - const debugMarker = new Marker({ draggable: true }).setLngLat([coords.lon, coords.lat]).addTo(map); + const debugMarker = new Marker({ draggable: true }).setLngLat([props.coords.lon, props.coords.lat]).addTo(map); debugMarker.on("dragend", () => { const lngLat = debugMarker.getLngLat(); - console.log(`debug marker "${props.data.id}": { lat: ${lngLat.lat}, lon: ${lngLat.lng} }`); - navigator.clipboard.writeText(`"${props.data.id}": { lat: ${lngLat.lat}, lon: ${lngLat.lng} }`); + console.log(`debug marker "${props.id}": { lat: ${lngLat.lat}, lon: ${lngLat.lng} }`); + navigator.clipboard.writeText(`"${props.id}": { lat: ${lngLat.lat}, lon: ${lngLat.lng} }`); }); } @@ -154,7 +159,7 @@ function initMap(containerId: string): Map { }; // There is a bug that the map doesn't update to the new size // when changing between fullscreen in the mobile version. - if (isMobile && ResizeObserver) { + if (isMobile) { const fullscreenObserver = new ResizeObserver(() => { fullscreenCtl._map.resize(); }); diff --git a/webclient/app/components/IndoorMap.vue b/webclient/app/components/IndoorMap.vue index 8aeb38238..c91751cf0 100644 --- a/webclient/app/components/IndoorMap.vue +++ b/webclient/app/components/IndoorMap.vue @@ -5,14 +5,20 @@ import { webglSupport } from "~/composables/webglSupport"; import type { IndoorMapOptions } from "maplibre-gl-indoor"; import type { components } from "~/api_types"; -const props = defineProps<{ data: DetailsResponse }>(); +type DetailsResponse = components["schemas"]["DetailsResponse"]; + +const props = defineProps<{ + coords: DetailsResponse["coords"]; + type: DetailsResponse["type"]; +}>(); const map = ref(undefined); const marker = ref(undefined); const runtimeConfig = useRuntimeConfig(); - -const initialLoaded = ref(false); - -type DetailsResponse = components["schemas"]["DetailsResponse"]; +const zoom = computed(() => { + if (props.type === "building") return 17; + if (props.type === "room") return 18; + return 16; +}); onMounted(async () => { if (!webglSupport) return; @@ -30,24 +36,12 @@ onMounted(async () => { } } - marker.value = new Marker({ element: createMarker() }); - const coords = props.data.coords; if (map.value !== undefined) { - marker.value.setLngLat([coords.lon, coords.lat]); - marker.value.addTo(map.value as Map); + const _marker = new Marker({ element: createMarker() }); + _marker.setLngLat([props.coords.lon, props.coords.lat]); + _marker.addTo(map.value as Map); + marker.value = _marker; } - - const defaultZooms: { [index: string]: number | undefined } = { - building: 17, - room: 18, - }; - - map.value?.flyTo({ - center: [11.670099, 48.266921], - zoom: defaultZooms[props.data.type || "undefined"] || 16, - speed: 1, - maxDuration: 2000, - }); }; // The map element should be visible when initializing @@ -88,8 +82,8 @@ async function initMap(containerId: string): Promise { // https://nav.tum.de/maps/ style: `${runtimeConfig.public.mapsURL}/maps/styles/navigatum-basemap/style.json`, - center: [11.670028798993783, 48.26684628456347], // Approx Garching - zoom: 11, // Zoomed out so that the whole city is visible + center: [11.670099, 48.266921], + zoom: zoom.value, // done manually, to have more control over when it is extended attributionControl: false, @@ -100,9 +94,6 @@ async function initMap(containerId: string): Promise { // enough to know whether just the initial loading has // succeeded. map.on("load", () => { - initialLoaded.value = true; - - // add controlls map.addControl(new NavigationControl({}), "top-left"); // (Browser) Fullscreen is enabled only on mobile, on desktop the map @@ -140,7 +131,7 @@ async function initMap(containerId: string): Promise { }; // There is a bug that the map doesn't update to the new size // when changing between fullscreen in the mobile version. - if (isMobile && ResizeObserver) { + if (isMobile) { const fullscreenObserver = new ResizeObserver(() => { fullscreenCtl._map.resize(); }); diff --git a/webclient/app/pages/[view]/[id].vue b/webclient/app/pages/[view]/[id].vue index eb94f9c09..5f3d7be0f 100644 --- a/webclient/app/pages/[view]/[id].vue +++ b/webclient/app/pages/[view]/[id].vue @@ -191,7 +191,13 @@ useSeoMeta({ - + diff --git a/webclient/app/pages/next.client.vue b/webclient/app/pages/next.client.vue index 56e7f88c0..706db6ffb 100644 --- a/webclient/app/pages/next.client.vue +++ b/webclient/app/pages/next.client.vue @@ -15,7 +15,9 @@ const { data } = useFetch(url, {