43 lines
992 B
TypeScript
43 lines
992 B
TypeScript
import { useSignal, useSignalEffect } from '@preact/signals'
|
|
import { JSX } from 'preact'
|
|
|
|
export function Input(
|
|
{ label, name, ...props }:
|
|
& { label: string; name: string }
|
|
& JSX.InputHTMLAttributes<HTMLInputElement>,
|
|
) {
|
|
if (props.type === 'password') {
|
|
const password = useSignal('')
|
|
const hash = useSignal('')
|
|
const salt = crypto.randomUUID()
|
|
|
|
useSignalEffect(() => {
|
|
crypto.subtle.digest(
|
|
'SHA-256',
|
|
new TextEncoder().encode(salt + password.value),
|
|
).then((digest) => hash.value = new TextDecoder().decode(digest))
|
|
})
|
|
|
|
return (
|
|
<label>
|
|
<span>{label}</span>
|
|
<input
|
|
{...props}
|
|
spellcheck={false}
|
|
onInput={(event) =>
|
|
password.value = (event.target as HTMLInputElement).value}
|
|
/>
|
|
<input type='text' hidden value={hash} name={name} />
|
|
<input type='text' hidden value={salt} name={`${name}_salt`} />
|
|
</label>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<label>
|
|
<span>{label}</span>
|
|
<input {...props} name={name} />
|
|
</label>
|
|
)
|
|
}
|