gpt-engineer-app[bot] commited on
Commit
f83a0e8
·
1 Parent(s): 1c1086c
Files changed (1) hide show
  1. src/server/forensic.functions.ts +10 -2
src/server/forensic.functions.ts CHANGED
@@ -119,6 +119,7 @@ const ConnectSchema = z.object({
119
  });
120
 
121
  export const testVehicleConnection = createServerFn({ method: "POST" })
 
122
  .inputValidator((d: unknown) => ConnectSchema.parse(d))
123
  .handler(async ({ data }) => {
124
  const results: Record<string, any> = {};
@@ -126,6 +127,7 @@ export const testVehicleConnection = createServerFn({ method: "POST" })
126
 
127
  if (data.manifestUrl) {
128
  try {
 
129
  const url = `${data.manifestUrl.replace(/\/$/, "")}/vehicles/${encodeURIComponent(data.vehicleId)}/manifest`;
130
  const res = await fetch(url, { signal: AbortSignal.timeout(8000) });
131
  results.manifestReachable = res.ok;
@@ -133,8 +135,11 @@ export const testVehicleConnection = createServerFn({ method: "POST" })
133
  if (res.ok) {
134
  const m = await res.json().catch(() => null);
135
  if (m && typeof m === "object") {
136
- results.deployedCommit = (m as any).commit ?? null;
137
- results.branch = (m as any).branch ?? null;
 
 
 
138
  }
139
  }
140
  } catch (e) {
@@ -174,6 +179,7 @@ const FetchSchema = z.object({
174
  });
175
 
176
  export const fetchVehicleCode = createServerFn({ method: "POST" })
 
177
  .inputValidator((d: unknown) => FetchSchema.parse(d))
178
  .handler(async ({ data }): Promise<FetchedCode> => {
179
  const warnings: string[] = [];
@@ -184,6 +190,7 @@ export const fetchVehicleCode = createServerFn({ method: "POST" })
184
  // Strategy 1: manifest endpoint
185
  if (!commit && data.manifestUrl) {
186
  try {
 
187
  const url = `${data.manifestUrl.replace(/\/$/, "")}/vehicles/${encodeURIComponent(data.vehicleId)}/manifest`;
188
  const r = await fetch(url, { signal: AbortSignal.timeout(8000) });
189
  if (r.ok) {
@@ -453,6 +460,7 @@ function deepRestore(value: any, rev: Map<string, string>): any {
453
  }
454
 
455
  export const runForensicStage = createServerFn({ method: "POST" })
 
456
  .inputValidator((d: unknown) => StageInput.parse(d))
457
  .handler(async ({ data }): Promise<{ result: StageResult; sanitizationStats: { identifiersTokenized: number; commentsStripped: number; secretsBlocked: number } }> => {
458
  const apiKey = process.env.LOVABLE_API_KEY;
 
119
  });
120
 
121
  export const testVehicleConnection = createServerFn({ method: "POST" })
122
+ .middleware([requireSupabaseAuth])
123
  .inputValidator((d: unknown) => ConnectSchema.parse(d))
124
  .handler(async ({ data }) => {
125
  const results: Record<string, any> = {};
 
127
 
128
  if (data.manifestUrl) {
129
  try {
130
+ assertSafePublicUrl(data.manifestUrl);
131
  const url = `${data.manifestUrl.replace(/\/$/, "")}/vehicles/${encodeURIComponent(data.vehicleId)}/manifest`;
132
  const res = await fetch(url, { signal: AbortSignal.timeout(8000) });
133
  results.manifestReachable = res.ok;
 
135
  if (res.ok) {
136
  const m = await res.json().catch(() => null);
137
  if (m && typeof m === "object") {
138
+ // Only reflect known typed fields back to caller
139
+ const commit = (m as any).commit;
140
+ const branch = (m as any).branch;
141
+ results.deployedCommit = typeof commit === "string" ? commit.slice(0, 80) : null;
142
+ results.branch = typeof branch === "string" ? branch.slice(0, 80) : null;
143
  }
144
  }
145
  } catch (e) {
 
179
  });
180
 
181
  export const fetchVehicleCode = createServerFn({ method: "POST" })
182
+ .middleware([requireSupabaseAuth])
183
  .inputValidator((d: unknown) => FetchSchema.parse(d))
184
  .handler(async ({ data }): Promise<FetchedCode> => {
185
  const warnings: string[] = [];
 
190
  // Strategy 1: manifest endpoint
191
  if (!commit && data.manifestUrl) {
192
  try {
193
+ assertSafePublicUrl(data.manifestUrl);
194
  const url = `${data.manifestUrl.replace(/\/$/, "")}/vehicles/${encodeURIComponent(data.vehicleId)}/manifest`;
195
  const r = await fetch(url, { signal: AbortSignal.timeout(8000) });
196
  if (r.ok) {
 
460
  }
461
 
462
  export const runForensicStage = createServerFn({ method: "POST" })
463
+ .middleware([requireSupabaseAuth])
464
  .inputValidator((d: unknown) => StageInput.parse(d))
465
  .handler(async ({ data }): Promise<{ result: StageResult; sanitizationStats: { identifiersTokenized: number; commentsStripped: number; secretsBlocked: number } }> => {
466
  const apiKey = process.env.LOVABLE_API_KEY;