Skip to content

Commit

Permalink
Add support for Edge history
Browse files Browse the repository at this point in the history
  • Loading branch information
Remy authored and RaymiiOrg committed Jan 16, 2024
1 parent 1238c9b commit 864f7fa
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 72 deletions.
3 changes: 2 additions & 1 deletion CertInfo.pro
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ QT += quick sql widgets quickcontrols2

QMAKE_CXXFLAGS = -Wno-deprecated-declarations

VERSION = 2024.01.1.0 # major.minor.patch.build
VERSION = 2024.01.2.0 # major.minor.patch.build
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
QMAKE_TARGET_PRODUCT = "CertInfo"
QMAKE_TARGET_COMPANY = "Sparkling Network"
Expand Down Expand Up @@ -64,6 +64,7 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
include(src/thirdparty/SortFilterProxyModel/SortFilterProxyModel.pri)

DISTFILES += \
README.md \
certinfo.ico


Expand Down
3 changes: 1 addition & 2 deletions src/+qt5/ImportHostsFileDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ FileDialog {
required property var db
required property var txt
id: root
title: isTextFile ? "Choose a txt file with one domain per line" : isFirefox ? "Please choose the Firefox places.sqlite file" : "Please choose the Chrome History file"
title: isTextFile ? "Choose a txt file with one domain per line" : isFirefox ? "Please choose the Firefox places.sqlite file" : "Please choose the Chrome/Edge History file"
nameFilters: isTextFile ? [ "text file (*.txt)", "All files (*)" ] : isFirefox ? [ "places.sqlite (places.sqlite)", "All files (*)" ] : [ "History (History)", "All files (*)" ]
folder: shortcuts.home
onAccepted: {
Expand All @@ -24,5 +24,4 @@ FileDialog {
}
}
}
Component.onCompleted: console.log("Using Qt 5 FileDialog")
}
3 changes: 1 addition & 2 deletions src/+qt6/ImportHostsFileDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ FileDialog {
required property var db
required property var txt
id: root
title: isTextFile ? "Choose a txt file with one domain per line" : isFirefox ? "Please choose the Firefox places.sqlite file" : "Please choose the Chrome History file"
title: isTextFile ? "Choose a txt file with one domain per line" : isFirefox ? "Please choose the Firefox places.sqlite file" : "Please choose the Chrome/Edge History file"
nameFilters: isTextFile ? [ "text file (*.txt)", "All files (*)" ] : isFirefox ? [ "places.sqlite (places.sqlite)", "All files (*)" ] : [ "History (History)", "All files (*)" ]
onAccepted: {
txt.hostnames = ""
Expand All @@ -23,5 +23,4 @@ FileDialog {
}
}
}
Component.onCompleted: console.log("Using Qt 6 FileDialog")
}
34 changes: 17 additions & 17 deletions src/listmodel/caissuerlistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,28 @@

CACertificateListModel::CACertificateListModel(QObject* parent) : GenericListModel<Certificate>(parent)
{
addValueSelector("subject", [](const Certificate &i) { return i.subject; });
addValueSelector("subjectInfo", [](const Certificate &i) { return QVariant::fromValue(i.subjectInfo); });
addValueSelector("string", [](const Certificate &i) { return QString::fromStdString(i.toString()); });
addValueSelector("issuer", [](const Certificate &i) { return i.issuer; });
addValueSelector("issuerInfo", [](const Certificate &i) { return QVariant::fromValue(i.issuerInfo); });
addValueSelector("validFromDate", [](const Certificate &i) { return i.validFromDate.toString(); });
addValueSelector("validUntilDate", [](const Certificate &i) { return i.validUntilDate.toString(); });
addValueSelector("count", [](const Certificate &i) { return i.count; });
addValueSelector("isca", [](const Certificate &i) { return i.isCA; });
addValueSelector("istrustedrootca", [](const Certificate &i) { return i.isSystemTrustedRootCA; });
addValueSelector("domains", [](const Certificate &i) { return i.domains.join(" "); });
addValueSelector("subjectAlternativeNames", [](const Certificate &i) { return i.subjectAlternativeNames.join(" "); });
addValueSelector("isselfsigned", [](const Certificate &i) { return i.isSelfSigned; });
addValueSelector("errors", [](const Certificate &i) { return i.errors.join(" "); });
addSelector("subject", [](const Certificate &i) { return i.subject; });
addSelector("subjectInfo", [](const Certificate &i) { return QVariant::fromValue(i.subjectInfo); });
addSelector("string", [](const Certificate &i) { return QString::fromStdString(i.toString()); });
addSelector("issuer", [](const Certificate &i) { return i.issuer; });
addSelector("issuerInfo", [](const Certificate &i) { return QVariant::fromValue(i.issuerInfo); });
addSelector("validFromDate", [](const Certificate &i) { return i.validFromDate.toString(); });
addSelector("validUntilDate", [](const Certificate &i) { return i.validUntilDate.toString(); });
addSelector("count", [](const Certificate &i) { return i.count; });
addSelector("isca", [](const Certificate &i) { return i.isCA; });
addSelector("istrustedrootca", [](const Certificate &i) { return i.isSystemTrustedRootCA; });
addSelector("domains", [](const Certificate &i) { return i.domains.join(" "); });
addSelector("subjectAlternativeNames", [](const Certificate &i) { return i.subjectAlternativeNames.join(" "); });
addSelector("isselfsigned", [](const Certificate &i) { return i.isSelfSigned; });
addSelector("errors", [](const Certificate &i) { return i.errors.join(" "); });
}

