diff --git a/src/lib/navigation/record-presentation.ts b/src/lib/navigation/record-presentation.ts index 3922c0243..b9d0f378b 100644 --- a/src/lib/navigation/record-presentation.ts +++ b/src/lib/navigation/record-presentation.ts @@ -18,6 +18,21 @@ export interface RecordPresentation { export function resolveRecordPresentation( entry: Pick, ): RecordPresentation { + const validRecordKind = + entry.recordKind === "shared" || entry.recordKind === "managed"; + const validAccess = + (entry.level === "read" && entry.canWrite === false) || + ((entry.level === "write" || entry.level === "manage") && + entry.canWrite === true); + + // `parseAccountAccess` normally makes this branch unreachable. Keep the + // presentation boundary defensive anyway: a stale cache or an untyped + // consumer must never turn contradictory data into a stronger affordance or + // claim that the browser is inside somebody else's record. + if (!validRecordKind || !validAccess) { + return { access: "view", recordKind: "self" }; + } + return { access: entry.level === "manage"