mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-03-13 01:26:37 -04:00
Passkeys: Register to an existing entry
This commit is contained in:
parent
505f338d28
commit
c9d71e7781
@ -866,23 +866,6 @@ Please select the correct database for saving credentials.</source>
|
|||||||
<numerusform></numerusform>
|
<numerusform></numerusform>
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Do you want to register Passkey for:</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Existing Passkey found.
|
|
||||||
Do you want to register a new Passkey for:</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Select the existing Passkey and press Update to replace it.</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Authenticate Passkey credentials for:</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Relying Party: %1</source>
|
<source>Relying Party: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@ -895,6 +878,27 @@ Do you want to register a new Passkey for:</source>
|
|||||||
<source>KeePassXC - Passkey credentials</source>
|
<source>KeePassXC - Passkey credentials</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Add to existing entry</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Existing passkey found.
|
||||||
|
Do you want to register a new passkey for:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Select the existing passkey and press Update to replace it.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Authenticate passkey credentials for:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Do you want to register a passkey for:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>BrowserService</name>
|
<name>BrowserService</name>
|
||||||
@ -935,11 +939,6 @@ Do you want to delete the entry?
|
|||||||
<source>%1 (Passkey)</source>
|
<source>%1 (Passkey)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Entry already has a Passkey.
|
|
||||||
Do you want to overwrite the Passkey in %1 - %2?</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>KeePassXC - Create a new group</source>
|
<source>KeePassXC - Create a new group</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@ -952,10 +951,6 @@ Do you want to overwrite the Passkey in %1 - %2?</source>
|
|||||||
<source>KeePassXC - Overwrite existing key?</source>
|
<source>KeePassXC - Overwrite existing key?</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>KeePassXC - Update Passkey</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>KeePassXC - Update Entry</source>
|
<source>KeePassXC - Update Entry</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@ -972,6 +967,27 @@ Do you want to overwrite the Passkey in %1 - %2?</source>
|
|||||||
<source>Passkey</source>
|
<source>Passkey</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>KeePassXC - Passkey credentials</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Register a new passkey to this entry:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>KeePassXC - Update passkey</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Entry already has a passkey.
|
||||||
|
Do you want to overwrite the passkey in %1 - %2?</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Register</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Abort</source>
|
<source>Abort</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@ -1253,11 +1269,11 @@ Would you like to migrate your existing settings now?</source>
|
|||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Allows using insecure http://localhost with Passkeys for testing purposes.</source>
|
<source>Allows using insecure http://localhost with passkeys for testing purposes.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Allow using localhost with Passkeys</source>
|
<source>Allow using localhost with passkeys</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
@ -6086,10 +6102,6 @@ We recommend you use the AppImage available on our downloads page.</source>
|
|||||||
<source>KeePassXC - Passkey Export</source>
|
<source>KeePassXC - Passkey Export</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Export the following Passkey entries.</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Filenames will be generated with title and .passkey file extension.</source>
|
<source>Filenames will be generated with title and .passkey file extension.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@ -6110,6 +6122,10 @@ We recommend you use the AppImage available on our downloads page.</source>
|
|||||||
<source>Export to folder</source>
|
<source>Export to folder</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Export the following passkey entries.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>PasskeyExporter</name>
|
<name>PasskeyExporter</name>
|
||||||
@ -6166,28 +6182,28 @@ Do you want to overwrite it?
|
|||||||
<source>Cancel</source>
|
<source>Cancel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Import the following Passkey:</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Entry</source>
|
<source>Entry</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Import the following Passkey to this entry:</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Create new entry</source>
|
<source>Create new entry</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Default Passkeys group (Imported Passkeys)</source>
|
<source>Relying Party: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Relying Party: %1</source>
|
<source>Import the following passkey:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Import the following passkey to this entry:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Default passkeys group (Imported Passkeys)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
@ -6201,10 +6217,6 @@ Do you want to overwrite it?
|
|||||||
<source>All files</source>
|
<source>All files</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Open Passkey file</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Cannot open file</source>
|
<source>Cannot open file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@ -6214,23 +6226,27 @@ Do you want to overwrite it?
|
|||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Cannot import Passkey</source>
|
<source>Open passkey file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Cannot import Passkey file "%1". Data is missing.</source>
|
<source>Cannot import passkey</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Cannot import Passkey file "%1". Private key is missing or malformed.</source>
|
<source>Cannot import passkey file "%1". Data is missing.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Cannot import Passkey file "%1".
|
<source>Cannot import passkey file "%1".
|
||||||
The following data is missing:
|
The following data is missing:
|
||||||
%2</source>
|
%2</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Cannot import passkey file "%1". Private key is missing or malformed.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>PasswordEditWidget</name>
|
<name>PasswordEditWidget</name>
|
||||||
@ -8352,10 +8368,6 @@ This option is deprecated, use --set-key-file instead.</source>
|
|||||||
<source>Wait for timer to expire</source>
|
<source>Wait for timer to expire</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unknown Passkeys error</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Challenge is shorter than required minimum length</source>
|
<source>Challenge is shorter than required minimum length</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@ -8486,6 +8498,10 @@ This option is deprecated, use --set-key-file instead.</source>
|
|||||||
<source>Unsupported KDF type, cannot decrypt json file</source>
|
<source>Unsupported KDF type, cannot decrypt json file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unknown passkeys error</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>QtIOCompressor</name>
|
<name>QtIOCompressor</name>
|
||||||
@ -8812,14 +8828,6 @@ This option is deprecated, use --set-key-file instead.</source>
|
|||||||
<source>List of entry URLs</source>
|
<source>List of entry URLs</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Please wait, list of entries with Passkeys is being updated…</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>No entries with Passkeys.</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Title</source>
|
<source>Title</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
@ -8867,6 +8875,14 @@ This option is deprecated, use --set-key-file instead.</source>
|
|||||||
<source>The passkey file will be vulnerable to theft and unauthorized use, if left unsecured. Are you sure you want to continue?</source>
|
<source>The passkey file will be vulnerable to theft and unauthorized use, if left unsecured. Are you sure you want to continue?</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Please wait, list of entries with passkeys is being updated…</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No entries with passkeys.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ReportsWidgetStatistics</name>
|
<name>ReportsWidgetStatistics</name>
|
||||||
|
@ -151,7 +151,7 @@ QString BrowserMessageBuilder::getErrorMessage(const int errorCode) const
|
|||||||
case ERROR_PASSKEYS_WAIT_FOR_LIFETIMER:
|
case ERROR_PASSKEYS_WAIT_FOR_LIFETIMER:
|
||||||
return QObject::tr("Wait for timer to expire");
|
return QObject::tr("Wait for timer to expire");
|
||||||
case ERROR_PASSKEYS_UNKNOWN_ERROR:
|
case ERROR_PASSKEYS_UNKNOWN_ERROR:
|
||||||
return QObject::tr("Unknown Passkeys error");
|
return QObject::tr("Unknown passkeys error");
|
||||||
case ERROR_PASSKEYS_INVALID_CHALLENGE:
|
case ERROR_PASSKEYS_INVALID_CHALLENGE:
|
||||||
return QObject::tr("Challenge is shorter than required minimum length");
|
return QObject::tr("Challenge is shorter than required minimum length");
|
||||||
case ERROR_PASSKEYS_INVALID_USER_ID:
|
case ERROR_PASSKEYS_INVALID_USER_ID:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2024 KeePassXC Team <team@keepassxc.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -32,7 +32,6 @@ BrowserPasskeysConfirmationDialog::BrowserPasskeysConfirmationDialog(QWidget* pa
|
|||||||
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
|
||||||
|
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
m_ui->updateButton->setVisible(false);
|
|
||||||
m_ui->verticalLayout->setAlignment(Qt::AlignTop);
|
m_ui->verticalLayout->setAlignment(Qt::AlignTop);
|
||||||
|
|
||||||
connect(m_ui->credentialsTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(accept()));
|
connect(m_ui->credentialsTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(accept()));
|
||||||
@ -53,21 +52,22 @@ void BrowserPasskeysConfirmationDialog::registerCredential(const QString& userna
|
|||||||
const QList<Entry*>& existingEntries,
|
const QList<Entry*>& existingEntries,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
m_ui->firstLabel->setText(tr("Do you want to register Passkey for:"));
|
m_ui->firstLabel->setText(tr("Do you want to register a passkey for:"));
|
||||||
m_ui->relyingPartyLabel->setText(tr("Relying Party: %1").arg(relyingParty));
|
m_ui->relyingPartyLabel->setText(tr("Relying Party: %1").arg(relyingParty));
|
||||||
m_ui->usernameLabel->setText(tr("Username: %1").arg(username));
|
m_ui->usernameLabel->setText(tr("Username: %1").arg(username));
|
||||||
|
m_ui->updateButton->setVisible(true);
|
||||||
m_ui->secondLabel->setText("");
|
m_ui->secondLabel->setText("");
|
||||||
|
|
||||||
if (!existingEntries.isEmpty()) {
|
if (!existingEntries.isEmpty()) {
|
||||||
m_ui->firstLabel->setText(tr("Existing Passkey found.\nDo you want to register a new Passkey for:"));
|
m_ui->firstLabel->setText(tr("Existing passkey found.\nDo you want to register a new passkey for:"));
|
||||||
m_ui->secondLabel->setText(tr("Select the existing Passkey and press Update to replace it."));
|
m_ui->secondLabel->setText(tr("Select the existing passkey and press Update to replace it."));
|
||||||
|
m_ui->updateButton->setText(tr("Update"));
|
||||||
m_ui->updateButton->setVisible(true);
|
|
||||||
m_ui->confirmButton->setText(tr("Register new"));
|
m_ui->confirmButton->setText(tr("Register new"));
|
||||||
updateEntriesToTable(existingEntries);
|
updateEntriesToTable(existingEntries);
|
||||||
} else {
|
} else {
|
||||||
m_ui->verticalLayout->setSizeConstraint(QLayout::SetFixedSize);
|
m_ui->verticalLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
m_ui->confirmButton->setText(tr("Register"));
|
m_ui->confirmButton->setText(tr("Register"));
|
||||||
|
m_ui->updateButton->setText(tr("Add to existing entry"));
|
||||||
m_ui->credentialsTable->setVisible(false);
|
m_ui->credentialsTable->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,9 +78,10 @@ void BrowserPasskeysConfirmationDialog::authenticateCredential(const QList<Entry
|
|||||||
const QString& relyingParty,
|
const QString& relyingParty,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
m_ui->firstLabel->setText(tr("Authenticate Passkey credentials for:"));
|
m_ui->firstLabel->setText(tr("Authenticate passkey credentials for:"));
|
||||||
m_ui->relyingPartyLabel->setText(tr("Relying Party: %1").arg(relyingParty));
|
m_ui->relyingPartyLabel->setText(tr("Relying Party: %1").arg(relyingParty));
|
||||||
m_ui->usernameLabel->setVisible(false);
|
m_ui->usernameLabel->setVisible(false);
|
||||||
|
m_ui->updateButton->setVisible(false);
|
||||||
m_ui->secondLabel->setText("");
|
m_ui->secondLabel->setText("");
|
||||||
updateEntriesToTable(entries);
|
updateEntriesToTable(entries);
|
||||||
startCounter(timeout);
|
startCounter(timeout);
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "BrowserPasskeysClient.h"
|
#include "BrowserPasskeysClient.h"
|
||||||
#include "BrowserPasskeysConfirmationDialog.h"
|
#include "BrowserPasskeysConfirmationDialog.h"
|
||||||
#include "PasskeyUtils.h"
|
#include "PasskeyUtils.h"
|
||||||
|
#include "gui/passkeys/PasskeyImporter.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
#include "gui/osutils/macutils/MacUtils.h"
|
#include "gui/osutils/macutils/MacUtils.h"
|
||||||
@ -605,13 +606,33 @@ QJsonObject BrowserService::showPasskeysRegisterPrompt(const QJsonObject& public
|
|||||||
|
|
||||||
const auto rpName = publicKeyOptions["rp"]["name"].toString();
|
const auto rpName = publicKeyOptions["rp"]["name"].toString();
|
||||||
if (confirmDialog.isPasskeyUpdated()) {
|
if (confirmDialog.isPasskeyUpdated()) {
|
||||||
addPasskeyToEntry(confirmDialog.getSelectedEntry(),
|
// If no entry is selected, show the import dialog for manual entry selection
|
||||||
rpId,
|
auto selectedEntry = confirmDialog.getSelectedEntry();
|
||||||
rpName,
|
if (!selectedEntry) {
|
||||||
username,
|
PasskeyImporter passkeyImporter(m_currentDatabaseWidget);
|
||||||
publicKeyCredentials.credentialId,
|
const auto result = passkeyImporter.showImportDialog(db,
|
||||||
userId,
|
nullptr,
|
||||||
publicKeyCredentials.key);
|
origin,
|
||||||
|
rpId,
|
||||||
|
username,
|
||||||
|
publicKeyCredentials.credentialId,
|
||||||
|
userId,
|
||||||
|
publicKeyCredentials.key,
|
||||||
|
tr("KeePassXC - Passkey credentials"),
|
||||||
|
tr("Register a new passkey to this entry:"),
|
||||||
|
tr("Register"));
|
||||||
|
if (!result) {
|
||||||
|
return getPasskeyError(ERROR_PASSKEYS_REQUEST_CANCELED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addPasskeyToEntry(selectedEntry,
|
||||||
|
rpId,
|
||||||
|
rpName,
|
||||||
|
username,
|
||||||
|
publicKeyCredentials.credentialId,
|
||||||
|
userId,
|
||||||
|
publicKeyCredentials.key);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
addPasskeyToGroup(db,
|
addPasskeyToGroup(db,
|
||||||
nullptr,
|
nullptr,
|
||||||
@ -737,8 +758,8 @@ void BrowserService::addPasskeyToEntry(Entry* entry,
|
|||||||
// Ask confirmation if entry already contains a Passkey
|
// Ask confirmation if entry already contains a Passkey
|
||||||
if (entry->hasPasskey()) {
|
if (entry->hasPasskey()) {
|
||||||
if (MessageBox::question(m_currentDatabaseWidget,
|
if (MessageBox::question(m_currentDatabaseWidget,
|
||||||
tr("KeePassXC - Update Passkey"),
|
tr("KeePassXC - Update passkey"),
|
||||||
tr("Entry already has a Passkey.\nDo you want to overwrite the Passkey in %1 - %2?")
|
tr("Entry already has a passkey.\nDo you want to overwrite the passkey in %1 - %2?")
|
||||||
.arg(entry->title(), passkeyUtils()->getUsernameFromEntry(entry)),
|
.arg(entry->title(), passkeyUtils()->getUsernameFromEntry(entry)),
|
||||||
MessageBox::Overwrite | MessageBox::Cancel,
|
MessageBox::Overwrite | MessageBox::Cancel,
|
||||||
MessageBox::Cancel)
|
MessageBox::Cancel)
|
||||||
|
@ -313,10 +313,10 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="allowLocalhostWithPasskeys">
|
<widget class="QCheckBox" name="allowLocalhostWithPasskeys">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Allows using insecure http://localhost with Passkeys for testing purposes.</string>
|
<string>Allows using insecure http://localhost with passkeys for testing purposes.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Allow using localhost with Passkeys</string>
|
<string>Allow using localhost with passkeys</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2024 KeePassXC Team <team@keepassxc.org>
|
||||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@ -1415,7 +1415,7 @@ void DatabaseWidget::switchToPasskeys()
|
|||||||
|
|
||||||
void DatabaseWidget::showImportPasskeyDialog(bool isEntry)
|
void DatabaseWidget::showImportPasskeyDialog(bool isEntry)
|
||||||
{
|
{
|
||||||
PasskeyImporter passkeyImporter;
|
PasskeyImporter passkeyImporter(this);
|
||||||
|
|
||||||
if (isEntry) {
|
if (isEntry) {
|
||||||
auto currentEntry = currentSelectedEntry();
|
auto currentEntry = currentSelectedEntry();
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Export the following Passkey entries.</string>
|
<string>Export the following passkey entries.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
@ -27,13 +27,18 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
PasskeyExporter::PasskeyExporter(QWidget* parent)
|
||||||
|
: m_parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void PasskeyExporter::showExportDialog(const QList<Entry*>& items)
|
void PasskeyExporter::showExportDialog(const QList<Entry*>& items)
|
||||||
{
|
{
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PasskeyExportDialog passkeyExportDialog;
|
PasskeyExportDialog passkeyExportDialog(m_parent);
|
||||||
passkeyExportDialog.setEntries(items);
|
passkeyExportDialog.setEntries(items);
|
||||||
auto ret = passkeyExportDialog.exec();
|
auto ret = passkeyExportDialog.exec();
|
||||||
|
|
||||||
@ -69,7 +74,7 @@ void PasskeyExporter::exportSelectedEntry(const Entry* entry, const QString& fol
|
|||||||
{
|
{
|
||||||
const auto fullPath = QString("%1/%2.passkey").arg(folder, Tools::cleanFilename(entry->title()));
|
const auto fullPath = QString("%1/%2.passkey").arg(folder, Tools::cleanFilename(entry->title()));
|
||||||
if (QFile::exists(fullPath)) {
|
if (QFile::exists(fullPath)) {
|
||||||
auto dialogResult = MessageBox::warning(nullptr,
|
auto dialogResult = MessageBox::warning(m_parent,
|
||||||
tr("KeePassXC: Passkey Export"),
|
tr("KeePassXC: Passkey Export"),
|
||||||
tr("File \"%1.passkey\" already exists.\n"
|
tr("File \"%1.passkey\" already exists.\n"
|
||||||
"Do you want to overwrite it?\n")
|
"Do you want to overwrite it?\n")
|
||||||
@ -84,7 +89,7 @@ void PasskeyExporter::exportSelectedEntry(const Entry* entry, const QString& fol
|
|||||||
QFile passkeyFile(fullPath);
|
QFile passkeyFile(fullPath);
|
||||||
if (!passkeyFile.open(QIODevice::WriteOnly)) {
|
if (!passkeyFile.open(QIODevice::WriteOnly)) {
|
||||||
MessageBox::information(
|
MessageBox::information(
|
||||||
nullptr, tr("Cannot open file"), tr("Cannot open file \"%1\" for writing.").arg(fullPath));
|
m_parent, tr("Cannot open file"), tr("Cannot open file \"%1\" for writing.").arg(fullPath));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2024 KeePassXC Team <team@keepassxc.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
class Entry;
|
class Entry;
|
||||||
|
|
||||||
@ -28,12 +30,15 @@ class PasskeyExporter : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PasskeyExporter() = default;
|
explicit PasskeyExporter(QWidget* parent = nullptr);
|
||||||
|
|
||||||
void showExportDialog(const QList<Entry*>& items);
|
void showExportDialog(const QList<Entry*>& items);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void exportSelectedEntry(const Entry* entry, const QString& folder);
|
void exportSelectedEntry(const Entry* entry, const QString& folder);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointer<QWidget> m_parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSXC_PASSKEYEXPORTER_H
|
#endif // KEEPASSXC_PASSKEYEXPORTER_H
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2024 KeePassXC Team <team@keepassxc.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -48,14 +48,17 @@ PasskeyImportDialog::~PasskeyImportDialog()
|
|||||||
void PasskeyImportDialog::setInfo(const QString& relyingParty,
|
void PasskeyImportDialog::setInfo(const QString& relyingParty,
|
||||||
const QString& username,
|
const QString& username,
|
||||||
const QSharedPointer<Database>& database,
|
const QSharedPointer<Database>& database,
|
||||||
bool isEntry)
|
bool isEntry,
|
||||||
|
const QString& titleText,
|
||||||
|
const QString& infoText,
|
||||||
|
const QString& importButtonText)
|
||||||
{
|
{
|
||||||
m_ui->relyingPartyLabel->setText(tr("Relying Party: %1").arg(relyingParty));
|
m_ui->relyingPartyLabel->setText(tr("Relying Party: %1").arg(relyingParty));
|
||||||
m_ui->usernameLabel->setText(tr("Username: %1").arg(username));
|
m_ui->usernameLabel->setText(tr("Username: %1").arg(username));
|
||||||
|
|
||||||
if (isEntry) {
|
if (isEntry) {
|
||||||
m_ui->verticalLayout->setSizeConstraint(QLayout::SetFixedSize);
|
m_ui->verticalLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
m_ui->infoLabel->setText(tr("Import the following Passkey to this entry:"));
|
m_ui->infoLabel->setText(tr("Import the following passkey to this entry:"));
|
||||||
m_ui->groupBox->setVisible(false);
|
m_ui->groupBox->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +73,18 @@ void PasskeyImportDialog::setInfo(const QString& relyingParty,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_ui->selectDatabaseCombobBox->setEnabled(openDatabaseCount > 1);
|
m_ui->selectDatabaseCombobBox->setEnabled(openDatabaseCount > 1);
|
||||||
|
|
||||||
|
if (!titleText.isEmpty()) {
|
||||||
|
setWindowTitle(titleText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!infoText.isEmpty()) {
|
||||||
|
m_ui->infoLabel->setText(infoText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!importButtonText.isEmpty()) {
|
||||||
|
m_ui->importButton->setText(importButtonText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Database> PasskeyImportDialog::getSelectedDatabase() const
|
QSharedPointer<Database> PasskeyImportDialog::getSelectedDatabase() const
|
||||||
@ -155,7 +170,7 @@ void PasskeyImportDialog::addGroups()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_ui->selectGroupComboBox->clear();
|
m_ui->selectGroupComboBox->clear();
|
||||||
m_ui->selectGroupComboBox->addItem(tr("Default Passkeys group (Imported Passkeys)"), {});
|
m_ui->selectGroupComboBox->addItem(tr("Default passkeys group (Imported Passkeys)"), {});
|
||||||
|
|
||||||
for (const auto& group : m_selectedDatabase->rootGroup()->groupsRecursive(true)) {
|
for (const auto& group : m_selectedDatabase->rootGroup()->groupsRecursive(true)) {
|
||||||
if (!group || group->isRecycled() || group == m_selectedDatabase->metadata()->recycleBin()) {
|
if (!group || group->isRecycled() || group == m_selectedDatabase->metadata()->recycleBin()) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2024 KeePassXC Team <team@keepassxc.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -39,7 +39,10 @@ public:
|
|||||||
void setInfo(const QString& relyingParty,
|
void setInfo(const QString& relyingParty,
|
||||||
const QString& username,
|
const QString& username,
|
||||||
const QSharedPointer<Database>& database,
|
const QSharedPointer<Database>& database,
|
||||||
bool isEntry);
|
bool isEntry,
|
||||||
|
const QString& titleText = {},
|
||||||
|
const QString& infoText = {},
|
||||||
|
const QString& importButtonText = {});
|
||||||
QSharedPointer<Database> getSelectedDatabase() const;
|
QSharedPointer<Database> getSelectedDatabase() const;
|
||||||
QUuid getSelectedEntryUuid() const;
|
QUuid getSelectedEntryUuid() const;
|
||||||
QUuid getSelectedGroupUuid() const;
|
QUuid getSelectedGroupUuid() const;
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Import the following Passkey:</string>
|
<string>Import the following passkey:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2024 KeePassXC Team <team@keepassxc.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -30,11 +30,16 @@
|
|||||||
|
|
||||||
static const QString IMPORTED_PASSKEYS_GROUP = QStringLiteral("Imported Passkeys");
|
static const QString IMPORTED_PASSKEYS_GROUP = QStringLiteral("Imported Passkeys");
|
||||||
|
|
||||||
|
PasskeyImporter::PasskeyImporter(QWidget* parent)
|
||||||
|
: m_parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void PasskeyImporter::importPasskey(QSharedPointer<Database>& database, Entry* entry)
|
void PasskeyImporter::importPasskey(QSharedPointer<Database>& database, Entry* entry)
|
||||||
{
|
{
|
||||||
auto filter = QString("%1 (*.passkey);;%2 (*)").arg(tr("Passkey file"), tr("All files"));
|
auto filter = QString("%1 (*.passkey);;%2 (*)").arg(tr("Passkey file"), tr("All files"));
|
||||||
auto fileName =
|
auto fileName =
|
||||||
fileDialog()->getOpenFileName(nullptr, tr("Open Passkey file"), FileDialog::getLastDir("passkey"), filter);
|
fileDialog()->getOpenFileName(nullptr, tr("Open passkey file"), FileDialog::getLastDir("passkey"), filter);
|
||||||
if (fileName.isEmpty()) {
|
if (fileName.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -56,9 +61,9 @@ void PasskeyImporter::importSelectedFile(QFile& file, QSharedPointer<Database>&
|
|||||||
const auto fileData = file.readAll();
|
const auto fileData = file.readAll();
|
||||||
const auto passkeyObject = browserMessageBuilder()->getJsonObject(fileData);
|
const auto passkeyObject = browserMessageBuilder()->getJsonObject(fileData);
|
||||||
if (passkeyObject.isEmpty()) {
|
if (passkeyObject.isEmpty()) {
|
||||||
MessageBox::information(nullptr,
|
MessageBox::information(m_parent,
|
||||||
tr("Cannot import Passkey"),
|
tr("Cannot import passkey"),
|
||||||
tr("Cannot import Passkey file \"%1\". Data is missing.").arg(file.fileName()));
|
tr("Cannot import passkey file \"%1\". Data is missing.").arg(file.fileName()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,43 +75,46 @@ void PasskeyImporter::importSelectedFile(QFile& file, QSharedPointer<Database>&
|
|||||||
<< "credentialId"
|
<< "credentialId"
|
||||||
<< "userHandle"
|
<< "userHandle"
|
||||||
<< "privateKey");
|
<< "privateKey");
|
||||||
|
|
||||||
if (!missingKeys.isEmpty()) {
|
if (!missingKeys.isEmpty()) {
|
||||||
MessageBox::information(nullptr,
|
MessageBox::information(m_parent,
|
||||||
tr("Cannot import Passkey"),
|
tr("Cannot import passkey"),
|
||||||
tr("Cannot import Passkey file \"%1\".\nThe following data is missing:\n%2")
|
tr("Cannot import passkey file \"%1\".\nThe following data is missing:\n%2")
|
||||||
.arg(file.fileName(), missingKeys.join(", ")));
|
.arg(file.fileName(), missingKeys.join(", ")));
|
||||||
} else if (!privateKey.startsWith("-----BEGIN PRIVATE KEY-----")
|
} else if (!privateKey.startsWith("-----BEGIN PRIVATE KEY-----")
|
||||||
|| !privateKey.trimmed().endsWith("-----END PRIVATE KEY-----")) {
|
|| !privateKey.trimmed().endsWith("-----END PRIVATE KEY-----")) {
|
||||||
MessageBox::information(
|
MessageBox::information(
|
||||||
nullptr,
|
m_parent,
|
||||||
tr("Cannot import Passkey"),
|
tr("Cannot import passkey"),
|
||||||
tr("Cannot import Passkey file \"%1\". Private key is missing or malformed.").arg(file.fileName()));
|
tr("Cannot import passkey file \"%1\". Private key is missing or malformed.").arg(file.fileName()));
|
||||||
} else {
|
} else {
|
||||||
const auto relyingParty = passkeyObject["relyingParty"].toString();
|
const auto relyingParty = passkeyObject["relyingParty"].toString();
|
||||||
const auto url = passkeyObject["url"].toString();
|
const auto url = passkeyObject["url"].toString();
|
||||||
const auto username = passkeyObject["username"].toString();
|
const auto username = passkeyObject["username"].toString();
|
||||||
const auto credentialId = passkeyObject["credentialId"].toString();
|
const auto credentialId = passkeyObject["credentialId"].toString();
|
||||||
const auto userHandle = passkeyObject["userHandle"].toString();
|
const auto userHandle = passkeyObject["userHandle"].toString();
|
||||||
showImportDialog(database, url, relyingParty, username, credentialId, userHandle, privateKey, entry);
|
showImportDialog(database, entry, url, relyingParty, username, credentialId, userHandle, privateKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PasskeyImporter::showImportDialog(QSharedPointer<Database>& database,
|
bool PasskeyImporter::showImportDialog(QSharedPointer<Database>& database,
|
||||||
|
Entry* entry,
|
||||||
const QString& url,
|
const QString& url,
|
||||||
const QString& relyingParty,
|
const QString& relyingParty,
|
||||||
const QString& username,
|
const QString& username,
|
||||||
const QString& credentialId,
|
const QString& credentialId,
|
||||||
const QString& userHandle,
|
const QString& userHandle,
|
||||||
const QString& privateKey,
|
const QString& privateKey,
|
||||||
Entry* entry)
|
const QString& titleText,
|
||||||
|
const QString& infoText,
|
||||||
|
const QString& importButtonText)
|
||||||
{
|
{
|
||||||
PasskeyImportDialog passkeyImportDialog;
|
PasskeyImportDialog passkeyImportDialog(m_parent);
|
||||||
passkeyImportDialog.setInfo(relyingParty, username, database, entry != nullptr);
|
passkeyImportDialog.setInfo(
|
||||||
|
relyingParty, username, database, entry != nullptr, titleText, infoText, importButtonText);
|
||||||
|
|
||||||
auto ret = passkeyImportDialog.exec();
|
auto ret = passkeyImportDialog.exec();
|
||||||
if (ret != QDialog::Accepted) {
|
if (ret != QDialog::Accepted) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto db = passkeyImportDialog.getSelectedDatabase();
|
auto db = passkeyImportDialog.getSelectedDatabase();
|
||||||
@ -118,7 +126,7 @@ void PasskeyImporter::showImportDialog(QSharedPointer<Database>& database,
|
|||||||
if (entry) {
|
if (entry) {
|
||||||
browserService()->addPasskeyToEntry(
|
browserService()->addPasskeyToEntry(
|
||||||
entry, relyingParty, relyingParty, username, credentialId, userHandle, privateKey);
|
entry, relyingParty, relyingParty, username, credentialId, userHandle, privateKey);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import to entry selected instead of creating a new one
|
// Import to entry selected instead of creating a new one
|
||||||
@ -134,7 +142,7 @@ void PasskeyImporter::showImportDialog(QSharedPointer<Database>& database,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group settings. Use default group "Imported Passkeys" if user did not select a specific one.
|
// Group settings. Use default group "Imported Passkeys" if user did not select a specific one.
|
||||||
@ -153,6 +161,8 @@ void PasskeyImporter::showImportDialog(QSharedPointer<Database>& database,
|
|||||||
|
|
||||||
browserService()->addPasskeyToGroup(
|
browserService()->addPasskeyToGroup(
|
||||||
db, group, url, relyingParty, relyingParty, username, credentialId, userHandle, privateKey);
|
db, group, url, relyingParty, relyingParty, username, credentialId, userHandle, privateKey);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Group* PasskeyImporter::getDefaultGroup(QSharedPointer<Database>& database) const
|
Group* PasskeyImporter::getDefaultGroup(QSharedPointer<Database>& database) const
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2024 KeePassXC Team <team@keepassxc.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -21,7 +21,9 @@
|
|||||||
#include "core/Database.h"
|
#include "core/Database.h"
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
class Entry;
|
class Entry;
|
||||||
|
|
||||||
@ -30,21 +32,27 @@ class PasskeyImporter : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PasskeyImporter() = default;
|
explicit PasskeyImporter(QWidget* parent = nullptr);
|
||||||
|
|
||||||
void importPasskey(QSharedPointer<Database>& database, Entry* entry = nullptr);
|
void importPasskey(QSharedPointer<Database>& database, Entry* entry = nullptr);
|
||||||
|
bool showImportDialog(QSharedPointer<Database>& database,
|
||||||
private:
|
Entry* entry,
|
||||||
void importSelectedFile(QFile& file, QSharedPointer<Database>& database, Entry* entry);
|
|
||||||
void showImportDialog(QSharedPointer<Database>& database,
|
|
||||||
const QString& url,
|
const QString& url,
|
||||||
const QString& relyingParty,
|
const QString& relyingParty,
|
||||||
const QString& username,
|
const QString& username,
|
||||||
const QString& credentialId,
|
const QString& credentialId,
|
||||||
const QString& userHandle,
|
const QString& userHandle,
|
||||||
const QString& privateKey,
|
const QString& privateKey,
|
||||||
Entry* entry);
|
const QString& titleText = {},
|
||||||
|
const QString& infoText = {},
|
||||||
|
const QString& importButtonText = {});
|
||||||
|
|
||||||
|
private:
|
||||||
|
void importSelectedFile(QFile& file, QSharedPointer<Database>& database, Entry* entry);
|
||||||
Group* getDefaultGroup(QSharedPointer<Database>& database) const;
|
Group* getDefaultGroup(QSharedPointer<Database>& database) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointer<QWidget> m_parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSXC_PASSKEYIMPORTER_H
|
#endif // KEEPASSXC_PASSKEYIMPORTER_H
|
||||||
|
@ -152,7 +152,7 @@ void ReportsWidgetPasskeys::loadSettings(QSharedPointer<Database> db)
|
|||||||
m_rowToEntry.clear();
|
m_rowToEntry.clear();
|
||||||
|
|
||||||
auto row = QList<QStandardItem*>();
|
auto row = QList<QStandardItem*>();
|
||||||
row << new QStandardItem(tr("Please wait, list of entries with Passkeys is being updated…"));
|
row << new QStandardItem(tr("Please wait, list of entries with passkeys is being updated…"));
|
||||||
m_referencesModel->appendRow(row);
|
m_referencesModel->appendRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ void ReportsWidgetPasskeys::updateEntries()
|
|||||||
|
|
||||||
// Set the table header
|
// Set the table header
|
||||||
if (m_referencesModel->rowCount() == 0) {
|
if (m_referencesModel->rowCount() == 0) {
|
||||||
m_referencesModel->setHorizontalHeaderLabels(QStringList() << tr("No entries with Passkeys."));
|
m_referencesModel->setHorizontalHeaderLabels(QStringList() << tr("No entries with passkeys."));
|
||||||
} else {
|
} else {
|
||||||
m_referencesModel->setHorizontalHeaderLabels(QStringList() << tr("Title") << tr("Path") << tr("Username")
|
m_referencesModel->setHorizontalHeaderLabels(QStringList() << tr("Title") << tr("Path") << tr("Username")
|
||||||
<< tr("Relying Party") << tr("URLs"));
|
<< tr("Relying Party") << tr("URLs"));
|
||||||
@ -282,7 +282,7 @@ void ReportsWidgetPasskeys::selectionChanged()
|
|||||||
|
|
||||||
void ReportsWidgetPasskeys::importPasskey()
|
void ReportsWidgetPasskeys::importPasskey()
|
||||||
{
|
{
|
||||||
PasskeyImporter passkeyImporter;
|
PasskeyImporter passkeyImporter(this);
|
||||||
passkeyImporter.importPasskey(m_db);
|
passkeyImporter.importPasskey(m_db);
|
||||||
|
|
||||||
updateEntries();
|
updateEntries();
|
||||||
@ -300,6 +300,6 @@ void ReportsWidgetPasskeys::exportPasskey()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PasskeyExporter passkeyExporter;
|
PasskeyExporter passkeyExporter(this);
|
||||||
passkeyExporter.showExportDialog(getSelectedEntries());
|
passkeyExporter.showExportDialog(getSelectedEntries());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user