chore: fix

This commit is contained in:
Lluis Agusti
2025-07-03 13:40:52 +04:00
parent f1cc2afbda
commit bed812d7a5
2 changed files with 86 additions and 32 deletions

View File

@@ -1,23 +1,5 @@
import { FC, useEffect, useMemo, useState } from "react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import SchemaTooltip from "@/components/SchemaTooltip";
import useCredentials from "@/hooks/useCredentials";
import { NotionLogoIcon } from "@radix-ui/react-icons";
import {
FaDiscord,
FaGithub,
FaTwitter,
FaGoogle,
FaMedium,
FaKey,
FaHubspot,
} from "react-icons/fa";
import {
BlockIOCredentialsSubSchema,
CredentialsMetaInput,
CredentialsProviderName,
} from "@/lib/autogpt-server-api/types";
import { Button } from "@/components/ui/button";
import { IconKey, IconKeyPlus, IconUserPlus } from "@/components/ui/icons";
import {
Select,
@@ -27,12 +9,30 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import useCredentials from "@/hooks/useCredentials";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import {
BlockIOCredentialsSubSchema,
CredentialsMetaInput,
CredentialsProviderName,
} from "@/lib/autogpt-server-api/types";
import { cn } from "@/lib/utils";
import { getHostFromUrl } from "@/lib/utils/url";
import { NotionLogoIcon } from "@radix-ui/react-icons";
import { FC, useEffect, useMemo, useState } from "react";
import {
FaDiscord,
FaGithub,
FaGoogle,
FaHubspot,
FaKey,
FaMedium,
FaTwitter,
} from "react-icons/fa";
import { APIKeyCredentialsModal } from "./api-key-credentials-modal";
import { UserPasswordCredentialsModal } from "./user-password-credentials-modal";
import { HostScopedCredentialsModal } from "./host-scoped-credentials-modal";
import { OAuth2FlowWaitingModal } from "./oauth2-flow-waiting-modal";
import { getHostFromUrl } from "@/lib/utils/url";
import { UserPasswordCredentialsModal } from "./user-password-credentials-modal";
const fallbackIcon = FaKey;

View File

@@ -2,7 +2,6 @@ import { getWebSocketToken } from "@/lib/supabase/actions";
import { getServerSupabase } from "@/lib/supabase/server/getServerSupabase";
import { createBrowserClient } from "@supabase/ssr";
import type { SupabaseClient } from "@supabase/supabase-js";
import { proxyApiRequest, proxyFileUpload } from "./proxy-action";
import type {
AddUserCreditsResponse,
AnalyticsDetails,
@@ -27,6 +26,7 @@ import type {
GraphID,
GraphMeta,
GraphUpdateable,
HostScopedCredentials,
LibraryAgent,
LibraryAgentID,
LibraryAgentPreset,
@@ -62,12 +62,23 @@ import type {
User,
UserOnboarding,
UserPasswordCredentials,
HostScopedCredentials,
UsersBalanceHistoryResponse,
} from "./types";
const isClient = typeof window !== "undefined";
class ApiError extends Error {
public status: number;
public response?: any;
constructor(message: string, status: number, response?: any) {
super(message);
this.name = "ApiError";
this.status = status;
this.response = response;
}
}
export default class BackendAPI {
private baseUrl: string;
private wsUrl: string;
@@ -521,8 +532,6 @@ export default class BackendAPI {
}
uploadStoreSubmissionMedia(file: File): Promise<string> {
const formData = new FormData();
formData.append("file", file);
return this._uploadFile("/store/submissions/media", file);
}
@@ -813,8 +822,29 @@ export default class BackendAPI {
const formData = new FormData();
formData.append("file", file);
// Use proxy server action for secure file upload
return await proxyFileUpload(path, formData, this.baseUrl);
// Use existing proxy route with form data
// The existing proxy removes /api from base URL, so we need to add it back
const uploadUrl = `/api/proxy/api${path}`;
const response = await fetch(uploadUrl, {
method: "POST",
body: formData,
credentials: "include", // Include cookies for authentication
});
if (!response.ok) {
const errorData = await response
.json()
.catch(() => ({ error: response.statusText }));
throw new ApiError(
errorData.error || "Upload failed",
response.status,
errorData,
);
}
// Return the response as text (typically a URL)
return await response.text();
}
private async _request(
@@ -826,13 +856,37 @@ export default class BackendAPI {
console.debug(`${method} ${path} payload:`, payload);
}
// Always use proxy server action to not expose any auth tokens to the browser
return await proxyApiRequest({
// Build URL with query params for GET/DELETE requests
// The existing proxy removes /api from base URL, so we need to add it back
let url = `/api/proxy/api${path}`;
const payloadAsQuery = ["GET", "DELETE"].includes(method);
if (payloadAsQuery && payload) {
const queryParams = new URLSearchParams(payload);
url += `?${queryParams.toString()}`;
}
const response = await fetch(url, {
method,
path,
payload,
baseUrl: this.baseUrl,
headers: {
"Content-Type": "application/json",
},
body: !payloadAsQuery && payload ? JSON.stringify(payload) : undefined,
credentials: "include", // Include cookies for authentication
});
if (!response.ok) {
const errorData = await response
.json()
.catch(() => ({ error: response.statusText }));
throw new ApiError(
errorData.error || "Request failed",
response.status,
errorData,
);
}
return await response.json();
}
////////////////////////////////////////