Skip to content

feat: support parent-based areaRestrictions in config for areas.json#1195

Open
unseenmagik wants to merge 123 commits intoWatWowMap:developfrom
unseenmagik:main
Open

feat: support parent-based areaRestrictions in config for areas.json#1195
unseenmagik wants to merge 123 commits intoWatWowMap:developfrom
unseenmagik:main

Conversation

@unseenmagik
Copy link
Copy Markdown
Contributor

📝 PR Overview

  • feature: non breaking, additional config option.

For those that still use an areas.json file (rather than Koji), you can add a new parent parameter in the features.collection which can be used to filter access to areas on ReactMap.

  • Added a new optional parent: string[] field to authentication.areaRestrictions so you 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.

## 📝 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.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 600eed64d7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

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.
@Mygod Mygod changed the base branch from main to develop March 20, 2026 02:56
@unseenmagik
Copy link
Copy Markdown
Contributor Author

Thanks for the updates @Mygod i will test these out.

@Mygod
Copy link
Copy Markdown
Collaborator

Mygod commented Mar 31, 2026

bruh why so many bugs 😠

@Mygod
Copy link
Copy Markdown
Collaborator

Mygod commented Mar 31, 2026

I think I may have let my agent be too free. Steering it. (Rip my tokens.)

Btw just in case you can't tell yet, I'm using your PR as a testing playground for my new skill. ;)

@Mygod
Copy link
Copy Markdown
Collaborator

Mygod commented Apr 2, 2026

Ok done. Please test thoroughly. Do not make any mistakes.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds parent-based area restriction support (including multi-domain/scoped behavior) so areas.json users can grant access via parent areas while keeping scan area selection/filtering consistent across the UI and GraphQL/backend filters.

Changes:

  • Extend authentication.areaRestrictions rules with optional parent entries and implement scoped/normalized area restriction handling (including parent→children expansion).
  • Update GraphQL scan area resolvers + SQL/RTREE filtering to operate on canonical area keys/features and respect unrestricted/no-access grants.
  • Update the scan-area UI (map tile + drawer table) to handle parent/child selection and reset persisted scan-area selections when needed.

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/store/useStorage.js Adds persisted store versioning + migration to reset scan area selections.
src/features/scanArea/utils.js Adds helper utilities for deriving selectable/valid area keys (parent/child aware).
src/features/scanArea/ScanAreaTile.jsx Updates scan-area map interactions to toggle parent/child selections and search by key/name.
src/features/drawer/areas/Child.jsx Updates scan-area drawer row selection logic to account for parent keys and grouped selection.
src/features/drawer/areas/AreaTable.jsx Updates scan-area drawer table filtering, match counting, and grouped parent rendering.
src/components/auth/Local.jsx Redirects to /blocked/... flow for blocked responses during local login.
server/src/utils/mergePerms.js Minor formatting-only change.
server/src/utils/getServerSettings.js Normalizes/sanitizes area restrictions before returning settings to the client.
server/src/utils/getAreaSql.js Switches area SQL filtering to operate on consolidated feature geometries + unrestricted sentinel.
server/src/utils/getAccessibleScanAreasMenu.js New helper to filter scan area menu output based on effective area restrictions.
server/src/utils/filterRTree.js Updates in-memory RTree filtering to use consolidated feature objects + unrestricted sentinel behavior.
server/src/utils/consolidateAreas.js Reworks consolidation to handle scoped grants, parent grants, multi-domain ambiguity, and feature-based filtering.
server/src/utils/areaPerms.js Major expansion: encoding/decoding grants, parent grants, scopes, normalization, and public-safe restrictions.
server/src/services/TelegramClient.js Adds strict group lookup option and request-scoped areaPerms serialization; adds linked-perms refresh.
server/src/services/logUserAuth.js Logs only public/normalized area restrictions to avoid leaking internal sentinel/grant metadata.
server/src/services/LocalClient.js Merges linked provider perms (discord/telegram) with optional live refresh + request-scoped areaPerms.
server/src/services/DiscordClient.js Adds strict lookup support, request-scoped resolveAreaPerms, and linked-perms refresh.
server/src/services/areas.js Builds RTree and scan-area objects across multi-domain scan areas.
server/src/routes/rootRouter.js Ensures session perms use request-scoped serialized area restrictions for settings bootstrap.
server/src/models/Weather.js Applies consolidated area filtering using feature geometries and unrestricted sentinel behavior.
server/src/middleware/apollo.js Normalizes area restrictions into the GraphQL context (request-scoped).
server/src/graphql/resolvers.js Updates scan area filtering logic and delegates menu filtering to getAccessibleScanAreasMenu.
packages/types/lib/config.d.ts Updates config typings to include optional parent on area restriction rules.
packages/config/lib/mutations.js Preserves parent on area restriction rules when applying config mutations.
config/local.example.json Documents parent: [] in example config for clarity.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 112 to 115
return { ...rest, children, rows }
}),
[data, search],
)
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allRows's useMemo uses accessibleAreaKeys (e.g., for groupKey), but the dependency array is [data, search]. If permissions change, the memo can return stale rows. Include accessibleAreaKeys in the dependency list (or restructure so the memo doesn't close over it).

