Skip to content

Instantly share code, notes, and snippets.

@kwhitejr
Created May 12, 2019 01:04
Show Gist options
  • Save kwhitejr/cda4fbecaff30c41072e92c033a02b5b to your computer and use it in GitHub Desktop.
Save kwhitejr/cda4fbecaff30c41072e92c033a02b5b to your computer and use it in GitHub Desktop.
A hideous but stateful React Class Component for AWS Amplify authorization
import React, { Component } from "react";
import { withRouter, Redirect } from "react-router-dom";
import { Authenticator } from "aws-amplify-react";
import { Auth, Logger, JS } from "aws-amplify";
import {
CustomSignIn,
CustomSignUp,
CustomConfirmSignIn,
CustomConfirmSignUp,
CustomForgotPassword,
CustomPasswordReset,
} from "../components/auth";
const logger = new Logger("Login");
const CustomAuthenticator = props => (
<Authenticator hideDefault>
<CustomSignIn {...props} />
<CustomSignUp {...props} />
<CustomConfirmSignIn {...props} />
<CustomConfirmSignUp {...props} />
<CustomForgotPassword {...props} />
<CustomPasswordReset {...props} />
</Authenticator>
);
class Login extends Component {
state = {
loaded: false,
isAuthenticated: false,
error: "",
username: "",
password: "",
email: "",
code: "",
};
// TODO: refactor success functions
// TODO: remove references to this.state.message
componentDidMount = () => {
this.authenticate();
};
authenticate = () => {
Auth.currentAuthenticatedUser()
.then(() => {
this.setState({ loaded: true, isAuthenticated: true });
})
.catch(() => this.props.history.push("/login"));
};
handleStateChange = name => event => {
this.setState({
[name]: event.target.value,
});
};
handleAuthStateChange = (state, data) => {
const { onStateChange } = this.props; // where dis come frum
// logger.info(state);
if (onStateChange) {
logger.info(`Changing state to ${state}`);
onStateChange(state, data);
}
};
signIn = () => {
const { username, password } = this.state;
// logger.info("sign in with " + username);
console.log("sign in with " + username);
Auth.signIn(username, password)
.then(user => this.signInSuccess(user))
.catch(err => this.handleError(err));
};
signInSuccess = user => {
// logger.info("sign in success", user);
console.log("sign in success", user);
this.setState({ error: "", username: "", password: "" });
// There are other sign in challenges we don't cover here.
// SMS_MFA, SOFTWARE_TOKEN_MFA, NEW_PASSWORD_REQUIRED, MFA_SETUP ...
if (
user.challengeName === "SMS_MFA" ||
user.challengeName === "SOFTWARE_TOKEN_MFA"
) {
this.handleAuthStateChange("confirmSignIn", user);
} else {
this.checkContact(user);
}
};
confirmSignIn = () => {
const { username } = this.state;
const { code } = this.state;
logger.info("confirm sign in with " + code);
const mfaType =
username.challengeName === "SOFTWARE_TOKEN_MFA"
? "SOFTWARE_TOKEN_MFA"
: null;
Auth.confirmSignIn(username, code, mfaType)
.then(() => this.confirmSuccess(username))
.catch(err => this.handleError(err));
};
confirmSuccess = user => {
logger.info("confirm sign in success", user);
this.setState({ error: "" });
this.checkContact(user);
};
signUp = () => {
const { username, password, email } = this.state;
logger.info("sign up with " + username);
Auth.signUp(username, password, email)
.then(() => this.signUpSuccess(username))
.catch(err => this.handleError(err));
};
confirmSignUp = () => {
const { username, code } = this.state;
logger.info("confirm sign up with " + code);
Auth.confirmSignUp(username, code)
.then(() => this.confirmSuccess(username))
.catch(err => this.handleError(err));
};
signUpSuccess = username => {
logger.info("sign up success with " + username);
this.setState({ error: "" });
this.handleAuthStateChange("confirmSignUp", username);
};
signOut = () => {
Auth.signOut();
};
checkContact = user => {
Auth.verifiedContact(user)
.then(data => {
if (!JS.isEmpty(data.verified)) {
this.handleAuthStateChange("signedIn", user);
} else {
user = Object.assign(user, data);
this.handleAuthStateChange("verifyContact", user);
}
this.props.history.push("/");
})
.catch(err => {
logger.info("check verified contact error", err);
console.error("check verified contact error", err);
});
};
resetPassword = () => {
const { username } = this.state;
if (!username) {
this.setState({ error: "missing username" });
return;
}
const { code, password } = this.state;
logger.info("reset password for " + username);
Auth.forgotPasswordSubmit(username, code, password)
.then(data => this.resetPasswordSuccess(username, data))
.catch(err => this.handleError(err));
};
sendCode = () => {
const { username } = this.state;
logger.info("resend code to " + username);
Auth.forgotPassword(username)
.then(data => this.sendSuccess(username, data))
.catch(err => this.handleError(err));
};
sendSuccess = (username, data) => {
logger.info("sent code for " + username, data);
this.handleAuthStateChange("passwordReset", username);
};
resetPasswordSuccess = (username, data) => {
logger.info("forgot password reset success for " + username, data);
this.handleAuthStateChange("signIn", username);
};
resendCode = () => {
const { username } = this.state;
logger.info("resend code to " + username);
Auth.resendSignUp(username)
.then(() => this.setState({ message: "Code sent" }))
.catch(err => this.handleError(err));
};
confirmSuccess = username => {
logger.info("confirm sign up success with " + username);
this.setState({ message: "", error: "" });
this.handleAuthStateChange("signIn", username);
};
handleError = err => {
logger.error("An error occurred:", err);
this.setState({ error: err.message || err });
};
render() {
const { isAuthenticated, username, password, email, code } = this.state;
return isAuthenticated ? (
<Redirect
to={{
pathname: "/",
}}
/>
) : (
<CustomAuthenticator
username={username}
password={password}
email={email}
code={code}
handleStateChange={this.handleStateChange}
onStateChange={this.handleAuthStateChange}
signIn={this.signIn}
signUp={this.signUp}
signOut={this.signOut}
sendCode={this.sendCode}
resendCode={this.resendCode}
resetPassword={this.resetPassword}
confirmSignUp={this.confirmSignUp}
confirmSignIn={this.confirmSignIn}
/>
);
}
}
export default withRouter(Login);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment