-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy path2faConfirmationDialog.js
More file actions
162 lines (153 loc) · 5.38 KB
/
2faConfirmationDialog.js
File metadata and controls
162 lines (153 loc) · 5.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import React, {useState, useEffect, useRef, useCallback} from 'react';
import ReactFileViewDialog from '../../../ReactFileViewDialog/ReactFileViewDialog';
import {generateTwoFaConfirmationCode, checkTwoFaConfirmationCode} from './2faConfirmationApi';
const {__, sprintf} = wp.i18n;
/**
* @param {object} props
* @param {boolean} props.isOpen
* @param {function(): void} props.onCancel
* @param {function(): void} props.onVerified
* @param {string} props.verificationEmail
* @return {JSX.Element|null}
*/
export default function TwoFaConfirmationDialog(props) {
const {isOpen, onCancel, onVerified, verificationEmail} = props;
const [code, setCode] = useState('');
const [resendBusy, setResendBusy] = useState(false);
const [resendCooldown, setResendCooldown] = useState(false);
const [okBusy, setOkBusy] = useState(false);
const resendTimerRef = useRef(null);
const clearResendTimer = useCallback(() => {
if (resendTimerRef.current) {
clearTimeout(resendTimerRef.current);
resendTimerRef.current = null;
}
}, []);
const startResendCooldown = useCallback(() => {
clearResendTimer();
setResendCooldown(true);
resendTimerRef.current = setTimeout(() => {
setResendCooldown(false);
resendTimerRef.current = null;
}, 30000);
}, [clearResendTimer]);
useEffect(() => {
if (!isOpen) {
setCode('');
setResendBusy(false);
setResendCooldown(false);
setOkBusy(false);
clearResendTimer();
return;
}
startResendCooldown();
return () => {
clearResendTimer();
};
}, [isOpen, clearResendTimer, startResendCooldown]);
const handleResend = async () => {
if (resendBusy || resendCooldown) {
return;
}
setResendBusy(true);
try {
const res = await generateTwoFaConfirmationCode();
if (res.success) {
setCode('');
startResendCooldown();
} else {
const msg = typeof res.data === 'string' ?
res.data :
__('Request failed.', 'security-malware-firewall');
alert(msg);
}
} finally {
setResendBusy(false);
}
};
const handleOk = async () => {
if (okBusy) {
return;
}
setOkBusy(true);
try {
const res = await checkTwoFaConfirmationCode(code.trim());
if (res.success) {
clearResendTimer();
onVerified();
} else {
const msg = typeof res.data === 'string' ?
res.data :
__('Code verification failed!', 'security-malware-firewall');
alert(msg);
}
} finally {
setOkBusy(false);
}
};
const email = verificationEmail || '';
const checkInboxMsg = __(
'Check %s inbox for the confirmation code.',
'security-malware-firewall',
);
/* eslint-disable max-len */
const codeValidityNote = __(
'The code is valid for 10 minutes. If you want to change the status in this period, the new code won\'t be sent, please, use the code you\'ve already received.',
'security-malware-firewall',
);
/* eslint-enable max-len */
return (
<ReactFileViewDialog
isOpen={isOpen}
onClose={onCancel}
title={__('Confirmation code', 'security-malware-firewall')}
maxWidth="360px"
>
<p>
{sprintf(
/* translators: %s: email address */
checkInboxMsg,
email,
)}
</p>
<p>
<em>
{codeValidityNote}
</em>
</p>
<p>
<input
type="text"
name="spbct-confirmation-code"
value={code}
onChange={(e) => setCode(e.target.value)}
className="regular-text"
autoComplete="one-time-code"
/>
<button
type="button"
className="button button-primary spbc-2fa-confirmation-resend"
onClick={handleResend}
disabled={resendBusy || resendCooldown}
>
{__('Resend', 'security-malware-firewall')}
{resendCooldown && (
<span className="circle circle--small -animation--circle -animation--30s">
<span className="circle-inner"></span>
</span>
)}
</button>
</p>
<p style={{marginTop: 16, textAlign: 'right'}}>
<button type="button" className="button" onClick={onCancel} disabled={okBusy}>
{__('Cancel', 'security-malware-firewall')}
</button>
<button type="button" className="button button-primary" onClick={handleOk} disabled={okBusy}>
{__('OK', 'security-malware-firewall')}
</button>
</p>
</ReactFileViewDialog>
);
}