void CACertificateListModel::addOrUpdateItem(const Certificate &item, const QString& findBySubject)
{
auto it = std::find_if(_listObjects.begin(), _listObjects.end(), [&findBySubject](const Certificate& c){ return c.subject == findBySubject;});
if(it != _listObjects.end())
auto it = std::find_if(m_listObjects.begin(), m_listObjects.end(), [&findBySubject](const Certificate& c){ return c.subject == findBySubject;});
if(it != m_listObjects.end())
{
int index = std::distance(_listObjects.begin(), it);
int index = std::distance(m_listObjects.begin(), it);
updateRow(index, item);
} else {
addRow(item);
Expand Down
4 changes: 2 additions & 2 deletions src/listmodel/domaincountlistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@

domainCountListModel::domainCountListModel(QObject* parent) : GenericListModel<QIntPair>(parent)
{
addValueSelector("domain", [](const QIntPair &m) { return m.first; });
addValueSelector("count", [](const QIntPair &m) { return m.second; });
addSelector("domain", [](const QIntPair &m) { return m.first; });
addSelector("count", [](const QIntPair &m) { return m.second; });
}
81 changes: 40 additions & 41 deletions src/listmodel/genericlistmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,29 @@ class GenericListModel : public QAbstractListModelWithRowCountSignal
int rowCount(const QModelIndex &parent = QModelIndex()) const override;

virtual void move(int from, int to);
int addValueSelector(QByteArray name, std::function<QVariant(const TObject &, const QModelIndex &)> valueSelector);
int addValueSelector(QByteArray name, std::function<QVariant(const TObject &)> valueSelector);
int addValueSelector(QByteArray name, std::function<QVariant(const TObject &)> valueSelector, std::function<bool(TObject &, QVariant)> valueSetter);
int addValueSelector(QByteArray name, std::function<QVariant(const TObject &, const QModelIndex &)> valueSelector, std::function<bool(TObject &, QVariant)> valueSetter);
int addSelector(QByteArray name, std::function<QVariant(const TObject &, const QModelIndex &)> selector);
int addSelector(QByteArray name, std::function<QVariant(const TObject &)> selector);
int addSelector(QByteArray name, std::function<QVariant(const TObject &)> selector, std::function<bool(TObject &, QVariant)> valueSetter);
int addSelector(QByteArray name, std::function<QVariant(const TObject &, const QModelIndex &)> selector, std::function<bool(TObject &, QVariant)> valueSetter);
QVariant dataByRoleName(const QModelIndex &index, const QString &name) const;
void resync();
int getRoleIdByName(const QString &name) const;
QVariantMap getRowByField(const QString &fieldName, const QVariant &value) const;

protected:
QList<TObject> _listObjects;
QMap<int, QPair<QByteArray, std::function<QVariant(const TObject &, const QModelIndex &)>>> _valueSelectorMap;
QMap<int, QPair<QByteArray, std::function<bool(TObject &, QVariant)>>> _valueSetterMap;
QList<TObject> m_listObjects;
QMap<int, QPair<QByteArray, std::function<QVariant(const TObject &, const QModelIndex &)>>> m_selectors;
QMap<int, QPair<QByteArray, std::function<bool(TObject &, QVariant)>>> m_valueSetters;
};

template <typename TObject>
void GenericListModel<TObject>::updateFromVector(const std::vector<TObject> &newObjects)
{
beginResetModel();
_listObjects.clear();
m_listObjects.clear();
for (const TObject &item : newObjects)
{
_listObjects << item;
m_listObjects << item;
}
endResetModel();
}
Expand All @@ -72,23 +72,23 @@ template <typename TObject>
void GenericListModel<TObject>::updateFromQList(const QList<TObject> &newObjects)
{
beginResetModel();
_listObjects = newObjects;
m_listObjects = newObjects;
endResetModel();
}

template <typename TObject>
void GenericListModel<TObject>::clear()
{
beginResetModel();
_listObjects.clear();
m_listObjects.clear();
endResetModel();
}

template <typename TObject>
QHash<int, QByteArray> GenericListModel<TObject>::roleNames() const
{
QHash<int, QByteArray> roles;
for (auto it = _valueSelectorMap.begin(); it != _valueSelectorMap.end(); ++it)
for (auto it = m_selectors.begin(); it != m_selectors.end(); ++it)
{
roles[it.key()] = it->first;
}
Expand All @@ -103,10 +103,10 @@ QVariant GenericListModel<TObject>::data(const QModelIndex &index, int role) con
return QVariant();
}

const TObject &object = _listObjects[index.row()];
auto valueSelectorIterator = _valueSelectorMap.find(role);
if (valueSelectorIterator != _valueSelectorMap.end())
return valueSelectorIterator->second(object, index);
const TObject &object = m_listObjects[index.row()];
auto selectorIterator = m_selectors.find(role);
if (selectorIterator != m_selectors.end())
return selectorIterator->second(object, index);
return QVariant();
}

