Summary
Before publishing, check that every data source a project references will actually load for someone else, and report the ones that will not.
Why
A .geolibre.json is mostly references: tile URLs, COG and PMTiles endpoints, STAC and OGC API services, hosted map services, PostGIS-backed layers, remote GeoParquet. The publish path in useProjectFileActions.ts embeds local vector data so a shared project is self-contained in that respect, but everything remote stays a URL.
So a project can publish cleanly and still be broken for every recipient:
- a service that needs a token the author has in Settings and the recipient does not;
- a host with no permissive CORS headers, which works in the desktop app and fails in the browser;
- a PostGIS or sidecar-backed layer that only resolves on the author's machine or network;
- an intranet URL, or a signed URL that has since expired;
- a local file path that slipped through in a layer type the embed step does not cover.
The author finds out when someone tells them the map is empty — if they tell them. This is the single most common "shared project doesn't work" class of report, and it is entirely detectable before upload.
Proposal
Add a readiness check to the Share flow, run when the dialog opens:
1. Classify every source in the project
Walk the serialized project the same way the publish path already walks it, and bucket each remote reference: reachable anonymously / requires a credential the author holds / not reachable from a browser (CORS) / local or private-network / unknown.
2. Probe what can be probed
A cheap HEAD or ranged GET per distinct host, without the author's credentials attached, is enough to distinguish "public" from "401/403". Cache per host, cap the number of probes, and time out fast — the dialog must not hang on a slow service. Run the probes from the browser so a CORS failure is detected as a CORS failure rather than masked by a server-side fetch.
3. Report, in the dialog, before the upload button
A short list with a per-layer verdict and a plain-language reason, plus what to do about each:
- credential-gated → point at the credential-broker path once that exists, or suggest making the service public
- CORS-blocked → note that it will work in the desktop app but not in the browser viewer, since the recipient's build matters
- local or private → offer to convert/embed where possible, or flag it as unusable for recipients
The check informs; it does not block. An author sharing an intranet map with intranet colleagues is doing the right thing and should not have to fight a warning.
Scope notes
- Entirely client-side and needs no identity, no organization, and no server change, so it can land independently of everything else in the access-control umbrella.
- Reuse the layer-walking logic in the publish path rather than writing a second traversal that will drift from it.
- The same check is useful outside sharing: as a "why is this layer empty?" diagnostic on a project someone else opened.
Effort
Medium, and unusually self-contained for its value.
Part of #1665 (access control umbrella).
Summary
Before publishing, check that every data source a project references will actually load for someone else, and report the ones that will not.
Why
A
.geolibre.jsonis mostly references: tile URLs, COG and PMTiles endpoints, STAC and OGC API services, hosted map services, PostGIS-backed layers, remote GeoParquet. The publish path inuseProjectFileActions.tsembeds local vector data so a shared project is self-contained in that respect, but everything remote stays a URL.So a project can publish cleanly and still be broken for every recipient:
The author finds out when someone tells them the map is empty — if they tell them. This is the single most common "shared project doesn't work" class of report, and it is entirely detectable before upload.
Proposal
Add a readiness check to the Share flow, run when the dialog opens:
1. Classify every source in the project
Walk the serialized project the same way the publish path already walks it, and bucket each remote reference: reachable anonymously / requires a credential the author holds / not reachable from a browser (CORS) / local or private-network / unknown.
2. Probe what can be probed
A cheap
HEADor rangedGETper distinct host, without the author's credentials attached, is enough to distinguish "public" from "401/403". Cache per host, cap the number of probes, and time out fast — the dialog must not hang on a slow service. Run the probes from the browser so a CORS failure is detected as a CORS failure rather than masked by a server-side fetch.3. Report, in the dialog, before the upload button
A short list with a per-layer verdict and a plain-language reason, plus what to do about each:
The check informs; it does not block. An author sharing an intranet map with intranet colleagues is doing the right thing and should not have to fight a warning.
Scope notes
Effort
Medium, and unusually self-contained for its value.
Part of #1665 (access control umbrella).