mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-11 09:55:59 +00:00
Avoid password autofill for channel secrets
This commit is contained in:
@@ -1,7 +1,13 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { LoaderCircleIcon } from "lucide-react";
|
import { LoaderCircleIcon } from "lucide-react";
|
||||||
import { type FormEvent, useEffect, useMemo, useState } from "react";
|
import {
|
||||||
|
type CSSProperties,
|
||||||
|
type FormEvent,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -30,6 +36,14 @@ type ChannelRuntimeConfigDialogProps = {
|
|||||||
) => void;
|
) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type SecretInputStyle = CSSProperties & {
|
||||||
|
WebkitTextSecurity?: "disc";
|
||||||
|
};
|
||||||
|
|
||||||
|
const SECRET_INPUT_STYLE: SecretInputStyle = {
|
||||||
|
WebkitTextSecurity: "disc",
|
||||||
|
};
|
||||||
|
|
||||||
export function ChannelRuntimeConfigDialog({
|
export function ChannelRuntimeConfigDialog({
|
||||||
provider,
|
provider,
|
||||||
open,
|
open,
|
||||||
@@ -83,6 +97,7 @@ export function ChannelRuntimeConfigDialog({
|
|||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{fields.map((field) => {
|
{fields.map((field) => {
|
||||||
const inputId = `channel-${provider.provider}-${field.name}`;
|
const inputId = `channel-${provider.provider}-${field.name}`;
|
||||||
|
const isSecretField = field.type === "password";
|
||||||
return (
|
return (
|
||||||
<div key={field.name} className="space-y-1.5">
|
<div key={field.name} className="space-y-1.5">
|
||||||
<label
|
<label
|
||||||
@@ -93,10 +108,18 @@ export function ChannelRuntimeConfigDialog({
|
|||||||
</label>
|
</label>
|
||||||
<Input
|
<Input
|
||||||
id={inputId}
|
id={inputId}
|
||||||
type={field.type === "password" ? "password" : "text"}
|
type="text"
|
||||||
value={values[field.name] ?? ""}
|
value={values[field.name] ?? ""}
|
||||||
required={field.required}
|
required={field.required}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
autoCorrect="off"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck={false}
|
||||||
|
data-1p-ignore={isSecretField ? "true" : undefined}
|
||||||
|
data-bwignore={isSecretField ? "true" : undefined}
|
||||||
|
data-form-type={isSecretField ? "other" : undefined}
|
||||||
|
data-lpignore={isSecretField ? "true" : undefined}
|
||||||
|
style={isSecretField ? SECRET_INPUT_STYLE : undefined}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
setValues((current) => ({
|
setValues((current) => ({
|
||||||
...current,
|
...current,
|
||||||
|
|||||||
@@ -226,6 +226,12 @@ test.describe("IM channels", () => {
|
|||||||
|
|
||||||
const setupDialog = page.getByRole("dialog", { name: "Connect Slack" });
|
const setupDialog = page.getByRole("dialog", { name: "Connect Slack" });
|
||||||
await expect(setupDialog).toBeVisible();
|
await expect(setupDialog).toBeVisible();
|
||||||
|
const botTokenInput = setupDialog.getByLabel("Bot token");
|
||||||
|
await expect(botTokenInput).toHaveAttribute("type", "text");
|
||||||
|
await expect(botTokenInput).toHaveAttribute("autocomplete", "off");
|
||||||
|
await expect(botTokenInput).toHaveAttribute("data-lpignore", "true");
|
||||||
|
await expect(botTokenInput).toHaveAttribute("data-1p-ignore", "true");
|
||||||
|
await expect(botTokenInput).toHaveCSS("-webkit-text-security", "disc");
|
||||||
await setupDialog.getByLabel("Bot token").fill("xoxb-ui");
|
await setupDialog.getByLabel("Bot token").fill("xoxb-ui");
|
||||||
await setupDialog.getByLabel("App token").fill("xapp-ui");
|
await setupDialog.getByLabel("App token").fill("xapp-ui");
|
||||||
await setupDialog.getByRole("button", { name: "Save and connect" }).click();
|
await setupDialog.getByRole("button", { name: "Save and connect" }).click();
|
||||||
|
|||||||
Reference in New Issue
Block a user