mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-05-17 21:27:05 +02:00
Address cookie editing PR feedback
This commit is contained in:
@@ -24,6 +24,7 @@ import { EventDetailHeader } from "./core/EventViewer";
|
|||||||
import { KeyValueRow, KeyValueRows } from "./core/KeyValueRow";
|
import { KeyValueRow, KeyValueRows } from "./core/KeyValueRow";
|
||||||
import { EmptyStateText } from "./EmptyStateText";
|
import { EmptyStateText } from "./EmptyStateText";
|
||||||
import { PlainInput } from "./core/PlainInput";
|
import { PlainInput } from "./core/PlainInput";
|
||||||
|
import { Select } from "./core/Select";
|
||||||
import { showAlert } from "../lib/alert";
|
import { showAlert } from "../lib/alert";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -38,6 +39,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
const [selectedCookieKey, setSelectedCookieKey] = useState<string | null>(null);
|
const [selectedCookieKey, setSelectedCookieKey] = useState<string | null>(null);
|
||||||
const [editingCookieKey, setEditingCookieKey] = useState<string | null>(null);
|
const [editingCookieKey, setEditingCookieKey] = useState<string | null>(null);
|
||||||
const [draftCookie, setDraftCookie] = useState<Cookie | null>(null);
|
const [draftCookie, setDraftCookie] = useState<Cookie | null>(null);
|
||||||
|
const [draftExpiresInput, setDraftExpiresInput] = useState("");
|
||||||
const filteredCookies = useMemo(() => {
|
const filteredCookies = useMemo(() => {
|
||||||
return cookieJar?.cookies.filter((cookie) => cookieMatchesFilter(cookie, filter)) ?? [];
|
return cookieJar?.cookies.filter((cookie) => cookieMatchesFilter(cookie, filter)) ?? [];
|
||||||
}, [cookieJar?.cookies, filter]);
|
}, [cookieJar?.cookies, filter]);
|
||||||
@@ -56,6 +58,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
setSelectedCookieKey(null);
|
setSelectedCookieKey(null);
|
||||||
setEditingCookieKey(NEW_COOKIE_KEY);
|
setEditingCookieKey(NEW_COOKIE_KEY);
|
||||||
setDraftCookie(newCookieDraft());
|
setDraftCookie(newCookieDraft());
|
||||||
|
setDraftExpiresInput("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditCookie = () => {
|
const handleEditCookie = () => {
|
||||||
@@ -65,6 +68,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
|
|
||||||
setEditingCookieKey(cookieKey(selectedCookie));
|
setEditingCookieKey(cookieKey(selectedCookie));
|
||||||
setDraftCookie(selectedCookie);
|
setDraftCookie(selectedCookie);
|
||||||
|
setDraftExpiresInput(cookieExpiresInputValue(selectedCookie));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancelEdit = () => {
|
const handleCancelEdit = () => {
|
||||||
@@ -73,6 +77,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
}
|
}
|
||||||
setEditingCookieKey(null);
|
setEditingCookieKey(null);
|
||||||
setDraftCookie(null);
|
setDraftCookie(null);
|
||||||
|
setDraftExpiresInput("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCloseDetails = () => {
|
const handleCloseDetails = () => {
|
||||||
@@ -89,7 +94,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextCookie = normalizeCookie(draftCookie);
|
let nextCookie = normalizeCookie(draftCookie);
|
||||||
if (nextCookie.name.trim().length === 0) {
|
if (nextCookie.name.trim().length === 0) {
|
||||||
showAlert({
|
showAlert({
|
||||||
id: "invalid-cookie-name",
|
id: "invalid-cookie-name",
|
||||||
@@ -99,6 +104,20 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextCookie.expires !== "SessionEnd") {
|
||||||
|
const expires = cookieExpiresFromInput(draftExpiresInput);
|
||||||
|
if (expires == null) {
|
||||||
|
showAlert({
|
||||||
|
id: "invalid-cookie-expires",
|
||||||
|
title: "Invalid Cookie",
|
||||||
|
body: "Cookie expiration must be a valid date.",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextCookie = { ...nextCookie, expires };
|
||||||
|
}
|
||||||
|
|
||||||
const nextCookieKey = cookieKey(nextCookie);
|
const nextCookieKey = cookieKey(nextCookie);
|
||||||
const nextCookies = cookieJar.cookies.filter((cookie) => {
|
const nextCookies = cookieJar.cookies.filter((cookie) => {
|
||||||
const key = cookieKey(cookie);
|
const key = cookieKey(cookie);
|
||||||
@@ -112,6 +131,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
setSelectedCookieKey(nextCookieKey);
|
setSelectedCookieKey(nextCookieKey);
|
||||||
setEditingCookieKey(null);
|
setEditingCookieKey(null);
|
||||||
setDraftCookie(null);
|
setDraftCookie(null);
|
||||||
|
setDraftExpiresInput("");
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cookieJar == null) {
|
if (cookieJar == null) {
|
||||||
@@ -156,6 +176,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
layout="vertical"
|
layout="vertical"
|
||||||
storageKey="cookie-dialog-details"
|
storageKey="cookie-dialog-details"
|
||||||
defaultRatio={0.65}
|
defaultRatio={0.65}
|
||||||
|
className="-mx-2"
|
||||||
minHeightPx={10}
|
minHeightPx={10}
|
||||||
firstSlot={({ style }) =>
|
firstSlot={({ style }) =>
|
||||||
filteredCookies.length === 0 ? (
|
filteredCookies.length === 0 ? (
|
||||||
@@ -163,7 +184,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
<EmptyStateText>No cookies match the current filter.</EmptyStateText>
|
<EmptyStateText>No cookies match the current filter.</EmptyStateText>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Table scrollable style={style}>
|
<Table scrollable style={style} className="pr-0.5">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHeaderCell>Name</TableHeaderCell>
|
<TableHeaderCell>Name</TableHeaderCell>
|
||||||
@@ -185,6 +206,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
setSelectedCookieKey(null);
|
setSelectedCookieKey(null);
|
||||||
setEditingCookieKey(null);
|
setEditingCookieKey(null);
|
||||||
setDraftCookie(null);
|
setDraftCookie(null);
|
||||||
|
setDraftExpiresInput("");
|
||||||
patchModel(cookieJar, { cookies: [] });
|
patchModel(cookieJar, { cookies: [] });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -208,9 +230,12 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
setSelectedCookieKey(key);
|
setSelectedCookieKey(key);
|
||||||
setEditingCookieKey(null);
|
setEditingCookieKey(null);
|
||||||
setDraftCookie(null);
|
setDraftCookie(null);
|
||||||
|
setDraftExpiresInput("");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TableCell>{c.name}</TableCell>
|
<TableCell className={classNames("pl-2", isSelected && "rounded-l")}>
|
||||||
|
{c.name}
|
||||||
|
</TableCell>
|
||||||
<TruncatedWideTableCell className="min-w-[10rem]">
|
<TruncatedWideTableCell className="min-w-[10rem]">
|
||||||
{c.value}
|
{c.value}
|
||||||
</TruncatedWideTableCell>
|
</TruncatedWideTableCell>
|
||||||
@@ -231,7 +256,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>{c.sameSite}</TableCell>
|
<TableCell>{c.sameSite}</TableCell>
|
||||||
<TableCell>
|
<TableCell className="rounded-r pr-2">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon="trash"
|
icon="trash"
|
||||||
size="xs"
|
size="xs"
|
||||||
@@ -246,6 +271,7 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
if (editingCookieKey === key) {
|
if (editingCookieKey === key) {
|
||||||
setEditingCookieKey(null);
|
setEditingCookieKey(null);
|
||||||
setDraftCookie(null);
|
setDraftCookie(null);
|
||||||
|
setDraftExpiresInput("");
|
||||||
}
|
}
|
||||||
patchModel(cookieJar, {
|
patchModel(cookieJar, {
|
||||||
cookies: cookieJar.cookies.filter(
|
cookies: cookieJar.cookies.filter(
|
||||||
@@ -298,7 +324,12 @@ export const CookieDialog = ({ cookieJarId }: Props) => {
|
|||||||
onClose={handleCloseDetails}
|
onClose={handleCloseDetails}
|
||||||
/>
|
/>
|
||||||
{isEditingCookie ? (
|
{isEditingCookie ? (
|
||||||
<CookieEditor cookie={detailCookie} onChange={setDraftCookie} />
|
<CookieEditor
|
||||||
|
cookie={detailCookie}
|
||||||
|
expiresInputValue={draftExpiresInput}
|
||||||
|
onChange={setDraftCookie}
|
||||||
|
onExpiresInputChange={setDraftExpiresInput}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CookieDetails cookie={detailCookie} />
|
<CookieDetails cookie={detailCookie} />
|
||||||
)}
|
)}
|
||||||
@@ -354,17 +385,21 @@ function CookieDetails({ cookie }: { cookie: Cookie }) {
|
|||||||
|
|
||||||
function CookieEditor({
|
function CookieEditor({
|
||||||
cookie,
|
cookie,
|
||||||
|
expiresInputValue,
|
||||||
onChange,
|
onChange,
|
||||||
|
onExpiresInputChange,
|
||||||
}: {
|
}: {
|
||||||
cookie: Cookie;
|
cookie: Cookie;
|
||||||
|
expiresInputValue: string;
|
||||||
onChange: (cookie: Cookie) => void;
|
onChange: (cookie: Cookie) => void;
|
||||||
|
onExpiresInputChange: (value: string) => void;
|
||||||
}) {
|
}) {
|
||||||
const sessionCookie = cookie.expires === "SessionEnd";
|
const sessionCookie = cookie.expires === "SessionEnd";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-y-auto">
|
<div className="overflow-y-auto">
|
||||||
<KeyValueRows>
|
<KeyValueRows>
|
||||||
<CookieKeyValueRow label="Name">
|
<CookieKeyValueRow align="middle" label="Name">
|
||||||
<CookieTextInput
|
<CookieTextInput
|
||||||
required
|
required
|
||||||
autoFocus
|
autoFocus
|
||||||
@@ -378,14 +413,14 @@ function CookieEditor({
|
|||||||
onChange={(value) => onChange({ ...cookie, value })}
|
onChange={(value) => onChange({ ...cookie, value })}
|
||||||
/>
|
/>
|
||||||
</CookieKeyValueRow>
|
</CookieKeyValueRow>
|
||||||
<CookieKeyValueRow label="Domain">
|
<CookieKeyValueRow align="middle" label="Domain">
|
||||||
<CookieTextInput
|
<CookieTextInput
|
||||||
value={cookieDomainInputValue(cookie)}
|
value={cookieDomainInputValue(cookie)}
|
||||||
placeholder="n/a"
|
placeholder="n/a"
|
||||||
onChange={(domain) => onChange(cookieWithDomain(cookie, domain))}
|
onChange={(domain) => onChange(cookieWithDomain(cookie, domain))}
|
||||||
/>
|
/>
|
||||||
</CookieKeyValueRow>
|
</CookieKeyValueRow>
|
||||||
<CookieKeyValueRow label="Path">
|
<CookieKeyValueRow align="middle" label="Path">
|
||||||
<CookieTextInput
|
<CookieTextInput
|
||||||
value={cookie.path}
|
value={cookie.path}
|
||||||
placeholder="/"
|
placeholder="/"
|
||||||
@@ -397,24 +432,40 @@ function CookieEditor({
|
|||||||
<Checkbox
|
<Checkbox
|
||||||
checked={sessionCookie}
|
checked={sessionCookie}
|
||||||
title="Session cookie"
|
title="Session cookie"
|
||||||
onChange={(checked) =>
|
onChange={(checked) => {
|
||||||
|
if (checked) {
|
||||||
|
onChange({ ...cookie, expires: "SessionEnd" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const expiresInput =
|
||||||
|
cookieExpiresFromInput(expiresInputValue) == null
|
||||||
|
? defaultCookieExpiresInputValue()
|
||||||
|
: expiresInputValue;
|
||||||
|
|
||||||
|
onExpiresInputChange(expiresInput);
|
||||||
onChange({
|
onChange({
|
||||||
...cookie,
|
...cookie,
|
||||||
expires: checked
|
expires: cookieExpiresFromInput(expiresInput)!,
|
||||||
? "SessionEnd"
|
});
|
||||||
: cookieExpiresFromInput(defaultCookieExpiresInputValue()),
|
}}
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<CookieTextInput
|
<CookieTextInput
|
||||||
value={sessionCookie ? "" : cookieExpiresInputValue(cookie)}
|
value={sessionCookie ? "" : expiresInputValue}
|
||||||
disabled={sessionCookie}
|
disabled={sessionCookie}
|
||||||
onChange={(value) => onChange({ ...cookie, expires: cookieExpiresFromInput(value) })}
|
onChange={(value) => {
|
||||||
|
onExpiresInputChange(value);
|
||||||
|
|
||||||
|
const expires = cookieExpiresFromInput(value);
|
||||||
|
if (expires != null) {
|
||||||
|
onChange({ ...cookie, expires });
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</CookieKeyValueRow>
|
</CookieKeyValueRow>
|
||||||
<CookieKeyValueRow label="Size">{cookieSize(cookie)}</CookieKeyValueRow>
|
<CookieKeyValueRow label="Size">{cookieSize(cookie)}</CookieKeyValueRow>
|
||||||
<CookieKeyValueRow label="HTTP Only">
|
<CookieKeyValueRow align="middle" label="HTTP Only">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
hideLabel
|
hideLabel
|
||||||
title="HTTP Only"
|
title="HTTP Only"
|
||||||
@@ -422,7 +473,7 @@ function CookieEditor({
|
|||||||
onChange={(httpOnly) => onChange({ ...cookie, httpOnly })}
|
onChange={(httpOnly) => onChange({ ...cookie, httpOnly })}
|
||||||
/>
|
/>
|
||||||
</CookieKeyValueRow>
|
</CookieKeyValueRow>
|
||||||
<CookieKeyValueRow label="Secure">
|
<CookieKeyValueRow align="middle" label="Secure">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
hideLabel
|
hideLabel
|
||||||
title="Secure"
|
title="Secure"
|
||||||
@@ -430,23 +481,27 @@ function CookieEditor({
|
|||||||
onChange={(secure) => onChange({ ...cookie, secure })}
|
onChange={(secure) => onChange({ ...cookie, secure })}
|
||||||
/>
|
/>
|
||||||
</CookieKeyValueRow>
|
</CookieKeyValueRow>
|
||||||
<CookieKeyValueRow label="Same Site">
|
<CookieKeyValueRow align="middle" label="Same Site">
|
||||||
<select
|
<Select
|
||||||
|
hideLabel
|
||||||
|
name="cookie-same-site"
|
||||||
|
label="Same Site"
|
||||||
value={cookie.sameSite ?? ""}
|
value={cookie.sameSite ?? ""}
|
||||||
className={cookieInputClassName}
|
size="xs"
|
||||||
onChange={(event) =>
|
className="w-full"
|
||||||
|
options={[
|
||||||
|
{ label: "n/a", value: "" },
|
||||||
|
{ label: "Lax", value: "Lax" },
|
||||||
|
{ label: "Strict", value: "Strict" },
|
||||||
|
{ label: "None", value: "None" },
|
||||||
|
]}
|
||||||
|
onChange={(sameSite) =>
|
||||||
onChange({
|
onChange({
|
||||||
...cookie,
|
...cookie,
|
||||||
sameSite:
|
sameSite: sameSite === "" ? null : (sameSite as Cookie["sameSite"]),
|
||||||
event.target.value === "" ? null : (event.target.value as Cookie["sameSite"]),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
<option value="">n/a</option>
|
|
||||||
<option value="Lax">Lax</option>
|
|
||||||
<option value="Strict">Strict</option>
|
|
||||||
<option value="None">None</option>
|
|
||||||
</select>
|
|
||||||
</CookieKeyValueRow>
|
</CookieKeyValueRow>
|
||||||
</KeyValueRows>
|
</KeyValueRows>
|
||||||
</div>
|
</div>
|
||||||
@@ -454,9 +509,7 @@ function CookieEditor({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function CookieKeyValueRow({ labelClassName, ...props }: ComponentProps<typeof KeyValueRow>) {
|
function CookieKeyValueRow({ labelClassName, ...props }: ComponentProps<typeof KeyValueRow>) {
|
||||||
return (
|
return <KeyValueRow labelClassName={classNames("w-[7rem]", labelClassName)} {...props} />;
|
||||||
<KeyValueRow labelClassName={classNames("w-[7rem] min-w-[7rem]", labelClassName)} {...props} />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function CookieTextInput({
|
function CookieTextInput({
|
||||||
@@ -581,10 +634,10 @@ function defaultCookieExpiresInputValue() {
|
|||||||
return new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();
|
return new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function cookieExpiresFromInput(value: string): Cookie["expires"] {
|
function cookieExpiresFromInput(value: string): Cookie["expires"] | null {
|
||||||
const time = new Date(value).getTime();
|
const time = new Date(value).getTime();
|
||||||
if (!Number.isFinite(time)) {
|
if (!Number.isFinite(time)) {
|
||||||
return "SessionEnd";
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { AtUtc: `${Math.floor(time / 1000)}` };
|
return { AtUtc: `${Math.floor(time / 1000)}` };
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ interface KeyValueRowProps {
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
rightSlot?: ReactNode;
|
rightSlot?: ReactNode;
|
||||||
leftSlot?: ReactNode;
|
leftSlot?: ReactNode;
|
||||||
|
align?: "top" | "middle";
|
||||||
labelClassName?: string;
|
labelClassName?: string;
|
||||||
labelColor?: "secondary" | "primary" | "info";
|
labelColor?: "secondary" | "primary" | "info";
|
||||||
enableCopy?: boolean;
|
enableCopy?: boolean;
|
||||||
@@ -45,6 +46,7 @@ export function KeyValueRow({
|
|||||||
children,
|
children,
|
||||||
rightSlot,
|
rightSlot,
|
||||||
leftSlot,
|
leftSlot,
|
||||||
|
align = "top",
|
||||||
labelColor = "secondary",
|
labelColor = "secondary",
|
||||||
labelClassName,
|
labelClassName,
|
||||||
enableCopy,
|
enableCopy,
|
||||||
@@ -69,7 +71,9 @@ export function KeyValueRow({
|
|||||||
<>
|
<>
|
||||||
<td
|
<td
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"select-none py-0.5 pr-2 h-full align-top max-w-[10rem]",
|
"select-none py-0.5 pr-2 h-full max-w-[10rem]",
|
||||||
|
align === "top" && "align-top",
|
||||||
|
align === "middle" && "align-middle",
|
||||||
labelClassName,
|
labelClassName,
|
||||||
labelColor === "primary" && "text-primary",
|
labelColor === "primary" && "text-primary",
|
||||||
labelColor === "secondary" && "text-text-subtle",
|
labelColor === "secondary" && "text-text-subtle",
|
||||||
@@ -78,7 +82,13 @@ export function KeyValueRow({
|
|||||||
>
|
>
|
||||||
<span className="select-text cursor-text">{label}</span>
|
<span className="select-text cursor-text">{label}</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="select-none py-0.5 break-all align-top max-w-[15rem]">
|
<td
|
||||||
|
className={classNames(
|
||||||
|
"select-none py-0.5 break-all max-w-[15rem]",
|
||||||
|
align === "top" && "align-top",
|
||||||
|
align === "middle" && "align-middle",
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div className="select-text cursor-text max-h-[12rem] overflow-y-auto grid grid-cols-[auto_minmax(0,1fr)_auto]">
|
<div className="select-text cursor-text max-h-[12rem] overflow-y-auto grid grid-cols-[auto_minmax(0,1fr)_auto]">
|
||||||
{leftSlot ?? <span aria-hidden />}
|
{leftSlot ?? <span aria-hidden />}
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ export function SettingRow({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SettingValue({
|
export function SettingValue({
|
||||||
actions,
|
actions,
|
||||||
className,
|
className,
|
||||||
|
|||||||
@@ -248,11 +248,16 @@ pub async fn cmd_ws_connect<R: Runtime>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add cookies to WS HTTP Upgrade
|
let mut cookie_jar =
|
||||||
if let (true, Some(id)) = (resolved_settings.send_cookies, cookie_jar_id) {
|
match (resolved_settings.send_cookies || resolved_settings.store_cookies, cookie_jar_id) {
|
||||||
let cookie_jar = app_handle.db().get_cookie_jar(&id)?;
|
(true, Some(id)) => Some(app_handle.db().get_cookie_jar(id)?),
|
||||||
let store = CookieStore::from_cookies(cookie_jar.cookies);
|
_ => None,
|
||||||
|
};
|
||||||
|
let cookie_store =
|
||||||
|
cookie_jar.as_ref().map(|jar| CookieStore::from_cookies(jar.cookies.clone()));
|
||||||
|
|
||||||
|
// Add cookies to WS HTTP Upgrade
|
||||||
|
if let (true, Some(store)) = (resolved_settings.send_cookies, cookie_store.as_ref()) {
|
||||||
// Convert WS URL -> HTTP URL because our cookie store matches based on
|
// Convert WS URL -> HTTP URL because our cookie store matches based on
|
||||||
// Path/HttpOnly/Secure attributes even though WS upgrades are HTTP requests
|
// Path/HttpOnly/Secure attributes even though WS upgrades are HTTP requests
|
||||||
let http_url = convert_ws_url_to_http(&url);
|
let http_url = convert_ws_url_to_http(&url);
|
||||||
@@ -329,6 +334,23 @@ pub async fn cmd_ws_connect<R: Runtime>(
|
|||||||
})
|
})
|
||||||
.collect::<Vec<HttpResponseHeader>>();
|
.collect::<Vec<HttpResponseHeader>>();
|
||||||
|
|
||||||
|
if let (true, Some(cookie_jar), Some(store)) =
|
||||||
|
(resolved_settings.store_cookies, cookie_jar.as_mut(), cookie_store.as_ref())
|
||||||
|
{
|
||||||
|
let set_cookie_headers = response
|
||||||
|
.headers()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|(name, _)| name.as_str().eq_ignore_ascii_case("set-cookie"))
|
||||||
|
.filter_map(|(_, value)| value.to_str().ok().map(ToString::to_string))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !set_cookie_headers.is_empty() {
|
||||||
|
store.store_cookies_from_response(&convert_ws_url_to_http(&url), &set_cookie_headers);
|
||||||
|
cookie_jar.cookies = store.get_all_cookies();
|
||||||
|
app_handle.db().upsert_cookie_jar(cookie_jar, &UpdateSource::Background)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let connection = app_handle.db().upsert_websocket_connection(
|
let connection = app_handle.db().upsert_websocket_connection(
|
||||||
&WebsocketConnection {
|
&WebsocketConnection {
|
||||||
state: WebsocketConnectionState::Connected,
|
state: WebsocketConnectionState::Connected,
|
||||||
|
|||||||
@@ -34,9 +34,13 @@ export function TableBody({ children, className }: { children: ReactNode; classN
|
|||||||
<tbody
|
<tbody
|
||||||
className={classNames(
|
className={classNames(
|
||||||
className,
|
className,
|
||||||
"[&>tr:not(:last-child)>td]:border-b [&>tr:not(:last-child)>td]:border-b-surface-highlight",
|
"[&>tr:not(:last-child):not([data-table-spacer])>td]:border-b",
|
||||||
|
"[&>tr:not(:last-child):not([data-table-spacer])>td]:border-b-surface-highlight",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
<tr aria-hidden data-table-spacer className="h-0.5">
|
||||||
|
<td className="p-0" colSpan={1000} />
|
||||||
|
</tr>
|
||||||
{children}
|
{children}
|
||||||
</tbody>
|
</tbody>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user