




























@@ -12,7 +12,7 @@ import {
1212} from "./agent.shared.js";
1313import { readRouteFiniteNumber } from "./route-numeric.js";
1414import type { BrowserRequest, BrowserResponse, BrowserRouteRegistrar } from "./types.js";
15-import { asyncBrowserRoute, jsonError, toBoolean, toNumber, toStringOrEmpty } from "./utils.js";
15+import { asyncBrowserRoute, jsonError, toBoolean, toStringOrEmpty } from "./utils.js";
16161717type StorageKind = "local" | "session";
1818@@ -24,6 +24,18 @@ type GeolocationOptions = {
2424origin?: string;
2525};
262627+type CookieSetOptions = {
28+name: string;
29+value: string;
30+url?: string;
31+domain?: string;
32+path?: string;
33+expires?: number;
34+httpOnly?: boolean;
35+secure?: boolean;
36+sameSite?: "Lax" | "None" | "Strict";
37+};
38+2739export function parseStorageKind(raw: string): StorageKind | null {
2840if (raw === "local" || raw === "session") {
2941return raw;
@@ -92,6 +104,30 @@ function assertRange(
92104return value;
93105}
94106107+function readOptionalRouteFiniteNumber(value: unknown, fieldName: string): number | undefined {
108+if (typeof value === "string" && value.trim() === "") {
109+return undefined;
110+}
111+return readRouteFiniteNumber(value, fieldName);
112+}
113+114+export function parseCookieSetOptions(cookie: Record<string, unknown>): CookieSetOptions {
115+return {
116+name: toStringOrEmpty(cookie.name),
117+value: toStringOrEmpty(cookie.value),
118+url: toStringOrEmpty(cookie.url) || undefined,
119+domain: toStringOrEmpty(cookie.domain) || undefined,
120+path: toStringOrEmpty(cookie.path) || undefined,
121+expires: readOptionalRouteFiniteNumber(cookie.expires, "cookie.expires"),
122+httpOnly: toBoolean(cookie.httpOnly) ?? undefined,
123+secure: toBoolean(cookie.secure) ?? undefined,
124+sameSite:
125+cookie.sameSite === "Lax" || cookie.sameSite === "None" || cookie.sameSite === "Strict"
126+ ? cookie.sameSite
127+ : undefined,
128+};
129+}
130+95131export function parseGeolocationOptions(body: Record<string, unknown>): GeolocationOptions {
96132const clear = toBoolean(body.clear) ?? false;
97133const origin = toStringOrEmpty(body.origin) || undefined;
@@ -158,6 +194,12 @@ export function registerBrowserAgentStorageRoutes(
158194if (!cookie) {
159195return jsonError(res, 400, "cookie is required");
160196}
197+let parsedCookie: CookieSetOptions;
198+try {
199+parsedCookie = parseCookieSetOptions(cookie);
200+} catch (err) {
201+return jsonError(res, 400, formatErrorMessage(err));
202+}
161203162204// Intentional: mutation routes are outside the tab-scoped read/export guard scope.
163205await withPlaywrightRouteContext({
@@ -170,22 +212,7 @@ export function registerBrowserAgentStorageRoutes(
170212await pw.cookiesSetViaPlaywright({
171213 cdpUrl,
172214targetId: tab.targetId,
173-cookie: {
174-name: toStringOrEmpty(cookie.name),
175-value: toStringOrEmpty(cookie.value),
176-url: toStringOrEmpty(cookie.url) || undefined,
177-domain: toStringOrEmpty(cookie.domain) || undefined,
178-path: toStringOrEmpty(cookie.path) || undefined,
179-expires: toNumber(cookie.expires) ?? undefined,
180-httpOnly: toBoolean(cookie.httpOnly) ?? undefined,
181-secure: toBoolean(cookie.secure) ?? undefined,
182-sameSite:
183-cookie.sameSite === "Lax" ||
184-cookie.sameSite === "None" ||
185-cookie.sameSite === "Strict"
186- ? cookie.sameSite
187- : undefined,
188-},
215+cookie: parsedCookie,
189216});
190217res.json({ ok: true, targetId: tab.targetId });
191218},
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。