Repository navigation
Conversation
tnunamak
force-pushed
the
feat/console-connector-identity-icons
branch
from
November 5, 2026 16:29
b3263e7 to
db77907
Compare
tnunamak
force-pushed
the
feat/console-connector-identity-icons
branch
from
November 5, 2026 18:07
db77907 to
63923e6
Compare
tnunamak
force-pushed
the
fix/console-install-before-account-setup
branch
from
November 5, 2026 21:34
22c5240 to
1317a91
Compare
tnunamak
force-pushed
the
feat/console-connector-identity-icons
branch
5 times, most recently
from
November 6, 2026 13:25
f8ec588 to
0de0510
Compare
Replace the per-surface connector logo markup with one shared mark: a 28px rounded tile with a 60% glyph, an official bundled icon looked up by the connector's exact identity, and an initials fallback. All 47 console call sites pass the connector ID instead of sizing the logo themselves. - resolve-connector-icon.ts and connector-icon-map.ts resolve a mark from the connector key or canonical ID. A safe icon the connector supplies wins; unknown IDs and unrelated registry origins get initials, never another brand. Underscore and hyphen spellings alias only for local keys and first-party registry IDs; any other URI scheme (for example a URN) stays an exact identity. - sanitize-svg.ts validates every inline SVG at the display boundary. - sync-connector-icons.mjs generates sanitized-assets.json and the NOTICE and PROVENANCE files from data-connectors at 23aee3aa (65 icons). The generated files are not edited by hand; --check verifies them. - The consent screen model carries the display connectorId so the consent UI can show the mark. The ID is display-only and never selects a grant. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…kdrop The manifest-setup pages passed `manifest.icon` to ConnectorMark. That icon came from `brand.icon` SVG bytes with no background, so a white glyph such as Amazon's was invisible on a light surface, while the summary pages got the declared `brand.background_color` from the icon map. Two paths decided the backdrop, and the map and the setup pages also disagreed when simple-icons and a bundled mark both matched. resolveManifestDisplayMark now turns a manifest into the display mark at the data boundary (listConnectorManifests): sanitized SVG, a validated hex backdrop, and its source. One precedence rule: the manifest's inline icon, then the file named by brand.icon (both take the declared backdrop unless the mark has its own), then the bundled mark for the connector identity, then simple-icons, then the monogram. Every reader of `manifest.icon` (setup, grants, sources, syncs, device exporters) now renders the same mark. The icon map only indexes manifest marks; it no longer adds a backdrop or skips marks by source. A cross-surface test loads the installed Amazon manifest and asserts that the setup, icon-map and manifest-less renderings are identical, keep the #FFFFFF glyph and carry the #FF9900 backdrop. It fails on the previous code, where the setup rendering has no backdrop. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
The icon map let a server template mark overwrite a manifest mark, while the manifest resolver let the manifest's own mark win. A connector with both showed one mark on the setup pages and another on the summary pages. - Add pickDisplayMark (manifest, template, bundled, simple-icons) and use it in resolveManifestDisplayMark and in buildConnectorIconMap. The map fills one layer per source and picks per identity, so it cannot reorder them. - Test a manifest and a template that disagree, and test that every installed manifest has the same mark in the map and on the setup pages. - Keep a catalog entry's own mark when the map does not index its key. - Fail the icon sync on a repeated connector key or ID, and test that no two bundled connectors claim one identity. - Drop the dead connectorId fallback, correct stale layer comments, and restore a destructive-status colour rule this change did not need. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
catalogEntryIcon returned a catalog entry's own icon unvalidated when the icon map had no entry for its key, skipping the SVG allowlist and the hex check. It now runs the same validatedConnectorIcon as every other layer. ConnectorIcon also trusted its callers: it passed icon.svg to dangerouslySetInnerHTML and wrote icon.color/backgroundColor into the style attribute as given. It now runs the shape-only SVG allowlist and a hex check itself, and falls back to the monogram when the markup is rejected. A non-hex color is dropped, so it cannot add CSS declarations such as a url() fetch. The allowlist (sanitizeSvg) moves into @pdpp/brand-react beside the component so the component can import it; the console imports it from the package. hexColorOrNull is the one color check, accepting #rgb and #rrggbb; the console's own 6-digit regex is removed. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
… by order The bundled icon corpus is indexed under every spelling of an identity (`foo-bar`, `foo_bar`, the registry-prefixed id). Nothing stopped two entries from claiming one spelling, a free-form background_color from being copied into the bundle, or entries that share a source id from carrying different marks (the source lookup then resolves to no brand). Which mark shipped depended on file order. The sync script now runs assertIconCorpusConsistent, which rejects all three on the normalized identity keys; a test runs the same check on the checked-in corpus. Identity-key normalization moves to its own module so the script and the resolver share it without loading the corpus. At runtime indexConnectorIcon no longer lets the last writer win within a layer. Two different marks claiming one spelling (two installed manifests `foo_bar` and `foo-bar`) now give that spelling no mark from the layer, with a logged warning; identical marks are not a collision. The icon map's bundled layer now comes from the resolver's own index instead of iterating the corpus a second time. corpusIcon no longer passes background_color twice. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
The offline simple-icons lookup treated the package as installed only if its package.json existed. Next's standalone tracer copies just the files next.config.mjs names (data/simple-icons.json and icons/*.svg), so in a standalone build the lookup found no package and the generic layer never resolved a mark. It now checks for the slug index it reads. The package root and slug set were cached once for the process, keyed by nothing. They are now keyed by working directory and root, which the candidate roots depend on, so the new test can run against a standalone-style layout. The doc comment no longer calls the package vendored, points at the real NOTICE, and states that `foo-bar` and `foobar` share a slug. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
resolveManifestDisplayMark supplies no template layer, yet pickDisplayMark's result type allowed "template" and the caller carried a branch for it that could never run. pickDisplayMark is now generic over the layers the caller passes, so an unsupplied layer cannot be reported as the source and the dead branch is gone. Precedence is unchanged. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…t its limits No bundled connector mark and none of the ~3,470 simple-icons marks use <defs>, and its useful children (gradients, clip paths) are not allowed elements, so it could only wrap shapes that sit directly under <svg>. The length cap is now documented against measurement: the bundled corpus tops out near 3.4 KB, and 32 simple-icons marks exceed 10 KB and fall back to the monogram. The docstring now says that text between elements is kept verbatim. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
tnunamak
force-pushed
the
feat/console-connector-identity-icons
branch
from
November 6, 2026 14:12
0de0510 to
c5f7d87
Compare
Contributor
Author
|
Review follow-ups deferred from this PR (simple-icons slug collision, icon revision vs spec pin, a wording nit) are tracked in #646. |
…d SVG sanitizer The server kept its own SVG allowlist beside the one the console renders with, and the two disagreed. The server accepted <defs>, duplicate attributes, character references, unbalanced nesting and text after the root; the console rejected all of those, so an accepted icon silently showed a monogram. The server rejected role and aria-hidden on the root, which the console accepts. validateManifestIcon now asks sanitizeSvg from vendor/brand-react, the function behind validatedConnectorIcon, so one vocabulary gives one verdict. It is imported by relative path because the staged reference stack resolves only LOCAL_PACKAGES. A rejected icon now reports one message instead of naming the element or attribute. The new table runs 16 SVGs plus the XSS vectors through both and requires the same verdict; 11 rows failed before the change. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
Base automatically changed from
fix/console-install-before-account-setup
to
main
November 6, 2026 17:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Console pages now show one identity-based mark per connector. Setup, grants, sources, syncs and consent draw the same 28px tile, a white glyph keeps its brand backdrop, and a connector with no known icon gets initials, never another brand's mark.
Each page used to draw its own logo and pick its own source, so one connector could look different from page to page. The server also kept a second SVG allowlist, so it could accept a manifest icon that the console then dropped without notice. It now validates icons with the sanitizer the console renders with, so both give one verdict.
Tests cover the mark precedence, the identity aliases, the icon corpus checks and the sanitizer, plus the Amazon mark rendering the same on every surface. A table of 25 SVGs, including the XSS vectors, must get the same verdict from the server and the sanitizer; 11 rows failed before the change.
Stacked on #617; merge that first.
Assisted-by: AI