1
0
mirror of https://github.com/0rangebananaspy/authelia.git synced 2024-09-14 22:47:21 +07:00
authelia/client/src/views/OneTimePasswordRegistrationView/OneTimePasswordRegistrationView.tsx
2019-03-03 11:39:40 +01:00

127 lines
3.8 KiB
TypeScript

import React, { Component } from "react";
import Button from "@material/react-button";
import styles from '../../assets/scss/views/OneTimePasswordRegistrationView/OneTimePasswordRegistrationView.module.scss';
import { RouteProps, RouterProps } from "react-router";
import QueryString from 'query-string';
import QRCode from 'qrcode.react';
import Notification from "../../components/Notification/Notification";
import googleStoreImage from '../../assets/images/googleplay-badge.svg';
import appleStoreImage from '../../assets/images/applestore-badge.svg';
import { Secret } from "./Secret";
import CircleLoader, { Status } from "../../components/CircleLoader/CircleLoader";
export interface Props extends RouteProps, RouterProps {
secret: Secret | null;
error: string | null;
onInit: (token: string) => void;
onRetryClicked: () => void;
onCancelClicked: () => void;
onLoginClicked: () => void;
}
class OneTimePasswordRegistrationView extends Component<Props> {
private token: string | null;
constructor(props: Props) {
super(props);
this.token = null;
}
componentWillMount() {
// If secret is already populated, we skip onInit (for testing purposes).
if (this.props.secret) return;
if (!this.props.location) {
console.error('There is no location to retrieve query params from...');
return;
}
const params = QueryString.parse(this.props.location.search);
if (!('token' in params)) {
console.error('Token parameter is expected and not provided');
return;
}
this.token = params['token'] as string;
this.props.onInit(this.token);
}
private renderWithSecret(secret: Secret) {
return (
<div>
<div className={styles.text}>
Register your device by scanning the barcode or adding the key.
</div>
<div className={styles.secretContainer}>
<div className={styles.qrcodeContainer}>
<QRCode value={secret.otpauth_url} size={180} level="Q"></QRCode>
</div>
<div className={styles.base32Container}>{secret.base32_secret}</div>
</div>
<div className={styles.loginButtonContainer}>
<Button
color="primary"
raised={true}
onClick={this.props.onLoginClicked}>
Login
</Button>
</div>
<div className={styles.needGoogleAuthenticator}>
<div className={styles.needGoogleAuthenticatorText}>Need Google Authenticator?</div>
<img src={appleStoreImage} className={styles.store} alt='Google Authenticator on Apple Store'/>
<img src={googleStoreImage} className={styles.store} alt='Google Authenticator on Google Store'/>
</div>
</div>
)
}
private renderError() {
return (
<div>
<Notification show={true}>
<div>{this.props.error}</div>
</Notification>
<div className={styles.buttonContainer}>
<Button
color="primary"
raised={true}
className={styles.button}
onClick={this.props.onRetryClicked}>
Retry
</Button>
<Button
color="primary"
raised={true}
className={styles.button}
onClick={this.props.onCancelClicked}>
Cancel
</Button>
</div>
</div>
);
}
private renderSecret() {
return this.props.secret
? this.renderWithSecret(this.props.secret)
: this.renderError();
}
private renderLoading() {
return (
<div>
<div>One-Time password secret is being generated...</div>
<div className={styles.progressContainer}><CircleLoader status={Status.LOADING} /></div>
</div>
)
}
render() {
return !this.props.secret && !this.props.error
? this.renderLoading()
: this.renderSecret();
}
}
export default OneTimePasswordRegistrationView;