Skip to content

Commit 0f0069c

Browse files
committed
#3484 homepage: add security token
Signed-off-by: Patrizio Bekerle <patrizio@bekerle.com>
1 parent 37e1501 commit 0f0069c

File tree

9 files changed

+650
-478
lines changed

9 files changed

+650
-478
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## 26.3.10
44

5+
- Added a security token setting for the Homepage-compatible bookmark
6+
suggestion API (with encrypted storage, settings dump masking, and
7+
token-validated `GET /suggest` requests), and updated Homepage
8+
integration docs (`custom.js`) to append the token query parameter
9+
(for [#3484](https://github.com/pbek/QOwnNotes/issues/3484))
510
- Improved portal handle token generation compatibility for older Qt5
611
distributions (e.g. Debian 9.0, SLE 15) by using `QUuid` on Qt5 and
712
keeping `QRandomGenerator` on Qt6 builds

docs/homepage/custom.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
Tune behavior with:
1414
- QON_URL: QOwnNotes suggestion endpoint
15+
- QON_TOKEN: security token configured in QOwnNotes settings
1516
- QON_LIMIT: number of QOwnNotes suggestions to request
1617
- QON_LABEL: marker shown in UI for QOwnNotes items
1718
- DEBUG: set true to print debug logs
@@ -21,6 +22,7 @@
2122
"use strict";
2223

2324
const QON_URL = "http://127.0.0.1:22224/suggest?q=";
25+
const QON_TOKEN = "";
2426
const QON_LIMIT = 20;
2527
const QON_LABEL = "[QON] ";
2628
const BLOCK_QON_TEXT_SEARCH = "__QON_BLOCK_TEXT_SEARCH__";
@@ -107,8 +109,11 @@
107109

108110
async function fetchQown(query) {
109111
try {
112+
const tokenPart = QON_TOKEN
113+
? `&token=${encodeURIComponent(QON_TOKEN)}`
114+
: "";
110115
const r = await origFetch(
111-
`${QON_URL}${encodeURIComponent(query)}&limit=${QON_LIMIT}`,
116+
`${QON_URL}${encodeURIComponent(query)}&limit=${QON_LIMIT}${tokenPart}`,
112117
);
113118
const txt = await r.text();
114119
const j = JSON.parse(txt);

src/dialogs/settingsdialog.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ SettingsDialog::SettingsDialog(int page, QWidget *parent)
174174
connect(ui->enableSocketServerCheckBox, SIGNAL(toggled(bool)), this, SLOT(needRestart()));
175175
connect(ui->bookmarkSuggestionApiEnabledCheckBox, SIGNAL(toggled(bool)), this,
176176
SLOT(needRestart()));
177+
connect(ui->bookmarkSuggestionApiTokenLineEdit, SIGNAL(textChanged(QString)), this,
178+
SLOT(needRestart()));
177179
connect(ui->enableWebApplicationCheckBox, SIGNAL(toggled(bool)), this, SLOT(needRestart()));
178180
connect(ui->enableNoteTreeCheckBox, SIGNAL(toggled(bool)), this, SLOT(needRestart()));
179181
connect(ui->aiAutocompleteCheckBox, SIGNAL(toggled(bool)), this, SLOT(needRestart()));
@@ -787,6 +789,13 @@ void SettingsDialog::storeSettings() {
787789
ui->bookmarkSuggestionApiEnabledCheckBox->isChecked());
788790
settings.setValue(QStringLiteral("webSocketServerService/bookmarkSuggestionApiPort"),
789791
ui->bookmarkSuggestionApiPortSpinBox->value());
792+
QString bookmarkSuggestionApiToken = ui->bookmarkSuggestionApiTokenLineEdit->text().trimmed();
793+
if (bookmarkSuggestionApiToken.isEmpty()) {
794+
bookmarkSuggestionApiToken = Utils::Misc::generateRandomString(32);
795+
ui->bookmarkSuggestionApiTokenLineEdit->setText(bookmarkSuggestionApiToken);
796+
}
797+
settings.setValue(QStringLiteral("webSocketServerService/bookmarkSuggestionApiToken"),
798+
CryptoService::instance()->encryptToString(bookmarkSuggestionApiToken));
790799
settings.setValue(QStringLiteral("webSocketServerService/bookmarksTag"),
791800
ui->bookmarksTagLineEdit->text());
792801
settings.setValue(QStringLiteral("webSocketServerService/bookmarksNoteName"),
@@ -1296,6 +1305,8 @@ void SettingsDialog::readSettings() {
12961305
WebSocketServerService::isBookmarkSuggestionApiEnabled());
12971306
ui->bookmarkSuggestionApiPortSpinBox->setValue(
12981307
WebSocketServerService::getBookmarkSuggestionApiPort());
1308+
ui->bookmarkSuggestionApiTokenLineEdit->setText(
1309+
WebSocketServerService::getOrGenerateBookmarkSuggestionApiToken());
12991310
on_bookmarkSuggestionApiEnabledCheckBox_toggled(
13001311
ui->bookmarkSuggestionApiEnabledCheckBox->isChecked());
13011312
ui->bookmarksTagLineEdit->setText(WebSocketServerService::getBookmarksTag());
@@ -4242,13 +4253,34 @@ void SettingsDialog::on_bookmarkSuggestionApiEnabledCheckBox_toggled(bool checke
42424253
ui->bookmarkSuggestionApiPortLabel->setEnabled(checked);
42434254
ui->bookmarkSuggestionApiPortSpinBox->setEnabled(checked);
42444255
ui->bookmarkSuggestionApiPortResetButton->setEnabled(checked);
4256+
ui->bookmarkSuggestionApiTokenLabel->setEnabled(checked);
4257+
ui->bookmarkSuggestionApiTokenLineEdit->setEnabled(checked);
4258+
ui->bookmarkSuggestionApiShowTokenButton->setEnabled(checked);
4259+
ui->bookmarkSuggestionApiCopyTokenButton->setEnabled(checked);
4260+
ui->bookmarkSuggestionApiGenerateTokenButton->setEnabled(checked);
42454261
}
42464262

42474263
void SettingsDialog::on_bookmarkSuggestionApiPortResetButton_clicked() {
42484264
ui->bookmarkSuggestionApiPortSpinBox->setValue(
42494265
WebSocketServerService::getBookmarkSuggestionApiDefaultPort());
42504266
}
42514267

4268+
void SettingsDialog::on_bookmarkSuggestionApiShowTokenButton_clicked() {
4269+
ui->bookmarkSuggestionApiTokenLineEdit->setEchoMode(
4270+
ui->bookmarkSuggestionApiTokenLineEdit->echoMode() == QLineEdit::EchoMode::Password
4271+
? QLineEdit::EchoMode::Normal
4272+
: QLineEdit::EchoMode::Password);
4273+
}
4274+
4275+
void SettingsDialog::on_bookmarkSuggestionApiCopyTokenButton_clicked() {
4276+
QApplication::clipboard()->setText(ui->bookmarkSuggestionApiTokenLineEdit->text());
4277+
}
4278+
4279+
void SettingsDialog::on_bookmarkSuggestionApiGenerateTokenButton_clicked() {
4280+
ui->bookmarkSuggestionApiTokenLineEdit->setText(Utils::Misc::generateRandomString(32));
4281+
ui->bookmarkSuggestionApiTokenLineEdit->setEchoMode(QLineEdit::EchoMode::Normal);
4282+
}
4283+
42524284
void SettingsDialog::on_internalIconThemeCheckBox_toggled(bool checked) {
42534285
if (checked) {
42544286
const QSignalBlocker blocker(ui->systemIconThemeCheckBox);

src/dialogs/settingsdialog.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ class SettingsDialog : public MasterDialog {
267267

268268
void on_bookmarkSuggestionApiPortResetButton_clicked();
269269

270+
void on_bookmarkSuggestionApiShowTokenButton_clicked();
271+
272+
void on_bookmarkSuggestionApiCopyTokenButton_clicked();
273+
274+
void on_bookmarkSuggestionApiGenerateTokenButton_clicked();
275+
270276
void on_internalIconThemeCheckBox_toggled(bool checked);
271277

272278
void on_systemIconThemeCheckBox_toggled(bool checked);

src/dialogs/settingsdialog.ui

Lines changed: 86 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6824,13 +6824,13 @@ Just test yourself if you get sync conflicts and set a higher value if so.</stri
68246824
<property name="title">
68256825
<string>Bookmark suggestion API</string>
68266826
</property>
6827-
<layout class="QGridLayout" name="gridLayout_96">
6828-
<item row="0" column="0" colspan="3">
6829-
<widget class="QCheckBox" name="bookmarkSuggestionApiEnabledCheckBox">
6830-
<property name="text">
6831-
<string>Enable Homepage-compatible bookmark suggestions API</string>
6832-
</property>
6833-
</widget>
6827+
<layout class="QGridLayout" name="gridLayout_96">
6828+
<item row="0" column="0" colspan="6">
6829+
<widget class="QCheckBox" name="bookmarkSuggestionApiEnabledCheckBox">
6830+
<property name="text">
6831+
<string>Enable Homepage-compatible bookmark suggestions API</string>
6832+
</property>
6833+
</widget>
68346834
</item>
68356835
<item row="1" column="0">
68366836
<widget class="QLabel" name="bookmarkSuggestionApiPortLabel">
@@ -6852,23 +6852,88 @@ Just test yourself if you get sync conflicts and set a higher value if so.</stri
68526852
</property>
68536853
</widget>
68546854
</item>
6855-
<item row="1" column="2">
6856-
<widget class="QToolButton" name="bookmarkSuggestionApiPortResetButton">
6857-
<property name="toolTip">
6858-
<string>Reset the suggestion API port</string>
6855+
<item row="1" column="2">
6856+
<widget class="QToolButton" name="bookmarkSuggestionApiPortResetButton">
6857+
<property name="toolTip">
6858+
<string>Reset the suggestion API port</string>
68596859
</property>
68606860
<property name="text">
68616861
<string notr="true">…</string>
68626862
</property>
68636863
<property name="icon">
68646864
<iconset theme="edit-clear" resource="../breeze-qownnotes.qrc">
68656865
<normaloff>:/icons/breeze-qownnotes/16x16/edit-clear.svg</normaloff>:/icons/breeze-qownnotes/16x16/edit-clear.svg</iconset>
6866-
</property>
6867-
</widget>
6868-
</item>
6869-
</layout>
6870-
</widget>
6871-
</item>
6866+
</property>
6867+
</widget>
6868+
</item>
6869+
<item row="2" column="0">
6870+
<widget class="QLabel" name="bookmarkSuggestionApiTokenLabel">
6871+
<property name="text">
6872+
<string>Security token:</string>
6873+
</property>
6874+
</widget>
6875+
</item>
6876+
<item row="2" column="1" colspan="2">
6877+
<widget class="QLineEdit" name="bookmarkSuggestionApiTokenLineEdit">
6878+
<property name="toolTip">
6879+
<string>If this is empty when saved, a new security token will be generated automatically.</string>
6880+
</property>
6881+
<property name="maxLength">
6882+
<number>32</number>
6883+
</property>
6884+
<property name="readOnly">
6885+
<bool>false</bool>
6886+
</property>
6887+
<property name="echoMode">
6888+
<enum>QLineEdit::EchoMode::Password</enum>
6889+
</property>
6890+
</widget>
6891+
</item>
6892+
<item row="2" column="3">
6893+
<widget class="QToolButton" name="bookmarkSuggestionApiShowTokenButton">
6894+
<property name="toolTip">
6895+
<string>Show security token</string>
6896+
</property>
6897+
<property name="text">
6898+
<string notr="true">…</string>
6899+
</property>
6900+
<property name="icon">
6901+
<iconset theme="document-decrypt" resource="../breeze-qownnotes.qrc">
6902+
<normaloff>:/icons/breeze-qownnotes/16x16/document-decrypt.svg</normaloff>:/icons/breeze-qownnotes/16x16/document-decrypt.svg</iconset>
6903+
</property>
6904+
</widget>
6905+
</item>
6906+
<item row="2" column="4">
6907+
<widget class="QToolButton" name="bookmarkSuggestionApiCopyTokenButton">
6908+
<property name="toolTip">
6909+
<string>Copy security token to clipboard</string>
6910+
</property>
6911+
<property name="text">
6912+
<string notr="true">…</string>
6913+
</property>
6914+
<property name="icon">
6915+
<iconset theme="edit-copy" resource="../breeze-qownnotes.qrc">
6916+
<normaloff>:/icons/breeze-qownnotes/16x16/edit-copy.svg</normaloff>:/icons/breeze-qownnotes/16x16/edit-copy.svg</iconset>
6917+
</property>
6918+
</widget>
6919+
</item>
6920+
<item row="2" column="5">
6921+
<widget class="QToolButton" name="bookmarkSuggestionApiGenerateTokenButton">
6922+
<property name="toolTip">
6923+
<string>Generate new security token</string>
6924+
</property>
6925+
<property name="text">
6926+
<string notr="true">…</string>
6927+
</property>
6928+
<property name="icon">
6929+
<iconset theme="view-refresh" resource="../breeze-qownnotes.qrc">
6930+
<normaloff>:/icons/breeze-qownnotes/16x16/view-refresh.svg</normaloff>:/icons/breeze-qownnotes/16x16/view-refresh.svg</iconset>
6931+
</property>
6932+
</widget>
6933+
</item>
6934+
</layout>
6935+
</widget>
6936+
</item>
68726937
</layout>
68736938
</widget>
68746939
</item>
@@ -7818,6 +7883,10 @@ Just test yourself if you get sync conflicts and set a higher value if so.</stri
78187883
<tabstop>bookmarkSuggestionApiEnabledCheckBox</tabstop>
78197884
<tabstop>bookmarkSuggestionApiPortSpinBox</tabstop>
78207885
<tabstop>bookmarkSuggestionApiPortResetButton</tabstop>
7886+
<tabstop>bookmarkSuggestionApiTokenLineEdit</tabstop>
7887+
<tabstop>bookmarkSuggestionApiShowTokenButton</tabstop>
7888+
<tabstop>bookmarkSuggestionApiCopyTokenButton</tabstop>
7889+
<tabstop>bookmarkSuggestionApiGenerateTokenButton</tabstop>
78217890
<tabstop>webSocketServerServicePortSpinBox</tabstop>
78227891
<tabstop>webSocketServerServicePortResetButton</tabstop>
78237892
<tabstop>webSocketTokenButton</tabstop>

0 commit comments

Comments
 (0)