mirror of
https://github.com/aljazceru/goose.git
synced 2026-01-01 13:34:30 +01:00
fix issue with generating a share url and add missing url verification in settings (#3482)
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' http://127.0.0.1:* https://api.github.com https://github.com https://objects.githubusercontent.com; object-src 'none'; frame-src 'none'; font-src 'self' data: https:; media-src 'self' mediastream:; form-action 'none'; base-uri 'self'; manifest-src 'self'; worker-src 'self';" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' http://127.0.0.1:* https:; object-src 'none'; frame-src 'none'; font-src 'self' data: https:; media-src 'self' mediastream:; form-action 'none'; base-uri 'self'; manifest-src 'self'; worker-src 'self';" />
|
||||
<title>Goose</title>
|
||||
<script>
|
||||
// Initialize theme before any content loads
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Input } from '../../ui/input';
|
||||
import { Check, Lock } from 'lucide-react';
|
||||
import { Check, Lock, Loader2, AlertCircle } from 'lucide-react';
|
||||
import { Switch } from '../../ui/switch';
|
||||
import { Button } from '../../ui/button';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../ui/card';
|
||||
@@ -15,6 +15,11 @@ export default function SessionSharingSection() {
|
||||
baseUrl: typeof envBaseUrlShare === 'string' ? envBaseUrlShare : '',
|
||||
});
|
||||
const [urlError, setUrlError] = useState('');
|
||||
const [testResult, setTestResult] = useState<{
|
||||
status: 'success' | 'error' | 'testing' | null;
|
||||
message: string;
|
||||
}>({ status: null, message: '' });
|
||||
|
||||
// isUrlConfigured is true if the user has configured a baseUrl and it is valid.
|
||||
const isUrlConfigured =
|
||||
!envBaseUrlShare &&
|
||||
@@ -74,6 +79,9 @@ export default function SessionSharingSection() {
|
||||
baseUrl: newBaseUrl,
|
||||
}));
|
||||
|
||||
// Clear previous test results when URL changes
|
||||
setTestResult({ status: null, message: '' });
|
||||
|
||||
if (isValidUrl(newBaseUrl)) {
|
||||
setUrlError('');
|
||||
const updated = { ...sessionSharingConfig, baseUrl: newBaseUrl };
|
||||
@@ -83,13 +91,72 @@ export default function SessionSharingSection() {
|
||||
}
|
||||
};
|
||||
|
||||
// Test connection to the configured URL
|
||||
const testConnection = async () => {
|
||||
const baseUrl = sessionSharingConfig.baseUrl;
|
||||
if (!baseUrl) return;
|
||||
|
||||
setTestResult({ status: 'testing', message: 'Testing connection...' });
|
||||
|
||||
try {
|
||||
// Create an AbortController for timeout
|
||||
const controller = new AbortController();
|
||||
const timeoutId = window.setTimeout(() => controller.abort(), 10000); // 10 second timeout
|
||||
|
||||
const response = await fetch(baseUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
},
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
window.clearTimeout(timeoutId);
|
||||
|
||||
// Consider any response (even 404) as a successful connection
|
||||
// since it means we can reach the server
|
||||
if (response.status < 500) {
|
||||
setTestResult({
|
||||
status: 'success',
|
||||
message: `Connection successful! Server responded with status ${response.status}.`,
|
||||
});
|
||||
} else {
|
||||
setTestResult({
|
||||
status: 'error',
|
||||
message: `Server error: HTTP ${response.status}. The server may not be configured correctly.`,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Connection test failed:', error);
|
||||
let errorMessage = 'Connection failed. ';
|
||||
|
||||
if (error instanceof TypeError && error.message.includes('fetch')) {
|
||||
errorMessage +=
|
||||
'Unable to reach the server. Please check the URL and your network connection.';
|
||||
} else if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
errorMessage += 'Connection timed out. The server may be slow or unreachable.';
|
||||
} else {
|
||||
errorMessage += error.message;
|
||||
}
|
||||
} else {
|
||||
errorMessage += 'Unknown error occurred.';
|
||||
}
|
||||
|
||||
setTestResult({
|
||||
status: 'error',
|
||||
message: errorMessage,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="session-sharing" className="space-y-4 pr-4 mt-1">
|
||||
<Card className="pb-2">
|
||||
<CardHeader className="pb-0">
|
||||
<CardTitle>Session Sharing</CardTitle>
|
||||
<CardDescription>
|
||||
{envBaseUrlShare
|
||||
{(envBaseUrlShare as string)
|
||||
? 'Session sharing is configured but fully opt-in — your sessions are only shared when you explicitly click the share button.'
|
||||
: 'You can enable session sharing to share your sessions with others.'}
|
||||
</CardDescription>
|
||||
@@ -99,7 +166,7 @@ export default function SessionSharingSection() {
|
||||
{/* Toggle for enabling session sharing */}
|
||||
<div className="flex items-center gap-3">
|
||||
<label className="text-sm cursor-pointer">
|
||||
{envBaseUrlShare
|
||||
{(envBaseUrlShare as string)
|
||||
? 'Session sharing has already been configured'
|
||||
: 'Enable session sharing'}
|
||||
</label>
|
||||
@@ -136,19 +203,44 @@ export default function SessionSharingSection() {
|
||||
/>
|
||||
</div>
|
||||
{urlError && <p className="text-red-500 text-sm">{urlError}</p>}
|
||||
{isUrlConfigured && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="mt-2"
|
||||
onClick={() => {
|
||||
// Test the connection to the configured URL
|
||||
console.log('Testing connection to:', sessionSharingConfig.baseUrl);
|
||||
// TODO: Implement actual connection test
|
||||
}}
|
||||
>
|
||||
Test Connection
|
||||
</Button>
|
||||
|
||||
{(isUrlConfigured || (envBaseUrlShare as string)) && (
|
||||
<div className="space-y-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={testConnection}
|
||||
disabled={testResult.status === 'testing'}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
{testResult.status === 'testing' ? (
|
||||
<>
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
Testing...
|
||||
</>
|
||||
) : (
|
||||
'Test Connection'
|
||||
)}
|
||||
</Button>
|
||||
|
||||
{/* Test Results */}
|
||||
{testResult.status && testResult.status !== 'testing' && (
|
||||
<div
|
||||
className={`flex items-start gap-2 p-3 rounded-md text-sm ${
|
||||
testResult.status === 'success'
|
||||
? 'bg-green-50 text-green-800 border border-green-200'
|
||||
: 'bg-red-50 text-red-800 border border-red-200'
|
||||
}`}
|
||||
>
|
||||
{testResult.status === 'success' ? (
|
||||
<Check className="w-4 h-4 mt-0.5 flex-shrink-0" />
|
||||
) : (
|
||||
<AlertCircle className="w-4 h-4 mt-0.5 flex-shrink-0" />
|
||||
)}
|
||||
<span>{testResult.message}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -874,9 +874,43 @@ const openDirectoryDialog = async (
|
||||
|
||||
addRecentDir(dirToAdd);
|
||||
const currentWindow = BrowserWindow.getFocusedWindow();
|
||||
await createChat(app, undefined, dirToAdd);
|
||||
|
||||
if (replaceWindow && currentWindow) {
|
||||
// Replace current window with new one
|
||||
await createChat(app, undefined, dirToAdd);
|
||||
currentWindow.close();
|
||||
} else {
|
||||
// Update the working directory in the current window's localStorage
|
||||
if (currentWindow) {
|
||||
try {
|
||||
const updateConfigScript = `
|
||||
try {
|
||||
const currentConfig = JSON.parse(localStorage.getItem('gooseConfig') || '{}');
|
||||
const updatedConfig = {
|
||||
...currentConfig,
|
||||
GOOSE_WORKING_DIR: '${dirToAdd.replace(/'/g, "\\'")}',
|
||||
};
|
||||
localStorage.setItem('gooseConfig', JSON.stringify(updatedConfig));
|
||||
|
||||
// Trigger a config update event so the UI can refresh
|
||||
window.dispatchEvent(new CustomEvent('goose-config-updated', {
|
||||
detail: { GOOSE_WORKING_DIR: '${dirToAdd.replace(/'/g, "\\'")}' }
|
||||
}));
|
||||
} catch (e) {
|
||||
console.error('Failed to update working directory in localStorage:', e);
|
||||
}
|
||||
`;
|
||||
await currentWindow.webContents.executeJavaScript(updateConfigScript);
|
||||
console.log(`Updated working directory to: ${dirToAdd}`);
|
||||
} catch (error) {
|
||||
console.error('Failed to update working directory:', error);
|
||||
// Fallback: create new window
|
||||
await createChat(app, undefined, dirToAdd);
|
||||
}
|
||||
} else {
|
||||
// No current window, create new one
|
||||
await createChat(app, undefined, dirToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user