Expand All @@ -117,9 +117,9 @@ bool GenericListModel<TObject>::setData(const QModelIndex &index, const QVariant
return false;

bool result = false;
TObject &object = _listObjects[index.row()];
auto valueSetterIterator = _valueSetterMap.find(role);
if (valueSetterIterator != _valueSetterMap.end())
TObject &object = m_listObjects[index.row()];
auto valueSetterIterator = m_valueSetters.find(role);
if (valueSetterIterator != m_valueSetters.end())
{
result = valueSetterIterator->second(object, value);
if (result)
Expand All @@ -135,45 +135,44 @@ int GenericListModel<TObject>::rowCount(const QModelIndex &index) const
{
return 0;
}
return _listObjects.count();
return m_listObjects.count();
}

template <typename TObject>
void GenericListModel<TObject>::move(int from, int to)
{
_listObjects.move(from, to);
m_listObjects.move(from, to);

}

template <typename TObject>
int GenericListModel<TObject>::addValueSelector(QByteArray name, std::function<QVariant(const TObject &)> valueSelector)
int GenericListModel<TObject>::addSelector(QByteArray name, std::function<QVariant(const TObject &)> selector)
{
// std::bind ignores extra arguments, (I.E. QModelIndex)
std::function<QVariant(TObject, const QModelIndex &)> newValueSelector = std::bind(valueSelector, std::placeholders::_1);
return addValueSelector(name, newValueSelector);
std::function<QVariant(TObject, const QModelIndex &)> newselector = std::bind(selector, std::placeholders::_1);
return addSelector(name, newselector);
}

template <typename TObject>
int GenericListModel<TObject>::addValueSelector(QByteArray name, std::function<QVariant(const TObject &)> valueSelector, std::function<bool(TObject &, QVariant)> valueSetter)
int GenericListModel<TObject>::addSelector(QByteArray name, std::function<QVariant(const TObject &)> selector, std::function<bool(TObject &, QVariant)> valueSetter)
{
int roleNumber = addValueSelector(name, valueSelector);
_valueSetterMap[roleNumber] = QPair<QByteArray, std::function<bool(TObject &, QVariant)>> {name, valueSetter};
int roleNumber = addSelector(name, selector);
m_valueSetters[roleNumber] = QPair<QByteArray, std::function<bool(TObject &, QVariant)>> {name, valueSetter};
return roleNumber;
}

template <typename TObject>
int GenericListModel<TObject>::addValueSelector(QByteArray name, std::function<QVariant(const TObject &, const QModelIndex &)> valueSelector, std::function<bool(TObject &, QVariant)> valueSetter)
int GenericListModel<TObject>::addSelector(QByteArray name, std::function<QVariant(const TObject &, const QModelIndex &)> selector, std::function<bool(TObject &, QVariant)> valueSetter)
{
int roleNumber = addValueSelector(name, valueSelector);
_valueSetterMap[roleNumber] = QPair<QByteArray, std::function<bool(TObject &, QVariant)>> {name, valueSetter};
int roleNumber = addSelector(name, selector);
m_valueSetters[roleNumber] = QPair<QByteArray, std::function<bool(TObject &, QVariant)>> {name, valueSetter};
return roleNumber;
}

template <typename TObject>
int GenericListModel<TObject>::addValueSelector(QByteArray name, std::function<QVariant(const TObject &, const QModelIndex &)> valueSelector)
int GenericListModel<TObject>::addSelector(QByteArray name, std::function<QVariant(const TObject &, const QModelIndex &)> selector)
{
int roleNumber = Qt::UserRole + _valueSelectorMap.size() + 1;
_valueSelectorMap[roleNumber] = QPair<QByteArray, std::function<QVariant(TObject, const QModelIndex &)>> {name, valueSelector};
int roleNumber = Qt::UserRole + m_selectors.size() + 1;
m_selectors[roleNumber] = QPair<QByteArray, std::function<QVariant(TObject, const QModelIndex &)>> {name, selector};
return roleNumber;
}

Expand All @@ -185,8 +184,8 @@ QVariant GenericListModel<TObject>::dataByRoleName(const QModelIndex &index, con
return QVariant();
}

const TObject &object = _listObjects[index.row()];
for (const QPair<QByteArray, std::function<QVariant(const TObject &, const QModelIndex &)>> &mapEntry : _valueSelectorMap)
const TObject &object = m_listObjects[index.row()];
for (const QPair<QByteArray, std::function<QVariant(const TObject &, const QModelIndex &)>> &mapEntry : m_selectors)
{
if (mapEntry.first == roleName)
return mapEntry.second(object, index);
Expand All @@ -198,27 +197,27 @@ template <typename TObject>
void GenericListModel<TObject>::resync()
{
std::vector<TObject> copiedListObjects;
std::copy(_listObjects.begin(), _listObjects.end(), std::back_inserter(copiedListObjects));
std::copy(m_listObjects.begin(), m_listObjects.end(), std::back_inserter(copiedListObjects));
updateFromVector(copiedListObjects);
}


template <typename TObject>
void GenericListModel<TObject>::addRow(const TObject& newRow)
{
auto size = _listObjects.size();
auto size = m_listObjects.size();
emit beginInsertRows(QModelIndex(), size, size);
_listObjects.push_back(newRow);
m_listObjects.push_back(newRow);
emit endInsertRows();
}


template <typename TObject>
void GenericListModel<TObject>::updateRow(int rowNr, const TObject& newRow)
{
if (rowNr >= _listObjects.size())
if (rowNr >= m_listObjects.size())
return;
_listObjects[rowNr] = newRow;
m_listObjects[rowNr] = newRow;
emit dataChanged(index(rowNr), index(rowNr));
}

Expand Down
23 changes: 16 additions & 7 deletions src/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Window {
anchors.margins: 5
width: 300
enabled: !proc.busy
text: "Open Firefox History file (places.sqlite)"
text: "Open Firefox History file "
onClicked: firefoxFileDialog.open()
}

Expand All @@ -126,7 +126,7 @@ Window {
anchors.margins: 5
width: 300
enabled: !proc.busy
text: "Open Chrome History file (history)"
text: "Open Chrome/Edge History file"
onClicked: chromeFileDialog.open()
}

Expand Down Expand Up @@ -583,17 +583,29 @@ Under the `Application Basics` section next to `Profile Folder`, click `Open Fol
<hr/>
# Where is my chrome history?
# Where is my Chrome history?
The path to your Chrome profile folder which contains the history file
named `history` (no extension) is: `%LOCALAPPDATA%\Google\Chrome\User Data`.
named `History` (no extension) is: `%LOCALAPPDATA%\Google\Chrome\User Data\Default`.
Via Chrome you can navigate to `chrome://version`, then look for
the `Profile Path`
# Where is my Edge history
Since Edge is based on Chrome, the file format is the same. The
`History` file is located here:
`%LOCALAPPDATA%\Microsoft\Edge\User Data\Default`
Please note that old versions of Edge (not based on Chrome)
are not supported.
# A list of domains
Expand Down Expand Up @@ -789,9 +801,6 @@ GNU Lesser General Public License v2.1
]
}

// ADD SYSTEM ROOT CA LIST AND REMOVE ALL FOUND CERTS,
// LEAVING ONLY A LIST OF UNUSED ROOT CA'S

DomainsListTextFile {
id: txt
}
Expand Down

0 comments on commit 864f7fa

Please sign in to comment.