15#include <QInputDialog>
19#define WIN32_LEAN_AND_MEAN
20#define WIN32_EXTRA_LEAN
31 : m_mainWindow(mainWindow), freshStart(true) {
33 clearClipboardTimer.setSingleShot(
true);
34 connect(&clearClipboardTimer, &QTimer::timeout,
this,
37#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
38#pragma GCC diagnostic push
39#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
41 QObject::connect(qApp, &QApplication::aboutToQuit,
this,
43#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
44#pragma GCC diagnostic pop
59 if (fusedav.state() == QProcess::Running) {
61 fusedav.waitForFinished(2000);
80 if (version.isEmpty()) {
82 dbg() <<
"assuming fresh install";
111 m_mainWindow->config();
129void QtPass::setMainWindow() {
132 fusedav.setParent(m_mainWindow);
139 &QtPass::passShowHandlerFinished);
149 dbg() <<
"Pass git init called";
155 [=](
const QString &batch) ->
void {
162void QtPass::connectPassSignalHandlers(
Pass *pass) {
163 connect(pass, &
Pass::error,
this, &QtPass::processError);
183 &QtPass::onKeyGenerationComplete);
189void QtPass::mountWebDav() {
193 memset(&netres, 0,
sizeof(netres));
194 netres.dwType = RESOURCETYPE_DISK;
195 netres.lpLocalName = 0;
197 DWORD size =
sizeof(dst);
198 DWORD r = WNetUseConnectionA(
199 reinterpret_cast<HWND
>(m_mainWindow->effectiveWinId()), &netres,
202 CONNECT_TEMPORARY | CONNECT_INTERACTIVE | CONNECT_REDIRECT, dst, &size,
207 char message[256] = {0};
208 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, r, 0, message,
210 m_mainWindow->
flashText(tr(
"Failed to connect WebDAV:\n") + message +
211 " (0x" + QString::number(r, 16) +
")",
215 fusedav.start(
"fusedav", QStringList()
222 fusedav.waitForStarted();
223 if (fusedav.state() == QProcess::Running) {
227 pwd = QInputDialog::getText(m_mainWindow, tr(
"QtPass WebDAV password"),
228 tr(
"Enter password to connect to WebDAV:"),
229 QLineEdit::Password,
"", &ok);
231 if (ok && !pwd.isEmpty()) {
232 fusedav.write(pwd.toUtf8() +
'\n');
233 fusedav.closeWriteChannel();
234 fusedav.waitForFinished(2000);
239 QString error = fusedav.readAllStandardError();
240 int prompt = error.indexOf(
"Password:");
242 error.remove(0, prompt + 10);
244 if (fusedav.state() != QProcess::Running) {
245 error = tr(
"fusedav exited unexpectedly\n") + error;
247 if (error.size() > 0) {
249 tr(
"Failed to start fusedav to connect WebDAV:\n") + error,
true);
258void QtPass::processError(QProcess::ProcessError error) {
261 case QProcess::FailedToStart:
262 errorString = tr(
"QProcess::FailedToStart");
264 case QProcess::Crashed:
265 errorString = tr(
"QProcess::Crashed");
267 case QProcess::Timedout:
268 errorString = tr(
"QProcess::Timedout");
270 case QProcess::ReadError:
271 errorString = tr(
"QProcess::ReadError");
273 case QProcess::WriteError:
274 errorString = tr(
"QProcess::WriteError");
276 case QProcess::UnknownError:
277 errorString = tr(
"QProcess::UnknownError");
281 m_mainWindow->
flashText(errorString,
true);
285void QtPass::processErrorExit(
int exitCode,
const QString &p_error) {
286 if (!p_error.isEmpty()) {
288 QString error = p_error.toHtmlEscaped();
291 output =
"<span style=\"color: darkgray;\">" + error +
"</span><br />";
293 output =
"<span style=\"color: red;\">" + error +
"</span><br />";
297 output.replace(QStringLiteral("\n"),
"<br />");
299 m_mainWindow->
flashText(output,
false,
true);
312void QtPass::processFinished(
const QString &p_output,
const QString &p_errout) {
313 showInTextBrowser(p_output);
316 processErrorExit(0, p_errout);
321void QtPass::passStoreChanged(
const QString &p_out,
const QString &p_err) {
322 processFinished(p_out, p_err);
326void QtPass::finishedInsert(
const QString &p_output,
const QString &p_errout) {
327 processFinished(p_output, p_errout);
332void QtPass::onKeyGenerationComplete(
const QString &p_output,
333 const QString &p_errout) {
336 qDebug() <<
"Keygen Done";
343 processFinished(p_output, p_errout);
346void QtPass::passShowHandlerFinished(QString output) {
347 showInTextBrowser(std::move(output));
350void QtPass::showInTextBrowser(QString output,
const QString &prefix,
351 const QString &postfix) {
352 output = output.toHtmlEscaped();
355 output.replace(QStringLiteral("\n"),
"<br />");
356 output = prefix + output + postfix;
358 m_mainWindow->
flashText(output,
false,
true);
361void QtPass::doGitPush() {
369 !p_output.isEmpty()) {
370 clippedText = password;
387 QClipboard *clipboard = QApplication::clipboard();
388 bool cleared =
false;
389 if (this->clippedText == clipboard->text(QClipboard::Selection)) {
390 clipboard->clear(QClipboard::Selection);
391 clipboard->setText(QString(
""), QClipboard::Selection);
394 if (this->clippedText == clipboard->text(QClipboard::Clipboard)) {
395 clipboard->clear(QClipboard::Clipboard);
412 QClipboard *clip = QApplication::clipboard();
414 clip->setText(text, QClipboard::Clipboard);
416 clip->setText(text, QClipboard::Selection);
422 clearClipboardTimer.start();
433 QStringList() <<
"-o-"
435 qrencode.write(text.toUtf8());
436 qrencode.closeWriteChannel();
437 qrencode.waitForFinished();
438 QByteArray output(qrencode.readAllStandardOutput());
440 if (qrencode.exitStatus() || qrencode.exitCode()) {
441 QString error(qrencode.readAllStandardError());
445 image.loadFromData(output,
"PNG");
447 auto *popup =
new QDialog(
nullptr, Qt::Popup | Qt::FramelessWindowHint);
448 auto *layout =
new QVBoxLayout;
449 auto *popupLabel =
new QLabel();
450 layout->addWidget(popupLabel);
451 popupLabel->setPixmap(image);
452 popupLabel->setScaledContents(
true);
454 popup->setLayout(layout);
455 popup->move(QCursor::pos());
void startReencryptPath()
The MainWindow class does way too much, not only is it a switchboard, configuration handler and more,...
void startReencryptPath()
MainWindow::startReencryptPath disable ui elements and treeview.
void passShowHandler(const QString &)
void endReencryptPath()
MainWindow::endReencryptPath re-enable ui elements.
void executeWrapperStarted()
void critical(const QString &, const QString &)
MainWindow::critical critical message popup wrapper.
void onPush()
MainWindow::onPush do a git push.
void showStatusMessage(const QString &msg, int timeout=2000)
Displays message in status bar.
void passOtpHandler(const QString &)
void passShowHandlerFinished(const QString &output)
void generateGPGKeyPair(const QString &batch)
void flashText(const QString &text, const bool isError, const bool isHtml=false)
void setUiElementsEnabled(bool state)
MainWindow::setUiElementsEnabled enable or disable the relevant UI elements.
auto getCurrentTreeViewIndex() -> QModelIndex
void on_treeView_clicked(const QModelIndex &index)
MainWindow::on_treeView_clicked read the selected password file.
auto getKeygenDialog() -> QDialog *
Acts as an abstraction for pass or pass imitation.
void startingExecuteWrapper()
void critical(const QString &, const QString &)
void finishedCopy(const QString &, const QString &)
void finishedShow(const QString &)
void finishedRemove(const QString &, const QString &)
void finishedMove(const QString &, const QString &)
void statusMsg(const QString &, int)
void finishedGitInit(const QString &, const QString &)
void finishedInsert(const QString &, const QString &)
void finishedInit(const QString &, const QString &)
void finishedOtpGenerate(const QString &)
void processErrorExit(int exitCode, const QString &err)
void finishedGitPull(const QString &, const QString &)
void finishedGitPush(const QString &, const QString &)
void error(QProcess::ProcessError)
void finishedGenerateGPGKeys(const QString &, const QString &)
void clearClipboard()
MainWindow::clearClipboard remove clipboard contents.
~QtPass()
QtPass::~QtPass destroy!
void setClippedText(const QString &, const QString &p_output=QString())
QtPass(MainWindow *mainWindow)
void copyTextToClipboard(const QString &text)
MainWindow::copyTextToClipboard copies text to your clipboard.
auto init() -> bool
QtPass::init make sure we are ready to go as soon as possible.
void showTextAsQRCode(const QString &text)
displays the text as qrcode
static auto isUseSelection(const bool &defaultValue=QVariant().toBool()) -> bool
static auto isUseAutoclear(const bool &defaultValue=QVariant().toBool()) -> bool
static void setAutoclearPanelSeconds(const int &autoClearPanelSeconds)
static auto getWebDavPassword(const QString &defaultValue=QVariant().toString()) -> QString
static auto getPwgenExecutable(const QString &defaultValue=QVariant().toString()) -> QString
static auto getWebDavUser(const QString &defaultValue=QVariant().toString()) -> QString
static void setPassStore(const QString &passStore)
static auto getPass() -> Pass *
static void setUsePwgen(const bool &usePwgen)
static auto getPassStore(const QString &defaultValue=QVariant().toString()) -> QString
static auto getVersion(const QString &defaultValue=QVariant().toString()) -> QString
static void initExecutables()
static void setPassTemplate(const QString &passTemplate)
static auto getQrencodeExecutable(const QString &defaultValue=QVariant().toString()) -> QString
static void setVersion(const QString &version)
static auto getRealPass() -> RealPass *
static auto getPassTemplate(const QString &defaultValue=QVariant().toString()) -> QString
static auto getClipBoardType(const Enums::clipBoardType &defaultvalue=Enums::CLIPBOARD_NEVER) -> Enums::clipBoardType
static auto getWebDavUrl(const QString &defaultValue=QVariant().toString()) -> QString
static auto isUseWebDav(const bool &defaultValue=QVariant().toBool()) -> bool
static auto getAutoclearPanelSeconds(const int &defaultValue=QVariant().toInt()) -> int
static void setAutoclearSeconds(const int &autoClearSeconds)
static auto getImitatePass() -> ImitatePass *
static auto getAutoclearSeconds(const int &defaultValue=QVariant().toInt()) -> int
static auto isAutoPush(const bool &defaultValue=QVariant().toBool()) -> bool
static auto protocolRegex() -> const QRegularExpression &
static auto findPasswordStore() -> QString
Util::findPasswordStore look for common .password-store folder location.
static auto checkConfig() -> bool
Util::checkConfig do we have prequisite settings?
constexpr int MS_PER_SECOND