fix: harden token and URL handling
* fix: harden token and URL handling * test: restore full web test suite --------- Co-authored-by: batumilove <batumilove@users.noreply.github.com>
This commit is contained in:
committed by
Offending Commit
parent
6960bf4ffe
commit
5cfbae6248
@@ -24,6 +24,7 @@ import {
|
||||
isCloudInstance,
|
||||
} from "@/lib/config";
|
||||
import { COLOR } from "@/lib/constants";
|
||||
import { tokenTransportError } from "@/lib/security";
|
||||
|
||||
export type ConnectionPreset = "cloud" | "self-hosted";
|
||||
|
||||
@@ -81,6 +82,13 @@ export function SettingsForm({
|
||||
async function handleTest() {
|
||||
setChecking(true);
|
||||
setHealth({ status: "checking", message: "Connecting..." });
|
||||
const transportError = token.trim() ? tokenTransportError(baseUrl) : null;
|
||||
if (transportError) {
|
||||
setErrors({ baseUrl: transportError });
|
||||
setHealth({ status: "unreachable", message: transportError });
|
||||
setChecking(false);
|
||||
return;
|
||||
}
|
||||
const result = await checkConnection(baseUrl, token || undefined);
|
||||
setHealth(result);
|
||||
setChecking(false);
|
||||
@@ -112,6 +120,11 @@ export function SettingsForm({
|
||||
setErrors({ token: "API key is required for Honcho Cloud" });
|
||||
return;
|
||||
}
|
||||
const transportError = token.trim() ? tokenTransportError(result.data.baseUrl) : null;
|
||||
if (transportError) {
|
||||
setErrors({ baseUrl: transportError });
|
||||
return;
|
||||
}
|
||||
setErrors({});
|
||||
|
||||
let id: string;
|
||||
|
||||
@@ -13,8 +13,12 @@ import { Input } from "@/components/ui/input";
|
||||
import { Body, Muted, PageTitle, SectionHeading } from "@/components/ui/typography";
|
||||
import { useDemo } from "@/hooks/useDemo";
|
||||
import { COLOR } from "@/lib/constants";
|
||||
import { isHttpOrHttpsUrl, isSafeExternalUrl } from "@/lib/security";
|
||||
|
||||
const urlSchema = z.string().url({ message: "Must be a valid URL" });
|
||||
const urlSchema = z
|
||||
.string()
|
||||
.url({ message: "Must be a valid URL" })
|
||||
.refine(isHttpOrHttpsUrl, { message: "Webhook URL must use http or https" });
|
||||
|
||||
interface Props {
|
||||
workspaceId: string;
|
||||
@@ -50,6 +54,15 @@ export function WebhookManager({ workspaceId }: Props) {
|
||||
setTimeout(() => setTestResult(null), 5000);
|
||||
};
|
||||
|
||||
const handleOpenWebhook = async (webhookUrl: string) => {
|
||||
if (!isSafeExternalUrl(webhookUrl)) {
|
||||
setTestResult(`Blocked unsafe webhook URL: ${webhookUrl}`);
|
||||
setTimeout(() => setTestResult(null), 5000);
|
||||
return;
|
||||
}
|
||||
await open(webhookUrl);
|
||||
};
|
||||
|
||||
const list = Array.isArray(webhooks) ? webhooks : [];
|
||||
|
||||
return (
|
||||
@@ -161,7 +174,7 @@ export function WebhookManager({ workspaceId }: Props) {
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void open((wh as { url: string }).url)}
|
||||
onClick={() => void handleOpenWebhook((wh as { url: string }).url)}
|
||||
className="flex-shrink-0"
|
||||
style={{
|
||||
color: "var(--text-4)",
|
||||
|
||||
Reference in New Issue
Block a user