From 2e1e6cf757cb82df82a9bf77a44eaaf2d8ddc4eb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 15 Mar 2026 03:14:13 +0000 Subject: [PATCH 1/5] chore(release): v1.41.0 [skip ci] # [1.41.0](https://github.com/WatWowMap/ReactMap/compare/v1.40.1...v1.41.0) (2026-03-15) ### Bug Fixes * area reload ([cea3141](https://github.com/WatWowMap/ReactMap/commit/cea3141386d804f502e83e89b9bf92da93102a5d)) * battle/raid filtering race condition ([2a9cbbf](https://github.com/WatWowMap/ReactMap/commit/2a9cbbf180313064830a524f86eae62f41b6b87b)) * battle/raid icon max height ([497f350](https://github.com/WatWowMap/ReactMap/commit/497f3504a4ea6000184c9df30c5a3c3e76d65d80)) * ditto shenanigans ([#1193](https://github.com/WatWowMap/ReactMap/issues/1193)) ([647a175](https://github.com/WatWowMap/ReactMap/commit/647a1758e6c3ab0dc4340c7a4b6fe8cc88e00084)) * escape gpx xml ([#1186](https://github.com/WatWowMap/ReactMap/issues/1186)) ([7bd5ce1](https://github.com/WatWowMap/ReactMap/commit/7bd5ce10d3e8aa6f64faac8d3d9773c589d6a28e)) * ground raid/battle icons ([cd01a92](https://github.com/WatWowMap/ReactMap/commit/cd01a92bda81f786ca2c14f10df8cc4489163fd6)) * hidden power in raids are fighting type ([018ba93](https://github.com/WatWowMap/ReactMap/commit/018ba93642eee0a08d2a864c1a04998ff63503a9)) * im dumdum ([ce37e2a](https://github.com/WatWowMap/ReactMap/commit/ce37e2a9123ea2808cde3f3f130361055141ae63)) * logic bug in loading non-clustered elements ([#1161](https://github.com/WatWowMap/ReactMap/issues/1161)) ([a2c7f17](https://github.com/WatWowMap/ReactMap/commit/a2c7f17e02ff7cd5467d4bf5ccd8b13a444ba725)) * more robust discord handling ([#1181](https://github.com/WatWowMap/ReactMap/issues/1181)) ([b579ded](https://github.com/WatWowMap/ReactMap/commit/b579dedeb196fb4d8b1da025e325049bfd7833e8)) * no scrollbars plz ([907ca33](https://github.com/WatWowMap/ReactMap/commit/907ca331beb1fe81dd671732d5ebe1980d8d6faa)) * pokemon onlyManualId filter in expert sql mode ([ee176da](https://github.com/WatWowMap/ReactMap/commit/ee176da3749c27b33aa659ba432706ad5c19951b)) * properly migrate to express 5 ([3907656](https://github.com/WatWowMap/ReactMap/commit/390765696dbdcd89ed2fd57b16d41ecc2725a1b9)) * remove extra Forms ([0f157ed](https://github.com/WatWowMap/ReactMap/commit/0f157edba37eb727fdb9f4a5b96bdf417298cdfc)) * sentry node version ([8640ee0](https://github.com/WatWowMap/ReactMap/commit/8640ee0da68cc2a23e4d12e472b109a6628507c6)) * showcase icons display ([b626d3d](https://github.com/WatWowMap/ReactMap/commit/b626d3d37c18b5ef6261f02b105796fdb8ce011f)) * weather icon in pokemon background popup ([21b50f5](https://github.com/WatWowMap/ReactMap/commit/21b50f51b81bf6f7723753a4f77289ead99c51e7)) ### Features * ar/no-ar quest dot badge ([8adba28](https://github.com/WatWowMap/ReactMap/commit/8adba286fea81d194e0dd4b7da5c680f6499b697)) * default clientPrompt to none to skip permission reapproval ([d3ea283](https://github.com/WatWowMap/ReactMap/commit/d3ea283b5eacda18b9f4725e50e5353a955a363d)) * dynamic placed Pokemon dropdown height ([8a0447c](https://github.com/WatWowMap/ReactMap/commit/8a0447c3e9d7df9c4aa9add657a234a1bc59b412)) * support stationed pokemon extras ([4f5aace](https://github.com/WatWowMap/ReactMap/commit/4f5aace285285d55e3a946fb2f465b7609a9caea)) --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd5b31f0e..f9764296f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +# [1.41.0](https://github.com/WatWowMap/ReactMap/compare/v1.40.1...v1.41.0) (2026-03-15) + + +### Bug Fixes + +* area reload ([cea3141](https://github.com/WatWowMap/ReactMap/commit/cea3141386d804f502e83e89b9bf92da93102a5d)) +* battle/raid filtering race condition ([2a9cbbf](https://github.com/WatWowMap/ReactMap/commit/2a9cbbf180313064830a524f86eae62f41b6b87b)) +* battle/raid icon max height ([497f350](https://github.com/WatWowMap/ReactMap/commit/497f3504a4ea6000184c9df30c5a3c3e76d65d80)) +* ditto shenanigans ([#1193](https://github.com/WatWowMap/ReactMap/issues/1193)) ([647a175](https://github.com/WatWowMap/ReactMap/commit/647a1758e6c3ab0dc4340c7a4b6fe8cc88e00084)) +* escape gpx xml ([#1186](https://github.com/WatWowMap/ReactMap/issues/1186)) ([7bd5ce1](https://github.com/WatWowMap/ReactMap/commit/7bd5ce10d3e8aa6f64faac8d3d9773c589d6a28e)) +* ground raid/battle icons ([cd01a92](https://github.com/WatWowMap/ReactMap/commit/cd01a92bda81f786ca2c14f10df8cc4489163fd6)) +* hidden power in raids are fighting type ([018ba93](https://github.com/WatWowMap/ReactMap/commit/018ba93642eee0a08d2a864c1a04998ff63503a9)) +* im dumdum ([ce37e2a](https://github.com/WatWowMap/ReactMap/commit/ce37e2a9123ea2808cde3f3f130361055141ae63)) +* logic bug in loading non-clustered elements ([#1161](https://github.com/WatWowMap/ReactMap/issues/1161)) ([a2c7f17](https://github.com/WatWowMap/ReactMap/commit/a2c7f17e02ff7cd5467d4bf5ccd8b13a444ba725)) +* more robust discord handling ([#1181](https://github.com/WatWowMap/ReactMap/issues/1181)) ([b579ded](https://github.com/WatWowMap/ReactMap/commit/b579dedeb196fb4d8b1da025e325049bfd7833e8)) +* no scrollbars plz ([907ca33](https://github.com/WatWowMap/ReactMap/commit/907ca331beb1fe81dd671732d5ebe1980d8d6faa)) +* pokemon onlyManualId filter in expert sql mode ([ee176da](https://github.com/WatWowMap/ReactMap/commit/ee176da3749c27b33aa659ba432706ad5c19951b)) +* properly migrate to express 5 ([3907656](https://github.com/WatWowMap/ReactMap/commit/390765696dbdcd89ed2fd57b16d41ecc2725a1b9)) +* remove extra Forms ([0f157ed](https://github.com/WatWowMap/ReactMap/commit/0f157edba37eb727fdb9f4a5b96bdf417298cdfc)) +* sentry node version ([8640ee0](https://github.com/WatWowMap/ReactMap/commit/8640ee0da68cc2a23e4d12e472b109a6628507c6)) +* showcase icons display ([b626d3d](https://github.com/WatWowMap/ReactMap/commit/b626d3d37c18b5ef6261f02b105796fdb8ce011f)) +* weather icon in pokemon background popup ([21b50f5](https://github.com/WatWowMap/ReactMap/commit/21b50f51b81bf6f7723753a4f77289ead99c51e7)) + + +### Features + +* ar/no-ar quest dot badge ([8adba28](https://github.com/WatWowMap/ReactMap/commit/8adba286fea81d194e0dd4b7da5c680f6499b697)) +* default clientPrompt to none to skip permission reapproval ([d3ea283](https://github.com/WatWowMap/ReactMap/commit/d3ea283b5eacda18b9f4725e50e5353a955a363d)) +* dynamic placed Pokemon dropdown height ([8a0447c](https://github.com/WatWowMap/ReactMap/commit/8a0447c3e9d7df9c4aa9add657a234a1bc59b412)) +* support stationed pokemon extras ([4f5aace](https://github.com/WatWowMap/ReactMap/commit/4f5aace285285d55e3a946fb2f465b7609a9caea)) + # [1.41.0-develop.11](https://github.com/WatWowMap/ReactMap/compare/v1.41.0-develop.10...v1.41.0-develop.11) (2026-03-15) diff --git a/package.json b/package.json index 7b9764019..b0da94f2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "reactmap", - "version": "1.41.0-develop.11", + "version": "1.41.0", "private": true, "description": "React based frontend map.", "license": "MIT", From e5dc6f90d14fa1afb8a75bb9bdb2246213ff1c88 Mon Sep 17 00:00:00 2001 From: Mygod Date: Sat, 14 Mar 2026 23:34:03 -0400 Subject: [PATCH 2/5] fix: workflow git creds --- .github/workflows/release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c7e63266c..bba06caa2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,6 +29,11 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} HUSKY: 0 run: npx semantic-release + - name: Configure git + if: ${{ github.ref_name == 'main'}} + run: | + git config --global user.name "turtlesocks-bot" + git config --global user.email "turtlesocks-bot@users.noreply.github.com" - name: Sync Dev to Main if: ${{ github.ref_name == 'main'}} env: From b20188fc6590c2bccffa5827088cfe2998b16019 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 15 Mar 2026 03:43:44 +0000 Subject: [PATCH 3/5] chore(release): v1.41.1 [skip ci] ## [1.41.1](https://github.com/WatWowMap/ReactMap/compare/v1.41.0...v1.41.1) (2026-03-15) ### Bug Fixes * workflow git creds ([e5dc6f9](https://github.com/WatWowMap/ReactMap/commit/e5dc6f90d14fa1afb8a75bb9bdb2246213ff1c88)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9764296f..230f0d171 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [1.41.1](https://github.com/WatWowMap/ReactMap/compare/v1.41.0...v1.41.1) (2026-03-15) + + +### Bug Fixes + +* workflow git creds ([e5dc6f9](https://github.com/WatWowMap/ReactMap/commit/e5dc6f90d14fa1afb8a75bb9bdb2246213ff1c88)) + # [1.41.0](https://github.com/WatWowMap/ReactMap/compare/v1.40.1...v1.41.0) (2026-03-15) diff --git a/package.json b/package.json index b0da94f2b..0c4bac6ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "reactmap", - "version": "1.41.0", + "version": "1.41.1", "private": true, "description": "React based frontend map.", "license": "MIT", From 600eed64d7445e4c5bc65dd62f230f3026e81dba Mon Sep 17 00:00:00 2001 From: Magik <30931287+unseenmagik@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:35:31 +0000 Subject: [PATCH 4/5] feat(auth): support parent-based areaRestrictions in config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📝 Commit description (detailed) - Added a new optional `parent: string[]` field to `authentication.areaRestrictions` so admins can grant access by parent area name (and automatically include all child areas). - Updated areaPerms.js to: - accept `parent` in the restriction rule, - build a parent→child key map from loaded geojson, - and grant access for both the parent area and its children. - Updated GraphQL area filtering (`scanAreas` / `scanAreasMenu`) to allow permissions to match by `feature.properties.key` (in addition to `name`/`parent`) so the filtering behavior stays consistent with the new parent-based key logic. - Updated type definitions (config.d.ts) to reflect the new optional `parent` array. - Updated the example config (local.example.json) with `parent: []` entries for documentation and schema clarity. --- config/local.example.json | 6 ++-- packages/config/lib/mutations.js | 3 +- packages/types/lib/config.d.ts | 2 +- server/src/graphql/resolvers.js | 5 +++- server/src/utils/areaPerms.js | 50 +++++++++++++++++++++++++------- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/config/local.example.json b/config/local.example.json index 5f93a1674..b44e5a377 100644 --- a/config/local.example.json +++ b/config/local.example.json @@ -90,11 +90,13 @@ "areaRestrictions": [ { "roles": [], - "areas": [] + "areas": [], + "parent": [] }, { "roles": [], - "areas": [] + "areas": [], + "parent": [] } ], "aliases": [ diff --git a/packages/config/lib/mutations.js b/packages/config/lib/mutations.js index aad7c2c08..f18f87a04 100644 --- a/packages/config/lib/mutations.js +++ b/packages/config/lib/mutations.js @@ -307,9 +307,10 @@ const applyMutations = (config) => { }) config.authentication.areaRestrictions = - config.authentication.areaRestrictions.map(({ roles, areas }) => ({ + config.authentication.areaRestrictions.map(({ roles, areas, parent }) => ({ roles: roles.flatMap(replaceAliases), areas, + parent, })) config.authentication.strategies = config.authentication.strategies.map( diff --git a/packages/types/lib/config.d.ts b/packages/types/lib/config.d.ts index 4c098138e..e4747dc4d 100644 --- a/packages/types/lib/config.d.ts +++ b/packages/types/lib/config.d.ts @@ -53,7 +53,7 @@ export type Config = DeepMerge< } areas: ConfigAreas authentication: { - areaRestrictions: { roles: string[]; areas: string[] }[] + areaRestrictions: { roles: string[]; areas: string[]; parent?: string[] }[] // Unfortunately these types are not convenient for looping the `perms` object... // excludeFromTutorial: (keyof BaseConfig['authentication']['perms'])[] // alwaysEnabledPerms: (keyof BaseConfig['authentication']['perms'])[] diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js index cf27d5fd8..6f43b8907 100644 --- a/server/src/graphql/resolvers.js +++ b/server/src/graphql/resolvers.js @@ -362,6 +362,7 @@ const resolvers = { (feature) => !feature.properties.hidden && (!perms.areaRestrictions.length || + perms.areaRestrictions.includes(feature.properties.key) || perms.areaRestrictions.includes(feature.properties.name) || perms.areaRestrictions.includes(feature.properties.parent)), ), @@ -380,7 +381,9 @@ const resolvers = { children: perms.areaRestrictions.includes(parent.name) ? parent.children : parent.children.filter((child) => - perms.areaRestrictions.includes(child.properties.name), + perms.areaRestrictions.includes(child.properties.key) || + perms.areaRestrictions.includes(child.properties.name) || + perms.areaRestrictions.includes(child.properties.parent), ), })) .filter((parent) => parent.children.length) diff --git a/server/src/utils/areaPerms.js b/server/src/utils/areaPerms.js index 596f239fe..7ff31fb9d 100644 --- a/server/src/utils/areaPerms.js +++ b/server/src/utils/areaPerms.js @@ -9,20 +9,50 @@ function areaPerms(roles) { const areaRestrictions = config.getSafe('authentication.areaRestrictions') const areas = config.getSafe('areas') + // Map parent names to child keys for easy lookup when parent-based restrictions are used. + const parentKeyMap = Object.values(areas.scanAreasObj).reduce( + (acc, feature) => { + const parent = feature.properties.parent + if (!parent) return acc + if (!acc[parent]) acc[parent] = [] + acc[parent].push(feature.properties.key) + return acc + }, + /** @type {Record} */ ({}), + ) + const perms = [] for (let i = 0; i < roles.length; i += 1) { for (let j = 0; j < areaRestrictions.length; j += 1) { - if (areaRestrictions[j].roles.includes(roles[i])) { - if (areaRestrictions[j].areas.length) { - for (let k = 0; k < areaRestrictions[j].areas.length; k += 1) { - if (areas.names.has(areaRestrictions[j].areas[k])) { - perms.push(areaRestrictions[j].areas[k]) - } else if (areas.withoutParents[areaRestrictions[j].areas[k]]) { - perms.push(...areas.withoutParents[areaRestrictions[j].areas[k]]) - } + if (!areaRestrictions[j].roles.includes(roles[i])) continue + + const hasAreas = Array.isArray(areaRestrictions[j].areas) + ? areaRestrictions[j].areas.length > 0 + : false + const hasParents = Array.isArray(areaRestrictions[j].parent) + ? areaRestrictions[j].parent.length > 0 + : false + + // No areas/parents means unrestricted access + if (!hasAreas && !hasParents) return [] + + if (hasAreas) { + for (let k = 0; k < areaRestrictions[j].areas.length; k += 1) { + const target = areaRestrictions[j].areas[k] + if (areas.names.has(target)) { + perms.push(target) + } else if (areas.withoutParents[target]) { + perms.push(...areas.withoutParents[target]) } - } else { - return [] + } + } + + if (hasParents) { + for (let k = 0; k < areaRestrictions[j].parent.length; k += 1) { + const parent = areaRestrictions[j].parent[k] + // If the parent itself exists as a top-level area, allow it too. + if (areas.names.has(parent)) perms.push(parent) + if (parentKeyMap[parent]) perms.push(...parentKeyMap[parent]) } } } From 37cd8ad813f9d302548a420f43bf4f1301b8d763 Mon Sep 17 00:00:00 2001 From: Magik <30931287+unseenmagik@users.noreply.github.com> Date: Fri, 20 Mar 2026 00:00:38 +0000 Subject: [PATCH 5/5] fix(areas): include parent keys in grouped child selection Adjust area permission handling and grouped child-area selection. Include the parent area key in grouped toggles when present, while preserving existing single-child behavior. --- server/src/graphql/resolvers.js | 9 +++++---- server/src/utils/areaPerms.js | 2 +- src/features/drawer/areas/Child.jsx | 20 +++++++++++--------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js index 6f43b8907..ac4690796 100644 --- a/server/src/graphql/resolvers.js +++ b/server/src/graphql/resolvers.js @@ -380,10 +380,11 @@ const resolvers = { ...parent, children: perms.areaRestrictions.includes(parent.name) ? parent.children - : parent.children.filter((child) => - perms.areaRestrictions.includes(child.properties.key) || - perms.areaRestrictions.includes(child.properties.name) || - perms.areaRestrictions.includes(child.properties.parent), + : parent.children.filter( + (child) => + perms.areaRestrictions.includes(child.properties.key) || + perms.areaRestrictions.includes(child.properties.name) || + perms.areaRestrictions.includes(child.properties.parent), ), })) .filter((parent) => parent.children.length) diff --git a/server/src/utils/areaPerms.js b/server/src/utils/areaPerms.js index 7ff31fb9d..fc3c2f5c4 100644 --- a/server/src/utils/areaPerms.js +++ b/server/src/utils/areaPerms.js @@ -12,7 +12,7 @@ function areaPerms(roles) { // Map parent names to child keys for easy lookup when parent-based restrictions are used. const parentKeyMap = Object.values(areas.scanAreasObj).reduce( (acc, feature) => { - const parent = feature.properties.parent + const { parent } = feature.properties if (!parent) return acc if (!acc[parent]) acc[parent] = [] acc[parent].push(feature.properties.key) diff --git a/src/features/drawer/areas/Child.jsx b/src/features/drawer/areas/Child.jsx index a22f72aa8..fd561b3c4 100644 --- a/src/features/drawer/areas/Child.jsx +++ b/src/features/drawer/areas/Child.jsx @@ -103,15 +103,17 @@ export function AreaChild({ indeterminate={name ? hasSome && !hasAll : false} checked={name ? hasAll : scanAreas.includes(feature.properties.key)} onClick={(e) => e.stopPropagation()} - onChange={() => - setAreas( - name - ? childAreas.map((c) => c.properties.key) - : feature.properties.key, - allAreas, - name ? hasSome : false, - ) - } + onChange={() => { + const areaKeys = name + ? [ + ...(feature?.properties?.key + ? [feature.properties.key] + : []), + ...childAreas.map((c) => c.properties.key), + ] + : feature.properties.key + setAreas(areaKeys, allAreas, name ? hasSome : false) + }} sx={{ p: 1, color,