Skip to content

Instantly share code, notes, and snippets.

@davekiss
Created November 17, 2020 12:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save davekiss/9af08fde4ce2d40e306a35028583d6e5 to your computer and use it in GitHub Desktop.
Save davekiss/9af08fde4ce2d40e306a35028583d6e5 to your computer and use it in GitHub Desktop.
Cognito's Complete New Password using Amplify + React
import React, { useState, useEffect } from "react";
import Auth from "@aws-amplify/auth";
import useNotification from "hooks/useNotification";
const URLSearchParams = require("url-search-params");
import { useHistory } from "react-router-dom";
const CompleteNewPassword = props => {
const history = useHistory();
const [currentUser, setCurrentUser] = useState(null);
const [password, setPassword] = useState();
const [passwordVerify, setPasswordVerify] = useState();
const [loading, setLoading] = useState(true);
const { showSuccessNotification, showErrorNotification } = useNotification();
const getRawUsername = () => {
const url = new URL(document.URL);
const username = url.search
.replace("?", "")
.split("&")
.map(kv => {
const [key, value] = kv.split("=");
return { key, value };
})
.find(({ key }) => key === `username`);
return username.value;
};
useEffect(() => {
let params = new URLSearchParams(location.search);
const email = getRawUsername();
const pass = params.get("code");
if (!email || !pass) return;
Auth.signIn(email, pass)
.then(results => {
if (results.challengeName !== `NEW_PASSWORD_REQUIRED`) {
history.push("/sign-in");
}
setCurrentUser(results);
setLoading(false);
})
.catch(error => {
showErrorNotification(error.message);
setLoading(false);
});
}, []);
const handleCompleteNewPassword = async e => {
e.preventDefault();
if (!password) return;
if (password.length < 8) {
showErrorNotification(
`Please make your password a minimum of 8 characters.`
);
return;
}
if (password !== passwordVerify) {
showErrorNotification(`Passwords do not match.`);
return;
}
setLoading(true);
try {
await Auth.completeNewPassword(currentUser, password);
showSuccessNotification(`Your password has been set.`);
history.push("/");
} catch (error) {
console.log(error);
showErrorNotification(error.message ?? error);
}
setLoading(false);
};
if (loading) return <div>Loading...</div>;
return (
<form
onSubmit={handleCompleteNewPassword}
className="w-1/2 flex flex-col items-start"
>
<svg
className="w-6 h-6 text-gray-800"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
<h2 className="text-2xl text-gray-800 mb-1 font-semibold">
Please set your password
</h2>
<p className="text-sm text-gray-700 italic mb-6">
Minimum of 8 characters, stronger is better
</p>
<input
className="px-4 py-3 rounded shadow block mb-4 w-full text-gray-700 outline-none focus:shadow-outline"
style={{ maxWidth: "400px" }}
type="password"
placeholder="Enter a password"
onChange={e => setPassword(e.target.value)}
required
/>
<input
className="px-4 py-3 rounded shadow block mb-8 w-full text-gray-700 outline-none focus:shadow-outline"
style={{ maxWidth: "400px" }}
type="password"
placeholder="Confirm your password"
onChange={e => setPasswordVerify(e.target.value)}
required
/>
<input
className="py-3 px-6 text-lg rounded bg-teal-600 hover:bg-teal-700 text-white cursor-pointer"
type="submit"
value={loading ? "Loading..." : "Set password"}
/>
</form>
);
};
export default CompleteNewPassword;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment