Skip to content

Commit 7dd721d

Browse files
cakekoailija-lazoroski
authored andcommitted
UI: Add a countdown timer for OTP expiration
1 parent fe3161d commit 7dd721d

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

monkey/monkey_island/cc/ui/package-lock.json

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

monkey/monkey_island/cc/ui/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"react-router-dom": "6.8.2",
101101
"react-spinners": "0.13.8",
102102
"react-table": "^6.11.5",
103+
"react-timer-hook": "^3.0.5",
103104
"react-tsparticles": "^1.43.1",
104105
"remark-breaks": "3.0.2",
105106
"request": "^2.88.2",

monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunManually/LocalManualRunOptions.js

+27-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import GenerateLocalLinuxCurl from '../commands/local_linux_curl';
88
import CommandDisplay from '../utils/CommandDisplay';
99
import {Button, Form} from 'react-bootstrap';
1010
import IslandHttpClient, { APIEndpoint } from '../../../IslandHttpClient';
11+
import { useTimer } from 'react-timer-hook';
12+
import { CommandExpirationTimer } from '../utils/CommandExpirationTimer';
1113

1214

1315
const LocalManualRunOptions = (props) => {
@@ -24,6 +26,12 @@ const getContents = (props) => {
2426
[OS_TYPES.LINUX_64]: 'Linux 64bit'
2527
}
2628

29+
const {
30+
seconds,
31+
minutes,
32+
restart
33+
} = useTimer({ expiryTimestamp: new Date() });
34+
2735
const [otp, setOtp] = useState('');
2836
const [osType, setOsType] = useState(OS_TYPES.WINDOWS_64);
2937
const [selectedIp, setSelectedIp] = useState(props.ips[0]);
@@ -52,8 +60,9 @@ const getContents = (props) => {
5260
}
5361

5462
function getOtp() {
55-
IslandHttpClient.get(APIEndpoint.agent_otp).then(res =>{
63+
IslandHttpClient.get(APIEndpoint.agent_otp).then(res => {
5664
setOtp(res.body.otp);
65+
restart(newExpirationTime());
5766
});
5867
}
5968

@@ -66,6 +75,13 @@ const getContents = (props) => {
6675
}
6776
}
6877

78+
function newExpirationTime() {
79+
const time = new Date();
80+
time.setSeconds(time.getSeconds() + 120);
81+
console.log('timeout is now: ' + time);
82+
return time;
83+
}
84+
6985
return (
7086
<>
7187
<DropdownSelect defaultKey={OS_TYPES.WINDOWS_64} options={osTypes} onClick={setOsType} variant={'outline-monkey'}/>
@@ -84,7 +100,16 @@ const getContents = (props) => {
84100
</div>
85101
</div>
86102
<CommandDisplay commands={commands} onCopy={getOtp} />
87-
<Button style={{'float': 'right'}} title="Copy to Clipboard" onClick={getOtp}>Re-generate</Button>
103+
<Button style={{'float': 'right'}} title="Copy to Clipboard" onClick={getOtp}>Re-generate</Button>
104+
<CommandDisplay commands={commands}/>
105+
<div style={{marginTop: '-0.5em', marginBottom: '0.5em'}}>
106+
<CommandExpirationTimer minutes={minutes} seconds={seconds}/>
107+
</div>
108+
<div style={{textAlign: 'right'}}>
109+
<span>
110+
<Button title="Copy to Clipboard" onClick={getOtp}>Re-generate</Button>
111+
</span>
112+
</div>
88113
</>
89114
)
90115
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
3+
export function CommandExpirationTimer({ minutes, seconds }) {
4+
5+
function formatDigits(number) {
6+
return number.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false})
7+
}
8+
9+
function generateText() {
10+
if (minutes === 0 && seconds === 0) {
11+
return 'Command expired';
12+
} else {
13+
return 'Command expires in: ' + formatDigits(minutes) + ':' + formatDigits(seconds);
14+
}
15+
}
16+
17+
return (
18+
<div style={{textAlign: 'right'}}>
19+
{generateText()}
20+
</div>
21+
);
22+
}

0 commit comments

Comments
 (0)