| 285 | * (same-owner connects, or sessions written before this field), so `complete` |
| 286 | * falls back to the session owner. */ |
| 287 | const clientOwnerFromPayload = (payload: unknown): Owner | null => { |
| 288 | const decoded = |
| 289 | typeof payload === "string" |
| 290 | ? decodeJsonPayload(payload).pipe(Option.getOrElse(() => payload)) |
| 291 | : payload; |
| 292 | if (decoded === null || typeof decoded !== "object") return null; |
| 293 | const value = (decoded as Record<string, unknown>).clientOwner; |
| 294 | return value === "user" || value === "org" ? value : null; |
| 295 | }; |
| 296 | |
| 297 | /** Narrow a stored `grant` string to the `OAuthGrant` union, or `null` when the |
| 298 | * value is neither known grant. EXPLICIT — there is no silent fallback to |