glass-app-manager
Version:
Informatica's Glass Framework CLI for bootstrapping
143 lines (117 loc) • 4.29 kB
JavaScript
// @flow
import React, { Component } from "react";
import PropTypes from "prop-types";
import ReactCountdownClock from "react-countdown-clock";
import Dialog from "../dialog/Dialog";
import Button from "../button/Button";
type Props = {
/**
* A custom function to extend the session when the user
* clicks to stay logged in.
*/
extendSession: () => any,
/**
* A callback to execute after the timer completes. Add all logout logic,
* `sessionStorage` cleanup, etc. in this callback.
*/
onLogout: () => any,
/**
* The length of the session as the number of _seconds_
* or as a string (e.g. `30m`, `0.5h`, etc.)
*/
sessionLength: number | string,
/**
* The number of seconds before the logout that the dialog is shown.
*/
showDialogBeforeLogout: number | string,
/**
* The time the user logged into the web app.
*/
loginTime: number,
};
const simpleConvert = (t: number | string): number => {
if (typeof t === "string") {
if (!/(0|\.)?\d+[smh]/.test(t)) {
throw new Error("Malformed time string. Acceptable values are h, m, and s only!");
}
let offset = 1000;
const time = parseFloat(t.substring(0, t.length - 1));
if (time < 0) {
throw new Error("Time cannot be negative");
}
const duration = t.substring(t.length - 1, t.length);
switch (duration) {
case "s":
break;
case "m":
offset *= 60;
break;
case "h":
offset *= 3600;
break;
default:
break;
}
return time * offset;
}
return t * 1000;
};
export default class Timeout extends Component<Props, { closed: boolean }> {
static propTypes = {
extendSession: PropTypes.func.isRequired,
onLogout: PropTypes.func.isRequired,
sessionLength: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
showDialogBeforeLogout: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
loginTime: PropTypes.number,
};
static defaultProps = {
sessionLength: "30m",
showDialogBeforeLogout: "1m",
loginTime:
window.sessionStorage.loginTime && window.sessionStorage.loginTime instanceof Date
? new Date(window.sessionStorage.loginTime).getTime()
: window.sessionStorage.loginTime,
};
state = { closed: true };
timeout = null;
sessionLength = simpleConvert(this.props.sessionLength);
showDialogBeforeLogout = simpleConvert(this.props.showDialogBeforeLogout);
componentDidMount() {
const showDialogTime = this.props.loginTime + this.sessionLength - this.showDialogBeforeLogout;
this.timeout = setInterval(() => {
if (this.timeout && new Date().getTime() >= showDialogTime) {
clearInterval(this.timeout);
this.timeout = null;
this.setState({ closed: false });
}
}, 1000);
}
componentWillUnmount() {
if (this.timeout) {
clearInterval(this.timeout);
this.timeout = null;
}
}
render() {
return (
<Dialog onClose={this.props.extendSession} closed={this.state.closed}>
<Dialog.Header title="Timeout" />
<Dialog.Content>
<ReactCountdownClock
seconds={this.showDialogBeforeLogout / 1000}
color="#39F"
size={175}
alpha={0.75}
fontSize="3rem"
showMilliseconds={false}
weight={8}
onComplete={this.props.onLogout}
/>
</Dialog.Content>
<Dialog.Footer>
{(onClose) => <Button onClick={this.props.extendSession}>Stay Logged In</Button>}
</Dialog.Footer>
</Dialog>
);
}
}