From 5796af3bb7446a4c5020cbdcfc1d13d1e0d611b8 Mon Sep 17 00:00:00 2001 From: Jan-Felix Date: Mon, 6 Jan 2025 15:20:45 +0100 Subject: [PATCH 1/4] fix diffing issue when annotation URI use query params in different order --- packages/sdk/src/entrypoints/annotations.ts | 27 ++++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/sdk/src/entrypoints/annotations.ts b/packages/sdk/src/entrypoints/annotations.ts index bce5d4a85..5e731165e 100644 --- a/packages/sdk/src/entrypoints/annotations.ts +++ b/packages/sdk/src/entrypoints/annotations.ts @@ -143,9 +143,11 @@ export const resolveAnnotation = async ( fetchSchema: (url: string) => Promise } ): Promise => { + const normalizedUri = normalizeUri(annotation.uri) + const [permissions, schema] = await Promise.all([ - fetchPermissions(annotation.uri).catch((e: Error) => { - console.error(`Error resolving annotation ${annotation.uri}`, e) + fetchPermissions(normalizedUri).catch((e: Error) => { + console.error(`Error resolving annotation ${normalizedUri}`, e) throw new Error(`Error resolving annotation: ${e}`) }), fetchSchema(annotation.schema).catch((e) => { @@ -162,7 +164,7 @@ export const resolveAnnotation = async ( } const { serverUrl, path, query } = parseUri( - annotation.uri, + normalizedUri, schema, annotation.schema ) @@ -184,7 +186,7 @@ export const resolveAnnotation = async ( return { permissions, - uri: annotation.uri, + uri: normalizedUri, serverUrl, apiInfo: schema.definition.info || { title: "", version: "" }, path: operation.path, @@ -198,6 +200,23 @@ export const resolveAnnotation = async ( } } +/** Normalize a URI to a canonical form in which query params are sorted alphabetically */ +const normalizeUri = (uri: string) => { + let url: URL + try { + url = new URL(uri) // Parse the URI into its components + } catch (error) { + throw new Error(`Invalid URI: ${uri}`) // Handle invalid URI errors + } + + const searchParams = new URLSearchParams(url.search) + // Sort the key/value pairs in place + searchParams.sort() + + // Reconstruct the URI with normalized query parameters + return `${url.origin}${url.pathname}?${searchParams}` +} + /** Returns the annotation's path relative to the API server's base URL */ const parseUri = ( annotationUrl: string, From 599a03cec54a63df93ce8b1a95b1bba99c787603 Mon Sep 17 00:00:00 2001 From: Jan-Felix Date: Mon, 6 Jan 2025 15:34:27 +0100 Subject: [PATCH 2/4] fix import issues between client & server modules --- .../components/permissions/PermissionsDiff/classes.ts | 1 + .../components/permissions/PermissionsDiff/index.tsx | 10 +++++++--- .../PresetItem/IndividualPermissionsExpandable.tsx | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 packages/app/components/permissions/PermissionsDiff/classes.ts diff --git a/packages/app/components/permissions/PermissionsDiff/classes.ts b/packages/app/components/permissions/PermissionsDiff/classes.ts new file mode 100644 index 000000000..37cd63f8a --- /dev/null +++ b/packages/app/components/permissions/PermissionsDiff/classes.ts @@ -0,0 +1 @@ +export const DIFF_CONTAINER_CLASS = "diffContainer" diff --git a/packages/app/components/permissions/PermissionsDiff/index.tsx b/packages/app/components/permissions/PermissionsDiff/index.tsx index 045fae8f0..5404d2b86 100644 --- a/packages/app/components/permissions/PermissionsDiff/index.tsx +++ b/packages/app/components/permissions/PermissionsDiff/index.tsx @@ -8,7 +8,7 @@ import { diffPermissions, diffPresets } from "./diff" import { PresetsAndPermissionsView } from "../PermissionsList" import classes from "./style.module.css" import { SpawnAnchorContext } from "@/ui/Anchor" -import { DIFF_CONTAINER_CLASS } from "../PresetItem/IndividualPermissionsExpandable" +import { DIFF_CONTAINER_CLASS } from "./classes" interface Props { left: { targets: Target[]; annotations: Annotation[] } @@ -38,7 +38,11 @@ const PermissionsDiff = async ({ left, right, chainId }: Props) => { leftPresets, rightPresets ) - + console.log( + "cn", + cn(classes.left, DIFF_CONTAINER_CLASS), + DIFF_CONTAINER_CLASS + ) return ( @@ -54,7 +58,7 @@ const PermissionsDiff = async ({ left, right, chainId }: Props) => { /> - + = (props) => { const [hashOnMount, setHashOnMount] = useState(undefined) @@ -49,7 +50,6 @@ export default IndividualPermissionsExpandable const BOX_CLASS = "permissionBox" const TOGGLE_CLASS = "permissionBoxToggle" -export const DIFF_CONTAINER_CLASS = "diffContainer" // TODO: make this work! const syncToggle = (ev: React.MouseEvent) => { From 32e16e602a4947fe64e482e76e149d65ae9dc24d Mon Sep 17 00:00:00 2001 From: Jan-Felix Date: Mon, 6 Jan 2025 15:42:42 +0100 Subject: [PATCH 3/4] fix permissions toggling --- .../app/components/permissions/PermissionsDiff/index.tsx | 6 +----- .../PresetItem/IndividualPermissionsExpandable.tsx | 6 +++++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/app/components/permissions/PermissionsDiff/index.tsx b/packages/app/components/permissions/PermissionsDiff/index.tsx index 5404d2b86..3333facb6 100644 --- a/packages/app/components/permissions/PermissionsDiff/index.tsx +++ b/packages/app/components/permissions/PermissionsDiff/index.tsx @@ -38,11 +38,7 @@ const PermissionsDiff = async ({ left, right, chainId }: Props) => { leftPresets, rightPresets ) - console.log( - "cn", - cn(classes.left, DIFF_CONTAINER_CLASS), - DIFF_CONTAINER_CLASS - ) + return ( diff --git a/packages/app/components/permissions/PresetItem/IndividualPermissionsExpandable.tsx b/packages/app/components/permissions/PresetItem/IndividualPermissionsExpandable.tsx index 22ca2d2ba..6ebff3a01 100644 --- a/packages/app/components/permissions/PresetItem/IndividualPermissionsExpandable.tsx +++ b/packages/app/components/permissions/PresetItem/IndividualPermissionsExpandable.tsx @@ -51,8 +51,11 @@ export default IndividualPermissionsExpandable const BOX_CLASS = "permissionBox" const TOGGLE_CLASS = "permissionBoxToggle" -// TODO: make this work! const syncToggle = (ev: React.MouseEvent) => { + // Don't handle the programmatically triggered click on counterpartToggle, so we don't get into a loop + // https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted + if (!ev.isTrusted) return + const diffContainers = [ ...document.querySelectorAll(`.${DIFF_CONTAINER_CLASS}`), ] @@ -91,5 +94,6 @@ const syncToggle = (ev: React.MouseEvent) => { if (!counterpartToggle) { throw new Error("Expected to find counterpart toggle") } + counterpartToggle.click() } From 9d7e126f24adc8946a284d7cbc2bb4e1e2cf0131 Mon Sep 17 00:00:00 2001 From: Jan-Felix Date: Mon, 6 Jan 2025 15:45:37 +0100 Subject: [PATCH 4/4] collapse unmodified targets in diff view --- packages/app/components/permissions/TargetItem/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/components/permissions/TargetItem/index.tsx b/packages/app/components/permissions/TargetItem/index.tsx index c35a5045c..4be1ac606 100644 --- a/packages/app/components/permissions/TargetItem/index.tsx +++ b/packages/app/components/permissions/TargetItem/index.tsx @@ -96,7 +96,7 @@ const TargetItem: React.FC<{ diff={targetDiff === DiffFlag.Modified ? undefined : targetDiff} // we don't highlight the modified target since this would get a bit too colorful >