History

Parse auth profile and ref hint tables safely

Rhys Sullivan committed 8 months ago

Commit b11f3f21 parent f6c35902 files · +16 −5Browse files

Unified · Split

2 files
  1. executor/apps/web/src/lib/convex-provider.tsx +6 −2
  2. executor/packages/database/src/runtime/workspace_tools.ts +10 −3
executor/apps/web/src/lib/convex-provider.tsx+6−2
@@ -2,6 +2,7 @@ · 1 unmodified line
2 2
3import { createContext, useCallback, useContext, useMemo } from "react";3import { createContext, useCallback, useContext, useMemo } from "react";
4import { ConvexProviderWithAuth } from "convex/react";4import { ConvexProviderWithAuth } from "convex/react";
5import { z } from "zod";
5import {6import {
6 AuthKitProvider,7 AuthKitProvider,
7 useAccessToken,8 useAccessToken,
@@ -36,6 +37,8 @@ type WorkosAuthProfile = { · 28 unmodified lines
36 avatarUrl?: string | null;37 avatarUrl?: string | null;
37};38};
38 39
40const recordSchema = z.record(z.unknown());
41
39function readNonEmptyString(value: unknown): string | undefined {42function readNonEmptyString(value: unknown): string | undefined {
40 if (typeof value !== "string") {43 if (typeof value !== "string") {
41 return undefined;44 return undefined;
@@ -57,11 +60,12 @@ function getRecordString(record: Record<string, unknown>, keys: string[]): strin · 15 unmodified lines
57}60}
58 61
59function buildWorkosAuthProfile(user: unknown): WorkosAuthProfile | null {62function buildWorkosAuthProfile(user: unknown): WorkosAuthProfile | null {
60 if (!user || typeof user !== "object") {63 const parsedUser = recordSchema.safeParse(user);
64 if (!parsedUser.success) {
61 return null;65 return null;
62 }66 }
63 67
64 const userRecord = user as Record<string, unknown>;68 const userRecord = parsedUser.data;
65 const firstName = getRecordString(userRecord, ["firstName", "first_name", "givenName", "given_name"]);69 const firstName = getRecordString(userRecord, ["firstName", "first_name", "givenName", "given_name"]);
66 const lastName = getRecordString(userRecord, ["lastName", "last_name", "familyName", "family_name"]);70 const lastName = getRecordString(userRecord, ["lastName", "last_name", "familyName", "family_name"]);
67 const combinedName = [firstName, lastName].filter(Boolean).join(" ").trim();71 const combinedName = [firstName, lastName].filter(Boolean).join(" ").trim();
executor/packages/database/src/runtime/workspace_tools.ts+10−3
@@ -255,12 +255,19 @@ function buildBoundedOpenApiRefHintTables( · 254 unmodified lines
255 let remainingBudget = MAX_REF_HINT_METADATA_BYTES;255 let remainingBudget = MAX_REF_HINT_METADATA_BYTES;
256 256
257 const tables = externalArtifacts257 const tables = externalArtifacts
258 .filter((artifact) => typeof artifact.openApiSourceKey === "string" && typeof artifact.openApiRefHintTable === "object")258 .filter(
259 (
260 artifact,
261 ): artifact is CompiledToolSourceArtifact & { openApiSourceKey: string; openApiRefHintTable: Record<string, string> } => (
262 typeof artifact.openApiSourceKey === "string"
263 && artifact.openApiRefHintTable !== undefined
264 ),
265 )
259 .map((artifact) => {266 .map((artifact) => {
260 const sourceKey = artifact.openApiSourceKey!;267 const sourceKey = artifact.openApiSourceKey;
261 const refs: Array<{ key: string; hint: string }> = [];268 const refs: Array<{ key: string; hint: string }> = [];
262 269
263 const rawEntries = Object.entries(artifact.openApiRefHintTable ?? {})270 const rawEntries = Object.entries(artifact.openApiRefHintTable)
264 .filter((entry): entry is [string, string] => typeof entry[0] === "string" && typeof entry[1] === "string");271 .filter((entry): entry is [string, string] => typeof entry[0] === "string" && typeof entry[1] === "string");
265 272
266 for (const [key, rawHint] of rawEntries) {273 for (const [key, rawHint] of rawEntries) {