9#include <QWebEngineView>
10#include <QLoggingCategory>
11#include "ui_DlgWebAuth.h"
13#include "DlgWebAuth.h"
14static Q_LOGGING_CATEGORY(log,
"WebBrowser.Dlg.Auth")
16 : QDialog(parent), uxRequest(request), ui(new
Ui::
CDlgWebAuth)
18 qDebug(log) << Q_FUNC_INFO;
21 buttonGroup =
new QButtonGroup(
this);
22 buttonGroup->setExclusive(
true);
24 scrollArea =
new QScrollArea(
this);
25 selectAccountWidget =
new QWidget(
this);
26 scrollArea->setWidget(selectAccountWidget);
27 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
28 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
29 selectAccountWidget->resize(400, 150);
30 selectAccountLayout =
new QVBoxLayout(selectAccountWidget);
31 ui->m_mainVerticalLayout->addWidget(scrollArea);
32 selectAccountLayout->setAlignment(Qt::AlignTop);
36 connect(ui->buttonBox, &QDialogButtonBox::rejected,
this,
37 qOverload<>(&CDlgWebAuth::onCancelRequest));
39 connect(ui->buttonBox, &QDialogButtonBox::accepted,
this,
40 qOverload<>(&CDlgWebAuth::onAcceptRequest));
41 QAbstractButton *button = ui->buttonBox->button(QDialogButtonBox::Retry);
42 connect(button, &QAbstractButton::clicked,
this, qOverload<>(&CDlgWebAuth::onRetry));
43 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
46CDlgWebAuth::~CDlgWebAuth()
48 qDebug(log) << Q_FUNC_INFO;
49 QList<QAbstractButton *> buttons = buttonGroup->buttons();
50 auto itr = buttons.begin();
51 while (itr != buttons.end()) {
52 QAbstractButton *radioButton = *itr;
59 buttonGroup =
nullptr;
74void CDlgWebAuth::updateDisplay()
76 switch (uxRequest->state()) {
77 case QWebEngineWebAuthUxRequest::WebAuthUxState::SelectAccount:
78 setupSelectAccountUI();
80 case QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin:
83 case QWebEngineWebAuthUxRequest::WebAuthUxState::FinishTokenCollection:
84 setupFinishCollectTokenUI();
86 case QWebEngineWebAuthUxRequest::WebAuthUxState::RequestFailed:
95void CDlgWebAuth::setupSelectAccountUI()
97 ui->m_headingLabel->setText(tr(
"Choose a Passkey"));
98 ui->m_description->setText(tr(
"Which passkey do you want to use for ")
99 + uxRequest->relyingPartyId() + tr(
"? "));
100 ui->m_pinGroupBox->setVisible(
false);
101 ui->m_mainVerticalLayout->removeWidget(ui->m_pinGroupBox);
102 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(
false);
104 clearSelectAccountButtons();
105 scrollArea->setVisible(
true);
106 selectAccountWidget->resize(this->width(), this->height());
107 QStringList userNames = uxRequest->userNames();
109 for (
const QString &name : userNames) {
110 QRadioButton *radioButton =
new QRadioButton(name);
111 selectAccountLayout->addWidget(radioButton);
112 buttonGroup->addButton(radioButton);
115 ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr(
"Ok"));
116 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
true);
117 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(
true);
118 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(
false);
121void CDlgWebAuth::setupFinishCollectTokenUI()
123 clearSelectAccountButtons();
124 ui->m_headingLabel->setText(tr(
"Use your security key with")
125 + uxRequest->relyingPartyId());
126 ui->m_description->setText(
127 tr(
"Touch your security key again to complete the request."));
128 ui->m_pinGroupBox->setVisible(
false);
129 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
false);
130 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(
false);
131 scrollArea->setVisible(
false);
133void CDlgWebAuth::setupCollectPinUI()
135 clearSelectAccountButtons();
136 ui->m_mainVerticalLayout->addWidget(ui->m_pinGroupBox);
137 ui->m_pinGroupBox->setVisible(
true);
138 ui->m_confirmPinLabel->setVisible(
false);
139 ui->m_confirmPinLineEdit->setVisible(
false);
140 ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr(
"Next"));
141 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
true);
142 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(
true);
143 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(
false);
144 scrollArea->setVisible(
false);
146 QWebEngineWebAuthPinRequest pinRequestInfo = uxRequest->pinRequest();
148 if (pinRequestInfo.reason == QWebEngineWebAuthUxRequest::PinEntryReason::Challenge) {
149 ui->m_headingLabel->setText(tr(
"PIN Required"));
150 ui->m_description->setText(tr(
"Enter the PIN for your security key"));
151 ui->m_confirmPinLabel->setVisible(
false);
152 ui->m_confirmPinLineEdit->setVisible(
false);
154 if (pinRequestInfo.reason == QWebEngineWebAuthUxRequest::PinEntryReason::Set) {
155 ui->m_headingLabel->setText(tr(
"New PIN Required"));
156 ui->m_description->setText(tr(
"Set new PIN for your security key"));
158 ui->m_headingLabel->setText(tr(
"Change PIN Required"));
159 ui->m_description->setText(tr(
"Change PIN for your security key"));
161 ui->m_confirmPinLabel->setVisible(
true);
162 ui->m_confirmPinLineEdit->setVisible(
true);
165 QString errorDetails;
166 switch (pinRequestInfo.error) {
167 case QWebEngineWebAuthUxRequest::PinEntryError::NoError:
169 case QWebEngineWebAuthUxRequest::PinEntryError::InternalUvLocked:
170 errorDetails = tr(
"Internal User Verification Locked ");
172 case QWebEngineWebAuthUxRequest::PinEntryError::WrongPin:
173 errorDetails = tr(
"Wrong PIN");
175 case QWebEngineWebAuthUxRequest::PinEntryError::TooShort:
176 errorDetails = tr(
"Too Short");
178 case QWebEngineWebAuthUxRequest::PinEntryError::InvalidCharacters:
179 errorDetails = tr(
"Invalid Characters");
181 case QWebEngineWebAuthUxRequest::PinEntryError::SameAsCurrentPin:
182 errorDetails = tr(
"Same as current PIN");
185 if (!errorDetails.isEmpty()) {
186 errorDetails += tr(
" ") + QString::number(pinRequestInfo.remainingAttempts)
187 + tr(
" attempts remaining");
189 ui->m_pinEntryErrorLabel->setText(errorDetails);
192void CDlgWebAuth::onCancelRequest()
197void CDlgWebAuth::onAcceptRequest()
199 switch (uxRequest->state()) {
200 case QWebEngineWebAuthUxRequest::WebAuthUxState::SelectAccount:
201 if (buttonGroup->checkedButton()) {
202 uxRequest->setSelectedAccount(buttonGroup->checkedButton()->text());
205 case QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin:
206 uxRequest->setPin(ui->m_pinLineEdit->text());
213void CDlgWebAuth::setupErrorUI()
215 clearSelectAccountButtons();
216 QString errorDescription;
217 QString errorHeading = tr(
"Something went wrong");
218 bool isVisibleRetry =
false;
219 switch (uxRequest->requestFailureReason()) {
220 case QWebEngineWebAuthUxRequest::RequestFailureReason::Timeout:
221 errorDescription = tr(
"Request Timeout");
223 case QWebEngineWebAuthUxRequest::RequestFailureReason::KeyNotRegistered:
224 errorDescription = tr(
"Key not registered");
226 case QWebEngineWebAuthUxRequest::RequestFailureReason::KeyAlreadyRegistered:
227 errorDescription = tr(
"You already registered this device."
228 "Try again with device");
229 isVisibleRetry =
true;
231 case QWebEngineWebAuthUxRequest::RequestFailureReason::SoftPinBlock:
233 tr(
"The security key is locked because the wrong PIN was entered too many times."
234 "To unlock it, remove and reinsert it.");
235 isVisibleRetry =
true;
237 case QWebEngineWebAuthUxRequest::RequestFailureReason::HardPinBlock:
239 tr(
"The security key is locked because the wrong PIN was entered too many times."
240 " You'll need to reset the security key.");
242 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorRemovedDuringPinEntry:
244 tr(
"Authenticator removed during verification. Please reinsert and try again");
246 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingResidentKeys:
247 errorDescription = tr(
"Authenticator doesn't have resident key support");
249 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingUserVerification:
250 errorDescription = tr(
"Authenticator missing user verification");
252 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingLargeBlob:
253 errorDescription = tr(
"Authenticator missing Large Blob support");
255 case QWebEngineWebAuthUxRequest::RequestFailureReason::NoCommonAlgorithms:
256 errorDescription = tr(
"Authenticator missing Large Blob support");
258 case QWebEngineWebAuthUxRequest::RequestFailureReason::StorageFull:
259 errorDescription = tr(
"Storage Full");
261 case QWebEngineWebAuthUxRequest::RequestFailureReason::UserConsentDenied:
262 errorDescription = tr(
"User consent denied");
264 case QWebEngineWebAuthUxRequest::RequestFailureReason::WinUserCancelled:
265 errorDescription = tr(
"User Cancelled Request");
269 ui->m_headingLabel->setText(errorHeading);
270 ui->m_description->setText(errorDescription);
271 ui->m_description->adjustSize();
272 ui->m_pinGroupBox->setVisible(
false);
273 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
false);
274 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(isVisibleRetry);
276 ui->buttonBox->button(QDialogButtonBox::Retry)->setFocus();
277 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(
true);
278 ui->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr(
"Close"));
279 scrollArea->setVisible(
false);
282void CDlgWebAuth::onRetry()
287void CDlgWebAuth::clearSelectAccountButtons()
289 QList<QAbstractButton *> buttons = buttonGroup->buttons();
290 auto itr = buttons.begin();
291 while (itr != buttons.end()) {
292 QAbstractButton *radioButton = *itr;
293 selectAccountLayout->removeWidget(radioButton);
294 buttonGroup->removeButton(radioButton);