Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions src/react/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -904,8 +904,17 @@ async function resolveSourceUrl(
throw new Error("cannot resolve source URL from input");
}

/** Get the varg gateway client settings. */
function getGatewayConfig(): { apiKey: string; baseUrl: string } | null {
/** Get the varg gateway client settings.
* Checks for `_gateway` injected by `varg.slice()` / `varg.probe()` / `varg.ffmpeg()`
* first, then falls back to `process.env.VARG_API_KEY` for local CLI usage.
*/
function getGatewayConfig(
props?: Record<string, unknown>,
): { apiKey: string; baseUrl: string } | null {
if (props?._gateway) {
const gw = props._gateway as { apiKey: string; baseUrl: string };
if (gw.apiKey) return gw;
}
Comment on lines +914 to +917
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

don’t silently fall back when _gateway exists but is invalid

right now, _gateway being present but malformed still drops to env auth. that breaks the “fallback only when _gateway is absent” behavior and can route jobs with unintended creds.

suggested diff
 function getGatewayConfig(
   props?: Record<string, unknown>,
 ): { apiKey: string; baseUrl: string } | null {
-  if (props?._gateway) {
-    const gw = props._gateway as { apiKey: string; baseUrl: string };
-    if (gw.apiKey) return gw;
+  if (props?._gateway) {
+    const gw = props._gateway as { apiKey: string; baseUrl: string };
+    if (!gw.apiKey || !gw.baseUrl) {
+      throw new Error("invalid _gateway config: apiKey and baseUrl are required");
+    }
+    return gw;
   }
   const apiKey = process.env.VARG_API_KEY;

Also applies to: 918-923

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/react/resolve.ts` around lines 914 - 917, The current check silently
falls back to env auth when props._gateway is present but malformed; update the
logic in resolve.ts (the block that reads props?._gateway and the similar block
around lines 918-923) to validate the gateway shape (e.g., ensure gw.apiKey and
gw.baseUrl are present and valid) and, if props._gateway exists but is invalid,
throw a clear error (or return a validation failure) instead of falling back to
environment credentials; reference the gw variable and the props._gateway checks
so you alter those branches to enforce strict validation and fail-fast on
malformed gateway objects.

const apiKey = process.env.VARG_API_KEY;
if (!apiKey) return null;
return {
Expand All @@ -918,8 +927,9 @@ function getGatewayConfig(): { apiKey: string; baseUrl: string } | null {
async function gatewayJobRequest(
path: string,
body: Record<string, unknown>,
props?: Record<string, unknown>,
): Promise<Record<string, unknown>> {
const config = getGatewayConfig();
const config = getGatewayConfig(props);
if (!config) throw new Error("VARG_API_KEY not set");

const submitRes = await fetch(`${config.baseUrl}/v1${path}`, {
Expand Down Expand Up @@ -982,7 +992,11 @@ export async function resolveSliceElement(
if (props.count !== undefined) body.count = props.count;
if (props.ranges !== undefined) body.ranges = props.ranges;

const result = await gatewayJobRequest("/ffmpeg/slice", body);
const result = await gatewayJobRequest(
"/ffmpeg/slice",
body,
props as unknown as Record<string, unknown>,
);
const output = result.output as
| { url?: string; metadata?: Record<string, unknown> }
| undefined;
Expand Down Expand Up @@ -1052,11 +1066,15 @@ export async function resolveFFmpegElement(
? "OUTPUT_FOLDER"
: { out_1: "output.mp4" };

const result = await gatewayJobRequest("/ffmpeg", {
command,
input_files: inputFiles,
output_files: outputFiles,
});
const result = await gatewayJobRequest(
"/ffmpeg",
{
command,
input_files: inputFiles,
output_files: outputFiles,
},
props as unknown as Record<string, unknown>,
);

const output = result.output as
| { url?: string; media_type?: string }
Expand All @@ -1079,7 +1097,7 @@ export async function resolveProbeElement(
): Promise<ResolvedElement<"probe">> {
const srcUrl = await resolveSourceUrl(props.src);

const config = getGatewayConfig();
const config = getGatewayConfig(props as unknown as Record<string, unknown>);
if (!config) throw new Error("VARG_API_KEY not set");

const res = await fetch(`${config.baseUrl}/v1/ffmpeg/probe`, {
Expand Down
6 changes: 6 additions & 0 deletions src/react/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,8 @@ export interface SliceProps {
count?: number;
/** Split at explicit time ranges */
ranges?: Array<{ start: number; end: number }>;
/** @internal Gateway config injected by varg.slice() for cloud auth. */
_gateway?: { apiKey: string; baseUrl: string };
}

export interface FFmpegProps {
Expand All @@ -428,11 +430,15 @@ export interface FFmpegProps {
inputs?: Record<string, string | File | VargElement>;
/** FFmpeg command flags (without -i input, which is added automatically for src) */
command: string;
/** @internal Gateway config injected by varg.ffmpeg() for cloud auth. */
_gateway?: { apiKey: string; baseUrl: string };
}

export interface ProbeProps {
/** Source to probe: URL string, File object, or ResolvedElement */
src: string | File | VargElement;
/** @internal Gateway config injected by varg.probe() for cloud auth. */
_gateway?: { apiKey: string; baseUrl: string };
}

/**
Expand Down
Loading