Copilot uses AI. Check for mistakes.
Comment on lines +61 to +65
const parsedStoredPerms = storedPerms
? typeof storedPerms === 'string'
? JSON.parse(storedPerms)
: storedPerms
: null
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mergeLinkedPerms parses storedPerms via JSON.parse(storedPerms) without a guard. If the DB value is malformed/corrupted, this will throw and can break local login. Wrap the parse in a try/catch and fall back to null (and optionally log a warning with the user id/provider).

Suggested change
const parsedStoredPerms = storedPerms
? typeof storedPerms === 'string'
? JSON.parse(storedPerms)
: storedPerms
: null
let parsedStoredPerms = null
if (storedPerms) {
if (typeof storedPerms === 'string') {
try {
parsedStoredPerms = JSON.parse(storedPerms)
} catch (error) {
this.log.warn(
`Failed to parse stored linked ${type} perms for id ${id}`,
error,
)
}
} else {
parsedStoredPerms = storedPerms
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +42
const safeUser = {
...user,
perms: normalizedPerms
? {
...normalizedPerms,
areaRestrictions: getPublicAreaRestrictions(
normalizedPerms.areaRestrictions,
),
}
: normalizedPerms,
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getPublicAreaRestrictions() filters out NO_ACCESS_SENTINEL, and getServerSettings sends only these public restrictions to the client. That means a user whose resolved restrictions are [NO_ACCESS_SENTINEL] will appear to have an empty restriction list on the client (which elsewhere is treated as “unrestricted”), leading to inconsistent UI vs server behavior. Consider preserving an explicit “no access” signal for the client (e.g., keep a boolean/flag, or include a dedicated sentinel that the client understands) while still stripping scoped/grant metadata.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +47
export function getValidAreaKeys(features, accessibleAreaKeys = []) {
return [
...new Set(
features.flatMap((feature) =>
getAreaKeys(features, feature, accessibleAreaKeys),
),
),
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getValidAreaKeys calls getAreaKeys for every feature, and getAreaKeys may scan features again to find children. This is O(n²) and is invoked on each tap in ScanAreaTile. Consider precomputing a parentName→childKeys map once (e.g., via useMemo) and using that to build valid keys in O(n).

Copilot uses AI. Check for mistakes.
@Mygod
Copy link
Copy Markdown
Collaborator

Mygod commented Apr 2, 2026

My agent has decided that this PR cannot be merged unless a major refactor is done first.

I would stop trying to salvage this as a mergeable feature PR. Either:

  • drop parent restrictions entirely for now, or
  • do a real redesign first with one canonical area identifier model and explicit validation for ambiguous configs

Sorry to disappoint you but the codebase at this point probably can't handle more complexity.

@Mygod Mygod closed this Apr 2, 2026
@Mygod Mygod reopened this Apr 2, 2026
@Mygod Mygod added the Won't Fix This will not be worked on label Apr 2, 2026
@Mygod
Copy link
Copy Markdown
Collaborator

Mygod commented Apr 2, 2026

Also rip to wasted tokens.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Won't Fix This will not be worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants