feat: add a more seamless credential management ux

This commit is contained in:
thecodrr
2020-12-09 21:20:23 +05:00
parent 178bf26bfe
commit c8d07eeea2

View File

@@ -10,24 +10,19 @@ const requiredValues = ["username", "password"];
function LoginDialog(props) {
const { onClose } = props;
const [error, setError] = useState();
const [credential, setCredential] = useState();
const isLoggingIn = useStore((store) => store.isLoggingIn);
const login = useStore((store) => store.login);
useEffect(() => {
if (!window.PasswordCredential) return;
(async function () {
console.log("Trying to automatically login...");
const credential = await navigator.credentials.get({
mediation: "optional",
password: true,
});
if (credential) {
console.log("Got credentials...");
await login({
username: credential.id,
password: credential.password,
});
} else {
console.log("Did not get credentials...", credential);
setCredential(credential);
}
})();
}, [login]);
@@ -64,57 +59,85 @@ function LoginDialog(props) {
disabled: isLoggingIn,
}}
>
<Flex
id="loginForm"
as="form"
onSubmit={(e) => {
e.preventDefault();
const data = requiredValues.reduce((prev, curr) => {
prev[curr] = e.target[curr].value;
return prev;
}, {});
<Flex flexDirection="column">
<Flex
id="loginForm"
as="form"
onSubmit={(e) => {
e.preventDefault();
const data = requiredValues.reduce((prev, curr) => {
prev[curr] = e.target[curr].value;
return prev;
}, {});
setError();
setError();
login(data)
.then(async () => {
// Instantiate PasswordCredential with the form
if (window.PasswordCredential) {
var c = new window.PasswordCredential({
id: data.username,
name: data.username,
type: "password",
password: data.password,
});
await navigator.credentials.store(c);
console.log("Credentails stored...");
onClose();
login(data)
.then(async () => {
// Instantiate PasswordCredential with the form
if (window.PasswordCredential) {
var c = new window.PasswordCredential({
id: data.email,
name: data.username,
type: "password",
password: data.password,
});
await navigator.credentials.store(c);
onClose();
} else {
onClose();
}
})
.catch((e) => setError(e.message));
}}
flexDirection="column"
>
<Field
autoFocus
required
id="username"
label="Username"
name="username"
autoComplete="username"
/>
<Field
required
id="password"
label="Password"
name="password"
type="password"
autoComplete="current-password"
sx={{ mt: 1 }}
/>
{error && <Text variant="error">{error}</Text>}
</Flex>
{credential && (
<Button
variant="tertiary"
mt={2}
sx={{ textAlign: "left" }}
onClick={async () => {
if (!credential.password) {
const element = document.querySelector("#loginForm #username");
if (!element) {
return setCredential();
}
element.value = credential.name;
} else {
await login({
password: credential.password,
username: credential.name,
});
onClose();
}
})
.catch((e) => setError(e.message));
}}
flexDirection="column"
>
<Field
autoFocus
required
id="username"
label="Username"
name="username"
autoComplete="username"
/>
<Field
required
id="password"
label="Password"
name="password"
type="password"
autoComplete="current-password"
sx={{ mt: 1 }}
/>
{error && <Text variant="error">{error}</Text>}
}}
>
<Text as="span">
Login as <b>{credential.name}</b>
{credential.id && <Text variant="subBody">{credential.id}</Text>}
</Text>
</Button>
)}
</Flex>
</Dialog>
);