9#include <QWebEngineView>
10#include <QLoggingCategory>
12#include "DlgWebAuth.h"
13static Q_LOGGING_CATEGORY(log,
"WebBrowser.Dlg.Auth")
15 : QDialog(parent), uxRequest(request), ui(new
Ui::
CDlgWebAuth)
17 qDebug(log) << Q_FUNC_INFO;
20 buttonGroup =
new QButtonGroup(
this);
21 buttonGroup->setExclusive(
true);
23 scrollArea =
new QScrollArea(
this);
24 selectAccountWidget =
new QWidget(
this);
25 scrollArea->setWidget(selectAccountWidget);
26 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
27 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
28 selectAccountWidget->resize(400, 150);
29 selectAccountLayout =
new QVBoxLayout(selectAccountWidget);
30 ui->m_mainVerticalLayout->addWidget(scrollArea);
31 selectAccountLayout->setAlignment(Qt::AlignTop);
35 connect(ui->buttonBox, &QDialogButtonBox::rejected,
this,
36 qOverload<>(&CDlgWebAuth::onCancelRequest));
38 connect(ui->buttonBox, &QDialogButtonBox::accepted,
this,
39 qOverload<>(&CDlgWebAuth::onAcceptRequest));
40 QAbstractButton *button = ui->buttonBox->button(QDialogButtonBox::Retry);
41 connect(button, &QAbstractButton::clicked,
this, qOverload<>(&CDlgWebAuth::onRetry));
42 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
45CDlgWebAuth::~CDlgWebAuth()
47 qDebug(log) << Q_FUNC_INFO;
48 QList<QAbstractButton *> buttons = buttonGroup->buttons();
49 auto itr = buttons.begin();
50 while (itr != buttons.end()) {
51 QAbstractButton *radioButton = *itr;
58 buttonGroup =
nullptr;
73void CDlgWebAuth::updateDisplay()
75 switch (uxRequest->state()) {
76 case QWebEngineWebAuthUxRequest::WebAuthUxState::SelectAccount:
77 setupSelectAccountUI();
79 case QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin:
82 case QWebEngineWebAuthUxRequest::WebAuthUxState::FinishTokenCollection:
83 setupFinishCollectTokenUI();
85 case QWebEngineWebAuthUxRequest::WebAuthUxState::RequestFailed:
94void CDlgWebAuth::setupSelectAccountUI()
96 ui->m_headingLabel->setText(tr(
"Choose a Passkey"));
97 ui->m_description->setText(tr(
"Which passkey do you want to use for ")
98 + uxRequest->relyingPartyId() + tr(
"? "));
99 ui->m_pinGroupBox->setVisible(
false);
100 ui->m_mainVerticalLayout->removeWidget(ui->m_pinGroupBox);
101 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(
false);
103 clearSelectAccountButtons();
104 scrollArea->setVisible(
true);
105 selectAccountWidget->resize(this->width(), this->height());
106 QStringList userNames = uxRequest->userNames();
108 for (
const QString &name : userNames) {
109 QRadioButton *radioButton =
new QRadioButton(name);
110 selectAccountLayout->addWidget(radioButton);
111 buttonGroup->addButton(radioButton);
114 ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr(
"Ok"));
115 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
true);
116 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(
true);
117 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(
false);
120void CDlgWebAuth::setupFinishCollectTokenUI()
122 clearSelectAccountButtons();
123 ui->m_headingLabel->setText(tr(
"Use your security key with")
124 + uxRequest->relyingPartyId());
125 ui->m_description->setText(
126 tr(
"Touch your security key again to complete the request."));
127 ui->m_pinGroupBox->setVisible(
false);
128 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
false);
129 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(
false);
130 scrollArea->setVisible(
false);
132void CDlgWebAuth::setupCollectPinUI()
134 clearSelectAccountButtons();
135 ui->m_mainVerticalLayout->addWidget(ui->m_pinGroupBox);
136 ui->m_pinGroupBox->setVisible(
true);
137 ui->m_confirmPinLabel->setVisible(
false);
138 ui->m_confirmPinLineEdit->setVisible(
false);
139 ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr(
"Next"));
140 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
true);
141 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(
true);
142 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(
false);
143 scrollArea->setVisible(
false);
145 QWebEngineWebAuthPinRequest pinRequestInfo = uxRequest->pinRequest();
147 if (pinRequestInfo.reason == QWebEngineWebAuthUxRequest::PinEntryReason::Challenge) {
148 ui->m_headingLabel->setText(tr(
"PIN Required"));
149 ui->m_description->setText(tr(
"Enter the PIN for your security key"));
150 ui->m_confirmPinLabel->setVisible(
false);
151 ui->m_confirmPinLineEdit->setVisible(
false);
153 if (pinRequestInfo.reason == QWebEngineWebAuthUxRequest::PinEntryReason::Set) {
154 ui->m_headingLabel->setText(tr(
"New PIN Required"));
155 ui->m_description->setText(tr(
"Set new PIN for your security key"));
157 ui->m_headingLabel->setText(tr(
"Change PIN Required"));
158 ui->m_description->setText(tr(
"Change PIN for your security key"));
160 ui->m_confirmPinLabel->setVisible(
true);
161 ui->m_confirmPinLineEdit->setVisible(
true);
164 QString errorDetails;
165 switch (pinRequestInfo.error) {
166 case QWebEngineWebAuthUxRequest::PinEntryError::NoError:
168 case QWebEngineWebAuthUxRequest::PinEntryError::InternalUvLocked:
169 errorDetails = tr(
"Internal User Verification Locked ");
171 case QWebEngineWebAuthUxRequest::PinEntryError::WrongPin:
172 errorDetails = tr(
"Wrong PIN");
174 case QWebEngineWebAuthUxRequest::PinEntryError::TooShort:
175 errorDetails = tr(
"Too Short");
177 case QWebEngineWebAuthUxRequest::PinEntryError::InvalidCharacters:
178 errorDetails = tr(
"Invalid Characters");
180 case QWebEngineWebAuthUxRequest::PinEntryError::SameAsCurrentPin:
181 errorDetails = tr(
"Same as current PIN");
184 if (!errorDetails.isEmpty()) {
185 errorDetails += tr(
" ") + QString::number(pinRequestInfo.remainingAttempts)
186 + tr(
" attempts remaining");
188 ui->m_pinEntryErrorLabel->setText(errorDetails);
191void CDlgWebAuth::onCancelRequest()
196void CDlgWebAuth::onAcceptRequest()
198 switch (uxRequest->state()) {
199 case QWebEngineWebAuthUxRequest::WebAuthUxState::SelectAccount:
200 if (buttonGroup->checkedButton()) {
201 uxRequest->setSelectedAccount(buttonGroup->checkedButton()->text());
204 case QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin:
205 uxRequest->setPin(ui->m_pinLineEdit->text());
212void CDlgWebAuth::setupErrorUI()
214 clearSelectAccountButtons();
215 QString errorDescription;
216 QString errorHeading = tr(
"Something went wrong");
217 bool isVisibleRetry =
false;
218 switch (uxRequest->requestFailureReason()) {
219 case QWebEngineWebAuthUxRequest::RequestFailureReason::Timeout:
220 errorDescription = tr(
"Request Timeout");
222 case QWebEngineWebAuthUxRequest::RequestFailureReason::KeyNotRegistered:
223 errorDescription = tr(
"Key not registered");
225 case QWebEngineWebAuthUxRequest::RequestFailureReason::KeyAlreadyRegistered:
226 errorDescription = tr(
"You already registered this device."
227 "Try again with device");
228 isVisibleRetry =
true;
230 case QWebEngineWebAuthUxRequest::RequestFailureReason::SoftPinBlock:
232 tr(
"The security key is locked because the wrong PIN was entered too many times."
233 "To unlock it, remove and reinsert it.");
234 isVisibleRetry =
true;
236 case QWebEngineWebAuthUxRequest::RequestFailureReason::HardPinBlock:
238 tr(
"The security key is locked because the wrong PIN was entered too many times."
239 " You'll need to reset the security key.");
241 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorRemovedDuringPinEntry:
243 tr(
"Authenticator removed during verification. Please reinsert and try again");
245 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingResidentKeys:
246 errorDescription = tr(
"Authenticator doesn't have resident key support");
248 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingUserVerification:
249 errorDescription = tr(
"Authenticator missing user verification");
251 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingLargeBlob:
252 errorDescription = tr(
"Authenticator missing Large Blob support");
254 case QWebEngineWebAuthUxRequest::RequestFailureReason::NoCommonAlgorithms:
255 errorDescription = tr(
"Authenticator missing Large Blob support");
257 case QWebEngineWebAuthUxRequest::RequestFailureReason::StorageFull:
258 errorDescription = tr(
"Storage Full");
260 case QWebEngineWebAuthUxRequest::RequestFailureReason::UserConsentDenied:
261 errorDescription = tr(
"User consent denied");
263 case QWebEngineWebAuthUxRequest::RequestFailureReason::WinUserCancelled:
264 errorDescription = tr(
"User Cancelled Request");
268 ui->m_headingLabel->setText(errorHeading);
269 ui->m_description->setText(errorDescription);
270 ui->m_description->adjustSize();
271 ui->m_pinGroupBox->setVisible(
false);
272 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
false);
273 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(isVisibleRetry);
275 ui->buttonBox->button(QDialogButtonBox::Retry)->setFocus();
276 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(
true);
277 ui->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr(
"Close"));
278 scrollArea->setVisible(
false);
281void CDlgWebAuth::onRetry()
286void CDlgWebAuth::clearSelectAccountButtons()
288 QList<QAbstractButton *> buttons = buttonGroup->buttons();
289 auto itr = buttons.begin();
290 while (itr != buttons.end()) {
291 QAbstractButton *radioButton = *itr;
292 selectAccountLayout->removeWidget(radioButton);
293 buttonGroup->removeButton(radioButton);