-
Notifications
You must be signed in to change notification settings - Fork 18
migrate(chat): repoint /api/upload to recoup-api #1740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: test
Are you sure you want to change the base?
Changes from all commits
080e3f1
28b2ce5
889363c
e1241fe
d72cd0e
6c7e1c7
fd320a5
23e9e23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -6,10 +6,7 @@ import { Download } from "lucide-react"; | |||||
|
|
||||||
| export interface TxtFileGenerationResult { | ||||||
| success: boolean; | ||||||
| arweaveUrl: string | null; | ||||||
| smartAccountAddress?: string; | ||||||
| transactionHash?: string | null; | ||||||
| blockExplorerUrl?: string | null; | ||||||
| txtUrl: string | null; | ||||||
| message?: string; | ||||||
| error?: string; | ||||||
| } | ||||||
|
|
@@ -24,12 +21,12 @@ export function TxtFileResult({ result }: TxtFileResultProps) { | |||||
| const [fetchError, setFetchError] = useState<string | null>(null); | ||||||
|
|
||||||
| useEffect(() => { | ||||||
| if (result.arweaveUrl && !fileContent) { | ||||||
| if (result.txtUrl && !fileContent) { | ||||||
| setLoading(true); | ||||||
| setFetchError(null); | ||||||
| fetch(result.arweaveUrl) | ||||||
| fetch(result.txtUrl) | ||||||
| .then((res) => { | ||||||
| if (!res.ok) throw new Error("Failed to fetch file from Arweave"); | ||||||
| if (!res.ok) throw new Error("Failed to fetch file"); | ||||||
| return res.text(); | ||||||
| }) | ||||||
| .then((text) => { | ||||||
|
|
@@ -42,7 +39,7 @@ export function TxtFileResult({ result }: TxtFileResultProps) { | |||||
| }); | ||||||
| } | ||||||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||||||
| }, [result.arweaveUrl]); | ||||||
| }, [result.txtUrl]); | ||||||
|
|
||||||
| if (!result.success) { | ||||||
| return ( | ||||||
|
|
@@ -60,13 +57,13 @@ export function TxtFileResult({ result }: TxtFileResultProps) { | |||||
| } | ||||||
|
|
||||||
| const handleDownload = () => { | ||||||
| if (result.arweaveUrl) { | ||||||
| window.open(result.arweaveUrl, "_blank"); | ||||||
| if (result.txtUrl) { | ||||||
| window.open(result.txtUrl, "_blank"); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Use Prompt for AI agents
Suggested change
|
||||||
| } | ||||||
|
Comment on lines
+60
to
62
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Inspect the reported file around the target lines
echo "== TxtFileResult.tsx (around lines 40-90) =="
sed -n '40,90p' components/ui/TxtFileResult.tsx | cat -n
echo
echo "== Search for window.open in the repo (limit output) =="
rg -n "window\.open\(" --glob='**/*.{ts,tsx,js,jsx}' -S . || true
echo
echo "== Search for noopener/noreferrer usage patterns =="
rg -n "noopener|noreferrer" --glob='**/*.{ts,tsx,js,jsx}' -S components . || trueRepository: recoupable/chat Length of output: 6895 Harden external
💡 Proposed fix- window.open(result.txtUrl, "_blank");
+ window.open(result.txtUrl, "_blank", "noopener,noreferrer");Also found an unprotected 🤖 Prompt for AI Agents |
||||||
| }; | ||||||
|
|
||||||
| let displayText: string | JSX.Element = "TXT file generated."; | ||||||
| if (result.arweaveUrl) { | ||||||
| if (result.txtUrl) { | ||||||
| if (loading) { | ||||||
| displayText = "Loading file contents..."; | ||||||
| } else if (fetchError) { | ||||||
|
|
@@ -88,7 +85,7 @@ export function TxtFileResult({ result }: TxtFileResultProps) { | |||||
| variant="outline" | ||||||
| size="sm" | ||||||
| onClick={handleDownload} | ||||||
| disabled={!result.arweaveUrl} | ||||||
| disabled={!result.txtUrl} | ||||||
| className="h-8 px-3 text-xs rounded-xl ml-auto" | ||||||
| > | ||||||
| <Download className="w-4 h-4" />{" "} | ||||||
|
|
@@ -101,7 +98,7 @@ export function TxtFileResult({ result }: TxtFileResultProps) { | |||||
| <div | ||||||
| className={cn( | ||||||
| "mb-4 whitespace-pre-wrap font-mono text-sm p-3 bg-muted/50 rounded-md overflow-auto", | ||||||
| "max-h-[200px] md:max-h-[400px] scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-gray-300 dark:scrollbar-thumb-gray-600" | ||||||
| "max-h-[200px] md:max-h-[400px] scrollbar-thin scrollbar-thumb-rounded scrollbar-thumb-gray-300 dark:scrollbar-thumb-gray-600", | ||||||
| )} | ||||||
| style={{ | ||||||
| transition: "max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1)", | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import { useState, useEffect, useRef, useCallback } from "react"; | ||
| import { useQueryClient } from "@tanstack/react-query"; | ||
| import { uploadFile } from "@/lib/arweave/uploadFile"; | ||
| import { uploadFile } from "@/lib/files/uploadFile"; | ||
| import { getFileMimeType } from "@/utils/getFileMimeType"; | ||
| import { getClientApiBaseUrl } from "@/lib/api/getClientApiBaseUrl"; | ||
| import useAccountOrganizations from "./useAccountOrganizations"; | ||
|
|
@@ -50,7 +50,7 @@ const useOrgSettings = (orgId: string | null) => { | |
|
|
||
| // Find the organization from the list (same as button does) | ||
| const selectedOrg = organizations.find( | ||
| (org) => org.organization_id === orgId | ||
| (org) => org.organization_id === orgId, | ||
| ); | ||
|
|
||
| if (!selectedOrg) { | ||
|
|
@@ -67,7 +67,7 @@ const useOrgSettings = (orgId: string | null) => { | |
| setIsLoading(true); | ||
| try { | ||
| const response = await fetch( | ||
| `${getClientApiBaseUrl()}/api/accounts/${orgId}` | ||
| `${getClientApiBaseUrl()}/api/accounts/${orgId}`, | ||
| ); | ||
| if (response.ok) { | ||
| const data = await response.json(); | ||
|
|
@@ -94,13 +94,14 @@ const useOrgSettings = (orgId: string | null) => { | |
|
|
||
| setImageUploading(true); | ||
| try { | ||
| const { uri } = await uploadFile(file); | ||
| const accessToken = await getAccessToken(); | ||
| const { uri } = await uploadFile(file, accessToken); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Handle the null-token case before uploading knowledges to avoid throwing from Prompt for AI agents |
||
| setImage(uri); | ||
| } finally { | ||
| setImageUploading(false); | ||
| } | ||
| }, | ||
| [] | ||
| [getAccessToken], | ||
| ); | ||
|
|
||
| const removeImage = useCallback(() => { | ||
|
|
@@ -118,10 +119,11 @@ const useOrgSettings = (orgId: string | null) => { | |
| setKnowledgeUploading(true); | ||
| const newKnowledges: KnowledgeItem[] = []; | ||
| try { | ||
| const accessToken = await getAccessToken(); | ||
| for (const file of files) { | ||
| const name = file.name; | ||
| const type = getFileMimeType(file); | ||
| const { uri } = await uploadFile(file); | ||
| const { uri } = await uploadFile(file, accessToken); | ||
| newKnowledges.push({ name, url: uri, type }); | ||
| } | ||
| setKnowledges((prev) => [...prev, ...newKnowledges]); | ||
|
|
@@ -132,7 +134,7 @@ const useOrgSettings = (orgId: string | null) => { | |
| } | ||
| } | ||
| }, | ||
| [] | ||
| [getAccessToken], | ||
| ); | ||
|
|
||
| const handleDeleteKnowledge = useCallback((index: number) => { | ||
|
|
@@ -158,12 +160,22 @@ const useOrgSettings = (orgId: string | null) => { | |
| knowledges, | ||
| }); | ||
| setOrgData(data); | ||
| await queryClient.invalidateQueries({ queryKey: ["accountOrganizations"] }); | ||
| await queryClient.invalidateQueries({ | ||
| queryKey: ["accountOrganizations"], | ||
| }); | ||
| return true; | ||
| } finally { | ||
| setIsSaving(false); | ||
| } | ||
| }, [orgId, name, image, instruction, knowledges, queryClient, getAccessToken]); | ||
| }, [ | ||
| orgId, | ||
| name, | ||
| image, | ||
| instruction, | ||
| knowledges, | ||
| queryClient, | ||
| getAccessToken, | ||
| ]); | ||
|
|
||
| return { | ||
| orgData, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: A new
txtUrlcan be ignored because the fetch is blocked when priorfileContentexists, causing stale file preview data.Prompt for AI agents