fix: API key input uses password type and no autocomplete (#24864)

Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Atif
2025-09-02 07:07:24 +05:30
committed by GitHub
parent 2c462154f7
commit 84d09b8b8a
3 changed files with 50 additions and 11 deletions

View File

@@ -0,0 +1,16 @@
import { render } from '@testing-library/react'
import Input from './Input'
test('Input renders correctly as password type with no autocomplete', () => {
const { asFragment, getByPlaceholderText } = render(
<Input
type="password"
placeholder="API Key"
onChange={jest.fn()}
/>,
)
const input = getByPlaceholderText('API Key')
expect(input).toHaveAttribute('type', 'password')
expect(input).not.toHaveAttribute('autocomplete')
expect(asFragment()).toMatchSnapshot()
})

View File

@@ -13,6 +13,7 @@ type InputProps = {
min?: number min?: number
max?: number max?: number
} }
const Input: FC<InputProps> = ({ const Input: FC<InputProps> = ({
value, value,
onChange, onChange,
@@ -32,23 +33,23 @@ const Input: FC<InputProps> = ({
onChange(`${min}`) onChange(`${min}`)
return return
} }
if (!isNaN(maxNum) && Number.parseFloat(v) > maxNum) if (!isNaN(maxNum) && Number.parseFloat(v) > maxNum)
onChange(`${max}`) onChange(`${max}`)
} }
return ( return (
<div className='relative'> <div className='relative'>
<input <input
autoComplete="new-password"
tabIndex={0} tabIndex={0}
// Do not set autoComplete for security - prevents browser from storing sensitive API keys
className={` className={`
block h-8 w-full appearance-none rounded-lg border border-transparent bg-components-input-bg-normal px-3 text-sm block h-8 w-full appearance-none rounded-lg border border-transparent bg-components-input-bg-normal px-3 text-sm
text-components-input-text-filled caret-primary-600 outline-none text-components-input-text-filled caret-primary-600 outline-none
placeholder:text-sm placeholder:text-text-tertiary placeholder:text-sm placeholder:text-text-tertiary
hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active
focus:bg-components-input-bg-active focus:shadow-xs focus:bg-components-input-bg-active focus:shadow-xs
${validated && 'pr-[30px]'} ${validated ? 'pr-[30px]' : ''}
${className} ${className || ''}
`} `}
placeholder={placeholder || ''} placeholder={placeholder || ''}
onChange={e => onChange(e.target.value)} onChange={e => onChange(e.target.value)}
@@ -60,13 +61,11 @@ const Input: FC<InputProps> = ({
min={min} min={min}
max={max} max={max}
/> />
{ {validated && (
validated && (
<div className='absolute right-2.5 top-2.5'> <div className='absolute right-2.5 top-2.5'>
<CheckCircle className='h-4 w-4 text-[#039855]' /> <CheckCircle className='h-4 w-4 text-[#039855]' />
</div> </div>
) )}
}
</div> </div>
) )
} }

View File

@@ -0,0 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Input renders correctly as password type with no autocomplete 1`] = `
<DocumentFragment>
<div
class="relative"
>
<input
class="
block h-8 w-full appearance-none rounded-lg border border-transparent bg-components-input-bg-normal px-3 text-sm
text-components-input-text-filled caret-primary-600 outline-none
placeholder:text-sm placeholder:text-text-tertiary
hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active
focus:bg-components-input-bg-active focus:shadow-xs
"
placeholder="API Key"
tabindex="0"
type="password"
/>
</div>
</DocumentFragment>
`;